From 1b5a8035391346088ebdf4792b99c324c1731151 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Wed, 20 Sep 2023 21:00:28 -0400 Subject: [PATCH] Continuing core refactor, particularly for LocalizationSystem (followup from ca9be6003, 43e7f89ad, also see #961) Continuing to remove localization operations from Context. The idea here is to remove "magic" from the code. - Removed `context.t`, `.tHtml`, `.tAppend` Code must go through the LocalizationSystem to do these things now. --- modules/Context.js | 3 - modules/core/LocalizationSystem.js | 2 +- modules/core/lib/Preset.js | 15 +- modules/core/lib/ValidationIssue.js | 7 +- modules/services/ImproveOsmService.js | 12 +- modules/services/KeepRightService.js | 11 +- modules/services/StreetsideService.js | 8 +- modules/ui/account.js | 5 +- modules/ui/attribution.js | 19 +- modules/ui/changeset_editor.js | 8 +- modules/ui/cmd.js | 28 +-- modules/ui/confirm.js | 3 +- modules/ui/contributors.js | 16 +- modules/ui/data_editor.js | 8 +- modules/ui/data_header.js | 3 +- modules/ui/feature_info.js | 13 +- modules/ui/field_help.js | 11 +- modules/ui/fields/access.js | 3 +- modules/ui/fields/address.js | 9 +- modules/ui/fields/cycleway.js | 6 +- modules/ui/fields/radio.js | 12 +- modules/ui/fields/roadspeed.js | 6 +- modules/ui/fields/textarea.js | 8 +- modules/ui/form_fields.js | 3 +- modules/ui/geolocate.js | 7 +- modules/ui/improveOSM_comments.js | 3 +- modules/ui/improveOSM_editor.js | 13 +- modules/ui/improveOSM_header.js | 5 +- modules/ui/info.js | 5 +- modules/ui/issues_info.js | 11 +- modules/ui/keepRight_editor.js | 13 +- modules/ui/keepRight_header.js | 7 +- modules/ui/map_in_map.js | 14 +- modules/ui/note_comments.js | 5 +- modules/ui/note_editor.js | 34 +-- modules/ui/note_header.js | 7 +- modules/ui/note_report.js | 3 +- modules/ui/osmose_editor.js | 7 +- modules/ui/osmose_header.js | 4 +- modules/ui/panes/background.js | 12 +- modules/ui/panes/issues.js | 8 +- modules/ui/panes/map_data.js | 8 +- modules/ui/panes/preferences.js | 8 +- modules/ui/rapid_first_edit_dialog.js | 9 +- modules/ui/rapid_poweruser_features_dialog.js | 11 +- modules/ui/rapid_service_license.js | 4 +- modules/ui/rapid_splash.js | 17 +- modules/ui/rapid_view_manage_datasets.js | 29 +-- modules/ui/rapid_whatsnew.js | 18 +- modules/ui/sections/grid_display_options.js | 21 +- modules/ui/sections/map_features.js | 11 +- .../ui/sections/map_interaction_options.js | 10 +- modules/ui/sections/map_style_options.js | 12 +- modules/ui/sections/photo_overlays.js | 56 ++--- modules/ui/sections/privacy.js | 16 +- modules/ui/sections/validation_issues.js | 11 +- modules/ui/sections/validation_options.js | 5 +- modules/ui/sections/validation_rules.js | 15 +- modules/ui/sections/validation_status.js | 9 +- modules/ui/settings/custom_background.js | 41 ++-- modules/ui/settings/custom_data.js | 35 +-- modules/ui/shortcuts.js | 18 +- modules/ui/success.js | 51 ++--- modules/ui/tools/download_osc.js | 7 +- modules/ui/tools/modes.js | 15 +- modules/ui/tools/notes.js | 9 +- modules/ui/tools/rapid_features.js | 9 +- modules/ui/tools/save.js | 9 +- modules/ui/tooltip.js | 3 +- modules/ui/version.js | 11 +- modules/ui/view_on_keepRight.js | 3 +- modules/ui/view_on_osm.js | 3 +- modules/ui/view_on_osmose.js | 3 +- test/spec/ui/confirm.js | 201 +++++++++--------- 74 files changed, 589 insertions(+), 476 deletions(-) diff --git a/modules/Context.js b/modules/Context.js index d0eefb049d..2943e1d9f0 100644 --- a/modules/Context.js +++ b/modules/Context.js @@ -127,9 +127,6 @@ export class Context extends EventEmitter { // LocalizationSystem const l10n = this.systems.l10n; - this.t = l10n.t; - this.tHtml = l10n.tHtml; - this.tAppend = l10n.tAppend; if (this._prelocale) { // set preferred locale codes, if we have them this.systems.l10n.preferredLocaleCodes = this._prelocale; } diff --git a/modules/core/LocalizationSystem.js b/modules/core/LocalizationSystem.js index 9a6be62d10..83b2ccb54a 100644 --- a/modules/core/LocalizationSystem.js +++ b/modules/core/LocalizationSystem.js @@ -80,7 +80,7 @@ export class LocalizationSystem extends AbstractSystem { this._languageNames = {}; this._scriptNames = {}; - // When called like `context.t`, don't lose `this` + // Ensure methods used as callbacks always have `this` bound correctly. this.t = this.t.bind(this); this.tHtml = this.tHtml.bind(this); this.tAppend = this.tAppend.bind(this); diff --git a/modules/core/lib/Preset.js b/modules/core/lib/Preset.js index a6f6ba92e6..636f898847 100644 --- a/modules/core/lib/Preset.js +++ b/modules/core/lib/Preset.js @@ -120,31 +120,36 @@ export class Preset { t(scope, options) { - return this.context.t(`_tagging.presets.presets.${this.id}.${scope}`, options); + const l10n = this.context.systems.l10n; + return l10n.t(`_tagging.presets.presets.${this.id}.${scope}`, options); } tHtml(scope, options) { - return this.context.tHtml(`_tagging.presets.presets.${this.id}.${scope}`, options); + const l10n = this.context.systems.l10n; + return l10n.tHtml(`_tagging.presets.presets.${this.id}.${scope}`, options); } tAppend (scope, options) { - return this.context.tAppend(`_tagging.presets.presets.${this.id}.${scope}`, options); + const l10n = this.context.systems.l10n; + return l10n.tAppend(`_tagging.presets.presets.${this.id}.${scope}`, options); } subtitle() { if (this.suggestion) { + const l10n = this.context.systems.l10n; let path = this.id.split('/'); path.pop(); // remove brand name - return this.context.t('_tagging.presets.presets.' + path.join('/') + '.name'); + return l10n.t('_tagging.presets.presets.' + path.join('/') + '.name'); } return null; } subtitleLabel() { if (this.suggestion) { + const l10n = this.context.systems.l10n; let path = this.id.split('/'); path.pop(); // remove brand name - return this.context.tHtml('_tagging.presets.presets.' + path.join('/') + '.name'); + return l10n.tHtml('_tagging.presets.presets.' + path.join('/') + '.name'); } return null; } diff --git a/modules/core/lib/ValidationIssue.js b/modules/core/lib/ValidationIssue.js index 1634b08b13..2b1136cc65 100644 --- a/modules/core/lib/ValidationIssue.js +++ b/modules/core/lib/ValidationIssue.js @@ -45,11 +45,14 @@ export class ValidationIssue { // For warnings, create an "ignore" option if (this.severity === 'warning') { + const l10n = this.context.systems.l10n; + const validator = this.context.systems.validator; + fixes.push(new ValidationFix({ - title: this.context.tHtml('issues.fix.ignore_issue.title'), + title: l10n.tHtml('issues.fix.ignore_issue.title'), icon: 'rapid-icon-close', onClick: () => { - this.context.systems.validator.ignoreIssue(this.id); + validator.ignoreIssue(this.id); } })); } diff --git a/modules/services/ImproveOsmService.js b/modules/services/ImproveOsmService.js index 2b478c3450..a6af131aa7 100644 --- a/modules/services/ImproveOsmService.js +++ b/modules/services/ImproveOsmService.js @@ -122,6 +122,7 @@ export class ImproveOsmService extends AbstractSystem { // determine the needed tiles to cover the view const context = this.context; + const l10n = context.systems.l10n; const tiles = this._tiler.getTiles(context.projection).tiles; // abort inflight requests that are no longer needed @@ -193,7 +194,7 @@ export class ImproveOsmService extends AbstractSystem { d.replacements = { percentage: feature.percentOfTrips, num_trips: feature.numberOfTrips, - highway: this._linkErrorObject(context.t('QA.keepRight.error_parts.highway')), + highway: this._linkErrorObject(l10n.t('QA.keepRight.error_parts.highway')), from_node: this._linkEntity('n' + feature.fromNodeId), to_node: this._linkEntity('n' + feature.toNodeId) }; @@ -222,12 +223,12 @@ export class ImproveOsmService extends AbstractSystem { d.replacements = { num_trips: numberOfTrips, - geometry_type: context.t(`QA.improveOSM.geometry_types.${geoType}`) + geometry_type: l10n.t(`QA.improveOSM.geometry_types.${geoType}`) }; // -1 trips indicates data came from a 3rd party if (numberOfTrips === -1) { - d.desc = context.t('QA.improveOSM.error_types.mr.description_alt', d.replacements); + d.desc = l10n.t('QA.improveOSM.error_types.mr.description_alt', d.replacements); } this._cache.data[d.id] = d; @@ -270,7 +271,7 @@ export class ImproveOsmService extends AbstractSystem { from_way: this._linkEntity('w' + from_way), to_way: this._linkEntity('w' + to_way), travel_direction: dir_of_travel, - junction: this._linkErrorObject(context.t('QA.keepRight.error_parts.this_node')) + junction: this._linkErrorObject(l10n.t('QA.keepRight.error_parts.this_node')) }; this._cache.data[d.id] = d; @@ -566,7 +567,8 @@ export class ImproveOsmService extends AbstractSystem { 360: 'north' }; - return this.context.t(`QA.improveOSM.directions.${compass[dir]}`); + const l10n = this.context.systems.l10n; + return l10n.t(`QA.improveOSM.directions.${compass[dir]}`); } diff --git a/modules/services/KeepRightService.js b/modules/services/KeepRightService.js index c391eaf3a1..196487cc94 100644 --- a/modules/services/KeepRightService.js +++ b/modules/services/KeepRightService.js @@ -415,6 +415,7 @@ export class KeepRightService extends AbstractSystem { _tokenReplacements(d) { if (!(d instanceof QAItem)) return; + const l10n = this.context.systems.l10n; const htmlRegex = new RegExp(/<\/[a-z][\s\S]*>/); const replacements = {}; @@ -454,7 +455,7 @@ export class KeepRightService extends AbstractSystem { } else { const compare = capture.toLowerCase(); if (this._krData.localizeStrings[compare]) { // some replacement strings can be localized - capture = this.context.t('QA.keepRight.error_parts.' + this._krData.localizeStrings[compare]); + capture = l10n.t('QA.keepRight.error_parts.' + this._krData.localizeStrings[compare]); } } @@ -466,9 +467,11 @@ export class KeepRightService extends AbstractSystem { _parseError(capture, idType) { + const l10n = this.context.systems.l10n; const compare = capture.toLowerCase(); + if (this._krData.localizeStrings[compare]) { // some replacement strings can be localized - capture = this.context.t('QA.keepRight.error_parts.' + this._krData.localizeStrings[compare]); + capture = l10n.t('QA.keepRight.error_parts.' + this._krData.localizeStrings[compare]); } switch (idType) { @@ -544,7 +547,7 @@ export class KeepRightService extends AbstractSystem { const match = item.match(/\#(\d+)\((.+)\)?/); if (match !== null && match.length > 2) { newList.push(linkEntity('w' + match[1]) + ' ' + - this.context.t('QA.keepRight.errorTypes.231.layer', { layer: match[2] }) + l10n.t('QA.keepRight.errorTypes.231.layer', { layer: match[2] }) ); } } @@ -577,7 +580,7 @@ export class KeepRightService extends AbstractSystem { const match = capture.match(/\(including the name (\'.+\')\)/); if (match?.length) { - return this.context.t('QA.keepRight.errorTypes.370.including_the_name', { name: match[1] }); + return l10n.t('QA.keepRight.errorTypes.370.including_the_name', { name: match[1] }); } return ''; } diff --git a/modules/services/StreetsideService.js b/modules/services/StreetsideService.js index 89a511d9d5..96810a3c65 100644 --- a/modules/services/StreetsideService.js +++ b/modules/services/StreetsideService.js @@ -307,6 +307,8 @@ export class StreetsideService extends AbstractSystem { let d = this._cache.bubbles.get(bubbleID); const context = this.context; + const l10n = context.systems.l10n; + let viewer = context.container().select('.photoviewer'); if (!viewer.empty()) { viewer.datum(d); @@ -367,7 +369,7 @@ export class StreetsideService extends AbstractSystem { label .append('span') - .text(this.context.t('streetside.hires')); + .text(l10n.t('streetside.hires')); let captureInfo = line1 @@ -408,7 +410,7 @@ export class StreetsideService extends AbstractSystem { .attr('target', '_blank') .attr('href', 'https://www.bing.com/maps?cp=' + d.loc[1] + '~' + d.loc[0] + '&lvl=17&dir=' + d.ca + '&style=x&v=2&sV=1') - .text(this.context.t('streetside.view_on_bing')); + .text(l10n.t('streetside.view_on_bing')); line2 .append('a') @@ -416,7 +418,7 @@ export class StreetsideService extends AbstractSystem { .attr('target', '_blank') .attr('href', 'https://www.bing.com/maps/privacyreport/streetsideprivacyreport?bubbleid=' + encodeURIComponent(d.id) + '&focus=photo&lat=' + d.loc[1] + '&lng=' + d.loc[0] + '&z=17') - .text(this.context.t('streetside.report')); + .text(l10n.t('streetside.report')); // const streetsideImagesApi = 'https://t.ssl.ak.tiles.virtualearth.net/tiles/'; diff --git a/modules/ui/account.js b/modules/ui/account.js index 27205276f9..c8fd2e9925 100644 --- a/modules/ui/account.js +++ b/modules/ui/account.js @@ -2,6 +2,7 @@ import { uiIcon } from './icon'; export function uiAccount(context) { + const l10n = context.systems.l10n; const osm = context.services.osm; @@ -58,7 +59,7 @@ export function uiAccount(context) { loginLogout .classed('hide', false) .select('a') - .text(context.t('logout')) + .text(l10n.t('logout')) .on('click', e => { e.preventDefault(); osm.logout(); @@ -69,7 +70,7 @@ export function uiAccount(context) { loginLogout .classed('hide', false) .select('a') - .text(context.t('login')) + .text(l10n.t('login')) .on('click', e => { e.preventDefault(); osm.authenticate(); diff --git a/modules/ui/attribution.js b/modules/ui/attribution.js index 321f262881..bf8346d496 100644 --- a/modules/ui/attribution.js +++ b/modules/ui/attribution.js @@ -3,7 +3,10 @@ import { select as d3_select } from 'd3-selection'; export function uiAttribution(context) { - const imagerySystem = context.systems.imagery; + const imagery = context.systems.imagery; + const l10n = context.systems.l10n; + const map = context.systems.map; + let _selection = d3_select(null); @@ -41,7 +44,7 @@ export function uiAttribution(context) { .attr('target', '_blank'); } - const terms_text = context.t(`imagery.${d.idtx}.attribution.text`, { default: d.terms_text || d.id || d.name }); + const terms_text = l10n.t(`imagery.${d.idtx}.attribution.text`, { default: d.terms_text || d.id || d.name }); if (d.icon && !d.overlay) { attribution @@ -60,7 +63,7 @@ export function uiAttribution(context) { let copyright = attributions.selectAll('.copyright-notice') .data(d => { - let notice = d.copyrightNotices(context.systems.map.zoom(), context.systems.map.extent()); + let notice = d.copyrightNotices(map.zoom(), map.extent()); return notice ? [notice] : []; }); @@ -78,12 +81,12 @@ export function uiAttribution(context) { function update() { - let baselayer = imagerySystem.baseLayerSource(); + let baselayer = imagery.baseLayerSource(); _selection .call(render, (baselayer ? [baselayer] : []), 'base-layer-attribution'); - const z = context.systems.map.zoom(); - let overlays = imagerySystem.overlayLayerSources() || []; + const z = map.zoom(); + let overlays = imagery.overlayLayerSources() || []; _selection .call(render, overlays.filter(s => s.validZoom(z)), 'overlay-layer-attribution'); } @@ -92,8 +95,8 @@ export function uiAttribution(context) { return function(selection) { _selection = selection; - imagerySystem.on('imagerychange', update); - context.systems.map.on('draw', _throttle(update, 400, { leading: false })); + imagery.on('imagerychange', update); + map.on('draw', _throttle(update, 400, { leading: false })); update(); }; diff --git a/modules/ui/changeset_editor.js b/modules/ui/changeset_editor.js index 12fd18a5db..fe2aed6dc3 100644 --- a/modules/ui/changeset_editor.js +++ b/modules/ui/changeset_editor.js @@ -9,7 +9,9 @@ import { utilRebind, utilTriggerEvent } from '../util'; export function uiChangesetEditor(context) { - var dispatch = d3_dispatch('change'); + const l10n = context.systems.l10n; + const dispatch = d3_dispatch('change'); + var formFields = uiFormFields(context); var commentCombo = uiCombobox(context, 'comment').caseSensitive(true); var _uifields; @@ -104,9 +106,9 @@ export function uiChangesetEditor(context) { .append('a') .attr('target', '_blank') .call(uiIcon('#rapid-icon-alert', 'inline')) - .attr('href', context.t('commit.google_warning_link')) + .attr('href', l10n.t('commit.google_warning_link')) .append('span') - .text(context.t('commit.google_warning')); + .text(l10n.t('commit.google_warning')); commentEnter .transition() diff --git a/modules/ui/cmd.js b/modules/ui/cmd.js index 00b44c1670..f11af13ddc 100644 --- a/modules/ui/cmd.js +++ b/modules/ui/cmd.js @@ -39,23 +39,23 @@ export let uiCmd = function(code) { uiCmd.display = function(context, code) { if (code.length !== 1) return code; - const t = context.t; + const l10n = context.systems.l10n; const detected = utilDetect(); const mac = (detected.os === 'mac'); const replacements = { - '⌘': mac ? '⌘ ' + t('shortcuts.key.cmd') : t('shortcuts.key.ctrl'), - '⇧': mac ? '⇧ ' + t('shortcuts.key.shift') : t('shortcuts.key.shift'), - '⌥': mac ? '⌥ ' + t('shortcuts.key.option') : t('shortcuts.key.alt'), - '⌃': mac ? '⌃ ' + t('shortcuts.key.ctrl') : t('shortcuts.key.ctrl'), - '⌫': mac ? '⌫ ' + t('shortcuts.key.delete') : t('shortcuts.key.backspace'), - '⌦': mac ? '⌦ ' + t('shortcuts.key.del') : t('shortcuts.key.del'), - '↖': mac ? '↖ ' + t('shortcuts.key.pgup') : t('shortcuts.key.pgup'), - '↘': mac ? '↘ ' + t('shortcuts.key.pgdn') : t('shortcuts.key.pgdn'), - '⇞': mac ? '⇞ ' + t('shortcuts.key.home') : t('shortcuts.key.home'), - '⇟': mac ? '⇟ ' + t('shortcuts.key.end') : t('shortcuts.key.end'), - '↵': mac ? '⏎ ' + t('shortcuts.key.return') : t('shortcuts.key.enter'), - '⎋': mac ? '⎋ ' + t('shortcuts.key.esc') : t('shortcuts.key.esc'), - '☰': mac ? '☰ ' + t('shortcuts.key.menu') : t('shortcuts.key.menu'), + '⌘': mac ? '⌘ ' + l10n.t('shortcuts.key.cmd') : l10n.t('shortcuts.key.ctrl'), + '⇧': mac ? '⇧ ' + l10n.t('shortcuts.key.shift') : l10n.t('shortcuts.key.shift'), + '⌥': mac ? '⌥ ' + l10n.t('shortcuts.key.option') : l10n.t('shortcuts.key.alt'), + '⌃': mac ? '⌃ ' + l10n.t('shortcuts.key.ctrl') : l10n.t('shortcuts.key.ctrl'), + '⌫': mac ? '⌫ ' + l10n.t('shortcuts.key.delete') : l10n.t('shortcuts.key.backspace'), + '⌦': mac ? '⌦ ' + l10n.t('shortcuts.key.del') : l10n.t('shortcuts.key.del'), + '↖': mac ? '↖ ' + l10n.t('shortcuts.key.pgup') : l10n.t('shortcuts.key.pgup'), + '↘': mac ? '↘ ' + l10n.t('shortcuts.key.pgdn') : l10n.t('shortcuts.key.pgdn'), + '⇞': mac ? '⇞ ' + l10n.t('shortcuts.key.home') : l10n.t('shortcuts.key.home'), + '⇟': mac ? '⇟ ' + l10n.t('shortcuts.key.end') : l10n.t('shortcuts.key.end'), + '↵': mac ? '⏎ ' + l10n.t('shortcuts.key.return') : l10n.t('shortcuts.key.enter'), + '⎋': mac ? '⎋ ' + l10n.t('shortcuts.key.esc') : l10n.t('shortcuts.key.esc'), + '☰': mac ? '☰ ' + l10n.t('shortcuts.key.menu') : l10n.t('shortcuts.key.menu'), }; return replacements[code] || code; diff --git a/modules/ui/confirm.js b/modules/ui/confirm.js index 7466eddb3c..dffc4e69f5 100644 --- a/modules/ui/confirm.js +++ b/modules/ui/confirm.js @@ -2,6 +2,7 @@ import { uiModal } from './modal'; export function uiConfirm(context, selection) { + const l10n = context.systems.l10n; let modalSelection = uiModal(selection); modalSelection.select('.modal') @@ -24,7 +25,7 @@ export function uiConfirm(context, selection) { .append('button') .attr('class', 'button ok-button action') .on('click.confirm', () => modalSelection.remove()) - .text(context.t('confirm.okay')) + .text(l10n.t('confirm.okay')) .node() .focus(); diff --git a/modules/ui/contributors.js b/modules/ui/contributors.js index 0ddd4e0ca4..e15a6b8ce6 100644 --- a/modules/ui/contributors.js +++ b/modules/ui/contributors.js @@ -5,7 +5,11 @@ import { uiIcon } from './icon'; export function uiContributors(context) { - var osm = context.services.osm; + const editor = context.systems.editor; + const l10n = context.systems.l10n; + const map = context.systems.map; + const osm = context.services.osm; + var debouncedUpdate = debounce(function() { update(); }, 1000); var limit = 4; var hidden = false; @@ -16,7 +20,7 @@ export function uiContributors(context) { if (!osm) return; let users = {}; - let entities = context.systems.editor.intersects(context.systems.map.extent()); + let entities = editor.intersects(map.extent()); entities.forEach(function(entity) { if (entity && entity.user) users[entity.user] = true; @@ -47,16 +51,16 @@ export function uiContributors(context) { count.append('a') .attr('target', '_blank') .attr('href', function() { - return osm.changesetsURL(context.systems.map.center(), context.systems.map.zoom()); + return osm.changesetsURL(map.center(), map.zoom()); }) .html(othersNum); wrap.append('span') - .html(context.tHtml('contributors.truncated_list', { n: othersNum, users: userList.html(), count: count.html() })); + .html(l10n.tHtml('contributors.truncated_list', { n: othersNum, users: userList.html(), count: count.html() })); } else { wrap.append('span') - .html(context.tHtml('contributors.list', { users: userList.html() })); + .html(l10n.tHtml('contributors.list', { users: userList.html() })); } if (!u.length) { @@ -79,6 +83,6 @@ export function uiContributors(context) { update(); osm.on('loaded.contributors', debouncedUpdate); - context.systems.map.on('draw', debouncedUpdate); + map.on('draw', debouncedUpdate); }; } diff --git a/modules/ui/data_editor.js b/modules/ui/data_editor.js index c778bbd179..5dd64a34c3 100644 --- a/modules/ui/data_editor.js +++ b/modules/ui/data_editor.js @@ -5,9 +5,11 @@ import { uiSectionRawTagEditor } from './sections/raw_tag_editor'; export function uiDataEditor(context) { - let dataHeader = uiDataHeader(context); - let rawTagEditor = uiSectionRawTagEditor(context, 'custom-data-tag-editor') + const l10n = context.systems.l10n; + const dataHeader = uiDataHeader(context); + const rawTagEditor = uiSectionRawTagEditor(context, 'custom-data-tag-editor') .readOnlyTags([/./]); + let _datum; @@ -27,7 +29,7 @@ export function uiDataEditor(context) { headerEnter .append('h3') - .html(context.tHtml('map_data.title')); + .html(l10n.tHtml('map_data.title')); let body = selection.selectAll('.body') diff --git a/modules/ui/data_header.js b/modules/ui/data_header.js index ee58a03b64..50d06950c3 100644 --- a/modules/ui/data_header.js +++ b/modules/ui/data_header.js @@ -2,6 +2,7 @@ import { uiIcon } from './icon'; export function uiDataHeader(context) { + const l10n = context.systems.l10n; let _datum; function dataHeader(selection) { @@ -27,7 +28,7 @@ export function uiDataHeader(context) { headerEnter .append('div') .attr('class', 'data-header-label') - .html(context.tHtml('map_data.layers.custom.title')); + .html(l10n.tHtml('map_data.layers.custom.title')); } diff --git a/modules/ui/feature_info.js b/modules/ui/feature_info.js index 00692414a1..640e4daa31 100644 --- a/modules/ui/feature_info.js +++ b/modules/ui/feature_info.js @@ -2,17 +2,18 @@ import { uiTooltip } from './tooltip'; export function uiFeatureInfo(context) { - const filterSystem = context.systems.filters; + const l10n = context.systems.l10n; + const filters = context.systems.filters; function update(selection) { - const stats = filterSystem.stats(); - const hidden = filterSystem.hidden(); + const stats = filters.stats(); + const hidden = filters.hidden(); let count = 0; const hiddenList = Array.from(hidden).map(k => { if (stats[k]) { count += stats[k]; - return context.t('inspector.title_count', { title: context.tHtml(`feature.${k}.description`), count: stats[k] }); + return l10n.t('inspector.title_count', { title: l10n.tHtml(`feature.${k}.description`), count: stats[k] }); } else { return null; } @@ -28,7 +29,7 @@ export function uiFeatureInfo(context) { selection.append('a') .attr('class', 'chip') .attr('href', '#') - .html(context.tHtml('feature_info.hidden_warning', { count: count })) + .html(l10n.tHtml('feature_info.hidden_warning', { count: count })) .call(tooltipBehavior) .on('click', (d3_event) => { tooltipBehavior.hide(); @@ -45,6 +46,6 @@ export function uiFeatureInfo(context) { return function(selection) { update(selection); - filterSystem.on('filterchange', () => update(selection)); + filters.on('filterchange', () => update(selection)); }; } diff --git a/modules/ui/field_help.js b/modules/ui/field_help.js index 9ff6257743..669b1291f7 100644 --- a/modules/ui/field_help.js +++ b/modules/ui/field_help.js @@ -9,6 +9,7 @@ //// It borrows some code from uiHelp // //export function uiFieldHelp(context, fieldName) { +// const l10n = context.systems.l10n; // var fieldHelp = {}; // var _inspector = d3_select(null); // var _wrap = d3_select(null); @@ -51,8 +52,8 @@ // var fieldHelpHeadings = {}; // // var replacements = { -// distField: context.tHtml('restriction.controls.distance'), -// viaField: context.tHtml('restriction.controls.via'), +// distField: l10n.tHtml('restriction.controls.distance'), +// viaField: l10n.tHtml('restriction.controls.via'), // fromShadow: icon('#rapid-turn-shadow', 'inline shadow from'), // allowShadow: icon('#rapid-turn-shadow', 'inline shadow allow'), // restrictShadow: icon('#rapid-turn-shadow', 'inline shadow restrict'), @@ -70,12 +71,12 @@ // var subkey = helpkey + '.' + part; // var depth = fieldHelpHeadings[subkey]; // is this subkey a heading? // var hhh = depth ? Array(depth + 1).join('#') + ' ' : ''; // if so, prepend with some ##'s -// return all + hhh + context.tHtml(subkey, replacements) + '\n\n'; +// return all + hhh + l10n.tHtml(subkey, replacements) + '\n\n'; // }, ''); // // return { // key: helpkey, -// title: context.tHtml(helpkey + '.title'), +// title: l10n.tHtml(helpkey + '.title'), // html: marked.parse(text.trim()) // }; // }); @@ -194,7 +195,7 @@ // titleEnter // .append('h2') // .attr('class', isRTL ? 'fr' : 'fl') -// .html(context.tHtml('help.field.' + fieldName + '.title')); +// .html(l10n.tHtml('help.field.' + fieldName + '.title')); // // titleEnter // .append('button') diff --git a/modules/ui/fields/access.js b/modules/ui/fields/access.js index 12a3ac36db..0afb943ae0 100644 --- a/modules/ui/fields/access.js +++ b/modules/ui/fields/access.js @@ -6,6 +6,7 @@ import { utilGetSetValue, utilNoAuto, utilRebind } from '../../util'; export function uiFieldAccess(context, uifield) { + const l10n = context.systems.l10n; const dispatch = d3_dispatch('change'); let items = d3_select(null); let _tags; @@ -217,7 +218,7 @@ export function uiFieldAccess(context, uifield) { }) .attr('placeholder', d => { if (tags[d] && Array.isArray(tags[d])) { - return context.t('inspector.multiple_values'); + return l10n.t('inspector.multiple_values'); } if (d === 'access') { return 'yes'; diff --git a/modules/ui/fields/address.js b/modules/ui/fields/address.js index a005259248..54df306121 100644 --- a/modules/ui/fields/address.js +++ b/modules/ui/fields/address.js @@ -10,10 +10,11 @@ import { utilGetSetValue, utilNoAuto, utilRebind } from '../../util'; export function uiFieldAddress(context, uifield) { - const editor = context.systems.editor; const dataloader = context.systems.dataloader; - + const editor = context.systems.editor; + const l10n = context.systems.l10n; const dispatch = d3_dispatch('change'); + let _selection = d3_select(null); let _wrap = d3_select(null); @@ -220,7 +221,7 @@ export function uiFieldAddress(context, uifield) { const center = uifield.entityExtent.center(); let countryCode; if (context.inIntro) { // localize the address format for the walkthrough - countryCode = context.t('intro.graph.countrycode'); + countryCode = l10n.t('intro.graph.countrycode'); } else { countryCode = iso1A2Code(center); } @@ -255,7 +256,7 @@ export function uiFieldAddress(context, uifield) { return inputSelection.attr('placeholder', function(subfield) { const key = uifield.key + ':' + subfield.id; if (_tags && Array.isArray(_tags[key])) { - return context.t('inspector.multiple_values'); + return l10n.t('inspector.multiple_values'); } if (_countryCode) { const localkey = subfield.id + '!' + _countryCode; diff --git a/modules/ui/fields/cycleway.js b/modules/ui/fields/cycleway.js index fe3389fb88..209d2ca2fc 100644 --- a/modules/ui/fields/cycleway.js +++ b/modules/ui/fields/cycleway.js @@ -6,7 +6,9 @@ import { utilGetSetValue, utilNoAuto, utilRebind } from '../../util'; export function uiFieldCycleway(context, uifield) { - var dispatch = d3_dispatch('change'); + const l10n = context.systems.l10n; + const dispatch = d3_dispatch('change'); + var items = d3_select(null); var wrap = d3_select(null); var _tags; @@ -147,7 +149,7 @@ export function uiFieldCycleway(context, uifield) { }) .attr('placeholder', function(d) { if (Array.isArray(tags.cycleway) || Array.isArray(tags[d])) { - return context.t('inspector.multiple_values'); + return l10n.t('inspector.multiple_values'); } return uifield.placeholder; }) diff --git a/modules/ui/fields/radio.js b/modules/ui/fields/radio.js index 9ce63db86e..dde07922f3 100644 --- a/modules/ui/fields/radio.js +++ b/modules/ui/fields/radio.js @@ -9,7 +9,9 @@ export { uiFieldRadio as uiFieldStructureRadio }; export function uiFieldRadio(context, uifield) { - var dispatch = d3_dispatch('change'); + const l10n = context.systems.l10n; + const dispatch = d3_dispatch('change'); + var placeholder = d3_select(null); var wrap = d3_select(null); var labels = d3_select(null); @@ -127,7 +129,7 @@ export function uiFieldRadio(context, uifield) { .append('span') .attr('class', 'label structure-label-type') .attr('for', 'preset-input-' + selected) - .html(context.tHtml('inspector.radio.structure.type')); + .html(l10n.tHtml('inspector.radio.structure.type')); typeEnter .append('div') @@ -172,7 +174,7 @@ export function uiFieldRadio(context, uifield) { .append('span') .attr('class', 'label structure-label-layer') .attr('for', 'preset-input-layer') - .html(context.tHtml('inspector.radio.structure.layer')); + .html(l10n.tHtml('inspector.radio.structure.layer')); layerEnter .append('div') @@ -288,14 +290,14 @@ export function uiFieldRadio(context, uifield) { }) .classed('mixed', isMixed) .attr('title', function(d) { - return isMixed(d) ? context.t('inspector.unshared_value_tooltip') : null; + return isMixed(d) ? l10n.t('inspector.unshared_value_tooltip') : null; }); var selection = radios.filter(function() { return this.checked; }); if (selection.empty()) { - placeholder.html(context.tHtml('inspector.none')); + placeholder.html(l10n.tHtml('inspector.none')); } else { placeholder.html(selection.attr('value')); _oldType[selection.datum()] = tags[selection.datum()]; diff --git a/modules/ui/fields/roadspeed.js b/modules/ui/fields/roadspeed.js index e45dec2c7e..7500f7cecf 100644 --- a/modules/ui/fields/roadspeed.js +++ b/modules/ui/fields/roadspeed.js @@ -7,7 +7,9 @@ import { utilGetSetValue, utilNoAuto, utilRebind } from '../../util'; export function uiFieldRoadspeed(context, uifield) { - var dispatch = d3_dispatch('change'); + const l10n = context.systems.l10n; + const dispatch = d3_dispatch('change'); + var unitInput = d3_select(null); var input = d3_select(null); var _tags; @@ -128,7 +130,7 @@ export function uiFieldRoadspeed(context, uifield) { utilGetSetValue(input, typeof value === 'string' ? value : '') .attr('title', isMixed ? value.filter(Boolean).join('\n') : null) - .attr('placeholder', isMixed ? context.t('inspector.multiple_values') : uifield.placeholder) + .attr('placeholder', isMixed ? l10n.t('inspector.multiple_values') : uifield.placeholder) .classed('mixed', isMixed); }; diff --git a/modules/ui/fields/textarea.js b/modules/ui/fields/textarea.js index 96bef1a1b3..c436aab879 100644 --- a/modules/ui/fields/textarea.js +++ b/modules/ui/fields/textarea.js @@ -5,7 +5,9 @@ import { utilGetSetValue, utilNoAuto, utilRebind } from '../../util'; export function uiFieldTextarea(context, uifield) { - let dispatch = d3_dispatch('change'); + const l10n = context.systems.l10n; + const dispatch = d3_dispatch('change'); + let input = d3_select(null); let _tags; @@ -53,8 +55,8 @@ export function uiFieldTextarea(context, uifield) { _tags = tags; const key = uifield.key; const isMixed = Array.isArray(tags[key]); - const placeholder = isMixed ? context.t('inspector.multiple_values') : - (uifield.placeholder || context.t('inspector.unknown')); + const placeholder = isMixed ? l10n.t('inspector.multiple_values') : + (uifield.placeholder || l10n.t('inspector.unknown')); utilGetSetValue(input, !isMixed && tags[key] ? tags[key] : '') .attr('title', isMixed ? tags[key].filter(Boolean).join('\n') : undefined) diff --git a/modules/ui/form_fields.js b/modules/ui/form_fields.js index 59583c1c96..279d58fef8 100644 --- a/modules/ui/form_fields.js +++ b/modules/ui/form_fields.js @@ -5,6 +5,7 @@ import { utilGetSetValue, utilNoAuto } from '../util'; export function uiFormFields(context) { + const l10n = context.systems.l10n; let moreCombo = uiCombobox(context, 'more-fields').minItems(1); let _uifields = []; let _lastPlaceholder = ''; @@ -82,7 +83,7 @@ export function uiFormFields(context) { moreEnter .append('span') - .text(context.t('inspector.add_fields')); + .text(l10n.t('inspector.add_fields')); more = moreEnter .merge(more); diff --git a/modules/ui/geolocate.js b/modules/ui/geolocate.js index bddce7b1b6..8b0a1508f8 100644 --- a/modules/ui/geolocate.js +++ b/modules/ui/geolocate.js @@ -14,7 +14,8 @@ const GEOLOCATE_OPTIONS = { export function uiGeolocate(context) { - let _uiModal = uiLoading(context).message(context.tHtml('geolocate.locating')).blocking(true); + const l10n = context.systems.l10n; + let _uiModal = uiLoading(context).message(l10n.tHtml('geolocate.locating')).blocking(true); let _layer = context.scene().layers.get('map-ui'); let _enabled = false; let _timeoutID; @@ -75,7 +76,7 @@ export function uiGeolocate(context) { function error() { if (_enabled) { // user may have disabled it before the callback fires context.systems.ui.flash - .label(context.tHtml('geolocate.location_unavailable')) + .label(l10n.tHtml('geolocate.location_unavailable')) .iconName('#rapid-icon-geolocate')(); } @@ -108,7 +109,7 @@ export function uiGeolocate(context) { .call(uiIcon('#rapid-icon-geolocate', 'light')) .call(uiTooltip(context) .placement(isRTL ? 'right' : 'left') - .title(context.tHtml('geolocate.title')) + .title(l10n.tHtml('geolocate.title')) ); }; } diff --git a/modules/ui/improveOSM_comments.js b/modules/ui/improveOSM_comments.js index 60d5f61ef0..faa1492611 100644 --- a/modules/ui/improveOSM_comments.js +++ b/modules/ui/improveOSM_comments.js @@ -4,6 +4,7 @@ import { uiIcon } from './icon'; export function uiImproveOsmComments(context) { + const l10n = context.systems.l10n; let _qaItem; @@ -64,7 +65,7 @@ export function uiImproveOsmComments(context) { metadataEnter .append('div') .attr('class', 'comment-date') - .html(d => context.tHtml('note.status.commented', { when: localeDateString(d.timestamp) })); + .html(d => l10n.tHtml('note.status.commented', { when: localeDateString(d.timestamp) })); mainEnter .append('div') diff --git a/modules/ui/improveOSM_editor.js b/modules/ui/improveOSM_editor.js index 1a63df16eb..1809400712 100644 --- a/modules/ui/improveOSM_editor.js +++ b/modules/ui/improveOSM_editor.js @@ -9,6 +9,7 @@ import { utilNoAuto, utilRebind } from '../util'; export function uiImproveOsmEditor(context) { + const l10n = context.systems.l10n; const improveosm = context.services.improveOSM; const dispatch = d3_dispatch('change'); const qaDetails = uiImproveOsmDetails(context); @@ -32,7 +33,7 @@ export function uiImproveOsmEditor(context) { headerEnter .append('h3') - .html(context.tHtml('QA.improveOSM.title')); + .html(l10n.tHtml('QA.improveOSM.title')); let body = selection.selectAll('.body') .data([0]); @@ -77,12 +78,12 @@ export function uiImproveOsmEditor(context) { saveSectionEnter .append('h4') .attr('class', '.qa-save-header') - .html(context.tHtml('note.newComment')); + .html(l10n.tHtml('note.newComment')); saveSectionEnter .append('textarea') .attr('class', 'new-comment-input') - .attr('placeholder', context.t('QA.keepRight.comment_placeholder')) + .attr('placeholder', l10n.t('QA.keepRight.comment_placeholder')) .attr('maxlength', 1000) .property('value', d => d.newComment) .call(utilNoAuto) @@ -132,7 +133,7 @@ export function uiImproveOsmEditor(context) { buttonEnter .append('button') .attr('class', 'button comment-button action') - .html(context.tHtml('QA.keepRight.save_comment')); + .html(l10n.tHtml('QA.keepRight.save_comment')); buttonEnter .append('button') @@ -158,7 +159,7 @@ export function uiImproveOsmEditor(context) { buttonSection.select('.close-button') .html(d => { const andComment = (d.newComment ? '_comment' : ''); - return context.tHtml(`QA.keepRight.close${andComment}`); + return l10n.tHtml(`QA.keepRight.close${andComment}`); }) .on('click.close', function(d3_event, d) { this.blur(); // avoid keeping focus on the button - iD#4641 @@ -171,7 +172,7 @@ export function uiImproveOsmEditor(context) { buttonSection.select('.ignore-button') .html(d => { const andComment = (d.newComment ? '_comment' : ''); - return context.tHtml(`QA.keepRight.ignore${andComment}`); + return l10n.tHtml(`QA.keepRight.ignore${andComment}`); }) .on('click.ignore', function(d3_event, d) { this.blur(); // avoid keeping focus on the button - iD#4641 diff --git a/modules/ui/improveOSM_header.js b/modules/ui/improveOSM_header.js index c43f120551..fffac7992d 100644 --- a/modules/ui/improveOSM_header.js +++ b/modules/ui/improveOSM_header.js @@ -2,14 +2,15 @@ import { Color } from 'pixi.js'; export function uiImproveOsmHeader(context) { + const l10n = context.systems.l10n; let _qaItem; function issueTitle(d) { const issueKey = d.issueKey; d.replacements = d.replacements || {}; - d.replacements.default = context.tHtml('inspector.unknown'); // special key `default` works as a fallback string - return context.tHtml(`QA.improveOSM.error_types.${issueKey}.title`, d.replacements); + d.replacements.default = l10n.tHtml('inspector.unknown'); // special key `default` works as a fallback string + return l10n.tHtml(`QA.improveOSM.error_types.${issueKey}.title`, d.replacements); } diff --git a/modules/ui/info.js b/modules/ui/info.js index f284164d2e..5fc8439030 100644 --- a/modules/ui/info.js +++ b/modules/ui/info.js @@ -16,6 +16,7 @@ import { UiPanelMeasurement } from './panels/UiPanelMeasurement'; * and provide extra information about the map or the selection. */ export function uiInfo(context) { + const l10n = context.systems.l10n; const panels = { background: new UiPanelBackground(context), history: new UiPanelHistory(context), @@ -137,7 +138,7 @@ export function uiInfo(context) { // bind ⌘I to show/hide all panels context.keybinding() - .on(uiCmd('⌘' + context.t('info_panels.key')), e => { + .on(uiCmd('⌘' + l10n.t('info_panels.key')), e => { e.stopImmediatePropagation(); e.preventDefault(); info.toggle(); @@ -145,7 +146,7 @@ export function uiInfo(context) { // bind keys to show/hide individual panels panelIDs.forEach(k => { - const key = context.t(`info_panels.${k}.key`, { default: null }); + const key = l10n.t(`info_panels.${k}.key`, { default: null }); if (!key) return; context.keybinding() diff --git a/modules/ui/issues_info.js b/modules/ui/issues_info.js index e39bb37d47..288bcd629c 100644 --- a/modules/ui/issues_info.js +++ b/modules/ui/issues_info.js @@ -5,8 +5,9 @@ import { uiTooltip } from './tooltip'; export function uiIssuesInfo(context) { + const l10n = context.systems.l10n; + const storage = context.systems.storage; const validator = context.systems.validator; - const prefs = context.systems.storage; let warningsItem = { id: 'warnings', @@ -26,15 +27,15 @@ export function uiIssuesInfo(context) { function update(selection) { let shownItems = []; let liveIssues = validator.getIssues({ - what: prefs.getItem('validate-what') ?? 'edited', - where: prefs.getItem('validate-where') ?? 'all' + what: storage.getItem('validate-what') ?? 'edited', + where: storage.getItem('validate-where') ?? 'all' }); if (liveIssues.length) { warningsItem.count = liveIssues.length; shownItems.push(warningsItem); } - if (prefs.getItem('validate-what') === 'all') { + if (storage.getItem('validate-what') === 'all') { let resolvedIssues = validator.getResolvedIssues(); if (resolvedIssues.length) { resolvedItem.count = resolvedIssues.length; @@ -56,7 +57,7 @@ export function uiIssuesInfo(context) { let tooltip = uiTooltip(context) .placement('top') - .title(context.tHtml(d.descriptionID)); + .title(l10n.tHtml(d.descriptionID)); chipSelection .call(tooltip) diff --git a/modules/ui/keepRight_editor.js b/modules/ui/keepRight_editor.js index 45ffa7db9b..6f04b80158 100644 --- a/modules/ui/keepRight_editor.js +++ b/modules/ui/keepRight_editor.js @@ -9,6 +9,7 @@ import { utilNoAuto, utilRebind } from '../util'; export function uiKeepRightEditor(context) { + const l10n = context.systems.l10n; const keepright = context.services.keepRight; const dispatch = d3_dispatch('change'); const qaDetails = uiKeepRightDetails(context); @@ -31,7 +32,7 @@ export function uiKeepRightEditor(context) { headerEnter .append('h3') - .html(context.tHtml('QA.keepRight.title')); + .html(l10n.tHtml('QA.keepRight.title')); let body = selection.selectAll('.body') @@ -87,12 +88,12 @@ export function uiKeepRightEditor(context) { saveSectionEnter .append('h4') .attr('class', '.qa-save-header') - .html(context.tHtml('QA.keepRight.comment')); + .html(l10n.tHtml('QA.keepRight.comment')); saveSectionEnter .append('textarea') .attr('class', 'new-comment-input') - .attr('placeholder', context.t('QA.keepRight.comment_placeholder')) + .attr('placeholder', l10n.t('QA.keepRight.comment_placeholder')) .attr('maxlength', 1000) .property('value', d => d.newComment || d.comment) .call(utilNoAuto) @@ -143,7 +144,7 @@ export function uiKeepRightEditor(context) { buttonEnter .append('button') .attr('class', 'button comment-button action') - .html(context.tHtml('QA.keepRight.save_comment')); + .html(l10n.tHtml('QA.keepRight.save_comment')); buttonEnter .append('button') @@ -169,7 +170,7 @@ export function uiKeepRightEditor(context) { buttonSection.select('.close-button') // select and propagate data .html(d => { const andComment = (d.newComment ? '_comment' : ''); - return context.tHtml(`QA.keepRight.close${andComment}`); + return l10n.tHtml(`QA.keepRight.close${andComment}`); }) .on('click.close', function(d3_event, d) { this.blur(); // avoid keeping focus on the button - #4641 @@ -182,7 +183,7 @@ export function uiKeepRightEditor(context) { buttonSection.select('.ignore-button') // select and propagate data .html(d => { const andComment = (d.newComment ? '_comment' : ''); - return context.tHtml(`QA.keepRight.ignore${andComment}`); + return l10n.tHtml(`QA.keepRight.ignore${andComment}`); }) .on('click.ignore', function(d3_event, d) { this.blur(); // avoid keeping focus on the button - #4641 diff --git a/modules/ui/keepRight_header.js b/modules/ui/keepRight_header.js index 929d5d19fa..119df652ae 100644 --- a/modules/ui/keepRight_header.js +++ b/modules/ui/keepRight_header.js @@ -4,17 +4,18 @@ import { uiIcon } from './icon'; export function uiKeepRightHeader(context) { + const l10n = context.systems.l10n; let _qaItem; function issueTitle(d) { - const unknown = context.tHtml('inspector.unknown'); + const unknown = l10n.tHtml('inspector.unknown'); let replacements = d.replacements || {}; replacements.default = unknown; // special key `default` works as a fallback string - let title = context.tHtml(`QA.keepRight.errorTypes.${d.itemType}.title`, replacements); + let title = l10n.tHtml(`QA.keepRight.errorTypes.${d.itemType}.title`, replacements); if (title === unknown) { - title = context.tHtml(`QA.keepRight.errorTypes.${d.parentIssueType}.title`, replacements); + title = l10n.tHtml(`QA.keepRight.errorTypes.${d.parentIssueType}.title`, replacements); } return title; } diff --git a/modules/ui/map_in_map.js b/modules/ui/map_in_map.js index cab41c4849..375bea3152 100644 --- a/modules/ui/map_in_map.js +++ b/modules/ui/map_in_map.js @@ -8,6 +8,8 @@ import { PixiLayerBackgroundTiles } from '../pixi/PixiLayerBackgroundTiles'; export function uiMapInMap(context) { + const l10n = context.systems.l10n; + const map = context.systems.map; function mapInMap(selection) { let projection = new Projection(); @@ -119,7 +121,7 @@ export function uiMapInMap(context) { updateProjection(); _gesture = null; - context.systems.map.center(projection.invert(_cMini)); // recenter main map.. + map.center(projection.invert(_cMini)); // recenter main map.. } @@ -128,7 +130,7 @@ export function uiMapInMap(context) { * Update the minimap projection and d3-zoom transform */ function updateProjection() { - const loc = context.systems.map.center(); + const loc = map.center(); const tMain = context.projection.transform(); const zMain = geoScaleToZoom(tMain.k); const zMini = Math.max(zMain - _zDiff, 0.5); @@ -165,7 +167,7 @@ export function uiMapInMap(context) { * Recalculates the position and size of the bounding box rectangle on the minimap */ function updateBoundingBox() { - const bbox = context.systems.map.extent().bbox(); + const bbox = map.extent().bbox(); const topLeftPoint = projection.project([bbox.minX, bbox.maxY]); const bottomRightPoint = projection.project([bbox.maxX, bbox.minY]); const boxWidth = Math.abs(bottomRightPoint[0] - topLeftPoint[0]); @@ -308,7 +310,7 @@ export function uiMapInMap(context) { stage.eventMode = 'none'; stage.sortableChildren = false; - const mainRenderer = context.systems.map.renderer; + const mainRenderer = map.renderer; // Construct the scene.. const miniRenderer = { // Mock Renderer @@ -340,7 +342,7 @@ export function uiMapInMap(context) { _dMini = [width, height]; _cMini = vecScale(_dMini, 0.5); - context.systems.map.on('draw', () => updateMinimap()); + map.on('draw', () => updateMinimap()); } wrapEnter @@ -356,7 +358,7 @@ export function uiMapInMap(context) { updateMinimap(); - context.keybinding().on(context.t('background.minimap.key'), toggle); + context.keybinding().on(l10n.t('background.minimap.key'), toggle); } return mapInMap; diff --git a/modules/ui/note_comments.js b/modules/ui/note_comments.js index 587bba3e2a..61f6b57087 100644 --- a/modules/ui/note_comments.js +++ b/modules/ui/note_comments.js @@ -4,6 +4,7 @@ import { uiIcon } from './icon'; export function uiNoteComments(context) { + const l10n = context.systems.l10n; let _note; @@ -51,13 +52,13 @@ export function uiNoteComments(context) { .attr('target', '_blank'); } selection - .html(d => d.user || context.tHtml('note.anonymous')); + .html(d => d.user || l10n.tHtml('note.anonymous')); }); metadataEnter .append('div') .attr('class', 'comment-date') - .html(d => context.t(`note.status.${d.action}`, { when: localeDateString(d.date) })); + .html(d => l10n.t(`note.status.${d.action}`, { when: localeDateString(d.date) })); mainEnter .append('div') diff --git a/modules/ui/note_editor.js b/modules/ui/note_editor.js index 247dc1aa5a..f4dfc4bb36 100644 --- a/modules/ui/note_editor.js +++ b/modules/ui/note_editor.js @@ -11,11 +11,13 @@ import { utilNoAuto, utilRebind } from '../util'; export function uiNoteEditor(context) { - var dispatch = d3_dispatch('change'); - var noteComments = uiNoteComments(context); - var noteHeader = uiNoteHeader(context); - var _note; - var _newNote; + const l10n = context.systems.l10n; + const dispatch = d3_dispatch('change'); + const noteComments = uiNoteComments(context); + const noteHeader = uiNoteHeader(context); + + var _note; + var _newNote; function noteEditor(selection) { @@ -36,7 +38,7 @@ export function uiNoteEditor(context) { headerEnter .append('h3') - .html(context.tHtml('note.title')); + .html(l10n.tHtml('note.title')); var body = selection.selectAll('.body') @@ -97,13 +99,13 @@ export function uiNoteEditor(context) { .append('h4') .attr('class', '.note-save-header') .html(function() { - return _note.isNew() ? context.t('note.newDescription') : context.t('note.newComment'); + return _note.isNew() ? l10n.t('note.newDescription') : l10n.t('note.newComment'); }); var commentTextarea = noteSaveEnter .append('textarea') .attr('class', 'new-comment-input') - .attr('placeholder', context.t('note.inputPlaceholder')) + .attr('placeholder', l10n.t('note.inputPlaceholder')) .attr('maxlength', 1000) .property('value', function(d) { return d.newComment; }) .call(utilNoAuto) @@ -205,14 +207,14 @@ export function uiNoteEditor(context) { authEnter .append('span') - .html(context.tHtml('note.login')); + .html(l10n.tHtml('note.login')); authEnter .append('a') .attr('target', '_blank') .call(uiIcon('#rapid-icon-out-link', 'inline')) .append('span') - .html(context.tHtml('login')) + .html(l10n.tHtml('login')) .on('click.note-login', function(d3_event) { d3_event.preventDefault(); osm.authenticate(); @@ -233,7 +235,7 @@ export function uiNoteEditor(context) { prose = prose.enter() .append('p') .attr('class', 'note-save-prose') - .html(context.tHtml('note.upload_explanation')) + .html(l10n.tHtml('note.upload_explanation')) .merge(prose); osm.userDetails(function(err, user) { @@ -256,7 +258,7 @@ export function uiNoteEditor(context) { .attr('target', '_blank'); prose - .html(context.tHtml('note.upload_explanation_with_user', { user: userLink.html() })); + .html(l10n.tHtml('note.upload_explanation_with_user', { user: userLink.html() })); }); } @@ -282,12 +284,12 @@ export function uiNoteEditor(context) { buttonEnter .append('button') .attr('class', 'button cancel-button secondary-action') - .html(context.tHtml('confirm.cancel')); + .html(l10n.tHtml('confirm.cancel')); buttonEnter .append('button') .attr('class', 'button save-button action') - .html(context.tHtml('note.save')); + .html(l10n.tHtml('note.save')); } else { buttonEnter @@ -297,7 +299,7 @@ export function uiNoteEditor(context) { buttonEnter .append('button') .attr('class', 'button comment-button action') - .html(context.tHtml('note.comment')); + .html(l10n.tHtml('note.comment')); } @@ -317,7 +319,7 @@ export function uiNoteEditor(context) { .html(function(d) { var action = (d.status === 'open' ? 'close' : 'open'); var andComment = (d.newComment ? '_comment' : ''); - return context.t('note.' + action + andComment); + return l10n.t('note.' + action + andComment); }) .on('click.status', clickStatus); diff --git a/modules/ui/note_header.js b/modules/ui/note_header.js index 4c239485af..b099e2bf99 100644 --- a/modules/ui/note_header.js +++ b/modules/ui/note_header.js @@ -2,6 +2,7 @@ import { uiIcon } from './icon'; export function uiNoteHeader(context) { + const l10n = context.systems.l10n; let _note; @@ -47,10 +48,10 @@ export function uiNoteHeader(context) { .attr('class', 'note-header-label') .text(d => { if (_note.isNew()) { - return context.t('note.new'); + return l10n.t('note.new'); } else { - return context.t('note.note') + ' ' + d.id + ' ' + - (d.status === 'closed' ? context.t('note.closed') : ''); + return l10n.t('note.note') + ' ' + d.id + ' ' + + (d.status === 'closed' ? l10n.t('note.closed') : ''); } }); } diff --git a/modules/ui/note_report.js b/modules/ui/note_report.js index 22781aa3c4..efdaec692f 100644 --- a/modules/ui/note_report.js +++ b/modules/ui/note_report.js @@ -3,6 +3,7 @@ import { uiIcon } from './icon'; export function uiNoteReport(context) { + const l10n = context.systems.l10n; let _note; function noteReport(selection) { @@ -29,7 +30,7 @@ export function uiNoteReport(context) { linkEnter .append('span') - .text(context.t('note.report')); + .text(l10n.t('note.report')); } diff --git a/modules/ui/osmose_editor.js b/modules/ui/osmose_editor.js index 5c2fbe6ca8..2550c1d2ce 100644 --- a/modules/ui/osmose_editor.js +++ b/modules/ui/osmose_editor.js @@ -9,6 +9,7 @@ import { utilRebind } from '../util'; export function uiOsmoseEditor(context) { + const l10n = context.systems.l10n; const osmose = context.services.osmose; const dispatch = d3_dispatch('change'); const qaDetails = uiOsmoseDetails(context); @@ -32,7 +33,7 @@ export function uiOsmoseEditor(context) { headerEnter .append('h3') - .html(context.tHtml('QA.osmose.title')); + .html(l10n.tHtml('QA.osmose.title')); let body = selection.selectAll('.body') .data([0]); @@ -113,7 +114,7 @@ export function uiOsmoseEditor(context) { .merge(buttonEnter); buttonSection.select('.close-button') - .html(context.tHtml('QA.keepRight.close')) + .html(l10n.tHtml('QA.keepRight.close')) .on('click.close', function(d3_event, d) { this.blur(); // avoid keeping focus on the button - iD#4641 if (osmose) { @@ -123,7 +124,7 @@ export function uiOsmoseEditor(context) { }); buttonSection.select('.ignore-button') - .html(context.tHtml('QA.keepRight.ignore')) + .html(l10n.tHtml('QA.keepRight.ignore')) .on('click.ignore', function(d3_event, d) { this.blur(); // avoid keeping focus on the button - iD#4641 if (osmose) { diff --git a/modules/ui/osmose_header.js b/modules/ui/osmose_header.js index ed8ce1a7ed..21d9f73a8b 100644 --- a/modules/ui/osmose_header.js +++ b/modules/ui/osmose_header.js @@ -2,11 +2,13 @@ import { Color } from 'pixi.js'; export function uiOsmoseHeader(context) { + const l10n = context.systems.l10n; const osmose = context.services.osmose; let _qaItem; + function issueTitle(d) { - const unknown = context.t('inspector.unknown'); + const unknown = l10n.t('inspector.unknown'); if (!osmose || !d) return unknown; // Issue titles supplied by Osmose diff --git a/modules/ui/panes/background.js b/modules/ui/panes/background.js index fd83fb36e1..210acab851 100644 --- a/modules/ui/panes/background.js +++ b/modules/ui/panes/background.js @@ -8,10 +8,12 @@ import { uiSectionOverlayList } from '../sections/overlay_list'; export function uiPaneBackground(context) { - var backgroundPane = uiPane(context, 'background') - .key(context.t('background.key')) - .label(context.tHtml('background.title')) - .description(context.tHtml('background.description')) + const l10n = context.systems.l10n; + + return uiPane(context, 'background') + .key(l10n.t('background.key')) + .label(l10n.tHtml('background.title')) + .description(l10n.tHtml('background.description')) .iconName('rapid-icon-layers') .sections([ uiSectionBackgroundList(context), @@ -21,6 +23,4 @@ export function uiPaneBackground(context) { uiSectionBackgroundDisplayOptions(context), uiSectionBackgroundOffset(context) ]); - - return backgroundPane; } diff --git a/modules/ui/panes/issues.js b/modules/ui/panes/issues.js index a361f81659..6f8cc275b4 100644 --- a/modules/ui/panes/issues.js +++ b/modules/ui/panes/issues.js @@ -7,10 +7,12 @@ import { uiSectionValidationStatus } from '../sections/validation_status'; export function uiPaneIssues(context) { + const l10n = context.systems.l10n; + return uiPane(context, 'issues') - .key(context.t('issues.key')) - .label(context.tHtml('issues.title')) - .description(context.tHtml('issues.title')) + .key(l10n.t('issues.key')) + .label(l10n.tHtml('issues.title')) + .description(l10n.tHtml('issues.title')) .iconName('rapid-icon-alert') .sections([ uiSectionValidationOptions(context), diff --git a/modules/ui/panes/map_data.js b/modules/ui/panes/map_data.js index 5107160ef7..b545b22994 100644 --- a/modules/ui/panes/map_data.js +++ b/modules/ui/panes/map_data.js @@ -7,10 +7,12 @@ import { uiSectionPhotoOverlays } from '../sections/photo_overlays'; export function uiPaneMapData(context) { + const l10n = context.systems.l10n; + return uiPane(context, 'map-data') - .key(context.t('map_data.key')) - .label(context.tHtml('map_data.title')) - .description(context.tHtml('map_data.description')) + .key(l10n.t('map_data.key')) + .label(l10n.tHtml('map_data.title')) + .description(l10n.tHtml('map_data.description')) .iconName('rapid-icon-data') .sections([ uiSectionDataLayers(context), diff --git a/modules/ui/panes/preferences.js b/modules/ui/panes/preferences.js index c65c0018e5..fb8a903b92 100644 --- a/modules/ui/panes/preferences.js +++ b/modules/ui/panes/preferences.js @@ -4,10 +4,12 @@ import { uiSectionMapInteractionOptions } from '../sections/map_interaction_opti export function uiPanePreferences(context) { + const l10n = context.systems.l10n; + return uiPane(context, 'preferences') - .key(context.t('preferences.key')) - .label(context.tHtml('preferences.title')) - .description(context.tHtml('preferences.description')) + .key(l10n.t('preferences.key')) + .label(l10n.tHtml('preferences.title')) + .description(l10n.tHtml('preferences.description')) .iconName('fas-user-cog') .sections([ uiSectionPrivacy(context), diff --git a/modules/ui/rapid_first_edit_dialog.js b/modules/ui/rapid_first_edit_dialog.js index d5460e4224..7569abdc9c 100644 --- a/modules/ui/rapid_first_edit_dialog.js +++ b/modules/ui/rapid_first_edit_dialog.js @@ -4,6 +4,7 @@ import { uiRapidSplash } from './rapid_splash'; export function uiRapidFirstEditDialog(context) { + const l10n = context.systems.l10n; return function(selection) { let modalSelection = uiModal(selection); @@ -17,13 +18,13 @@ export function uiRapidFirstEditDialog(context) { .append('div') .attr('class', 'modal-section') .append('h3') - .html(context.t('rapid_first_edit.nice', { rapidicon: icon('#rapid-logo-rapid-wordmark', 'logo-rapid') })); + .html(l10n.t('rapid_first_edit.nice', { rapidicon: icon('#rapid-logo-rapid-wordmark', 'logo-rapid') })); firstEditModal .append('div') .attr('class', 'modal-section') .append('p') - .text(context.t('rapid_first_edit.text')); + .text(l10n.t('rapid_first_edit.text')); let buttonWrap = firstEditModal .append('div') @@ -38,7 +39,7 @@ export function uiRapidFirstEditDialog(context) { exploring .append('div') - .text(context.t('rapid_first_edit.exploring')); + .text(l10n.t('rapid_first_edit.exploring')); let loginToOsm = buttonWrap .append('button') @@ -52,7 +53,7 @@ export function uiRapidFirstEditDialog(context) { loginToOsm .append('div') - .text(context.t('rapid_first_edit.login_with_osm')); + .text(l10n.t('rapid_first_edit.login_with_osm')); modalSelection.select('button.close') .attr('class', 'hide'); diff --git a/modules/ui/rapid_poweruser_features_dialog.js b/modules/ui/rapid_poweruser_features_dialog.js index 338791c44e..ca3dc2cb7a 100644 --- a/modules/ui/rapid_poweruser_features_dialog.js +++ b/modules/ui/rapid_poweruser_features_dialog.js @@ -4,6 +4,7 @@ import { uiModal } from './modal'; export function uiRapidPowerUserFeaturesDialog(context) { + const l10n = context.systems.l10n; const rapid = context.systems.rapid; const storage = context.systems.storage; const urlhash = context.systems.urlhash; @@ -108,12 +109,12 @@ export function uiRapidPowerUserFeaturesDialog(context) { headerEnter .append('h3') .attr('class', 'modal-heading') - .html(context.t('rapid_poweruser_features.heading.label')); + .html(l10n.t('rapid_poweruser_features.heading.label')); headerEnter .append('div') .attr('class', 'modal-heading-desc') - .text(context.t('rapid_poweruser_features.heading.description')) + .text(l10n.t('rapid_poweruser_features.heading.description')) .append('span') .attr('class', 'smile') .text('😎'); @@ -143,7 +144,7 @@ export function uiRapidPowerUserFeaturesDialog(context) { .append('button') .attr('class', 'button ok-button action') .on('click', () => _modalSelection.remove()) - .text(context.t('confirm.okay')); + .text(l10n.t('confirm.okay')); } @@ -166,13 +167,13 @@ export function uiRapidPowerUserFeaturesDialog(context) { selection .append('div') .attr('class', 'rapid-feature-label') - .text(d => context.t(`rapid_poweruser_features.${d}.label`)); + .text(d => l10n.t(`rapid_poweruser_features.${d}.label`)); // line2: description selection .append('div') .attr('class', 'rapid-feature-description') - .text(d => context.t(`rapid_poweruser_features.${d}.description`)); + .text(d => l10n.t(`rapid_poweruser_features.${d}.description`)); }); let inputsEnter = rowsEnter diff --git a/modules/ui/rapid_service_license.js b/modules/ui/rapid_service_license.js index 5a4f2179aa..1e9322bcb4 100644 --- a/modules/ui/rapid_service_license.js +++ b/modules/ui/rapid_service_license.js @@ -1,9 +1,11 @@ export function uiRapidServiceLicense(context) { + const l10n = context.systems.l10n; + return function(selection) { selection.append('a') .attr('href', 'https://mapwith.ai/doc/license/MapWithAILicense.pdf') .attr('target', '_blank') - .text(context.t('rapid_feature_license')); + .text(l10n.t('rapid_feature_license')); }; } diff --git a/modules/ui/rapid_splash.js b/modules/ui/rapid_splash.js index 1a40b8ab10..35d7a7cec6 100644 --- a/modules/ui/rapid_splash.js +++ b/modules/ui/rapid_splash.js @@ -4,11 +4,12 @@ import { uiModal } from './modal'; export function uiRapidSplash(context) { + const l10n = context.systems.l10n; + const storage = context.systems.storage; return function render(selection) { - const prefs = context.systems.storage; - if (prefs.getItem('sawRapidSplash')) return; - prefs.setItem('sawRapidSplash', true); + if (storage.getItem('sawRapidSplash')) return; + storage.setItem('sawRapidSplash', true); const modalSelection = uiModal(selection); @@ -20,13 +21,13 @@ export function uiRapidSplash(context) { introModal .append('div') .attr('class','modal-section') - .append('h3').text(context.t('rapid_splash.welcome')); + .append('h3').text(l10n.t('rapid_splash.welcome')); introModal .append('div') .attr('class','modal-section') .append('p') - .html(context.t('rapid_splash.text', { + .html(l10n.t('rapid_splash.text', { rapidicon: icon('#rapid-logo-rapid-wordmark', 'logo-rapid'), walkthrough: icon('#rapid-logo-walkthrough', 'logo-walkthrough'), edit: icon('#rapid-logo-features', 'logo-features') @@ -52,7 +53,7 @@ export function uiRapidSplash(context) { walkthrough .append('div') - .text(context.t('rapid_splash.walkthrough')); + .text(l10n.t('rapid_splash.walkthrough')); let rapidWalkthrough = buttonWrap .append('button') @@ -70,7 +71,7 @@ export function uiRapidSplash(context) { rapidWalkthrough .append('div') - .text(context.t('rapid_splash.skip_to_rapid')); + .text(l10n.t('rapid_splash.skip_to_rapid')); let startEditing = buttonWrap .append('button') @@ -87,7 +88,7 @@ export function uiRapidSplash(context) { startEditing .append('div') - .text(context.t('rapid_splash.start')); + .text(l10n.t('rapid_splash.start')); modalSelection.select('button.close') .attr('class', 'hide'); diff --git a/modules/ui/rapid_view_manage_datasets.js b/modules/ui/rapid_view_manage_datasets.js index 6adacdcf70..ccdf467aa6 100644 --- a/modules/ui/rapid_view_manage_datasets.js +++ b/modules/ui/rapid_view_manage_datasets.js @@ -9,6 +9,7 @@ import { utilKeybinding, utilNoAuto, utilRebind } from '../util'; export function uiRapidViewManageDatasets(context, parentModal) { + const l10n = context.systems.l10n; const rapid = context.systems.rapid; const dispatch = d3_dispatch('done'); const categoryCombo = uiCombobox(context, 'dataset-categories'); @@ -105,7 +106,7 @@ export function uiRapidViewManageDatasets(context, parentModal) { line1 .append('div') .attr('class', 'rapid-view-manage-header-text') - .text(context.t('rapid_feature_toggle.esri.title')); + .text(l10n.t('rapid_feature_toggle.esri.title')); let line2 = headerEnter .append('div'); @@ -113,7 +114,7 @@ export function uiRapidViewManageDatasets(context, parentModal) { line2 .append('div') .attr('class', 'rapid-view-manage-header-about') - .html(marked.parse(context.t('rapid_feature_toggle.esri.about'))); + .html(marked.parse(l10n.t('rapid_feature_toggle.esri.about'))); line2.selectAll('a') .attr('target', '_blank'); @@ -137,7 +138,7 @@ export function uiRapidViewManageDatasets(context, parentModal) { filterSearchEnter .append('input') .attr('class', 'rapid-view-manage-filter-search') - .attr('placeholder', context.t('rapid_feature_toggle.esri.filter_datasets')) + .attr('placeholder', l10n.t('rapid_feature_toggle.esri.filter_datasets')) .call(utilNoAuto) .on('input', d3_event => { const element = d3_event.currentTarget; @@ -154,7 +155,7 @@ export function uiRapidViewManageDatasets(context, parentModal) { filterTypeEnter .append('input') .attr('class', 'rapid-view-manage-filter-type') - .attr('placeholder', context.t('rapid_feature_toggle.esri.any_type')) + .attr('placeholder', l10n.t('rapid_feature_toggle.esri.any_type')) .call(utilNoAuto) .call(categoryCombo) .on('blur change', d3_event => { @@ -175,7 +176,7 @@ export function uiRapidViewManageDatasets(context, parentModal) { .attr('class', 'rapid-view-manage-filter-clear') .append('a') .attr('href', '#') - .text(context.t('rapid_feature_toggle.esri.clear_filters')) + .text(l10n.t('rapid_feature_toggle.esri.clear_filters')) .on('click', d3_event => { d3_event.preventDefault(); const element = d3_event.currentTarget; @@ -225,7 +226,7 @@ export function uiRapidViewManageDatasets(context, parentModal) { .append('button') .attr('class', 'button ok-button action') .on('click', _myClose) - .text(context.t('confirm.okay')); + .text(l10n.t('confirm.okay')); } @@ -239,14 +240,14 @@ export function uiRapidViewManageDatasets(context, parentModal) { if (!esri || (Array.isArray(_datasetInfo) && !_datasetInfo.length)) { results.classed('hide', true); - status.classed('hide', false).text(context.t('rapid_feature_toggle.esri.no_datasets')); + status.classed('hide', false).text(l10n.t('rapid_feature_toggle.esri.no_datasets')); return; } if (!_datasetInfo) { results.classed('hide', true); status.classed('hide', false) - .text(context.t('rapid_feature_toggle.esri.fetching_datasets')); + .text(l10n.t('rapid_feature_toggle.esri.fetching_datasets')); status .append('br'); @@ -341,7 +342,7 @@ export function uiRapidViewManageDatasets(context, parentModal) { .attr('class', 'rapid-view-manage-dataset-link') .attr('target', '_blank') .attr('href', d => d.itemURL) - .text(context.t('rapid_feature_toggle.esri.more_info')) + .text(l10n.t('rapid_feature_toggle.esri.more_info')) .call(uiIcon('#rapid-icon-out-link', 'inline')); let featuredEnter = labelsEnter.selectAll('.rapid-view-manage-dataset-featured') @@ -356,14 +357,14 @@ export function uiRapidViewManageDatasets(context, parentModal) { featuredEnter .append('span') - .text(context.t('rapid_feature_toggle.esri.featured')); + .text(l10n.t('rapid_feature_toggle.esri.featured')); labelsEnter.selectAll('.rapid-view-manage-dataset-beta') .data(d => d.groupCategories.filter(d => d.toLowerCase() === '/categories/preview')) .enter() .append('div') .attr('class', 'rapid-view-manage-dataset-beta beta') - .attr('title', context.t('rapid_poweruser_features.beta')); + .attr('title', l10n.t('rapid_poweruser_features.beta')); labelsEnter .append('div') @@ -397,12 +398,12 @@ export function uiRapidViewManageDatasets(context, parentModal) { datasets.selectAll('.rapid-view-manage-dataset-action') .classed('secondary', d => datasetAdded(d)) - .text(d => datasetAdded(d) ? context.t('rapid_feature_toggle.esri.remove') : context.t('rapid_feature_toggle.esri.add_to_map')); + .text(d => datasetAdded(d) ? l10n.t('rapid_feature_toggle.esri.remove') : l10n.t('rapid_feature_toggle.esri.add_to_map')); const numShown = _datasetInfo.filter(d => !d.filtered).length; const gt = (count > MAXRESULTS && numShown === MAXRESULTS) ? '>' : ''; _content.selectAll('.rapid-view-manage-filter-results') - .text(context.t('rapid_feature_toggle.esri.datasets_found', { num: `${gt}${numShown}` })); + .text(l10n.t('rapid_feature_toggle.esri.datasets_found', { num: `${gt}${numShown}` })); } @@ -454,7 +455,7 @@ export function uiRapidViewManageDatasets(context, parentModal) { color: colors[colorIndex], dataUsed: ['esri', d.title], label: d.title, - license_markdown: context.t('rapid_feature_toggle.esri.license_markdown') + license_markdown: l10n.t('rapid_feature_toggle.esri.license_markdown') }; if (d.extent) { diff --git a/modules/ui/rapid_whatsnew.js b/modules/ui/rapid_whatsnew.js index 6130581dbe..cb4649ea93 100644 --- a/modules/ui/rapid_whatsnew.js +++ b/modules/ui/rapid_whatsnew.js @@ -4,14 +4,16 @@ import { marked } from 'marked'; export function uiRapidWhatsNew(context) { + const l10n = context.systems.l10n; + const storage = context.systems.storage; + // If user has not seen this version of the what's new screen, show it again. // Just bump the version to a higher number to get it to come back. const currWhatsNewVersion = 20230823; let _dontShowAgain = false; return function render(selection) { - const prefs = context.systems.storage; - const sawWhatsNewVersion = parseInt(prefs.getItem('sawWhatsNewVersion'), 10) || 0; + const sawWhatsNewVersion = parseInt(storage.getItem('sawWhatsNewVersion'), 10) || 0; if (sawWhatsNewVersion === currWhatsNewVersion) return; const modalSelection = uiModal(selection); @@ -24,12 +26,12 @@ export function uiRapidWhatsNew(context) { .append('div') .attr('class', 'modal-section') .append('h2') - .html(context.t('rapid_whats_new.welcome', { rapidicon: icon('#rapid-logo-rapid-wordmark', 'pre-text rapid') })); + .html(l10n.t('rapid_whats_new.welcome', { rapidicon: icon('#rapid-logo-rapid-wordmark', 'pre-text rapid') })); let body = whatsNewModal .append('div') .attr('class', 'modal-section body') - .html(marked.parse(context.t('rapid_whats_new.text', { + .html(marked.parse(l10n.t('rapid_whats_new.text', { rapidicon: icon('#rapid-logo-rapid-wordmark', 'pre-text rapid'), bugicon: icon('#rapid-icon-bug', 'bugnub') }))); @@ -59,7 +61,7 @@ export function uiRapidWhatsNew(context) { checkbox .append('span') .attr('class', 'rapid-checkbox-text') - .text(context.t('rapid_whats_new.dontshowagain')); + .text(l10n.t('rapid_whats_new.dontshowagain')); checkbox .append('input') @@ -85,7 +87,7 @@ export function uiRapidWhatsNew(context) { // nothanks // .append('div') - // .text(context.t('rapid_whats_new.nope')); + // .text(l10n.t('rapid_whats_new.nope')); let okayButton = buttonWrap .append('button') @@ -93,10 +95,10 @@ export function uiRapidWhatsNew(context) { okayButton .append('div') - .text(context.t('rapid_whats_new.ok')) + .text(l10n.t('rapid_whats_new.ok')) .on('click', () => { if (_dontShowAgain) { - prefs.setItem('sawWhatsNewVersion', currWhatsNewVersion); + storage.setItem('sawWhatsNewVersion', currWhatsNewVersion); } modalSelection.close(); }); diff --git a/modules/ui/sections/grid_display_options.js b/modules/ui/sections/grid_display_options.js index d28c8a35d0..92fc119b0f 100644 --- a/modules/ui/sections/grid_display_options.js +++ b/modules/ui/sections/grid_display_options.js @@ -4,25 +4,26 @@ import { uiSection } from '../section'; export function uiSectionGridDisplayOptions(context) { - const imagerySystem = context.systems.imagery; + const imagery = context.systems.imagery; + const l10n = context.systems.l10n; const rapid = context.systems.rapid; let section = uiSection(context, 'grid-display-options') - .label(context.t('background.grid.grids')) + .label(l10n.t('background.grid.grids')) .disclosureContent(gridDisplayOptions); const gridData = [ - { numSplit: 0, name: context.t('background.grid.no_grid')}, - { numSplit: 2, name: context.t('background.grid.n_by_n', { num: 2 }) }, - { numSplit: 3, name: context.t('background.grid.n_by_n', { num: 3 }) }, - { numSplit: 4, name: context.t('background.grid.n_by_n', { num: 4 }) }, - { numSplit: 5, name: context.t('background.grid.n_by_n', { num: 5 }) }, - { numSplit: 6, name: context.t('background.grid.n_by_n', { num: 6 }) } + { numSplit: 0, name: l10n.t('background.grid.no_grid')}, + { numSplit: 2, name: l10n.t('background.grid.n_by_n', { num: 2 }) }, + { numSplit: 3, name: l10n.t('background.grid.n_by_n', { num: 3 }) }, + { numSplit: 4, name: l10n.t('background.grid.n_by_n', { num: 4 }) }, + { numSplit: 5, name: l10n.t('background.grid.n_by_n', { num: 5 }) }, + { numSplit: 6, name: l10n.t('background.grid.n_by_n', { num: 6 }) } ]; function chooseGrid(d3_event, d) { d3_event.preventDefault(); - imagerySystem.numGridSplits = d.numSplit; + imagery.numGridSplits = d.numSplit; } @@ -48,7 +49,7 @@ export function uiSectionGridDisplayOptions(context) { label.append('input') .attr('type', 'radio') .attr('name', 'grids') - .property('checked', d => d.numSplit === imagerySystem.numGridSplits) + .property('checked', d => d.numSplit === imagery.numGridSplits) .on('change', chooseGrid); label.append('span') diff --git a/modules/ui/sections/map_features.js b/modules/ui/sections/map_features.js index 07b5122eb1..a83f64b732 100644 --- a/modules/ui/sections/map_features.js +++ b/modules/ui/sections/map_features.js @@ -4,9 +4,10 @@ import { uiSection } from '../section'; export function uiSectionMapFeatures(context) { const filters = context.systems.filters; + const l10n = context.systems.l10n; const section = uiSection(context, 'map-features') - .label(context.tHtml('map_data.map_features')) + .label(l10n.tHtml('map_data.map_features')) .disclosureContent(renderDisclosureContent); @@ -30,7 +31,7 @@ export function uiSectionMapFeatures(context) { .append('a') .attr('class', 'feature-list-link') .attr('href', '#') - .html(context.tHtml('issues.disable_all')) + .html(l10n.tHtml('issues.disable_all')) .on('click', d3_event => { d3_event.preventDefault(); filters.disableAll(); @@ -40,7 +41,7 @@ export function uiSectionMapFeatures(context) { .append('a') .attr('class', 'feature-list-link') .attr('href', '#') - .html(context.tHtml('issues.enable_all')) + .html(l10n.tHtml('issues.enable_all')) .on('click', d3_event => { d3_event.preventDefault(); filters.enableAll(); @@ -67,7 +68,7 @@ export function uiSectionMapFeatures(context) { let enter = items.enter() .append('li') .call(uiTooltip(context) - .title(d => context.tHtml(`feature.${d}.tooltip`)) + .title(d => l10n.tHtml(`feature.${d}.tooltip`)) .placement('top') ); @@ -82,7 +83,7 @@ export function uiSectionMapFeatures(context) { label .append('span') - .html(d => context.tHtml(`feature.${d}.description`)); + .html(d => l10n.tHtml(`feature.${d}.description`)); // Update items = items diff --git a/modules/ui/sections/map_interaction_options.js b/modules/ui/sections/map_interaction_options.js index 69b428ff44..558482b2de 100644 --- a/modules/ui/sections/map_interaction_options.js +++ b/modules/ui/sections/map_interaction_options.js @@ -4,8 +4,10 @@ import { uiSection } from '../section'; export function uiSectionMapInteractionOptions(context) { const storage = context.systems.storage; + const l10n = context.systems.l10n; + const section = uiSection(context, 'map-interaction') - .label(context.tHtml('preferences.map_interaction.title')) + .label(l10n.tHtml('preferences.map_interaction.title')) .disclosureContent(renderDisclosureContent); const MOUSE_WHEEL_OPTIONS = ['auto', 'zoom', 'pan']; @@ -23,7 +25,7 @@ export function uiSectionMapInteractionOptions(context) { enter .append('div') .attr('class', 'mouse-wheel-title') - .text(context.t('preferences.map_interaction.mouse_wheel.title')); + .text(l10n.t('preferences.map_interaction.mouse_wheel.title')); enter .append('ul') @@ -49,7 +51,7 @@ export function uiSectionMapInteractionOptions(context) { let enter = items.enter() .append('li') .call(uiTooltip(context) - .title(d => context.t(`preferences.map_interaction.mouse_wheel.${d}.tooltip`)) + .title(d => l10n.t(`preferences.map_interaction.mouse_wheel.${d}.tooltip`)) .placement('top') ); @@ -64,7 +66,7 @@ export function uiSectionMapInteractionOptions(context) { label .append('span') - .text(d => context.t(`preferences.map_interaction.mouse_wheel.${d}.title`)); + .text(d => l10n.t(`preferences.map_interaction.mouse_wheel.${d}.title`)); // Update items.merge(enter) diff --git a/modules/ui/sections/map_style_options.js b/modules/ui/sections/map_style_options.js index 32e8838cb1..96f1108c02 100644 --- a/modules/ui/sections/map_style_options.js +++ b/modules/ui/sections/map_style_options.js @@ -3,8 +3,10 @@ import { uiSection } from '../section'; export function uiSectionMapStyleOptions(context) { + const l10n = context.systems.l10n; + const section = uiSection(context, 'fill-area') - .label(context.tHtml('map_data.style_options')) + .label(l10n.tHtml('map_data.style_options')) .disclosureContent(renderDisclosureContent); @@ -41,11 +43,11 @@ export function uiSectionMapStyleOptions(context) { let enter = items.enter() .append('li') .call(uiTooltip(context) - .title(d => context.tHtml(`${name}.${d}.tooltip`)) + .title(d => l10n.tHtml(`${name}.${d}.tooltip`)) .keys(d => { - let key = (d === 'wireframe' ? context.t('area_fill.wireframe.key') : null); + let key = (d === 'wireframe' ? l10n.t('area_fill.wireframe.key') : null); if (d === 'highlight_edits') { - key = context.t('map_data.highlight_edits.key'); + key = l10n.t('map_data.highlight_edits.key'); } return key ? [key] : null; }) @@ -63,7 +65,7 @@ export function uiSectionMapStyleOptions(context) { label .append('span') - .html(d => context.tHtml(`${name}.${d}.description`)); + .html(d => l10n.tHtml(`${name}.${d}.description`)); // Update items = items diff --git a/modules/ui/sections/photo_overlays.js b/modules/ui/sections/photo_overlays.js index df9db896c0..a799be52a9 100644 --- a/modules/ui/sections/photo_overlays.js +++ b/modules/ui/sections/photo_overlays.js @@ -6,9 +6,11 @@ import { utilGetSetValue, utilNoAuto } from '../../util'; export function uiSectionPhotoOverlays(context) { - const photoSystem = context.systems.photos; + const l10n = context.systems.l10n; + const photos = context.systems.photos; + const section = uiSection(context, 'photo-overlays') - .label(context.tHtml('photo_overlays.title')) + .label(l10n.tHtml('photo_overlays.title')) .disclosureContent(renderDisclosureContent); const scene = context.scene(); @@ -54,7 +56,7 @@ export function uiSectionPhotoOverlays(context) { function drawPhotoItems(selection) { - const photoKeys = photoSystem.overlayLayerIDs; + const photoKeys = photos.overlayLayerIDs; const photoLayers = photoKeys.map(layerID => scene.layers.get(layerID)).filter(Boolean); const data = photoLayers.filter(layer => layer.supported); @@ -100,7 +102,7 @@ export function uiSectionPhotoOverlays(context) { else titleID = d.id.replace(/-/g, '_') + '.tooltip'; d3_select(nodes[i]) .call(uiTooltip(context) - .title(context.tHtml(titleID)) + .title(l10n.tHtml(titleID)) .placement('top') ); }); @@ -115,7 +117,7 @@ export function uiSectionPhotoOverlays(context) { .html(d => { let titleID = d.id; if (titleID === 'mapillary-signs') titleID = 'photo_overlays.traffic_signs'; - return context.tHtml(titleID.replace(/-/g, '_') + '.title'); + return l10n.tHtml(titleID.replace(/-/g, '_') + '.title'); }); // Update @@ -128,10 +130,10 @@ export function uiSectionPhotoOverlays(context) { function drawPhotoTypeItems(selection) { - const photoTypes = photoSystem.allPhotoTypes; + const photoTypes = photos.allPhotoTypes; function typeEnabled(d) { - return photoSystem.showsPhotoType(d); + return photos.showsPhotoType(d); } let ul = selection @@ -147,7 +149,7 @@ export function uiSectionPhotoOverlays(context) { .merge(ul); let li = ul.selectAll('.list-item-photo-types') - .data(photoSystem.shouldFilterByPhotoType() ? photoTypes : []); + .data(photos.shouldFilterByPhotoType() ? photoTypes : []); li.exit() .remove(); @@ -161,7 +163,7 @@ export function uiSectionPhotoOverlays(context) { .each(function(d) { d3_select(this) .call(uiTooltip(context) - .title(context.tHtml(`photo_overlays.photo_type.${d}.tooltip`)) + .title(l10n.tHtml(`photo_overlays.photo_type.${d}.tooltip`)) .placement('top') ); }); @@ -169,11 +171,11 @@ export function uiSectionPhotoOverlays(context) { labelEnter .append('input') .attr('type', 'checkbox') - .on('change', (d3_event, d) => photoSystem.togglePhotoType(d)); + .on('change', (d3_event, d) => photos.togglePhotoType(d)); labelEnter .append('span') - .html(d => context.tHtml(`photo_overlays.photo_type.${d}.title`)); + .html(d => l10n.tHtml(`photo_overlays.photo_type.${d}.title`)); // Update li @@ -185,10 +187,10 @@ export function uiSectionPhotoOverlays(context) { function drawDateFilter(selection) { - const dateFilterTypes = photoSystem.dateFilters; + const dateFilterTypes = photos.dateFilters; function filterEnabled(d) { - return photoSystem.dateFilterValue(d); + return photos.dateFilterValue(d); } let ul = selection @@ -204,7 +206,7 @@ export function uiSectionPhotoOverlays(context) { .merge(ul); let li = ul.selectAll('.list-item-date-filter') - .data(photoSystem.shouldFilterByDate() ? dateFilterTypes : []); + .data(photos.shouldFilterByDate() ? dateFilterTypes : []); li.exit() .remove(); @@ -218,31 +220,31 @@ export function uiSectionPhotoOverlays(context) { .each((d, i, nodes) => { d3_select(nodes[i]) .call(uiTooltip(context) - .title(context.tHtml(`photo_overlays.date_filter.${d}.tooltip`)) + .title(l10n.tHtml(`photo_overlays.date_filter.${d}.tooltip`)) .placement('top') ); }); labelEnter .append('span') - .html(d => context.tHtml(`photo_overlays.date_filter.${d}.title`)); + .html(d => l10n.tHtml(`photo_overlays.date_filter.${d}.title`)); labelEnter .append('input') .attr('type', 'date') .attr('class', 'list-item-input') - .attr('placeholder', context.t('units.year_month_day')) + .attr('placeholder', l10n.t('units.year_month_day')) .call(utilNoAuto) .each((d, i, nodes) => { - utilGetSetValue(d3_select(nodes[i]), photoSystem.dateFilterValue(d) || ''); + utilGetSetValue(d3_select(nodes[i]), photos.dateFilterValue(d) || ''); }) .on('change', function(d3_event, d) { let value = utilGetSetValue(d3_select(this)).trim(); - photoSystem.setDateFilter(d, value, true); + photos.setDateFilter(d, value, true); // reload the displayed dates li.selectAll('input') .each(function(d) { - utilGetSetValue(d3_select(this), photoSystem.dateFilterValue(d) || ''); + utilGetSetValue(d3_select(this), photos.dateFilterValue(d) || ''); }); }); @@ -254,7 +256,7 @@ export function uiSectionPhotoOverlays(context) { function drawUsernameFilter(selection) { function filterEnabled() { - return photoSystem.usernames; + return photos.usernames; } let ul = selection @@ -270,7 +272,7 @@ export function uiSectionPhotoOverlays(context) { .merge(ul); let li = ul.selectAll('.list-item-username-filter') - .data(photoSystem.shouldFilterByUsername() ? ['username-filter'] : []); + .data(photos.shouldFilterByUsername() ? ['username-filter'] : []); li.exit() .remove(); @@ -284,14 +286,14 @@ export function uiSectionPhotoOverlays(context) { .each((d, i, nodes) => { d3_select(nodes[i]) .call(uiTooltip(context) - .title(context.tHtml('photo_overlays.username_filter.tooltip')) + .title(l10n.tHtml('photo_overlays.username_filter.tooltip')) .placement('top') ); }); labelEnter .append('span') - .html(context.tHtml('photo_overlays.username_filter.title')); + .html(l10n.tHtml('photo_overlays.username_filter.title')); labelEnter .append('input') @@ -301,7 +303,7 @@ export function uiSectionPhotoOverlays(context) { .property('value', usernameValue) .on('change', function() { let value = d3_select(this).property('value'); - photoSystem.setUsernameFilter(value, true); + photos.setUsernameFilter(value, true); d3_select(this).property('value', usernameValue); }); @@ -310,7 +312,7 @@ export function uiSectionPhotoOverlays(context) { .classed('active', filterEnabled); function usernameValue() { - let usernames = photoSystem.usernames; + let usernames = photos.usernames; if (usernames) return usernames.join('; '); return usernames; } @@ -318,7 +320,7 @@ export function uiSectionPhotoOverlays(context) { context.scene().on('layerchange', section.reRender); - photoSystem.on('photochange', section.reRender); + photos.on('photochange', section.reRender); return section; } diff --git a/modules/ui/sections/privacy.js b/modules/ui/sections/privacy.js index 49fab0db81..8492d6d3db 100644 --- a/modules/ui/sections/privacy.js +++ b/modules/ui/sections/privacy.js @@ -4,12 +4,14 @@ import { uiSection } from '../section'; export function uiSectionPrivacy(context) { - const prefs = context.systems.storage; + const l10n = context.systems.l10n; + const storage = context.systems.storage; + const section = uiSection(context, 'preferences-third-party') - .label(context.tHtml('preferences.privacy.title')) + .label(l10n.tHtml('preferences.privacy.title')) .disclosureContent(renderDisclosureContent); - let _showThirdPartyIcons = prefs.getItem('preferences.privacy.thirdpartyicons') || 'true'; + let _showThirdPartyIcons = storage.getItem('preferences.privacy.thirdpartyicons') || 'true'; function renderDisclosureContent(selection) { // enter @@ -24,7 +26,7 @@ export function uiSectionPrivacy(context) { .attr('class', 'privacy-third-party-icons-item') .append('label') .call(uiTooltip(context) - .title(context.tHtml('preferences.privacy.third_party_icons.tooltip')) + .title(l10n.tHtml('preferences.privacy.third_party_icons.tooltip')) .placement('bottom') ); @@ -34,13 +36,13 @@ export function uiSectionPrivacy(context) { .on('change', d3_event => { d3_event.preventDefault(); _showThirdPartyIcons = (_showThirdPartyIcons === 'true') ? 'false' : 'true'; - prefs.setItem('preferences.privacy.thirdpartyicons', _showThirdPartyIcons); + storage.setItem('preferences.privacy.thirdpartyicons', _showThirdPartyIcons); update(); }); thirdPartyIconsEnter .append('span') - .html(context.tHtml('preferences.privacy.third_party_icons.description')); + .html(l10n.tHtml('preferences.privacy.third_party_icons.description')); // Privacy Policy link @@ -54,7 +56,7 @@ export function uiSectionPrivacy(context) { .call(uiIcon('#rapid-icon-out-link', 'inline')) .attr('href', 'https://mapwith.ai/doc/license/MapWithAIPrivacyPolicy.pdf') .append('span') - .html(context.tHtml('preferences.privacy.privacy_link')); + .html(l10n.tHtml('preferences.privacy.privacy_link')); update(); diff --git a/modules/ui/sections/validation_issues.js b/modules/ui/sections/validation_issues.js index 14352cdfab..b692ed9638 100644 --- a/modules/ui/sections/validation_issues.js +++ b/modules/ui/sections/validation_issues.js @@ -18,6 +18,7 @@ const MAX_ISSUES = 1000; */ export function uiSectionValidationIssues(context, sectionID, severity) { const editor = context.systems.editor; + const l10n = context.systems.l10n; const map = context.systems.map; const storage = context.systems.storage; const validator = context.systems.validator; @@ -31,8 +32,8 @@ export function uiSectionValidationIssues(context, sectionID, severity) { function sectionLabel() { const countText = _issues.length > MAX_ISSUES ? `${MAX_ISSUES}+` : String(_issues.length); - const titleText = context.t(`issues.${severity}s.list_title`); - return context.t('inspector.title_count', { title: titleText, count: countText }); + const titleText = l10n.t(`issues.${severity}s.list_title`); + return l10n.t('inspector.title_count', { title: titleText, count: countText }); } function sectionShouldDisplay() { @@ -119,7 +120,7 @@ export function uiSectionValidationIssues(context, sectionID, severity) { d3_select(nodes[i]) .append('button') - .attr('title', context.t('issues.fix_one.title')) + .attr('title', l10n.t('issues.fix_one.title')) .datum(d) // set button datum to the issue .attr('class', 'autofix action') .on('click', (d3_event, d) => { @@ -163,7 +164,7 @@ export function uiSectionValidationIssues(context, sectionID, severity) { linkEnter .append('span') .attr('class', 'autofix-all-link-text') - .html(context.tHtml('issues.fix_all.title')); + .html(l10n.tHtml('issues.fix_all.title')); linkEnter .append('span') @@ -184,7 +185,7 @@ export function uiSectionValidationIssues(context, sectionID, severity) { if (typeof args[args.length - 1] !== 'function') { args.pop(); } - args.push(context.t('issues.fix_all.annotation')); + args.push(l10n.t('issues.fix_all.annotation')); editor.replace.apply(editor, args); // this does the fix }); editor.endTransaction(); diff --git a/modules/ui/sections/validation_options.js b/modules/ui/sections/validation_options.js index de4fd7fc24..41c0fe9539 100644 --- a/modules/ui/sections/validation_options.js +++ b/modules/ui/sections/validation_options.js @@ -2,6 +2,7 @@ import { uiSection } from '../section'; export function uiSectionValidationOptions(context) { + const l10n = context.systems.l10n; const storage = context.systems.storage; const validator = context.systems.validator; @@ -33,7 +34,7 @@ export function uiSectionValidationOptions(context) { optionsEnter .append('div') .attr('class', 'issues-option-title') - .html(d => context.tHtml(`issues.options.${d.key}.title`)); + .html(d => l10n.tHtml(`issues.options.${d.key}.title`)); let valuesEnter = optionsEnter.selectAll('label') .data(d => { @@ -52,7 +53,7 @@ export function uiSectionValidationOptions(context) { valuesEnter .append('span') - .html(d => context.tHtml(`issues.options.${d.key}.${d.value}`)); + .html(d => l10n.tHtml(`issues.options.${d.key}.${d.value}`)); } function getOptions() { diff --git a/modules/ui/sections/validation_rules.js b/modules/ui/sections/validation_rules.js index 994ed1d01c..8f71d5020c 100644 --- a/modules/ui/sections/validation_rules.js +++ b/modules/ui/sections/validation_rules.js @@ -6,8 +6,9 @@ import { uiSection } from '../section'; export function uiSectionValidationRules(context) { - const validator = context.systems.validator; + const l10n = context.systems.l10n; const storage = context.systems.storage; + const validator = context.systems.validator; const MINSQUARE = 0; const MAXSQUARE = 20; @@ -15,13 +16,13 @@ export function uiSectionValidationRules(context) { const section = uiSection(context, 'issues-rules') .disclosureContent(renderDisclosureContent) - .label(context.tHtml('issues.rules.title')); + .label(l10n.tHtml('issues.rules.title')); let _ruleKeys = validator.getRuleKeys() .sort((key1, key2) => { // alphabetize by localized title - return context.t(`issues.${key1}.title`) < context.t(`issues.${key2}.title`) ? -1 : 1; + return l10n.t(`issues.${key1}.title`) < l10n.t(`issues.${key2}.title`) ? -1 : 1; }); @@ -45,7 +46,7 @@ export function uiSectionValidationRules(context) { .append('a') .attr('class', 'issue-rules-link') .attr('href', '#') - .html(context.tHtml('issues.disable_all')) + .html(l10n.tHtml('issues.disable_all')) .on('click', d3_event => { d3_event.preventDefault(); validator.disableRules(_ruleKeys); @@ -55,7 +56,7 @@ export function uiSectionValidationRules(context) { .append('a') .attr('class', 'issue-rules-link') .attr('href', '#') - .html(context.tHtml('issues.enable_all')) + .html(l10n.tHtml('issues.enable_all')) .on('click', d3_event => { d3_event.preventDefault(); validator.disableRules([]); @@ -82,7 +83,7 @@ export function uiSectionValidationRules(context) { let enter = items.enter() .append('li') .call(uiTooltip(context) - .title(d => context.tHtml(`issues.${d}.tip`)) + .title(d => l10n.tHtml(`issues.${d}.tip`)) .placement('top') ); @@ -102,7 +103,7 @@ export function uiSectionValidationRules(context) { if (d === 'unsquare_way') { params.val = ''; } - return context.tHtml(`issues.${d}.title`, params); + return l10n.tHtml(`issues.${d}.title`, params); }); // Update diff --git a/modules/ui/sections/validation_status.js b/modules/ui/sections/validation_status.js index 8204adb26e..1cae9ff0e0 100644 --- a/modules/ui/sections/validation_status.js +++ b/modules/ui/sections/validation_status.js @@ -5,6 +5,7 @@ import { uiSection } from '../section'; export function uiSectionValidationStatus(context) { + const l10n = context.systems.l10n; const validator = context.systems.validator; const section = uiSection(context, 'issues-status') @@ -82,7 +83,7 @@ export function uiSectionValidationStatus(context) { .merge(resetIgnoredEnter); resetIgnored.select('a') - .html(context.t('inspector.title_count', { title: context.tHtml('issues.reset_ignored'), count: ignoredIssues.length })); + .html(l10n.t('inspector.title_count', { title: l10n.tHtml('issues.reset_ignored'), count: ignoredIssues.length })); resetIgnored.on('click', d3_event => { d3_event.preventDefault(); @@ -101,12 +102,12 @@ export function uiSectionValidationStatus(context) { const hiddenIssues = validator.getIssues(hiddenOpts); if (hiddenIssues.length) { selection.select('.box .details') - .html(context.tHtml('issues.no_issues.hidden_issues.' + type, { count: hiddenIssues.length.toString() } )); + .html(l10n.tHtml('issues.no_issues.hidden_issues.' + type, { count: hiddenIssues.length.toString() } )); return; } } selection.select('.box .details') - .html(context.tHtml('issues.no_issues.hidden_issues.none')); + .html(l10n.tHtml('issues.no_issues.hidden_issues.none')); } let messageType; @@ -154,7 +155,7 @@ export function uiSectionValidationStatus(context) { } selection.select('.box .message') - .html(context.tHtml(`issues.no_issues.message.${messageType}`)); + .html(l10n.tHtml(`issues.no_issues.message.${messageType}`)); } diff --git a/modules/ui/settings/custom_background.js b/modules/ui/settings/custom_background.js index 078de40be0..64e45a2fd5 100644 --- a/modules/ui/settings/custom_background.js +++ b/modules/ui/settings/custom_background.js @@ -6,13 +6,14 @@ import { utilNoAuto, utilRebind } from '../../util'; export function uiSettingsCustomBackground(context) { - const prefs = context.systems.storage; + const l10n = context.systems.l10n; + const storage = context.systems.storage; const dispatch = d3_dispatch('change'); function render(selection) { // keep separate copies of original and current settings - let _origSettings = { template: prefs.getItem('background-custom-template') }; + let _origSettings = { template: storage.getItem('background-custom-template') }; let _currSettings = Object.assign({}, _origSettings); let modal = uiConfirm(context, selection).okButton(); @@ -22,22 +23,22 @@ export function uiSettingsCustomBackground(context) { modal.select('.modal-section.header') .append('h3') - .html(context.tHtml('settings.custom_background.header')); + .html(l10n.tHtml('settings.custom_background.header')); const prefix = 'settings.custom_background.instructions'; - const info = context.t(`${prefix}.info`); - const wms_label = context.t(`${prefix}.wms.tokens_label`); - const wms_proj = context.t(`${prefix}.wms.tokens.proj`); - const wms_wkid = context.t(`${prefix}.wms.tokens.wkid`); - const wms_dims = context.t(`${prefix}.wms.tokens.dimensions`); - const wms_bbox = context.t(`${prefix}.wms.tokens.bbox`); - const tms_label = context.t(`${prefix}.tms.tokens_label`); - const tms_xyz = context.t(`${prefix}.tms.tokens.xyz`); - const tms_flip = context.t(`${prefix}.tms.tokens.flipped_y`); - const tms_switch = context.t(`${prefix}.tms.tokens.switch`); - const tms_quad = context.t(`${prefix}.tms.tokens.quadtile`); - const tms_scale = context.t(`${prefix}.tms.tokens.scale_factor`); - const example = context.t('example'); + const info = l10n.t(`${prefix}.info`); + const wms_label = l10n.t(`${prefix}.wms.tokens_label`); + const wms_proj = l10n.t(`${prefix}.wms.tokens.proj`); + const wms_wkid = l10n.t(`${prefix}.wms.tokens.wkid`); + const wms_dims = l10n.t(`${prefix}.wms.tokens.dimensions`); + const wms_bbox = l10n.t(`${prefix}.wms.tokens.bbox`); + const tms_label = l10n.t(`${prefix}.tms.tokens_label`); + const tms_xyz = l10n.t(`${prefix}.tms.tokens.xyz`); + const tms_flip = l10n.t(`${prefix}.tms.tokens.flipped_y`); + const tms_switch = l10n.t(`${prefix}.tms.tokens.switch`); + const tms_quad = l10n.t(`${prefix}.tms.tokens.quadtile`); + const tms_scale = l10n.t(`${prefix}.tms.tokens.scale_factor`); + const example = l10n.t('example'); const instructions = marked.parse(` ${info} @@ -73,7 +74,7 @@ ${info} textSection .append('textarea') .attr('class', 'field-template') - .attr('placeholder', context.t('settings.custom_background.template.placeholder')) + .attr('placeholder', l10n.t('settings.custom_background.template.placeholder')) .call(utilNoAuto) .property('value', _currSettings.template); @@ -84,7 +85,7 @@ ${info} buttonSection .insert('button', '.ok-button') .attr('class', 'button cancel-button secondary-action') - .html(context.tHtml('confirm.cancel')); + .html(l10n.tHtml('confirm.cancel')); buttonSection.select('.cancel-button') .on('click.cancel', _clickCancel); @@ -96,7 +97,7 @@ ${info} // restore the original template function _clickCancel() { textSection.select('.field-template').property('value', _origSettings.template); - prefs.setItem('background-custom-template', _origSettings.template); + storage.setItem('background-custom-template', _origSettings.template); this.blur(); modal.close(); } @@ -104,7 +105,7 @@ ${info} // accept the current template function _clickSave() { _currSettings.template = textSection.select('.field-template').property('value'); - prefs.setItem('background-custom-template', _currSettings.template); + storage.setItem('background-custom-template', _currSettings.template); this.blur(); modal.close(); dispatch.call('change', this, _currSettings); diff --git a/modules/ui/settings/custom_data.js b/modules/ui/settings/custom_data.js index 3d6e05abec..20faa306c0 100644 --- a/modules/ui/settings/custom_data.js +++ b/modules/ui/settings/custom_data.js @@ -6,6 +6,7 @@ import { utilNoAuto, utilRebind } from '../../util'; export function uiSettingsCustomData(context) { + const l10n = context.systems.l10n; const storage = context.systems.storage; const urlhash = context.systems.urlhash; const dispatch = d3_dispatch('change'); @@ -34,16 +35,16 @@ export function uiSettingsCustomData(context) { modal.select('.modal-section.header') .append('h3') - .html(context.tHtml('settings.custom_data.header')); + .html(l10n.tHtml('settings.custom_data.header')); const textSection = modal.select('.modal-section.message-text'); - const data_instructions = context.t(`${prefix}.instructions`); - const file_heading = context.t(`${prefix}.file.heading`); - const file_instructions = context.t(`${prefix}.file.instructions`); - const file_types = context.t(`${prefix}.file.types`); - const file_tip = context.t(`${prefix}.file.tip`); + const data_instructions = l10n.t(`${prefix}.instructions`); + const file_heading = l10n.t(`${prefix}.file.heading`); + const file_instructions = l10n.t(`${prefix}.file.instructions`); + const file_types = l10n.t(`${prefix}.file.types`); + const file_tip = l10n.t(`${prefix}.file.tip`); const fileHtml = marked.parse(` ${data_instructions} @@ -79,15 +80,15 @@ ${file_tip} } }); - const data_or = context.t(`${prefix}.or`); - const url_heading = context.t(`${prefix}.url.heading`); - const url_instructions = context.t(`${prefix}.url.instructions`); - const url_tokens = context.t(`${prefix}.url.tokens`); - const url_xyz = context.t(`${prefix}.url.xyz`); - const url_example_file = context.t(`${prefix}.url.example_file`); - const url_example_xyz = context.t(`${prefix}.url.example_xyz`); - const url_example_pmtiles = context.t(`${prefix}.url.example_pmtiles`); - const example = context.t('example'); + const data_or = l10n.t(`${prefix}.or`); + const url_heading = l10n.t(`${prefix}.url.heading`); + const url_instructions = l10n.t(`${prefix}.url.instructions`); + const url_tokens = l10n.t(`${prefix}.url.tokens`); + const url_xyz = l10n.t(`${prefix}.url.xyz`); + const url_example_file = l10n.t(`${prefix}.url.example_file`); + const url_example_xyz = l10n.t(`${prefix}.url.example_xyz`); + const url_example_pmtiles = l10n.t(`${prefix}.url.example_pmtiles`); + const example = l10n.t('example'); const urlHtml = marked.parse(` ### ${data_or} @@ -113,7 +114,7 @@ ${url_tokens} textSection .append('textarea') .attr('class', 'field-url') - .attr('placeholder', context.t('settings.custom_data.url.placeholder')) + .attr('placeholder', l10n.t('settings.custom_data.url.placeholder')) .call(utilNoAuto) .property('value', _currUrl); @@ -124,7 +125,7 @@ ${url_tokens} buttonSection .insert('button', '.ok-button') .attr('class', 'button cancel-button secondary-action') - .html(context.tHtml('confirm.cancel')); + .html(l10n.tHtml('confirm.cancel')); buttonSection.select('.cancel-button') .on('click.cancel', clickCancel); diff --git a/modules/ui/shortcuts.js b/modules/ui/shortcuts.js index 4e62980551..2b2e49d564 100644 --- a/modules/ui/shortcuts.js +++ b/modules/ui/shortcuts.js @@ -8,6 +8,8 @@ import { utilDetect } from '../util/detect'; export function uiShortcuts(context) { + const l10n = context.systems.l10n; + var detected = utilDetect(); var _activeTab = 0; var _modalSelection; @@ -25,7 +27,7 @@ export function uiShortcuts(context) { .append('div') .attr('class', 'modal-section') .append('h3') - .html(context.tHtml('shortcuts.title')); + .html(l10n.tHtml('shortcuts.title')); const dataloader = context.systems.dataloader; dataloader.getDataAsync('shortcuts') @@ -77,7 +79,7 @@ export function uiShortcuts(context) { tabsEnter .append('span') - .html(function (d) { return context.tHtml(d.text); }); + .html(function (d) { return l10n.tHtml(d.text); }); // Update wrapper.selectAll('.tab') @@ -120,7 +122,7 @@ export function uiShortcuts(context) { .append('td') .attr('class', 'shortcut-section') .append('h3') - .html(function (d) { return context.tHtml(d.text); }); + .html(function (d) { return l10n.tHtml(d.text); }); var shortcutRows = rowsEnter @@ -171,7 +173,7 @@ export function uiShortcuts(context) { // replace translations arr = arr.map(s => { - return uiCmd.display(context, s.indexOf('.') !== -1 ? context.t(s) : s); + return uiCmd.display(context, s.indexOf('.') !== -1 ? l10n.t(s) : s); }); return utilArrayUniq(arr).map(function(s) { @@ -207,7 +209,7 @@ export function uiShortcuts(context) { if (i < nodes.length - 1) { selection .append('span') - .html(d.separator || '\u00a0' + context.tHtml('shortcuts.or') + '\u00a0'); + .html(d.separator || '\u00a0' + l10n.tHtml('shortcuts.or') + '\u00a0'); } else if (i === nodes.length - 1 && d.suffix) { selection .append('span') @@ -238,14 +240,14 @@ export function uiShortcuts(context) { selection .append('span') .attr('class', 'gesture') - .html(function (d) { return context.tHtml(d.gesture); }); + .html(function (d) { return l10n.tHtml(d.gesture); }); }); shortcutRows .append('td') .attr('class', 'shortcut-desc') - .html(function (d) { return d.text ? context.tHtml(d.text) : '\u00a0'; }); + .html(function (d) { return d.text ? l10n.tHtml(d.text) : '\u00a0'; }); // Update @@ -263,7 +265,7 @@ export function uiShortcuts(context) { _modalSelection.call(shortcutsModal); } else { context.keybinding() - .on([context.t('shortcuts.toggle.key'), '?'], function () { + .on([l10n.t('shortcuts.toggle.key'), '?'], function () { if (context.container().selectAll('.modal-shortcuts').size()) { // already showing if (_modalSelection) { _modalSelection.close(); diff --git a/modules/ui/success.js b/modules/ui/success.js index c0c7aec86b..2cfd44d4be 100644 --- a/modules/ui/success.js +++ b/modules/ui/success.js @@ -11,15 +11,19 @@ import { utilRebind } from '../util/rebind'; let _oci = null; export function uiSuccess(context) { - const MAXEVENTS = 2; + const dataloader = context.systems.dataloader; + const locations = context.systems.locations; + const l10n = context.systems.l10n; const dispatch = d3_dispatch('cancel'); + const MAXEVENTS = 2; + let _changeset; let _location; + getCommunityIndexAsync(); // start fetching the data function getCommunityIndexAsync() { - const dataloader = context.systems.dataloader; return Promise.all([ dataloader.getDataAsync('oci_features'), dataloader.getDataAsync('oci_resources'), @@ -29,15 +33,14 @@ export function uiSuccess(context) { if (_oci) return _oci; // Merge Custom Features - const locationSystem = context.systems.locations; if (vals[0] && Array.isArray(vals[0].features)) { - locationSystem.mergeCustomGeoJSON(vals[0]); + locations.mergeCustomGeoJSON(vals[0]); } let ociResources = Object.values(vals[1].resources); if (ociResources.length) { // Resolve all locationSet features. - return locationSystem.mergeLocationSets(ociResources) + return locations.mergeLocationSets(ociResources) .then(() => { _oci = { resources: ociResources, @@ -79,7 +82,7 @@ export function uiSuccess(context) { header .append('h3') - .html(context.tHtml('success.just_edited')); + .html(l10n.tHtml('success.just_edited')); header .append('button') @@ -97,18 +100,18 @@ export function uiSuccess(context) { summary .append('h3') - .html(context.tHtml('success.thank_you' + (_location ? '_location' : ''), { where: _location })); + .html(l10n.tHtml('success.thank_you' + (_location ? '_location' : ''), { where: _location })); summary .append('p') - .html(context.tHtml('success.help_html')) + .html(l10n.tHtml('success.help_html')) .append('a') .attr('class', 'link-out') .attr('target', '_blank') - .attr('href', context.t('success.help_link_url')) + .attr('href', l10n.t('success.help_link_url')) .call(uiIcon('#rapid-icon-out-link', 'inline')) .append('span') - .html(context.tHtml('success.help_link_text')); + .html(l10n.tHtml('success.help_link_text')); let osm = context.services.osm; if (!osm) return; @@ -143,11 +146,11 @@ export function uiSuccess(context) { .attr('class', 'cell-detail summary-view-on-osm') .attr('target', '_blank') .attr('href', changesetURL) - .html(context.tHtml('success.view_on_osm')); + .html(l10n.tHtml('success.view_on_osm')); summaryDetail .append('div') - .html(context.tHtml('success.changeset_id', { + .html(l10n.tHtml('success.changeset_id', { changeset_id: `${_changeset.id}` })); @@ -156,8 +159,8 @@ export function uiSuccess(context) { getCommunityIndexAsync() .then(oci => { const loc = context.systems.map.center(); - const locationSystem = context.systems.locations; - const validHere = locationSystem.locationSetsAt(loc); + const locations = context.systems.locations; + const validHere = locations.locationSetsAt(loc); // Gather the communities let communities = []; @@ -166,7 +169,7 @@ export function uiSuccess(context) { if (!area) return; // Resolve strings - const localize = (stringID) => context.tHtml(`community.${stringID}`); + const localize = (stringID) => l10n.tHtml(`community.${stringID}`); resource.resolved = resolveStrings(resource, oci.defaults, localize); communities.push({ @@ -192,7 +195,7 @@ export function uiSuccess(context) { communityLinks .append('h3') - .html(context.tHtml('success.like_osm')); + .html(l10n.tHtml('success.like_osm')); let table = communityLinks .append('table') @@ -226,14 +229,14 @@ export function uiSuccess(context) { communityLinks .append('div') .attr('class', 'community-missing') - .html(context.tHtml('success.missing')) + .html(l10n.tHtml('success.missing')) .append('a') .attr('class', 'link-out') .attr('target', '_blank') .call(uiIcon('#rapid-icon-out-link', 'inline')) .attr('href', 'https://github.com/osmlab/osm-community-index/issues') .append('span') - .html(context.tHtml('success.tell_us')); + .html(l10n.tHtml('success.tell_us')); } @@ -258,7 +261,7 @@ export function uiSuccess(context) { .call(uiDisclosure(context, `community-more-${d.id}`) .expanded(false) .checkPreference(false) - .label(context.tHtml('success.more')) + .label(l10n.tHtml('success.more')) .content(showMore) ); } @@ -284,7 +287,7 @@ export function uiSuccess(context) { .call(uiDisclosure(context, `community-events-${d.id}`) .expanded(false) .checkPreference(false) - .label(context.tHtml('success.events')) + .label(l10n.tHtml('success.events')) .content(showNextEvents) ) .select('.hide-toggle') @@ -317,7 +320,7 @@ export function uiSuccess(context) { moreEnter .append('div') .attr('class', 'community-languages') - .html(context.tHtml('success.languages', { languages: languageList })); + .html(l10n.tHtml('success.languages', { languages: languageList })); } } @@ -343,7 +346,7 @@ export function uiSuccess(context) { .html(d => { let name = d.name; if (d.i18n && d.id) { - name = context.t(`community.${communityID}.events.${d.id}.name`, { default: name }); + name = l10n.t(`community.${communityID}.events.${d.id}.name`, { default: name }); } return name; }); @@ -367,7 +370,7 @@ export function uiSuccess(context) { .html(d => { let where = d.where; if (d.i18n && d.id) { - where = context.t(`community.${communityID}.events.${d.id}.where`, { default: where }); + where = l10n.t(`community.${communityID}.events.${d.id}.where`, { default: where }); } return where; }); @@ -378,7 +381,7 @@ export function uiSuccess(context) { .html(d => { let description = d.description; if (d.i18n && d.id) { - description = context.t(`community.${communityID}.events.${d.id}.description`, { default: description }); + description = l10n.t(`community.${communityID}.events.${d.id}.description`, { default: description }); } return description; }); diff --git a/modules/ui/tools/download_osc.js b/modules/ui/tools/download_osc.js index bdc9563255..a9cc084d5c 100644 --- a/modules/ui/tools/download_osc.js +++ b/modules/ui/tools/download_osc.js @@ -7,10 +7,11 @@ import { uiTooltip } from '../tooltip'; export function uiToolDownloadOsc(context) { const editor = context.systems.editor; + const l10n = context.systems.l10n; let tool = { id: 'download_osc', - label: context.t('download_osc.title') + label: l10n.t('download_osc.title') }; let _button = null; @@ -40,7 +41,7 @@ export function uiToolDownloadOsc(context) { if (_tooltip) { _tooltip - .title(context.t(_numChanges > 0 ? 'download_osc.help' : 'download_osc.no_changes')); + .title(l10n.t(_numChanges > 0 ? 'download_osc.help' : 'download_osc.no_changes')); } updateStyle(); } @@ -77,7 +78,7 @@ export function uiToolDownloadOsc(context) { _tooltip = uiTooltip(context) .placement('bottom') - .title(context.t('download_osc.no_changes')); + .title(l10n.t('download_osc.no_changes')); _button = selection .append('button') diff --git a/modules/ui/tools/modes.js b/modules/ui/tools/modes.js index 7e0c8efcdc..eb65e1224d 100644 --- a/modules/ui/tools/modes.js +++ b/modules/ui/tools/modes.js @@ -6,6 +6,7 @@ import { uiTooltip } from '../tooltip'; export function uiToolDrawModes(context) { + const l10n = context.systems.l10n; const map = context.systems.map; const presets = context.systems.presets; const ui = context.systems.ui; @@ -15,31 +16,31 @@ export function uiToolDrawModes(context) { let tool = { id: 'draw_modes', - label: context.tHtml('toolbar.add_feature') + label: l10n.tHtml('toolbar.add_feature') }; const modes = [ { id: 'add-point', - title: context.tHtml('modes.add_point.title'), + title: l10n.tHtml('modes.add_point.title'), button: 'point', - description: context.tHtml('modes.add_point.description'), + description: l10n.tHtml('modes.add_point.description'), preset: presets.item('point'), key: '1' }, { id: 'draw-line', - title: context.tHtml('modes.add_line.title'), + title: l10n.tHtml('modes.add_line.title'), button: 'line', - description: context.tHtml('modes.add_line.description'), + description: l10n.tHtml('modes.add_line.description'), preset: presets.item('line'), key: '2' }, { id: 'draw-area', - title: context.tHtml('modes.add_area.title'), + title: l10n.tHtml('modes.add_area.title'), button: 'area', - description: context.tHtml('modes.add_area.description'), + description: l10n.tHtml('modes.add_area.description'), preset: presets.item('area'), key: '3' } diff --git a/modules/ui/tools/notes.js b/modules/ui/tools/notes.js index 9fbf34c956..da2bcee328 100644 --- a/modules/ui/tools/notes.js +++ b/modules/ui/tools/notes.js @@ -6,20 +6,21 @@ import { uiTooltip } from '../tooltip'; export function uiToolNotes(context) { + const l10n = context.systems.l10n; const map = context.systems.map; const ui = context.systems.ui; let tool = { id: 'notes', - label: context.tHtml('modes.add_note.label') + label: l10n.tHtml('modes.add_note.label') }; const mode = { id: 'add-note', - title: context.tHtml('modes.add_note.title'), + title: l10n.tHtml('modes.add_note.title'), button: 'note', - description: context.tHtml('modes.add_note.description'), - key: context.t('modes.add_note.key') + description: l10n.tHtml('modes.add_note.description'), + key: l10n.t('modes.add_note.key') }; diff --git a/modules/ui/tools/rapid_features.js b/modules/ui/tools/rapid_features.js index e48293c6bd..2d0be43900 100644 --- a/modules/ui/tools/rapid_features.js +++ b/modules/ui/tools/rapid_features.js @@ -6,11 +6,12 @@ import { uiRapidPowerUserFeaturesDialog } from '../rapid_poweruser_features_dial export function uiToolRapidFeatures(context) { + const l10n = context.systems.l10n; const map = context.systems.map; const urlhash = context.systems.urlhash; const toggleKeyDispatcher = d3_dispatch('ai_feature_toggle'); - const rapidFeaturesToggleKey = '⇧' + context.t('map_data.layers.ai-features.key'); + const rapidFeaturesToggleKey = '⇧' + l10n.t('map_data.layers.ai-features.key'); const datasetDialog = uiRapidFeatureToggleDialog(context, uiCmd(rapidFeaturesToggleKey), toggleKeyDispatcher); const powerUserDialog = uiRapidPowerUserFeaturesDialog(context); @@ -18,7 +19,7 @@ export function uiToolRapidFeatures(context) { let tool = { id: 'rapid_features', - label: context.t('toolbar.rapid_features') + label: l10n.t('toolbar.rapid_features') }; @@ -64,7 +65,7 @@ export function uiToolRapidFeatures(context) { .on('click', showFeatureToggleDialog) .call(uiTooltip(context) .placement('bottom') - .title(context.t('shortcuts.browsing.display_options.rapid_features_data')) + .title(l10n.t('shortcuts.browsing.display_options.rapid_features_data')) .keys(rapidFeaturesToggleKey) ); @@ -92,7 +93,7 @@ export function uiToolRapidFeatures(context) { .on('click', showPowerUserFeaturesDialog) .call(uiTooltip(context) .placement('bottom') - .title(context.t('rapid_poweruser_features.heading.label')) + .title(l10n.t('rapid_poweruser_features.heading.label')) ) .append('div') .attr('class', 'beta'); diff --git a/modules/ui/tools/save.js b/modules/ui/tools/save.js index 4a3ae02d57..6d79cd3e0b 100644 --- a/modules/ui/tools/save.js +++ b/modules/ui/tools/save.js @@ -7,10 +7,11 @@ import { uiTooltip } from '../tooltip'; export function uiToolSave(context) { const editor = context.systems.editor; + const l10n = context.systems.l10n; let tool = { id: 'save', - label: context.tHtml('save.title') + label: l10n.tHtml('save.title') }; let key = uiCmd('⌘S'); @@ -56,7 +57,7 @@ export function uiToolSave(context) { if (_tooltip) { _tooltip - .title(context.tHtml(_numChanges > 0 ? 'save.help' : 'save.no_changes')) + .title(l10n.tHtml(_numChanges > 0 ? 'save.help' : 'save.no_changes')) .keys([key]); } @@ -84,7 +85,7 @@ export function uiToolSave(context) { _tooltip = uiTooltip(context) .placement('bottom') - .title(context.tHtml('save.no_changes')) + .title(l10n.tHtml('save.no_changes')) .keys([key]) .scrollContainer(context.container().select('.top-toolbar')); @@ -106,7 +107,7 @@ export function uiToolSave(context) { // .duration(2000) // .iconName('#rapid-icon-save') // .iconClass('disabled') - // .label(context.tHtml('save.no_changes'))(); + // .label(l10n.tHtml('save.no_changes'))(); // } // lastPointerUpType = null; }) diff --git a/modules/ui/tooltip.js b/modules/ui/tooltip.js index 4ffd5f1c82..e2562f18ea 100644 --- a/modules/ui/tooltip.js +++ b/modules/ui/tooltip.js @@ -3,6 +3,7 @@ import { uiPopover } from './popover'; export function uiTooltip(context) { + const l10n = context.systems.l10n; var tooltip = uiPopover(context, 'tooltip').displayType('hover'); var _title = function() { @@ -83,7 +84,7 @@ export function uiTooltip(context) { keyhintWrapEnter .append('span') - .html(context.tHtml('tooltip_keyhint')); + .html(l10n.tHtml('tooltip_keyhint')); keyhintWrap = keyhintWrapEnter.merge(keyhintWrap); diff --git a/modules/ui/version.js b/modules/ui/version.js index 271b405d18..cfebbb4dbe 100644 --- a/modules/ui/version.js +++ b/modules/ui/version.js @@ -9,19 +9,20 @@ let isNewUser = false; export function uiVersion(context) { + const l10n = context.systems.l10n; + const storage = context.systems.storage; const currVersion = context.version; const matchedVersion = currVersion.match(/\d+\.\d+\.\d+.*/); - const prefs = context.systems.storage; if (sawVersion === null && matchedVersion !== null) { - if (prefs.getItem('sawVersion')) { + if (storage.getItem('sawVersion')) { isNewUser = false; - isNewVersion = prefs.getItem('sawVersion') !== currVersion && currVersion.indexOf('-') === -1; + isNewVersion = storage.getItem('sawVersion') !== currVersion && currVersion.indexOf('-') === -1; } else { isNewUser = true; isNewVersion = true; } - prefs.setItem('sawVersion', currVersion); + storage.setItem('sawVersion', currVersion); sawVersion = currVersion; } @@ -43,7 +44,7 @@ export function uiVersion(context) { .attr('href', 'https://github.com/facebook/Rapid/blob/main/CHANGELOG.md') .call(uiIcon('#maki-gift')) .call(uiTooltip(context) - .title(context.tHtml('version.whats_new', { version: currVersion })) + .title(l10n.tHtml('version.whats_new', { version: currVersion })) .placement('top') .scrollContainer(context.container().select('.main-footer-wrap')) ); diff --git a/modules/ui/view_on_keepRight.js b/modules/ui/view_on_keepRight.js index 759c48e203..c150960283 100644 --- a/modules/ui/view_on_keepRight.js +++ b/modules/ui/view_on_keepRight.js @@ -3,6 +3,7 @@ import { QAItem } from '../osm'; export function uiViewOnKeepRight(context) { + const l10n = context.systems.l10n; const keepright = context.services.keepRight; let _qaItem; @@ -31,7 +32,7 @@ export function uiViewOnKeepRight(context) { linkEnter .append('span') - .text(context.t('inspector.view_on_keepRight')); + .text(l10n.t('inspector.view_on_keepRight')); } diff --git a/modules/ui/view_on_osm.js b/modules/ui/view_on_osm.js index c9a2c909e0..918c1d5601 100644 --- a/modules/ui/view_on_osm.js +++ b/modules/ui/view_on_osm.js @@ -3,6 +3,7 @@ import { uiIcon } from './icon'; export function uiViewOnOSM(context) { + const l10n = context.systems.l10n; const osm = context.services.osm; let _what; // an osmEntity or osmNote @@ -32,7 +33,7 @@ export function uiViewOnOSM(context) { linkEnter .append('span') - .text(context.t('inspector.view_on_osm')); + .text(l10n.t('inspector.view_on_osm')); } diff --git a/modules/ui/view_on_osmose.js b/modules/ui/view_on_osmose.js index cee0fecc05..08fdf8ff86 100644 --- a/modules/ui/view_on_osmose.js +++ b/modules/ui/view_on_osmose.js @@ -3,6 +3,7 @@ import { QAItem } from '../osm'; export function uiViewOnOsmose(context) { + const l10n = context.systems.l10n; const osmose = context.services.osmose; let _qaItem; @@ -31,7 +32,7 @@ export function uiViewOnOsmose(context) { linkEnter .append('span') - .text(context.t('inspector.view_on_osmose')); + .text(l10n.t('inspector.view_on_osmose')); } diff --git a/test/spec/ui/confirm.js b/test/spec/ui/confirm.js index 302ec2325c..28a9dc32b7 100644 --- a/test/spec/ui/confirm.js +++ b/test/spec/ui/confirm.js @@ -1,98 +1,109 @@ -describe('uiConfirm', function () { - var elem; +describe('uiConfirm', () => { + let elem; - class MockContext { - constructor() {} - t() {} + class MockLocalizationSystem { + constructor() { } + initAsync() { return Promise.resolve(); } + t(id) { return id; } + tHtml(id) { return id; } + } + + class MockContext { + constructor() { + this.systems = { + l10n: new MockLocalizationSystem() + }; } - const context = new MockContext(); - - - beforeEach(function() { - elem = d3.select('body') - .append('div') - .attr('class', 'confirm-wrap'); - }); - - afterEach(function() { - d3.select('.confirm-wrap') - .remove(); - }); - - it('can be instantiated', function () { - var selection = Rapid.uiConfirm(context, elem); - expect(selection).to.be.ok; - }); - - it('has a header section', function () { - var selection = Rapid.uiConfirm(context, elem); - expect(selection.selectAll('div.content div.header').size()).to.equal(1); - }); - - it('has a message section', function () { - var selection = Rapid.uiConfirm(context, elem); - expect(selection.selectAll('div.content div.message-text').size()).to.equal(1); - }); - - it('has a buttons section', function () { - var selection = Rapid.uiConfirm(context, elem); - expect(selection.selectAll('div.content div.buttons').size()).to.equal(1); - }); - - it('can have an ok button added to it', function () { - var selection = Rapid.uiConfirm(context, elem).okButton(); - expect(selection.selectAll('div.content div.buttons button.action').size()).to.equal(1); - }); - - it('can be dismissed by calling close function', function (done) { - var selection = Rapid.uiConfirm(context, elem); - selection.close(); - window.setTimeout(function() { - d3.timerFlush(); - expect(selection.node().parentNode).to.be.null; - done(); - }, 275); - }); - - it('can be dismissed by clicking the close button', function (done) { - var selection = Rapid.uiConfirm(context, elem); - happen.click(selection.select('button.close').node()); - window.setTimeout(function() { - d3.timerFlush(); - expect(selection.node().parentNode).to.be.null; - done(); - }, 275); - }); - - it('can be dismissed by pressing escape', function (done) { - var selection = Rapid.uiConfirm(context, elem); - happen.keydown(document, {keyCode: 27}); - happen.keyup(document, {keyCode: 27}); - window.setTimeout(function() { - d3.timerFlush(); - expect(selection.node().parentNode).to.be.null; - done(); - }, 275); - }); - - it('can be dismissed by pressing backspace', function (done) { - var selection = Rapid.uiConfirm(context, elem); - happen.keydown(document, {keyCode: 8}); - happen.keyup(document, {keyCode: 8}); - window.setTimeout(function() { - d3.timerFlush(); - expect(selection.node().parentNode).to.be.null; - done(); - }, 275); - }); - - it('can be dismissed by clicking the ok button', function (done) { - var selection = Rapid.uiConfirm(context, elem).okButton(); - happen.click(selection.select('div.content div.buttons button.action').node()); - window.setTimeout(function() { - d3.timerFlush(); - expect(selection.node().parentNode).to.be.null; - done(); - }, 275); - }); + } + + const context = new MockContext(); + + + beforeEach(() => { + elem = d3.select('body') + .append('div') + .attr('class', 'confirm-wrap'); + }); + + afterEach(() => { + d3.select('.confirm-wrap') + .remove(); + }); + + it('can be instantiated', () => { + const selection = Rapid.uiConfirm(context, elem); + expect(selection).to.be.ok; + }); + + it('has a header section', () => { + const selection = Rapid.uiConfirm(context, elem); + expect(selection.selectAll('div.content div.header').size()).to.equal(1); + }); + + it('has a message section', () => { + const selection = Rapid.uiConfirm(context, elem); + expect(selection.selectAll('div.content div.message-text').size()).to.equal(1); + }); + + it('has a buttons section', () => { + const selection = Rapid.uiConfirm(context, elem); + expect(selection.selectAll('div.content div.buttons').size()).to.equal(1); + }); + + it('can have an ok button added to it', () => { + const selection = Rapid.uiConfirm(context, elem).okButton(); + expect(selection.selectAll('div.content div.buttons button.action').size()).to.equal(1); + }); + + it('can be dismissed by calling close function', done => { + const selection = Rapid.uiConfirm(context, elem); + selection.close(); + window.setTimeout(() => { + d3.timerFlush(); + expect(selection.node().parentNode).to.be.null; + done(); + }, 275); + }); + + it('can be dismissed by clicking the close button', done => { + const selection = Rapid.uiConfirm(context, elem); + happen.click(selection.select('button.close').node()); + window.setTimeout(() => { + d3.timerFlush(); + expect(selection.node().parentNode).to.be.null; + done(); + }, 275); + }); + + it('can be dismissed by pressing escape', done => { + const selection = Rapid.uiConfirm(context, elem); + happen.keydown(document, {keyCode: 27}); + happen.keyup(document, {keyCode: 27}); + window.setTimeout(() => { + d3.timerFlush(); + expect(selection.node().parentNode).to.be.null; + done(); + }, 275); + }); + + it('can be dismissed by pressing backspace', done => { + const selection = Rapid.uiConfirm(context, elem); + happen.keydown(document, {keyCode: 8}); + happen.keyup(document, {keyCode: 8}); + window.setTimeout(() => { + d3.timerFlush(); + expect(selection.node().parentNode).to.be.null; + done(); + }, 275); + }); + + it('can be dismissed by clicking the ok button', done => { + const selection = Rapid.uiConfirm(context, elem).okButton(); + happen.click(selection.select('div.content div.buttons button.action').node()); + window.setTimeout(() => { + d3.timerFlush(); + expect(selection.node().parentNode).to.be.null; + done(); + }, 275); + }); });