The tool delivered to localize strings apply only on files named xxx.strings but, as nothing is really simple with Apple, some strings are stored in files named yyy.js.
In High Sierra there are several sets of resources using this format:
Macintosh HD:Applications:Safari.app: table:localizedStrings.js
Macintosh HD:Library:Widgets:Calculator.wdgt: table:localizedStrings.js
Macintosh HD:Library:Widgets:Calendar.wdgt: table:localizedStrings.js
Macintosh HD:Library:Widgets:Contacts.wdgt: table:localizedStrings.js
Macintosh HD:Library:Widgets:Dictionary.wdgt: table:localizedStrings.js
Macintosh HD:Library:Widgets:Stickies.wdgt: table:localizedStrings.js
Macintosh HD:Library:Widgets:Stocks.wdgt: table:localizedStrings.js
Macintosh HD:Library:Widgets:Unit Converter.wdgt: table:localizedStrings.js
Macintosh HD:Library:Widgets:Weather.wdgt: table:localizedStrings.js
Macintosh HD:Library:Widgets:Web Clip.wdgt: table:localizedStrings.js
Macintosh HD:Library:Widgets:World Clock.wdgt: table:localizedStrings.js
Macintosh HD:System:Library:CoreServices:HelpViewer.app: table:localizedStrings.js
Macintosh HD:System:Library:Frameworks:WebKit.framework:Versions:A:Frameworks:WebCore.framework: table:mediaControlsLocalizedStrings.js
Macintosh HD:System:Library:Frameworks:WebKit.framework:Versions:A:Frameworks:WebCore.framework: table:modern-media-controls-localized-strings.js
Macintosh HD:System:Library:PrivateFrameworks:Safari.framework: table:localizedStrings.js
Macintosh HD:System:Library:PrivateFrameworks:SafariShared.framework: table:WBSLocalizedStrings.js don’t ask what need for this ‘special’ name
Macintosh HD:System:Library:PrivateFrameworks:WebInspectorUI.framework: table:localizedStrings.js
Macintosh HD:Library:Widgets:Movies.wdgt: table:localizedStrings.js
For this late one, in High Sierra there is only an English file so it’s not really useful.
As imagination of Apple engineers has no limit, they use (at least) four different syntaxes and two encodings utf8 or ut16.
Below is a script supposed to extract localized strings from these different formats.
----------------------------------------------------------------
use AppleScript version "2.5"
use framework "Foundation"
use scripting additions
----------------------------------------------------------------
-- localize strings defined in yyy.js files
-- use quote & ":"
set key_loc1 to my shared((path to library folder from system domain as text) & "Frameworks:WebKit.framework:Versions:A:Frameworks:WebCore.framework:Versions:A:Resources:", "Display Picture in Picture")
-- use "':"
set key_loc2 to my shared((path to library folder from system domain as text) & "Frameworks:WebKit.framework:Versions:A:Frameworks:WebCore.framework:Versions:A:Resources:", "This video is playing in picture in picture.")
-- use quote & "]"
set key_loc3 to my shared((path to applications folder as text) & "Safari.app:Contents:Resources:", "Updates are available for one or more of your extensions. To install an update, click its Update button.")
-- use "']"
set key_loc4 to my shared((path to library folder from local domain as text) & "Widgets:Contacts.wdgt:", "No Matching Cards")
-- use "']"
set key_loc5 to my shared((path to library folder from local domain as text) & "Widgets:Contacts.wdgt:", "McCoy Tyner")
{key_loc1, key_loc2, key_loc3, key_loc4, key_loc5}
#=====
on shared(begPath, theKey)
if begPath contains ":WebKit.framework:" then
set tableNames to {"modern-media-controls-localized-strings.js", "mediaControlsLocalizedStrings.js"}
else if begPath contains ":Safari.framework:" then
set tableNames to {"WBSLocalizedStrings.js"}
else
set tableNames to {"localizedStrings.js"}
end if
repeat with tableName in tableNames
set key_loc to (my localize:theKey fromTable:tableName inBundle:begPath)
if key_loc is not missing value then exit repeat
end repeat
if key_loc is missing value then set key_loc to "the key “" & theKey & "” is unavaible in this file!"
return key_loc
end shared
#=====
on localize:the_Key fromTable:theTable inBundle:begPath
set thisLocale to current application's NSLocale's currentLocale()
set langX to thisLocale's localeIdentifier as string --> "fr_FR"
set lang2 to text 1 thru 2 of langX
if langX starts with "zh_Hans" then # "zh-Hans"
set path2lproj to begPath & "zh_CN.lproj"
else if langX starts with "zh_Hant" then # "zh-Hant"
set path2lproj to begPath & "zh_TW.lproj"
else if langX starts with "pt_PT" then -- "pt_PT"
set path2lproj to begPath & "pt_PT.lproj"
else if langX starts with "pt_BR" then -- "pt_BR"
set path2lproj to begPath & "pt_BR.lproj"
else if lang2 is in {"ar", "ca", "cs", "da", "el", "fi", "he", "hr", "hu", "id", "ko", "ms", "pl", "pt", "ro", "ru", "sk", "sv", "th", "tr", "uk", "vi"} then
set path2lproj to begPath & lang2 & ".lproj"
else if lang2 is "de" then # {"de", "de-AT", "de-CH"}
set path2lproj to begPath & "German.lproj"
else if lang2 is "en" then # {"en", "en_AU", "en_CA", "en_GB", "en_US"}
set path2lproj to begPath & "English.lproj"
else if lang2 is "es" then # {"es", "es_419", "es_ES", "es_MX"}
set path2lproj to begPath & "Spanish.lproj"
else if lang2 is "fr" then # {"fr_FR", "fr_CA", "fr_CH"}
tell application "System Events"
if exists folder (begPath & "French.lproj") then
set path2lproj to begPath & "French.lproj"
else
set path2lproj to begPath & "fr.lproj"
end if
end tell
else if lang2 is "it" then
set path2lproj to begPath & "Italian.lproj"
else if lang2 is "ja" then
set path2lproj to begPath & "Japanese.lproj"
else if lang2 is "nb" then
set path2lproj to begPath & "no.lproj"
else if lang2 is "nl" then # {"nl", "nl_BE"}
set path2lproj to begPath & "Dutch.lproj"
end if
set theFile to (path2lproj & ":" & theTable) as «class furl»
try
set itsText to read theFile as «class utf8»
on error
set itsText to read theFile as «class ut16»
end try
set theTable to contents of theTable -- must deref
if theTable is "modern-media-controls-localized-strings.js" then
set theDelim to quote & the_Key & quote & ":"
else if theTable is "mediaControlsLocalizedStrings.js" then
set theDelim to "'" & the_Key & "':"
else
if itsText contains "';" then
set theDelim to "['" & the_Key & "']"
else
set theDelim to "[" & quote & the_Key & quote & "]"
end if
end if
-- For info, in front of theDelim we may have "localizedStrings", "localizedControls","localizedFonts", "localizedContinentNames" or "localizedCityNames"
if itsText does not contain theDelim then return missing value
set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, theDelim}
set l to text items of itsText
set AppleScript's text item delimiters to oTIDs
set key_loc to paragraph 1 of (item 2 of l)
if theTable is "modern-media-controls-localized-strings.js" then
set dels to {" " & quote, quote & ","}
else if theTable is "mediaControlsLocalizedStrings.js" then
set dels to {" '", "',"}
else
if key_loc contains "';" then
set dels to {" '", "';"}
else
set dels to {" " & quote, quote & ";"}
end if
end if
set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, dels}
set l to text items of key_loc
set AppleScript's text item delimiters to oTIDs
return (item 2 of l) as string
end localize:fromTable:inBundle:
#=====
Maybe, one day, I would convert this code in a library so it would be easier to use it in our scripts.
Maybe too, I would scan Mojave and/or Catalina to check if they use the yyy.js format in other lprojs.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 10 mars 2020 17:48:07