From 033cdc3fdfad743295fc00e1eb8f844880dea6bc Mon Sep 17 00:00:00 2001 From: Stephen Cameron Date: Thu, 24 Aug 2017 17:55:37 +0200 Subject: [PATCH] Refactor locale handling and implement new locale switcher design. WIP #1597 @6 --- images/interface.svg | 4 ++ js/libs/fluidbook/fluidbook.l10n.js | 33 +++++++++++++- js/libs/fluidbook/fluidbook.menu.js | 13 ++---- js/libs/fluidbook/fluidbook.nav.js | 68 +++++++++++------------------ style/mmenu/mmenu.less | 2 +- style/nav-horizontal.less | 32 +++++++++++++- 6 files changed, 97 insertions(+), 55 deletions(-) diff --git a/images/interface.svg b/images/interface.svg index b7ab5936..07c181e7 100644 --- a/images/interface.svg +++ b/images/interface.svg @@ -84,4 +84,8 @@ + + + + diff --git a/js/libs/fluidbook/fluidbook.l10n.js b/js/libs/fluidbook/fluidbook.l10n.js index dd48a971..ea186090 100644 --- a/js/libs/fluidbook/fluidbook.l10n.js +++ b/js/libs/fluidbook/fluidbook.l10n.js @@ -88,7 +88,8 @@ FluidbookL10N.prototype = { var o = {lang: l[0], flag: l[1], url: url, langName: l[3], countryName: l[4]}; - $this.multilang[$this.multilang.length] = o; + // $this.multilang[$this.multilang.length] = o; + $this.multilang[l[0]] = o; // Indexed by language code to allow easier lookups later }); }, getActiveFlag: function () { @@ -116,6 +117,36 @@ FluidbookL10N.prototype = { } } }, + + getCurrentLanguageName: function () { + return this.getLanguageName(this.getActiveLang()); + }, + + // Format the language name according to the settings + getLanguageName: function (languageCode) { + + var details = this.multilang[languageCode], + name = ''; + + if (details === undefined) { + return name; + } + + switch(this.fluidbook.datas.multilangDisplay) { + case 'lang': + name = details.langName; + break; + case 'lang_country': + name = details.langName + ' (' + details.countryName + ')'; + break; + case 'country_lang': + name = details.countryName + ' (' + details.langName + ')'; + break; + } + + return name; + }, + updateTranslations: function () { var $this = this; $("#q").attr('placeholder', this.__('search')); diff --git a/js/libs/fluidbook/fluidbook.menu.js b/js/libs/fluidbook/fluidbook.menu.js index 798bd661..0b89d6c7 100644 --- a/js/libs/fluidbook/fluidbook.menu.js +++ b/js/libs/fluidbook/fluidbook.menu.js @@ -287,7 +287,9 @@ FluidbookMenu.prototype = { view += '
'; view += '
    '; var $this = this; - $.each(this.fluidbook.l10n.multilang, function (k, v) { + + Object.keys(this.fluidbook.l10n.multilang).forEach(function (langCode) { + var v = this.fluidbook.l10n.multilang[langCode]; var url = v.url; if (url.substr(0, 3) == '../' && !$this.fluidbook.datas.standalone) { url = '../' + url; @@ -296,14 +298,7 @@ FluidbookMenu.prototype = { __('Langue') . ' (' . __('Pays') . ')' => 'lang_country', __('Pays') . ' (' . __('Langue') . ')' => 'country_lang'));*/ - var name = ''; - if ($this.fluidbook.datas.multilangDisplay == 'lang') { - name = v.langName; - } else if ($this.fluidbook.datas.multilangDisplay == 'lang_country') { - name = v.langName + ' (' + v.countryName + ')'; - } else if ($this.fluidbook.datas.multilangDisplay == 'country_lang') { - name = v.countryName + ' (' + v.langName + ')'; - } + var name = $this.fluidbook.l10n.getLanguageName(langCode); var c = ''; if ($this.fluidbook.datas.phonegap) { diff --git a/js/libs/fluidbook/fluidbook.nav.js b/js/libs/fluidbook/fluidbook.nav.js index 7f7d90b7..064e99c3 100644 --- a/js/libs/fluidbook/fluidbook.nav.js +++ b/js/libs/fluidbook/fluidbook.nav.js @@ -137,10 +137,10 @@ FluidbookNav.prototype = { } } - // Only the Menu should have titles - if (navType == 'menu') { + // Only the Menu should have titles + the locales icon in the horizontal menu + if (navType == 'menu' || id == 'locales') { if (title != undefined && title != '') { - res += ' ' + this.fluidbook.l10n.__(title); + res += ' ' + this.fluidbook.l10n.__(title) + ''; } } @@ -223,13 +223,21 @@ FluidbookNav.prototype = { } - var all = "index,chapters,search,friend,print,bookmark,archives,basket,fullscreen,sound,3d,help".split(","); - var hide = array_diff(all, this.fluidbook.datas.navOrder); - var loop = [].concat(this.fluidbook.datas.navOrder).concat(hide); + // All possible icons and default ordering + var all = "index,chapters,search,friend,print,bookmark,archives,basket,fullscreen,sound,3d,help,lang".split(","); + // var hide = array_diff(all, this.fluidbook.datas.navOrder); // Array of icons that aren't in the navOrder list and should be hidden + // var loop = [].concat(this.fluidbook.datas.navOrder).concat(hide); + var loop = this.fluidbook.datas.navOrder; + var localeIconIndex; + + // If the locales icon is included, it should always be placed last in the list for formatting reasons + if ((localeIconIndex = loop.indexOf('lang')) !== -1) { + loop.push(loop.splice(localeIconIndex, 1)[0]); // Push to end of array + } for (var e in loop) { var icon = loop[e]; - var visible = hide.indexOf(icon) == -1; + //var visible = hide.indexOf(icon) == -1; var link; if (icon == 'home' && !skipHome) { @@ -326,7 +334,8 @@ FluidbookNav.prototype = { link = this.addLink(navType, 'interface-print', '#', 'print', 'print', 'print'); } else if (icon == 'lang' && this.fluidbook.l10n.multilangEnabled) { - link = this.addMultilangLink(navType); + // Note: the "!" at the beginning of the title/help parameters means that we don't want these strings translated + link = this.addLink(navType, 'interface-locales', '#/locales', 'locales', '!' + this.fluidbook.l10n.getCurrentLanguageName(), '!Select Language'); } else if (icon == 'archives') { if (this.fluidbook.datas.archivesLink != '') { @@ -354,9 +363,9 @@ FluidbookNav.prototype = { } - if (!visible) { - $(link).addClass('hidden'); - } + // if (!visible) { + // $(link).addClass('hidden'); + // } } @@ -495,37 +504,6 @@ FluidbookNav.prototype = { }, - addMultilangLink: function (navType) { - var $nav = this.getNavFromType(navType), - id = 'locales', - elementID = navType + '_' + id; - - if ($nav.find('#' + elementID).length > 0) { - return; - } - - var label = this.fluidbook.l10n.__('Select language'); - var url = '#/locales'; - var flagHolder = ''; - var link; - if (navType == 'horizontalNav') { - link = ''+ flagHolder +''; - } else { - link = ''+ flagHolder +' '+ label +''; - } - - var flag = this.fluidbook.l10n.getActiveFlag(); - if (flag === false) { - return; - } - - // Add to menu and set flag - $nav.find('ul').append('
  • ' + link + '
  • '); - $nav.find(".locale-flag").css('background-image', 'url("images/flags/' + flag + '.png")'); - - return link; - }, - getMenuCloseButton: function () { var $this = this, buttonID = 'menuClose'; @@ -728,6 +706,12 @@ FluidbookNav.prototype = { }, setInterface: function () { + // Ensure we don't add interface elements more than once + if (this._inited['interface'] == true) { + return; + } + this._inited['interface'] = true; + var res = this.getLink('interface-previous', '#', 'previous', '', '', '', false); res += this.getLink('interface-next', '#', 'next', '', '', '', false); $('#interface').append(res); diff --git a/style/mmenu/mmenu.less b/style/mmenu/mmenu.less index 9d7d5e38..25e40b36 100644 --- a/style/mmenu/mmenu.less +++ b/style/mmenu/mmenu.less @@ -75,7 +75,7 @@ html.mm-opening .mm-menu.mm-opened[class*=mm-pagedim]~#mm-blocker { background-color: @menu-background; color: @menu-text; - a, span { + a, li > span { padding: 10px 10px 10px 29px; img { diff --git a/style/nav-horizontal.less b/style/nav-horizontal.less index fa4fa651..eacf9500 100644 --- a/style/nav-horizontal.less +++ b/style/nav-horizontal.less @@ -6,6 +6,17 @@ @media all and (max-width: @menu-breakpoint) { display: none; } + + // Locales icon + text link + &_locales { + border-left: 1px solid; + margin-right: 1.5em; + margin-left: 14px; + + .svg-icon { + margin: 0 7px 0 30px !important; + } + } } #iconList { @@ -17,12 +28,29 @@ display: inline-block; } + a { + color: @icon-color; + display: inline-block; + } + .svg-icon { width: 25px; height: 25px; - margin: 0 18px; + margin: 0 17px; color: @icon-color; + vertical-align: middle; } +} - +// Small dropdown arrow after locale name +.icon-locales .menu-item-title:after { + content: ''; + width: 6px; + height: 6px; + vertical-align: middle; + margin: -3px 0 0 10px; + border-style: solid; + border-width: 0 2px 2px 0; // Make right angle for arrow + transform: rotate(45deg); // Rotate to downwards position + display: inline-block; } \ No newline at end of file -- 2.39.5