From c6c7abcfef706445e275157e3209f0ca1085d7b4 Mon Sep 17 00:00:00 2001 From: Marc Boucher Date: Wed, 29 Apr 2020 17:50:53 +0200 Subject: [PATCH 1/7] Update setting-definitions.js --- app/common/setting-definitions.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/common/setting-definitions.js b/app/common/setting-definitions.js index 5ae69044..f63a7c08 100755 --- a/app/common/setting-definitions.js +++ b/app/common/setting-definitions.js @@ -132,6 +132,20 @@ _VAL[_NAM.CFGS_THEME_NAME] = (v)=>{ return (( v === 'default-dark' || v === 'default' ) ? v : undefined); }; +// language options +_NAM.CFGS_LANG_NAME = 'language'; +_DEF[_NAM.CFGS_LANG_NAME] = 'fr'; +_VAL[_NAM.CFGS_LANG_NAME] = (v)=>{ + return v; +}; +_NAM.CFGS_LANG_LOCALE = 'lang-locale'; +_DEF[_NAM.CFGS_LANG_LOCALE] = ''; +_VAL[_NAM.CFGS_LANG_LOCALE] = (v)=>{ + return v; +}; +// END language + + _NAM.CFGS_SCROLLBAR_COLOR = 'skinny-scrollbar-color'; _DEF[_NAM.CFGS_SCROLLBAR_COLOR] = ''; _VAL[_NAM.CFGS_SCROLLBAR_COLOR] = (v)=>{ From 0e31ad1ae6276502756154a4cacba144ab5440dc Mon Sep 17 00:00:00 2001 From: Marc Boucher Date: Wed, 29 Apr 2020 17:53:10 +0200 Subject: [PATCH 2/7] Update manifest.js --- app/settings/manifest.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/app/settings/manifest.js b/app/settings/manifest.js index eb0a580c..7b3d7cba 100755 --- a/app/settings/manifest.js +++ b/app/settings/manifest.js @@ -219,6 +219,34 @@ vote at ${issue(125,true)}. "type": "description", "text": future_i18n("Refresh the TabFern window to apply changes to these options. To refresh, click TabFern's title bar and hit F5."), }, + { + "tab": future_i18n("Appearance"), + "group": future_i18n("Language"), + "name": S.S_LANG_NAME, + "type": "popupButton", + "label": future_i18n('Select a language'), + 'options': [ + { value: '', text: 'Browser default' }, + { value: '_user_', text: '[ User defined ]' }, + { value: 'en', text: 'English (EN)' }, + { value: 'de', text: 'Deutsch (DE)' }, + { value: 'fr', text: 'Français (FR)' }, + { value: 'ru', text: 'Russian (RU)' }, + ], + }, + { + "tab": future_i18n("Appearance"), + "group": future_i18n("Language"), + "type": "description", + "text": future_i18n('Locale:'), + }, + { + "tab": future_i18n("Appearance"), + "group": future_i18n("Language"), + "name": S.S_LANG_LOCALE, + "type": "textarea", + "NOlabel": future_i18n('Locale'), + }, { "tab": future_i18n("Appearance"), "group": future_i18n("Scrollbars"), From 44d26a26e48c9a2a3beff9996bdc9106a3156917 Mon Sep 17 00:00:00 2001 From: Marc Boucher Date: Wed, 29 Apr 2020 17:55:35 +0200 Subject: [PATCH 3/7] Update common.js --- vendor/common.js | 86 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/vendor/common.js b/vendor/common.js index a4565407..b7cd793c 100755 --- a/vendor/common.js +++ b/vendor/common.js @@ -144,9 +144,91 @@ function loadCSS(doc, url, before) { // Miscellaneous functions // {{{1 /// Shortcut for i18n. Call _T("name") to pull the localized "name". -var _T; +var _T, _locale; if(chrome && chrome.i18n && chrome.i18n.getMessage) { - _T = chrome.i18n.getMessage; + if (!_T) _T = chrome.i18n.getMessage; + + function LoadLocale(L) { + var locale, f=new XMLHttpRequest(); + f.open("GET", chrome.runtime.getURL('_locales/'+L+'/messages.json'), false); + try { + f.send(); + if (f.responseText) locale=JSON.parse(f.responseText); + }catch(e){ void chrome.runtime.lastError; } + return locale; + } + + // fill missing keys in O1 with keys from O2 + function MergeObjects(O1,O2) { + for (let k in O2) { + if (!O1[k]) O1[k]=O2[k]; + } + } + + if (!_locale) { + let lang=localStorage['store.settings.language'], + defaultLang=chrome.runtime.getManifest().default_locale, + isDefault=false, + tried={}; + if (lang) lang=lang.replace(/"/g,''); + + let langs=[lang || '', chrome.i18n.getUILanguage()].concat(navigator.languages).concat([defaultLang]); + +console.info(langs); + + let L; + for (let i=0; i1) { + langs.splice(i+1,0,sL[0]); + } + } + if (L==defaultLang) isDefault=true; + L=L.split('-'); + if (L.length>1) { + L=L[0]; + let loc2=LoadLocale(L); + if (loc2) MergeObjects(_locale,loc2); + if (L==defaultLang) isDefault=true; + } + + if (!isDefault) { + let loc2=LoadLocale(defaultLang); + if (loc2) MergeObjects(_locale,loc2); + } +//console.info('parsed locale:', _locale); + /**/ + + // if something has failed, use _T definition above + // else link our own function + if (_locale) _T = function(v){ +//console.info(arguments); + let m=_locale[v], r; + if (m) { + r=m.message; + if (r && m.placeholders) { +//console.info(m); + for (let i in m.placeholders) { + r=r.replace( new RegExp('\\$'+i+'\\$' ,'gi') , arguments[ m.placeholders[i].content.substring(1) ] || '') + } + } + } + return r; + } + /**/ + } } else { // #171 HACK console.warn("Using #171 hack"); // The following line is substituted at build time with the messages From c307ab4b0d1f2ccc0afe9b65966a095ba65a07cf Mon Sep 17 00:00:00 2001 From: Marc Boucher Date: Tue, 5 May 2020 00:38:45 +0200 Subject: [PATCH 4/7] Update FR locale added "settings" messages --- static/_locales/fr/messages.json | 153 ++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 1 deletion(-) diff --git a/static/_locales/fr/messages.json b/static/_locales/fr/messages.json index 2ba69fcf..04bf4ba5 100755 --- a/static/_locales/fr/messages.json +++ b/static/_locales/fr/messages.json @@ -332,4 +332,155 @@ ,"description":"The lines below here do not need translation." } ,"modeline":{"description":"Keep the following on the last line of the file" - ,"message":" // vi: set ts=2 sts=2 sw=2 et ai fenc=utf8 ff=dos: //"}} + ,"message":" // vi: set ts=2 sts=2 sw=2 et ai fenc=utf8 ff=dos: //"} + + + ,"s_welcome": { + "message": "Bienvenue / Aide"} + ,"s_intro": { + "message": "Introduction"} + ,"s_intro_txt": { + "message": "

Bienvenue sur TabFern! Dans Chrome, chaque fenêtre que vous avez ouverte ou sauvegardée est représentée dans la fenêtre de TabFern. Cliquez avec le bouton droit sur ces éléments ou déplacez la souris par dessus pour accéder aux options. Cliquez le menu $HAM$ pour plus d'options.

Les onglets à gauche contiennent des options et, en bas de la liste, des informations à propos des changements ou ajouts récents.

" + ,"placeholders": { + "ham": { "content": "$1" } + } + } + ,"s_inco": { + "message": "Navigation privée"} + ,"s_inco_txt": { + "message": "TabFern ne peut pas voir les fenêtres et onglets en mode navigation privée, et n'a pas encore été testé en mode navigation privée. Si vous désirez que ce mode soit pris en charge par TabFern, votez ici: $VOTE$" + ,"placeholders": { + "vote": { "content": "$1" } + } + } + ,"s_import": { + "message": "Importer/Exporter"} + ,"s_save": { + "message": "Sauvegarder les réglages dans un fichier"} + ,"s_load": { + "message": "Charger les réglages depuis un fichier"} + ,"s_legal": { + "message": "Mention légale"} + ,"s_legal_txt": { + "message": "Le nom TabFern, le logo, et les icônes sont des marques déposées de Chris White."} + ,"s_behaviour": { + "message": "Comportement"} + ,"s_chr_st": { + "message": "Démarrage de Chrome"} + ,"s_auto_openTF": { + "message": "Ouvrir TabFern automatiquement"} + ,"s_openTF_txt": { + "message": "Vous pouvez ouvrir la fenêtre de TabFern à tout moment en cliquant sur l'icône \"fougère\" à côté de la barre d'adresse."} + ,"s_startup": { + "message": "Au démarrage ou au raffaîchissement..."} + ,"s_collapse": { + "message": "Réduire toutes les arborescences sauvées"} + ,"s_sort_open": { + "message": "Trier les fenêtres ouvertes en haut"} + ,"s_when": { + "message": "Quand je..."} + ,"s_close_open": { + "message": "Ferme une fenêtre, réduire son arborescence"} + ,"s_restore_del": { + "message": "Restaure la dernière fenêtre effacée, rouvrir ses onglets"} + ,"s_sort_scroll": { + "message": "Trie les fenetres ouvertes en haut, faire défiler en faut de la liste"} + ,"s_new_top": { + "message": "Ouvre une nouvelle fenêtre, la déplacer en haut de la liste"} + ,"s_new_top_txt": { + "message": "Ceci a aussi pour effet que toutes fenêtres ouvertes seront triés en haut au moment de l'ouverture de la fenêtre de TabFern. Et ceci même si vous n'avez pas coché l'option \"Trie les fenetres ouvertes\" çi-dessus."} + ,"s_partly": { + "message": "Fenêtres partiellement ouvertes"} + ,"s_partly_txt": { + "message": "Quand seulement certains des onglets sont ouverts, que doit-il se passer quand vous cliquez sur le nom de cette fenêtre ?"} + ,"s_partly_openAllRem": { + "message": "Ouvrir tous les onglets restants"} + ,"s_partly_toFront": { + "message": "Afficher la fenêtre à l'avant-plan (vous pouvez ouvrir les onglets restants depuis le menu clic-droit)"} + ,"s_del_win": { + "message": "Supprimer des fenêtres"} + ,"s_del_SWin": { + "message": "Demander confirmation avant de supprimer une fenêtre sauvegardée"} + ,"s_del_UnsWin": { + "message": "Demander confirmation avant de supprimer une fenêtre non-sauvegardée"} + ,"s_del_tab": { + "message": "Deleting tabs"} + ,"s_del_STab": { + "message": "Demander confirmation avant de supprimer un onglet dans une fenêtre sauvegardée"} + ,"s_del_UnsTab": { + "message": "Demander confirmation avant de supprimer un onglet dans une fenêtre non-sauvegardée"} + ,"s_music": { + "message": "Musique"} + ,"s_music_tab": { + "message": "Demander confirmation avant de fermer ou supprimer un onglet qui diffuse du son $music$" + ,"placeholders": { + "music": { "content": "$1" } + } + } + ,"s_appear": { + "message": "Apparence"} + ,"s_appear_txt": { + "message": "Raffraichir la fenêtre de TabFern pour appliquer la modification des options. Pour raffraichir, cliquer sur la barre de titre de TabFern et appuyer sur F5."} + ,"s_lang": { + "message": "Langue"} + ,"s_lang_txt": { + "message": "Choisissez une langue"} + ,"s_locDef": { + "message": "Défauts du navigateur"} + ,"s_locUser": { + "message": "[ Fournie par l'utilisateur ]"} + ,"s_loc_btn": { + "message": "Editer"} + ,"s_scroll": { + "message": "Barres de défilement"} + ,"s_hideHscroll": { + "message": "Cacher la barre de défilement horizontale"} + ,"s_skinnyScroll": { + "message": "Barres de défilement fines"} + ,"s_skinnyColor": { + "message": "Couleur de la barre de défilement fine (\"X\" pour couleur par défaut)"} + ,"s_tree": { + "message": "Arborescence"} + ,"s_tree_txt": { + "message": "Afficher les lignes de connexion entre les nœuds "} + ,"s_theme": { + "message": "Thème"} + ,"s_background": { + "message": "Couleur ou image de fond"} + ,"s_theme_txt": { + "message": "L'arrière-plan peut être une couleur CSS, rgb(r,g,b), hsl(h,s,l), ou une URL (donnée, https, chrome-extension, ou fichier). Pour utiliser une image de votre disque dur (fichier):
  • Cocher la case \"Autoriser l'accès aux URL de fichier\" dans chrome://extensions
  • Ouvrir dans Chrome l'image que vous voulez utiliser et copier l'adresse depuis la barre d'adresse (cela commence pas \"file://\")
  • Coller l'URL \"file://...\" dans le champ de saisie çi-dessus.
  • "} + ,"s_tooltips": { + "message": "Info-bulles"} + ,"s_TT_showURL": { + "message": "Montrer l'URL dans l'info-bulle de chaque élément"} + ,"s_TT_showTitle": { + "message": "Montrer le titre de la page dans l'info-bulle de chaque élément"} + ,"s_actionB_order": { + "description": "Action-button order for windows"} + ,"s_action_txt": { + "description": "This also sets the order of the corresponding buttons for tabs."} + ,"s_features": { + "message": "Fonctionnalités"} + ,"s_cmenu": { + "message": "Menu contextuel"} + ,"s_refresh_msg": { + "message": " (rafraîchir la fenêtre de TabFern après avoir modifié cette option pour que le changement prenne effet)"} + ,"s_rcMenu": { + "message": "Activer les menus clic-droit $REFRESH$" + ,"placeholders": { + "refresh": { "content": "$1" } + } + } + ,"s_credits": { + "message": "Crédits et remerciements"} + ,"s_progr": { + "message": "Programmation"} + ,"s_transl": { + "message": "Traduction"} + ,"s_art_pub": { + "message": "Artwork et publicité"} + ,"s_other": { + "message": "Autre"} + ,"s_whatsnew": { + "message": "Quoi de neuf ?"} +} From b8375e16a476c4b33f9d89cd4ace0d1c018dc2e4 Mon Sep 17 00:00:00 2001 From: Marc Boucher Date: Tue, 5 May 2020 00:44:27 +0200 Subject: [PATCH 5/7] settings.js -- added i18n + form behaviour added localized string handling of "locale selection" form's elements --- app/settings/settings.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/app/settings/settings.js b/app/settings/settings.js index ebe91303..7116b5ca 100755 --- a/app/settings/settings.js +++ b/app/settings/settings.js @@ -60,7 +60,7 @@ let createPicker = function createPicker() { // Add the text that would otherwise have gone in the manifest let newlabel = $j('').text( - 'Skinny-scrollbar color ("X" for the default): ') // TODO i18n + _T('s_skinnyColor') || 'Skinny-scrollbar color ("X" for the default): ' ) // TODO i18n .addClass('setting label'); $j(picker).before(newlabel); @@ -245,6 +245,20 @@ function main() S.set(S.SETTINGS_LOADED_OK, false); } + // handle locale selection events + let SL=$j('#s_select_lang'), SLb = $j('#user_locale_btn'), SLtxt = $j('#user_locale')[0]; + function toggleLocaleBtn(e) { + let val = e.value == '_user_'; + SLb[0].classList.toggle('show',val); + if (!val) SLtxt.classList.remove('show'); + } + SL.on('change', (e)=>{toggleLocaleBtn(e.target);}); + SLb.on('click', ()=>{SLtxt.classList.toggle('show');}); + // set classes and init button state (visible or hidden) + SL[0].parentNode.classList.add('floatLeft'); + SLb[0].classList.add('floatLeft'); + toggleLocaleBtn(SL[0]); + // ---------------------------- // open tab specified in a query parm, if known. // See https://stackoverflow.com/a/12151322/2877364 From a43965803d2a0891a61bae723f58117e6a2dbea3 Mon Sep 17 00:00:00 2001 From: Marc Boucher Date: Tue, 5 May 2020 00:47:40 +0200 Subject: [PATCH 6/7] manifest.js -- localization of setting_definitions modified function to handle i18n localization --- app/settings/manifest.js | 300 ++++++++++++++++++++------------------- 1 file changed, 154 insertions(+), 146 deletions(-) diff --git a/app/settings/manifest.js b/app/settings/manifest.js index 7b3d7cba..3f007742 100755 --- a/app/settings/manifest.js +++ b/app/settings/manifest.js @@ -20,7 +20,10 @@ function issue(nums, noparens) { function brplain(text){return `
    ${text}`;} -function future_i18n(x) { return x; } +function future_i18n(x,n) { + var r = n && _T.apply(null, [].slice.call(arguments,1) ); + return r || x; +} let ham = icon('fa fa-bars'); let gt = icon('fa fa-lg fa-caret-right'); @@ -28,97 +31,97 @@ var editImg = icon('fff-pencil tf-action-button'); var delImg = icon('fff-cross tf-action-button'); var saveImg = icon('fff-picture-delete tf-action-button'); let settings = `${ham} ${gt} Settings ${gt}`; -let refresh_message = " (refresh the TabFern window after you change this to make the change take effect)"; +let refresh_message = future_i18n(" (refresh the TabFern window after you change this to make the change take effect)", 's_refresh_msg'); // Settings {{{2 let setting_definitions = ([ // Welcome page { - "tab": future_i18n("Welcome / Help"), - "group": future_i18n("Introduction"), + "tab": future_i18n("Welcome / Help", 's_welcome'), + "group": future_i18n("Introduction", 's_intro'), "name": "welcome-intro", "type": "description", - "text": "

    Welcome to TabFern! Each Chrome window you have open "+ + "text": future_i18n("

    Welcome to TabFern! Each Chrome window you have open "+ "or saved is represented in the TabFern window. "+ "Right-click on those representations or hover " + "the mouse over them for options. Click the " + ham + ' menu for more options.

    ' + '

    The tabs at the left have settings and, at the bottom'+ ' of the list, information about recent feature additions'+ - ' or changes.

    ' + ' or changes.

    ', 's_intro_txt', ham) }, { - "tab": future_i18n("Welcome / Help"), - "group": future_i18n("Incognito mode"), + "tab": future_i18n("Welcome / Help", 's_welcome'), + "group": future_i18n("Incognito mode", 's_inco'), "type": "description", - "text": + "text": future_i18n( `TabFern cannot see Incognito windows or tabs, and is not yet tested in Incognito mode. If you would like Incognito support in TabFern, please vote at ${issue(125,true)}. -`, +`, 's_inco_txt', issue(125,true) ), }, { - "tab": future_i18n("Welcome / Help"), - "group": future_i18n("Import/Export"), + "tab": future_i18n("Welcome / Help", 's_welcome'), + "group": future_i18n("Import/Export", 's_import'), "name": "export-settings", "id": "export-settings", "type": "button", - "text": "Save settings to a file" + "text": future_i18n("Save settings to a file", 's_save') }, { - "tab": future_i18n("Welcome / Help"), - "group": future_i18n("Import/Export"), + "tab": future_i18n("Welcome / Help", 's_welcome'), + "group": future_i18n("Import/Export", 's_import'), "name": "import-settings", "id": "import-settings", "type": "button", - "text": "Load settings from a file" + "text": future_i18n("Load settings from a file", 's_load') }, { - "tab": future_i18n("Welcome / Help"), - "group": future_i18n("Legal"), + "tab": future_i18n("Welcome / Help", 's_welcome'), + "group": future_i18n("Legal", 's_legal'), "name": "legal", "type": "description", - "text": "The TabFern name, logo, and icons are trademarks of Chris White." + "text": future_i18n("The TabFern name, logo, and icons are trademarks of Chris White.", 's_legal_txt') }, // Behaviour. Yeah, there's a "u" in there! { - "tab": future_i18n("Behaviour"), - "group": future_i18n("When Chrome starts..."), + "tab": future_i18n("Behaviour", 's_behaviour'), + "group": future_i18n("When Chrome starts...", 's_chr_st'), "name": S.POPUP_ON_STARTUP, "type": "checkbox", - "label": future_i18n("Open the TabFern window automatically"), + "label": future_i18n("Open the TabFern window automatically", 's_auto_openTF'), }, { - "tab": future_i18n("Behaviour"), - "group": future_i18n("When Chrome starts..."), + "tab": future_i18n("Behaviour", 's_behaviour'), + "group": future_i18n("When Chrome starts...", 's_chr_st'), "type": "description", - "text": future_i18n("You can open the TabFern window any time by clicking the fern icon next to the address bar."), + "text": future_i18n("You can open the TabFern window any time by clicking the fern icon next to the address bar.", 's_openTF_txt'), }, { - "tab": future_i18n("Behaviour"), - "group": future_i18n("On startup or refresh..."), + "tab": future_i18n("Behaviour", 's_behaviour'), + "group": future_i18n("On startup or refresh...", 's_startup'), "name": S.COLLAPSE_ON_STARTUP, "type": "checkbox", - "label": future_i18n("Collapse all the saved trees"), + "label": future_i18n("Collapse all the saved trees", 's_collapse'), //"text": future_i18n("x-characters") }, { - "tab": future_i18n("Behaviour"), - "group": future_i18n("On startup or refresh..."), + "tab": future_i18n("Behaviour", 's_behaviour'), + "group": future_i18n("On startup or refresh...", 's_startup'), "name": S.OPEN_TOP_ON_STARTUP, "type": "checkbox", - "label": future_i18n("Sort open windows to the top") + "label": future_i18n("Sort open windows to the top", 's_sort_open') //"text": future_i18n("x-characters") }, { - "tab": future_i18n("Behaviour"), - "group": future_i18n("When I..."), + "tab": future_i18n("Behaviour", 's_behaviour'), + "group": future_i18n("When I...", 's_when'), "name": S.COLLAPSE_ON_WIN_CLOSE, "type": "checkbox", - "label": future_i18n("Close an open window, collapse its tree"), + "label": future_i18n("Close an open window, collapse its tree", 's_close_open'), //"text": future_i18n("x-characters") }, // { @@ -130,140 +133,145 @@ vote at ${issue(125,true)}. // //"text": future_i18n("x-characters") // }, { - "tab": future_i18n("Behaviour"), - "group": future_i18n("When I..."), + "tab": future_i18n("Behaviour", 's_behaviour'), + "group": future_i18n("When I...", 's_when'), "name": S.RESTORE_ON_LAST_DELETED, "type": "checkbox", - "label": future_i18n("Restore the last-deleted window, reopen its tabs"), + "label": future_i18n("Restore the last-deleted window, reopen its tabs", 's_restore_del'), }, { - "tab": future_i18n("Behaviour"), - "group": future_i18n("When I..."), + "tab": future_i18n("Behaviour", 's_behaviour'), + "group": future_i18n("When I...", 's_when'), "name": S.JUMP_WITH_SORT_OPEN_TOP, "type": "checkbox", - "label": future_i18n('Sort open windows to the top, scroll to the top of the list'), + "label": future_i18n('Sort open windows to the top, scroll to the top of the list', 's_sort_scroll'), }, { - "tab": future_i18n("Behaviour"), - "group": future_i18n("When I..."), + "tab": future_i18n("Behaviour", 's_behaviour'), + "group": future_i18n("When I...", 's_when'), "name": S.NEW_WINS_AT_TOP, "type": "checkbox", - "label": future_i18n('Open a new window, move it to the top of the list'), + "label": future_i18n('Open a new window, move it to the top of the list', 's_new_top'), }, { // some extra descriptive text for S.NEW_WINS_AT_TOP - "tab": future_i18n("Behaviour"), - "group": future_i18n("When I..."), + "tab": future_i18n("Behaviour", 's_behaviour'), + "group": future_i18n("When I...", 's_when'), "type": "description", - "text": `This has the practical side-effect that all open + "text": future_i18n( + `This has the practical side-effect that all open windows will be sorted to the top when you open the TabFern window, even if you didn't check the "Sort - open windows" box above.` + open windows" box above.`, 's_new_top_txt') }, { - 'tab': future_i18n('Behaviour'), - 'group': future_i18n('Partly-open windows'), + 'tab': future_i18n('Behaviour', 's_behaviour'), + 'group': future_i18n('Partly-open windows', 's_partly'), 'name': S.S_OPEN_REST_ON_CLICK, 'type': 'radioButtons', - 'label': `When only some of the tabs in a window are open, + 'label': future_i18n( + `When only some of the tabs in a window are open, what should happen when you click the - name of the window?`, + name of the window?`, 's_partly_txt'), 'options': [ - {value: S.OROC_DO, text: 'Open all the remaining closed tabs'}, - {value: S.OROC_DO_NOT, text: 'Just bring the window to the front' + - ' (you can open the remaining tabs from the right-click menu)'}, + {value: S.OROC_DO, text: future_i18n('Open all the remaining closed tabs', 's_partly_openAllRem')}, + {value: S.OROC_DO_NOT, text: future_i18n('Just bring the window to the front' + + ' (you can open the remaining tabs from the right-click menu)', 's_partly_toFront')}, ], }, { - "tab": future_i18n("Behaviour"), - "group": future_i18n("Deleting windows"), + "tab": future_i18n("Behaviour", 's_behaviour'), + "group": future_i18n("Deleting windows", 's_del_win'), "name": S.CONFIRM_DEL_OF_SAVED, "type": "checkbox", - "label": future_i18n('Prompt for confirmation before deleting saved windows'), + "label": future_i18n('Prompt for confirmation before deleting saved windows', 's_del_SWin'), }, { - "tab": future_i18n("Behaviour"), - "group": future_i18n("Deleting windows"), + "tab": future_i18n("Behaviour", 's_behaviour'), + "group": future_i18n("Deleting windows", 's_del_win'), "name": S.CONFIRM_DEL_OF_UNSAVED, "type": "checkbox", - "label": future_i18n('Prompt for confirmation before deleting unsaved windows'), + "label": future_i18n('Prompt for confirmation before deleting unsaved windows', 's_del_UnsWin'), }, { - "tab": future_i18n("Behaviour"), - "group": future_i18n("Deleting tabs"), + "tab": future_i18n("Behaviour", 's_behaviour'), + "group": future_i18n("Deleting tabs", 's_del_tab'), "name": S.CONFIRM_DEL_OF_SAVED_TABS, "type": "checkbox", - "label": future_i18n('Prompt for confirmation before deleting tabs in saved windows'), + "label": future_i18n('Prompt for confirmation before deleting tabs in saved windows', 's_del_STab'), }, { - "tab": future_i18n("Behaviour"), - "group": future_i18n("Deleting tabs"), + "tab": future_i18n("Behaviour", 's_behaviour'), + "group": future_i18n("Deleting tabs", 's_del_tab'), "name": S.CONFIRM_DEL_OF_UNSAVED_TABS, "type": "checkbox", - "label": future_i18n('Prompt for confirmation before deleting tabs in unsaved windows'), + "label": future_i18n('Prompt for confirmation before deleting tabs in unsaved windows', 's_del_UnsTab'), }, { - "tab": future_i18n("Behaviour"), - "group": future_i18n("Music"), + "tab": future_i18n("Behaviour", 's_behaviour'), + "group": future_i18n("Music", 's_music'), "name": S.CONFIRM_DEL_OF_AUDIBLE_TABS, "type": "checkbox", - "label": future_i18n('Prompt for confirmation before closing or deleting a tab that is currently playing audio ()'), + "label": future_i18n('Prompt for confirmation before closing or deleting a tab that is currently playing audio ()', 's_music_tab', '()'), }, // Appearance { - "tab": future_i18n("Appearance"), + "tab": future_i18n("Appearance", 's_appear'), "group": '', "type": "description", - "text": future_i18n("Refresh the TabFern window to apply changes to these options. To refresh, click TabFern's title bar and hit F5."), + "text": future_i18n("Refresh the TabFern window to apply changes to these options. To refresh, click TabFern's title bar and hit F5.", 's_appear_txt'), }, { - "tab": future_i18n("Appearance"), - "group": future_i18n("Language"), + "tab": future_i18n("Appearance", 's_appear'), + "group": future_i18n("Language", 's_lang'), "name": S.S_LANG_NAME, "type": "popupButton", - "label": future_i18n('Select a language'), + "label": future_i18n('Select a language', 's_lang_txt'), + "id": "s_select_lang", 'options': [ - { value: '', text: 'Browser default' }, - { value: '_user_', text: '[ User defined ]' }, + { value: '', text: future_i18n('Browser default', 's_locDef') }, + { value: '_user_', text: future_i18n('[ User defined ]', 's_locUser') }, { value: 'en', text: 'English (EN)' }, { value: 'de', text: 'Deutsch (DE)' }, { value: 'fr', text: 'Français (FR)' }, - { value: 'ru', text: 'Russian (RU)' }, + { value: 'ru', text: 'русский (RU)' }, ], }, { - "tab": future_i18n("Appearance"), - "group": future_i18n("Language"), - "type": "description", - "text": future_i18n('Locale:'), + "tab": future_i18n("Appearance", 's_appear'), + "group": future_i18n("Language", 's_lang'), + "type": "button", + "text": future_i18n('Edit locale', 's_loc_btn'), + "id": 'user_locale_btn', }, { - "tab": future_i18n("Appearance"), - "group": future_i18n("Language"), + "tab": future_i18n("Appearance", 's_appear'), + "group": future_i18n("Language", 's_lang'), "name": S.S_LANG_LOCALE, "type": "textarea", - "NOlabel": future_i18n('Locale'), + "style": 'display: none;', + "id": 'user_locale', }, { - "tab": future_i18n("Appearance"), - "group": future_i18n("Scrollbars"), + "tab": future_i18n("Appearance", 's_appear'), + "group": future_i18n("Scrollbars", 's_scroll'), "name": S.HIDE_HORIZONTAL_SCROLLBARS, "type": "checkbox", - "label": future_i18n('Hide horizontal scrollbar'), + "label": future_i18n('Hide horizontal scrollbar', 's_hideHscroll'), }, { - "tab": future_i18n("Appearance"), - "group": future_i18n("Scrollbars"), + "tab": future_i18n("Appearance", 's_appear'), + "group": future_i18n("Scrollbars", 's_scroll'), "name": S.SKINNY_SCROLLBARS, "type": "checkbox", - "label": future_i18n('Skinny scrollbars'), + "label": future_i18n('Skinny scrollbars', 's_skinnyScroll'), }, { - "tab": future_i18n("Appearance"), - "group": future_i18n("Scrollbars"), + "tab": future_i18n("Appearance", 's_appear'), + "group": future_i18n("Scrollbars", 's_scroll'), "id": 'scrollbar-color-picker-label', //"name": '', // Don't save - settings.js handles that "type": "text", @@ -274,37 +282,37 @@ vote at ${issue(125,true)}. // appear properly in search results }, { - "tab": future_i18n("Appearance"), - "group": future_i18n("Tree"), + "tab": future_i18n("Appearance", 's_appear'), + "group": future_i18n("Tree", 's_tree'), "name": S.SHOW_TREE_LINES, "type": "checkbox", - "label": future_i18n('Show connecting lines between nodes'), + "label": future_i18n('Show connecting lines between nodes', 's_tree_txt'), }, // Theming options { - "tab": future_i18n("Appearance"), - "group": future_i18n("Theme"), + "tab": future_i18n("Appearance", 's_appear'), + "group": future_i18n("Theme", 's_theme'), "name": S.S_THEME_NAME, "type": "popupButton", - "label": future_i18n('Theme'), + "label": future_i18n('Theme', 's_theme'), 'options': [ { value: 'default-dark', text: 'Dark' }, { value: 'default', text: 'Light' }, ], }, { - "tab": future_i18n("Appearance"), - "group": future_i18n("Theme"), + "tab": future_i18n("Appearance", 's_appear'), + "group": future_i18n("Theme", 's_theme'), "name": S.S_BACKGROUND, "type": "text", - "label": future_i18n('Background color or image'), + "label": future_i18n('Background color or image', 's_background'), }, { - "tab": future_i18n("Appearance"), - "group": future_i18n("Theme"), + "tab": future_i18n("Appearance", 's_appear'), + "group": future_i18n("Theme", 's_theme'), "type": "description", - "text": + "text": future_i18n( `The background can be specified as a CSS color name, rgb(r,g,b), hsl(h,s,l), or a URL (data, https, chrome-extension, or file). To use images from your local disk (file): @@ -312,35 +320,35 @@ To use images from your local disk (file):
  • Check the box for "Allow access to file URLs" in chrome://extensions
  • Open the image you want in Chrome and copy the address out of the address bar (it will start with "file://")
  • -
  • Paste the "file://..." URL into the box above.
  • ` +
  • Paste the "file://..." URL into the box above.
  • `, 's_theme_txt') }, { - "tab": future_i18n("Appearance"), - "group": future_i18n("Tooltips"), + "tab": future_i18n("Appearance", 's_appear'), + "group": future_i18n("Tooltips", 's_tooltips'), "name": S.URL_IN_TOOLTIP, "type": "checkbox", - "label": future_i18n("Show URL in each item's tooltip"), + "label": future_i18n("Show URL in each item's tooltip", 's_TT_showURL'), }, { - "tab": future_i18n("Appearance"), - "group": future_i18n("Tooltips"), + "tab": future_i18n("Appearance", 's_appear'), + "group": future_i18n("Tooltips", 's_tooltips'), "name": S.TITLE_IN_TOOLTIP, "type": "checkbox", - "label": future_i18n("Show page title in each item's tooltip"), + "label": future_i18n("Show page title in each item's tooltip", 's_TT_showTitle'), }, { - 'tab': future_i18n('Appearance'), - 'group': future_i18n('Action-button order for windows'), + 'tab': future_i18n('Appearance', 's_appear'), + 'group': future_i18n('Action-button order for windows', 's_actionB_order'), "type": "description", - "text": future_i18n("This also sets the order of the corresponding buttons for tabs."), + "text": future_i18n("This also sets the order of the corresponding buttons for tabs.", 's_action_txt'), }, ]); if(S.ISSUE35) setting_definitions.push( { - 'tab': future_i18n('Appearance'), - 'group': future_i18n('Action-button order for windows'), + 'tab': future_i18n('Appearance', 's_appear'), + 'group': future_i18n('Action-button order for windows', 's_actionB_order'), 'name': S.S_WIN_ACTION_ORDER, 'type': 'radioButtons', 'options': [ @@ -356,11 +364,11 @@ if(S.ISSUE35) setting_definitions.push( setting_definitions.push( // Features { - "tab": "Features", - "group": "Context Menu", + "tab": future_i18n("Features", 's_features'), + "group": future_i18n("Context Menu", 's_cMenu'), "name": S.ENB_CONTEXT_MENU, "type": "checkbox", - "label": "Enable right-click menus" + refresh_message, + "label": future_i18n("Enable right-click menus" + refresh_message, 's_rcMenu', refresh_message), }, /* { @@ -421,7 +429,7 @@ setting_definitions.push( // }}}2 // Credits {{{2 { - "tab": future_i18n("Credits and thanks"), + "tab": future_i18n("Credits and thanks", 's_credits'), "group": 'TabFern', 'group_html':true, "type": "description", @@ -434,8 +442,8 @@ order within each category.` }, { - "tab": future_i18n("Credits and thanks"), - "group": future_i18n("Programming"), + "tab": future_i18n("Credits and thanks", 's_credits'), + "group": future_i18n("Programming", 's_progr'), 'group_html':true, "type": "description", "text": @@ -447,8 +455,8 @@ order within each category.`
` }, { - "tab": future_i18n("Credits and thanks"), - "group": future_i18n("Translation"), + "tab": future_i18n("Credits and thanks", 's_credits'), + "group": future_i18n("Translation", 's_transl'), 'group_html':true, "type": "description", "text": @@ -459,8 +467,8 @@ order within each category.` ` }, { - "tab": future_i18n("Credits and thanks"), - "group": future_i18n("Artwork and publicity"), + "tab": future_i18n("Credits and thanks", 's_credits'), + "group": future_i18n("Artwork and publicity", 's_art_pub'), 'group_html':true, "type": "description", "text": @@ -470,8 +478,8 @@ order within each category.` ` }, { - "tab": future_i18n("Credits and thanks"), - "group": future_i18n("Other"), + "tab": future_i18n("Credits and thanks", 's_credits'), + "group": future_i18n("Other", 's_other'), 'group_html':true, "type": "description", "text": @@ -485,7 +493,7 @@ order within each category.` // Changelog {{{1 setting_definitions.push( { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.2.1${brplain('2020-04-04')}`, 'group_html':true, "type": "description", @@ -527,7 +535,7 @@ recovered window will show up in TabFern as a separate, unsaved window ), }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.2.0${brplain('2019-04-07')}`, 'group_html':true, "type": "description", @@ -557,7 +565,7 @@ ${issue(171)}

` }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.1.19${brplain('2018-10-03')}`, 'group_html':true, "type": "description", @@ -565,7 +573,7 @@ ${issue(171)}

${issue([102, 131, 149],true)}`, }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.1.18${brplain('2018-09-17')}`, 'group_html':true, "type": "description", @@ -579,7 +587,7 @@ ${issue(143)} `, }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.1.17${brplain('2018-09-02')}`, 'group_html':true, "type": "description", @@ -617,7 +625,7 @@ and Chrome get out of sync. ${issue(127)} ` }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.1.16${brplain('2018-03-08')}`, 'group_html':true, "type": "description", @@ -630,7 +638,7 @@ Hopefully this saves you a little bit of time. ${issue(109)} ` }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.1.15${brplain('2018-02-09')}`, 'group_html':true, "type": "description", @@ -643,7 +651,7 @@ status! One step closer to `, }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.1.13${brplain('2017-12-12')}`, 'group_html':true, "type": "description", @@ -685,7 +693,7 @@ scrollbars." ${issue(68)} ` }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.1.12${brplain('2017-11-05')}`, 'group_html':true, "type": "description", @@ -714,7 +722,7 @@ ${issue(78)} ` }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.1.11${brplain('2017-10-19')}`, 'group_html':true, "type": "description", @@ -747,7 +755,7 @@ if you run across them. Thanks for considering this request! }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.1.10${brplain('2017-09-26')}`, 'group_html':true, "type": "description", @@ -769,7 +777,7 @@ locally-stored PDFs, and this helps me find them more quickly. `, }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Versions 0.1.8 and 0.1.9${brplain('2017-09-22')}`, 'group_html':true, "type": "description", @@ -792,7 +800,7 @@ ready yet.) ${issue(36)} `, }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.1.7${brplain('2017-09-18')}`, 'group_html':true, "type": "description", @@ -808,7 +816,7 @@ ready yet.) ${issue(36)} '' }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.1.6${brplain('2017-09-10')}`, 'group_html':true, "type": "description", @@ -821,7 +829,7 @@ ready yet.) ${issue(36)} '' }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.1.5${brplain('2017-09-07')}`, 'group_html':true, "type": "description", @@ -832,7 +840,7 @@ ready yet.) ${issue(36)} 'workarounds for Chrome 61 changes.' }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.1.4${brplain('2017-09-06')}`, 'group_html':true, "type": "description", @@ -842,7 +850,7 @@ saving of TabFern window position ${issue(22)}, and Expand All/Collapse All.` }, { - "tab": future_i18n("What's new?"), + "tab": future_i18n("What's new?", 's_whatsnew'), "group": `Version 0.1.2${brplain('2017-09-02')}`, 'group_html':true, "type": "description", From a59bb38861a62ba24594108a44d9a62b5f882f1f Mon Sep 17 00:00:00 2001 From: Marc Boucher Date: Tue, 5 May 2020 00:49:19 +0200 Subject: [PATCH 7/7] Update __custom.css added style for "select language" form elements --- app/settings/__custom.css | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/app/settings/__custom.css b/app/settings/__custom.css index 0f9fc9bf..e77faa41 100755 --- a/app/settings/__custom.css +++ b/app/settings/__custom.css @@ -25,4 +25,20 @@ span.plain { text-decoration: none; } +#user_locale { + display: none; + resize: vertical; +} + +#user_locale_btn { + display: none; + margin-left: 0.5em; +} +.floatLeft { + float: left; +} +.show { + display: initial; +} + /* vi: set ts=4 sts=4 sw=4 et ai: */