nwjs / nw.js

Call all Node.js modules directly from DOM/WebWorker and enable a new way of writing applications with all Web technologies.
https://nwjs.io
MIT License
40.41k stars 3.88k forks source link

Specify language when using the chromium-arg '--enable-spell-checking' #4954

Open emmetcampion opened 8 years ago

emmetcampion commented 8 years ago

Hi,

There doesn't seem to be any way to specify which language the spellchecker should use when using the chromium-args --enable-spell-checking. For me it always seems to default to en-US.

Does it set this based on the window.navigator.language?

Running nw 0.14.5 on Windows 10.

Thanks

PriteshGajjar008 commented 7 years ago

Is there any way to specify language for spell checking?

PriteshGajjar008 commented 7 years ago

Spell check is working for Mac OS but not for Windows. On Windows it always does spell checkign according to English(en-US) language.

rogerwang commented 7 years ago

Will see it soon. Thanks. cc @Christywl please confirm this first.

Christywl commented 7 years ago

@rogerwang , spell checking also works for me with English(en-US), but I don't know how to change the language to do spell checking.

PriteshGajjar008 commented 7 years ago

How it works on Mac OS X for all languages? Was this working before and broken? Please someone look into this.

PriteshGajjar008 commented 7 years ago

Guys, any updates on this?

rogerwang commented 7 years ago

This is fixed in git and will be available in the next nightly build.

semmel commented 7 years ago

So I still have to specify the languages for spellchecking in the Chrome preferences JSON file path.join(nw.App.dataPath, "Preferences")? e.g. for German

"spellcheck":{"dictionaries":["de-DE"],"dictionary":""}

However the Preferences file is not generated before the application is first run. So my installer cannot set it. Or can I ship a preferences file with my nwjs app? I wrote a companion C++ app which changes the Preferences JSON file and restarts my app afterwards.

What I'd rather like is something like the --lang command line parameter: I can set the navigator.language using the command line parameter --lang=en-US to English.

But setting the prefs from command line is not supported, isn't it?

rogerwang commented 7 years ago

The language for spell checking matches navigator.language. The fix is about spellchecking is always for English.

semmel commented 7 years ago

The language for spell checking matches navigator.language

No, it matches the language specified in the Chrome preferences file in the spellcheck.dictionaries path (see my last post above). This can be different from the navigator.language which can be set by --lang command line option. In this screenshot (nwjs 0.21.5) I have english browser language but german spelling:

Image of Yaktocat

PriteshGajjar008 commented 7 years ago

I tried specifying --lang option, it changes navigator.lang but spell checking doesn't have any effect. Spell checking works as per en-US. I have used latest 0.22.3 version. Once again I don't need to pass any option for Mac OS and spell check works fine for all languages. However, I am struggling to make this work for Windows OS. Please suggest.

When I tried "spellcheck":{"dictionaries":["de-DE"],"dictionary":""} it gives me following error: Failed to load extension from: /Applications/. Invalid value for spellcheck dictionary language.

semmel commented 7 years ago

@PriteshGajjar008 Near the very end of my C:\Users\Admin\AppData\Local\MyApp\User Data\Default\Preferences file I find this line for German spellchecking:

"spellcheck":{"dictionaries":["de"],"dictionary":""}

@Christywl This behaviour is easy to reproduce with a simple app containing an <input type="text"> and passing --enable-spellchecking and for example --lang=de-DE as parameters to nwjs.exe. See the screenshot posted above. Please reopen this issue.

Christywl commented 7 years ago

Hi, @semmel , yes, I also reproduce. I try on Windows with nwjs-sdk-v0.22.3. Here is my result: navigator.language is de, but the spell checking is en. image

package.json:

{
  "name": "test",
  "main": "index.html",
  "chromium-args": "--enable-spell-checking"
}

index.html:

<!DOCTYPE html>
<html>
<body>

<textarea rows="4" cols="50">
</textarea>

</body>
</html>

@rogerwang , I reopen this, please help check.

PriteshGajjar008 commented 7 years ago

@rogerwang Any ETA on this? Any workaround for spell check on Windows OS before this one gets fixed?

rogerwang commented 7 years ago

@PriteshGajjar008 could you please try to set the preference "spellcheck.dictionaries" by using "chrome.settingsPrivate.setPref(name, value, pageid, callback)"? The name parameter should be spellcheck.dictionaries, value should be a list, pageid is null.

rogerwang commented 7 years ago

@semmel we'll have a general way for settings. Let's see whether chrome.settingsPrivate could work.

PriteshGajjar008 commented 7 years ago

@rogerwang Thanks for quick response. I just tried this setting in console and seems to be working for my app. From which version we supporting this property? Will this setting have any impact on other functionality apart from spell checking?

semmel commented 7 years ago

It works like a charm! 😄 Thank you @rogerwang! I just tried in the dev console with nwjs v 0.22.3:

chrome.settingsPrivate.setPref('spellcheck.dictionaries', ["en-US"], "null", console.log.bind(console, "done"));

Now I can even switch the spellcheck language without restarting the app. Great! I guess this deserves mentioning in the api docs?

jonlepage commented 4 years ago

thanks work fine, i also add this for people need code list. If you have one better plz share !:) https://www.metamodpro.com/browser-language-codes

jonlepage commented 4 years ago

OK HAVE BETTER

        "af":"af",//Afrikaans
        "af-ZA":"af-ZA",//Afrikaans (South Africa)
        "ar":"ar",//Arabic
        "ar-AE":"ar-AE",//Arabic (U.A.E.)
        "ar-BH":"ar-BH",//Arabic (Bahrain)
        "ar-DZ":"ar-DZ",//Arabic (Algeria)
        "ar-EG":"ar-EG",//Arabic (Egypt)
        "ar-IQ":"ar-IQ",//Arabic (Iraq)
        "ar-JO":"ar-JO",//Arabic (Jordan)
        "ar-KW":"ar-KW",//Arabic (Kuwait)
        "ar-LB":"ar-LB",//Arabic (Lebanon)
        "ar-LY":"ar-LY",//Arabic (Libya)
        "ar-MA":"ar-MA",//Arabic (Morocco)
        "ar-OM":"ar-OM",//Arabic (Oman)
        "ar-QA":"ar-QA",//Arabic (Qatar)
        "ar-SA":"ar-SA",//Arabic (Saudi Arabia)
        "ar-SY":"ar-SY",//Arabic (Syria)
        "ar-TN":"ar-TN",//Arabic (Tunisia)
        "ar-YE":"ar-YE",//Arabic (Yemen)
        "az":"az",//Azeri (Latin)
        "az-AZ":"az-AZ",//Azeri (Latin) (Azerbaijan)
        "az-AZ":"az-AZ",//Azeri (Cyrillic) (Azerbaijan)
        "be":"be",//Belarusian
        "be-BY":"be-BY",//Belarusian (Belarus)
        "bg":"bg",//Bulgarian
        "bg-BG":"bg-BG",//Bulgarian (Bulgaria)
        "bs-BA":"bs-BA",//Bosnian (Bosnia and Herzegovina)
        "ca":"ca",//Catalan
        "ca-ES":"ca-ES",//Catalan (Spain)
        "cs":"cs",//Czech
        "cs-CZ":"cs-CZ",//Czech (Czech Republic)
        "cy":"cy",//Welsh
        "cy-GB":"cy-GB",//Welsh (United Kingdom)
        "da":"da",//Danish
        "da-DK":"da-DK",//Danish (Denmark)
        "de":"de",//German
        "de-AT":"de-AT",//German (Austria)
        "de-CH":"de-CH",//German (Switzerland)
        "de-DE":"de-DE",//German (Germany)
        "de-LI":"de-LI",//German (Liechtenstein)
        "de-LU":"de-LU",//German (Luxembourg)
        "dv":"dv",//Divehi
        "dv-MV":"dv-MV",//Divehi (Maldives)
        "el":"el",//Greek
        "el-GR":"el-GR",//Greek (Greece)
        "en":"en",//English
        "en-AU":"en-AU",//English (Australia)
        "en-BZ":"en-BZ",//English (Belize)
        "en-CA":"en-CA",//English (Canada)
        "en-NZ":"en-NZ",//English (New Zealand)
        "en-PH":"en-PH",//English (Republic of the Philippines)
        "en-TT":"en-TT",//English (Trinidad and Tobago)
        "en-US":"en-US",//English (United States)
        "en-ZA":"en-ZA",//English (South Africa)
        "en-ZW":"en-ZW",//English (Zimbabwe)
        "eo":"eo",//Esperanto
        "es":"es",//Spanish
        "es-AR":"es-AR",//Spanish (Argentina)
        "es-BO":"es-BO",//Spanish (Bolivia)
        "es-CL":"es-CL",//Spanish (Chile)
        "es-CO":"es-CO",//Spanish (Colombia)
        "es-CR":"es-CR",//Spanish (Costa Rica)
        "es-DO":"es-DO",//Spanish (Dominican Republic)
        "es-EC":"es-EC",//Spanish (Ecuador)
        "es-ES":"es-ES",//Spanish (Castilian)
        "es-ES":"es-ES",//Spanish (Spain)
        "es-GT":"es-GT",//Spanish (Guatemala)
        "es-HN":"es-HN",//Spanish (Honduras)
        "es-MX":"es-MX",//Spanish (Mexico)
        "es-NI":"es-NI",//Spanish (Nicaragua)
        "es-PA":"es-PA",//Spanish (Panama)
        "es-PE":"es-PE",//Spanish (Peru)
        "es-PR":"es-PR",//Spanish (Puerto Rico)
        "es-PY":"es-PY",//Spanish (Paraguay)
        "es-SV":"es-SV",//Spanish (El Salvador)
        "es-UY":"es-UY",//Spanish (Uruguay)
        "es-VE":"es-VE",//Spanish (Venezuela)
        "et":"et",//Estonian
        "et-EE":"et-EE",//Estonian (Estonia)
        "eu":"eu",//Basque
        "eu-ES":"eu-ES",//Basque (Spain)
        "fa":"fa",//Farsi
        "fa-IR":"fa-IR",//Farsi (Iran)
        "fi":"fi",//Finnish
        "fi-FI":"fi-FI",//Finnish (Finland)
        "fo":"fo",//Faroese
        "fo-FO":"fo-FO",//Faroese (Faroe Islands)
        "fr":"fr",//French
        "fr-BE":"fr-BE",//French (Belgium)
        "fr-CA":"fr-CA",//French (Canada)
        "fr-CH":"fr-CH",//French (Switzerland)
        "fr-FR":"fr-FR",//French (France)
        "fr-LU":"fr-LU",//French (Luxembourg)
        "fr-MC":"fr-MC",//French (Principality of Monaco)
        "gl":"gl",//Galician
        "gl-ES":"gl-ES",//Galician (Spain)
        "gu":"gu",//Gujarati
        "gu-IN":"gu-IN",//Gujarati (India)
        "he":"he",//Hebrew
        "he-IL":"he-IL",//Hebrew (Israel)
        "hi":"hi",//Hindi
        "hi-IN":"hi-IN",//Hindi (India)
        "hr":"hr",//Croatian
        "hr-BA":"hr-BA",//Croatian (Bosnia and Herzegovina)
        "hr-HR":"hr-HR",//Croatian (Croatia)
        "hu":"hu",//Hungarian
        "hu-HU":"hu-HU",//Hungarian (Hungary)
        "hy":"hy",//Armenian
        "hy-AM":"hy-AM",//Armenian (Armenia)
        "id":"id",//Indonesian
        "id-ID":"id-ID",//Indonesian (Indonesia)
        "is":"is",//Icelandic
        "is-IS":"is-IS",//Icelandic (Iceland)
        "it":"it",//Italian
        "it-CH":"it-CH",//Italian (Switzerland)
        "it-IT":"it-IT",//Italian (Italy)
        "ja":"ja",//Japanese
        "ja-JP":"ja-JP",//Japanese (Japan)
        "ka":"ka",//Georgian
        "ka-GE":"ka-GE",//Georgian (Georgia)
        "kk":"kk",//Kazakh
        "kk-KZ":"kk-KZ",//Kazakh (Kazakhstan)
        "kn":"kn",//Kannada
        "kn-IN":"kn-IN",//Kannada (India)
        "ko":"ko",//Korean
        "ko-KR":"ko-KR",//Korean (Korea)
        "kok":"kok",//Konkani
        "kok-IN":"kok-IN",//Konkani (India)
        "ky":"ky",//Kyrgyz
        "ky-KG":"ky-KG",//Kyrgyz (Kyrgyzstan)
        "lt":"lt",//Lithuanian
        "lt-LT":"lt-LT",//Lithuanian (Lithuania)
        "lv":"lv",//Latvian
        "lv-LV":"lv-LV",//Latvian (Latvia)
        "mi":"mi",//Maori
        "mi-NZ":"mi-NZ",//Maori (New Zealand)
        "mk":"mk",//FYRO Macedonian
        "mk-MK":"mk-MK",//FYRO Macedonian (Former Yugoslav Republic of Macedonia)
        "mn":"mn",//Mongolian
        "mn-MN":"mn-MN",//Mongolian (Mongolia)
        "mr":"mr",//Marathi
        "mr-IN":"mr-IN",//Marathi (India)
        "ms":"ms",//Malay
        "ms-BN":"ms-BN",//Malay (Brunei Darussalam)
        "ms-MY":"ms-MY",//Malay (Malaysia)
        "mt":"mt",//Maltese
        "mt-MT":"mt-MT",//Maltese (Malta)
        "nb":"nb",//Norwegian (Bokm?l)
        "nb-NO":"nb-NO",//Norwegian (Bokm?l) (Norway)
        "nl":"nl",//Dutch
        "nl-BE":"nl-BE",//Dutch (Belgium)
        "nl-NL":"nl-NL",//Dutch (Netherlands)
        "nn-NO":"nn-NO",//Norwegian (Nynorsk) (Norway)
        "ns":"ns",//Northern Sotho
        "ns-ZA":"ns-ZA",//Northern Sotho (South Africa)
        "pa":"pa",//Punjabi
        "pa-IN":"pa-IN",//Punjabi (India)
        "pl":"pl",//Polish
        "pl-PL":"pl-PL",//Polish (Poland)
        "ps":"ps",//Pashto
        "ps-AR":"ps-AR",//Pashto (Afghanistan)
        "pt":"pt",//Portuguese
        "pt-BR":"pt-BR",//Portuguese (Brazil)
        "pt-PT":"pt-PT",//Portuguese (Portugal)
        "qu":"qu",//Quechua
        "qu-BO":"qu-BO",//Quechua (Bolivia)
        "qu-EC":"qu-EC",//Quechua (Ecuador)
        "qu-PE":"qu-PE",//Quechua (Peru)
        "ro":"ro",//Romanian
        "ro-RO":"ro-RO",//Romanian (Romania)
        "ru":"ru",//Russian
        "ru-RU":"ru-RU",//Russian (Russia)
        "sa":"sa",//Sanskrit
        "sa-IN":"sa-IN",//Sanskrit (India)
        "se":"se",//Sami (Northern)
        "se-FI":"se-FI",//Sami (Northern) (Finland)
        "se-FI":"se-FI",//Sami (Skolt) (Finland)
        "se-FI":"se-FI",//Sami (Inari) (Finland)
        "se-NO":"se-NO",//Sami (Northern) (Norway)
        "se-NO":"se-NO",//Sami (Lule) (Norway)
        "se-NO":"se-NO",//Sami (Southern) (Norway)
        "se-SE":"se-SE",//Sami (Northern) (Sweden)
        "se-SE":"se-SE",//Sami (Lule) (Sweden)
        "se-SE":"se-SE",//Sami (Southern) (Sweden)
        "sk":"sk",//Slovak
        "sk-SK":"sk-SK",//Slovak (Slovakia)
        "sl":"sl",//Slovenian
        "sl-SI":"sl-SI",//Slovenian (Slovenia)
        "sq":"sq",//Albanian
        "sq-AL":"sq-AL",//Albanian (Albania)
        "sr-BA":"sr-BA",//Serbian (Latin) (Bosnia and Herzegovina)
        "sr-BA":"sr-BA",//Serbian (Cyrillic) (Bosnia and Herzegovina)
        "sr-SP":"sr-SP",//Serbian (Latin) (Serbia and Montenegro)
        "sr-SP":"sr-SP",//Serbian (Cyrillic) (Serbia and Montenegro)
        "sv":"sv",//Swedish
        "sv-FI":"sv-FI",//Swedish (Finland)
        "sv-SE":"sv-SE",//Swedish (Sweden)
        "sw":"sw",//Swahili
        "sw-KE":"sw-KE",//Swahili (Kenya)
        "syr":"syr",//Syriac
        "syr-SY":"syr-SY",//Syriac (Syria)
        "ta":"ta",//Tamil
        "ta-IN":"ta-IN",//Tamil (India)
        "te":"te",//Telugu
        "te-IN":"te-IN",//Telugu (India)
        "th":"th",//Thai
        "th-TH":"th-TH",//Thai (Thailand)
        "tl":"tl",//Tagalog
        "tl-PH":"tl-PH",//Tagalog (Philippines)
        "tn":"tn",//Tswana
        "tn-ZA":"tn-ZA",//Tswana (South Africa)
        "tr":"tr",//Turkish
        "tr-TR":"tr-TR",//Turkish (Turkey)
        "tt":"tt",//Tatar
        "tt-RU":"tt-RU",//Tatar (Russia)
        "ts":"ts",//Tsonga
        "uk":"uk",//Ukrainian
        "uk-UA":"uk-UA",//Ukrainian (Ukraine)
        "ur":"ur",//Urdu
        "ur-PK":"ur-PK",//Urdu (Islamic Republic of Pakistan)
        "uz":"uz",//Uzbek (Latin)
        "uz-UZ":"uz-UZ",//Uzbek (Latin) (Uzbekistan)
        "uz-UZ":"uz-UZ",//Uzbek (Cyrillic) (Uzbekistan)
        "vi":"vi",//Vietnamese
        "vi-VN":"vi-VN",//Vietnamese (Viet Nam)
        "xh":"xh",//Xhosa
        "xh-ZA":"xh-ZA",//Xhosa (South Africa)
        "zh":"zh",//Chinese
        "zh-CN":"zh-CN",//Chinese (S)
        "zh-HK":"zh-HK",//Chinese (Hong Kong)
        "zh-MO":"zh-MO",//Chinese (Macau)
        "zh-SG":"zh-SG",//Chinese (Singapore)
        "zh-TW":"zh-TW",//Chinese (T)
        "zu":"zu",//Zulu
        "zu-ZA":"zu-ZA",//Zulu (South Africa)
rowenbuzz commented 4 years ago

It works like a charm! 😄 Thank you @rogerwang! I just tried in the dev console with nwjs v 0.22.3:

chrome.settingsPrivate.setPref('spellcheck.dictionaries', ["en-US"], "null", console.log.bind(console, "done"));

Now I can even switch the spellcheck language without restarting the app. Great! I guess this deserves mentioning in the api docs?

Hey @semmel I know this is probably a blast from the past for you. Could you explain how or if this command is possible to run in a JavaScript file instead of in the dev console?
I don't know how to properly access chrome.* based on the documentation: http://docs.nwjs.io/en/latest/References/Chrome%20Extension%20APIs/

So I thought maybe something like...

gui = require('nw-gui')
gui.App.chrome.settingsPrivate.setPref('spellcheck.dictionaries', ["en-US", "fr-FR"], "null", console.log.bind(console, "done"));

General Idea: I'm trying to implement certain languages for different users so my plan is to have a configuration file that can be read, specify the languages, and then bring in the specified languages when the application starts. Different users, require different languages clearly.

Anyone else reading this, I'm also open to suggestions on how this can be done.

Current State: I'm using the chromium-args in my package.json to get spellchecking... "chromium-args": "--enable-spell-checking",

...and I see that a second chromium arg I found in Google's API documentation is called --enable-multilingual-spellchecker does not do anything and therefore is not currently implemented in NW.js as it makes no difference when I add or take it out.

So in summary, I'm trying to come up with a way to specify your "chrome.settingsPrivate......" code in JavaScript instead of using the dev tools console. Any other thoughts or suggestions welcome. Thank you.

semmel commented 4 years ago

@rowenbuzz I just verified with our current DesktopApp (nwjs 0.26.2) that chrome.settingsPrivate is exposed to the global scope. And no, it seems it's nowhere documented. (That's why this issue has been labeled documentation and is still open I guess.)

In my package.json I have "chromium-args": "--enable-spell-checking" and nothing unusual.

Although the spellchecking switching works on Windows, on Mac it just applies english as language.

rowenbuzz commented 4 years ago

@semmel Thank you for responding. I have the package.json same as you, but for some reason I was having an issue trying to use that code directly in my JavaScript file. That's what I get for trying to take it one step farther by accessing gui.App incorrectly. I have a working solution now, much appreciated for getting back to me.

For anyone else who comes across this thread here are few things to keep in mind...

Summary: To enable spellchecking, as stated in many places above, you can update package.json: "chromium-args": "--enable-spell-checking"

And to set up which dictionaries you want like English-USA and French-France it would be: chrome.settingsPrivate.setPref('spellcheck.dictionaries', ["en-US","fr-FR"], "null", ()=>{});

And one feature I'm going to try next is a toggle button, in order to toggle spellcheck ON/OFF. I already verified through hard-coding the lists that it works as I would expect.

So to turn it off, I just submit an empty list for value in my JS file: chrome.settingsPrivate.setPref('spellcheck.dictionaries', [], "null", ()=>{});

I hope this helps.

xthdraft commented 4 years ago

Followed all the above and my nw.js app now has all the misspelled words underlined with red squigglies. So far, so good. But how do you get a list of suggested corrections? Any pointer to this would be appreciated. Thanks.

dreamsavior commented 2 years ago

chrome.settingsPrivate.setPref('spellcheck.dictionaries', ["en-US","fr-FR"], "null", ()=>{}); is actually a good solution. But that argument parameters are so cryptic. I can't find the documentation anywhere on the internet about the list of available arguments for chrome.settingsPrivate.setPref(). I wonder if there is a list of that?

I think nwJs team should mention this on their documentation, because this way we can have a better control over our apps.

rowenbuzz commented 2 years ago

@dreamsavior I found the comments in the source code here: https://chromium.googlesource.com/chromium/src.git/+/62.0.3178.1/chrome/common/extensions/api/settings_private.idl

But I don't know of documentation in this case. Perhaps @rogerwang has better knowledge in this area of Chromium's documentation, but adding it to the documentation for NWjs would be helpful. When I go to "Search docs" and search for "spellcheck", no pages come up in NWjs here: https://nwjs.readthedocs.io/en/latest/