diff --git a/modules/behavior/select.js b/modules/behavior/select.js index 36e45f73d..9ee382ddb 100644 --- a/modules/behavior/select.js +++ b/modules/behavior/select.js @@ -1,6 +1,7 @@ import { event as d3_event, select as d3_select } from 'd3-selection'; import { geoVecLength } from '../geo'; +import { prefs } from '../core/preferences'; import { modeBrowse } from '../modes/browse'; import { modeSelect } from '../modes/select'; import { modeSelectData } from '../modes/select_data'; @@ -13,7 +14,7 @@ import { utilFastMouse } from '../util/util'; export function behaviorSelect(context) { // legacy option to show menu on every click - var isShowAlways = +context.storage('edit-menu-show-always') === 1; + var isShowAlways = +prefs('edit-menu-show-always') === 1; var tolerance = 4; var _lastMouse = null; var _showMenu = false; diff --git a/modules/core/context.js b/modules/core/context.js index e7d2d0f73..de6987552 100644 --- a/modules/core/context.js +++ b/modules/core/context.js @@ -8,6 +8,7 @@ import { t } from '../core/localizer'; import { fileFetcher as data } from './file_fetcher'; import { localizer } from './localizer'; +import { prefs } from './preferences'; import { coreHistory } from './history'; import { coreValidator } from './validator'; import { coreUploader } from './uploader'; @@ -28,34 +29,7 @@ export function coreContext() { context.version = '2.17.2'; context.privacyVersion = '20191217'; - - // https://github.com/openstreetmap/iD/issues/772 - // http://mathiasbynens.be/notes/localstorage-pattern#comment-9 - let _storage; - try { _storage = localStorage; } catch (e) {} // eslint-disable-line no-empty - _storage = _storage || (() => { - let s = {}; - return { - getItem: (k) => s[k], - setItem: (k, v) => s[k] = v, - removeItem: (k) => delete s[k] - }; - })(); - - context.storage = function(k, v) { - try { - if (arguments.length === 1) return _storage.getItem(k); - else if (v === null) _storage.removeItem(k); - else _storage.setItem(k, v); - } catch (e) { - /* eslint-disable no-console */ - if (typeof console !== 'undefined') { - console.error('localStorage quota exceeded'); - } - /* eslint-enable no-console */ - } - }; - context.isFirstSession = !context.storage('sawSplash') && !context.storage('sawPrivacyVersion'); + context.isFirstSession = !prefs('sawSplash') && !prefs('sawPrivacyVersion'); /* User interface and keybinding */ diff --git a/modules/core/history.js b/modules/core/history.js index 46dc56257..3ea1af48e 100644 --- a/modules/core/history.js +++ b/modules/core/history.js @@ -2,6 +2,7 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; import { easeLinear as d3_easeLinear } from 'd3-ease'; import { select as d3_select } from 'd3-selection'; +import { prefs } from './preferences'; import { coreDifference } from './difference'; import { coreGraph } from './graph'; import { coreTree } from './tree'; @@ -18,7 +19,7 @@ export function coreHistory(context) { var lock = utilSessionMutex('lock'); // restorable if iD not open in another window/tab and a saved history exists in localStorage - var _hasUnresolvedRestorableChanges = lock.lock() && !!context.storage(getKey('saved_history')); + var _hasUnresolvedRestorableChanges = lock.lock() && !!prefs(getKey('saved_history')); var duration = 150; var _imageryUsed = []; @@ -656,7 +657,7 @@ export function coreHistory(context) { // don't overwrite existing, unresolved changes !_hasUnresolvedRestorableChanges) { - context.storage(getKey('saved_history'), history.toJSON() || null); + prefs(getKey('saved_history'), history.toJSON() || null); } return history; }, @@ -667,19 +668,19 @@ export function coreHistory(context) { context.debouncedSave.cancel(); if (lock.locked()) { _hasUnresolvedRestorableChanges = false; - context.storage(getKey('saved_history'), null); + prefs(getKey('saved_history'), null); // clear the changeset metadata associated with the saved history - context.storage('comment', null); - context.storage('hashtags', null); - context.storage('source', null); + prefs('comment', null); + prefs('hashtags', null); + prefs('source', null); } return history; }, savedHistoryJSON: function() { - return context.storage(getKey('saved_history')); + return prefs(getKey('saved_history')); }, diff --git a/modules/core/index.js b/modules/core/index.js index 214bc865c..d169de83d 100644 --- a/modules/core/index.js +++ b/modules/core/index.js @@ -4,6 +4,7 @@ export { coreDifference } from './difference'; export { coreGraph } from './graph'; export { coreHistory } from './history'; export { coreLocalizer, t, localizer } from './localizer'; +export { prefs } from './preferences'; export { coreTree } from './tree'; export { coreUploader } from './uploader'; export { coreValidator } from './validator'; diff --git a/modules/core/preferences.js b/modules/core/preferences.js new file mode 100644 index 000000000..3e9b2d90b --- /dev/null +++ b/modules/core/preferences.js @@ -0,0 +1,35 @@ + +// https://github.com/openstreetmap/iD/issues/772 +// http://mathiasbynens.be/notes/localstorage-pattern#comment-9 +let _storage; +try { _storage = localStorage; } catch (e) {} // eslint-disable-line no-empty +_storage = _storage || (() => { + let s = {}; + return { + getItem: (k) => s[k], + setItem: (k, v) => s[k] = v, + removeItem: (k) => delete s[k] + }; +})(); + +// +// corePreferences is an interface for persisting basic key-value strings +// within and between iD sessions on the same site. +// +function corePreferences(k, v) { + + try { + if (arguments.length === 1) return _storage.getItem(k); + else if (v === null) _storage.removeItem(k); + else _storage.setItem(k, v); + } catch (e) { + /* eslint-disable no-console */ + if (typeof console !== 'undefined') { + console.error('localStorage quota exceeded'); + } + /* eslint-enable no-console */ + } + +} + +export { corePreferences as prefs }; diff --git a/modules/core/validator.js b/modules/core/validator.js index 0e21a7647..b209d6000 100644 --- a/modules/core/validator.js +++ b/modules/core/validator.js @@ -1,5 +1,6 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; +import { prefs } from './preferences'; import { coreDifference } from './difference'; import { geoExtent } from '../geo/extent'; import { modeSelect } from '../modes/select'; @@ -32,7 +33,7 @@ export function coreValidator(context) { _rules[key] = fn; }); - var disabledRules = context.storage('validate-disabledRules'); + var disabledRules = prefs('validate-disabledRules'); if (disabledRules) { disabledRules.split(',') .forEach(function(key) { _disabledRules[key] = true; }); @@ -256,7 +257,7 @@ export function coreValidator(context) { _disabledRules[key] = true; } - context.storage('validate-disabledRules', Object.keys(_disabledRules).join(',')); + prefs('validate-disabledRules', Object.keys(_disabledRules).join(',')); validator.validate(); }; @@ -267,7 +268,7 @@ export function coreValidator(context) { _disabledRules[k] = true; }); - context.storage('validate-disabledRules', Object.keys(_disabledRules).join(',')); + prefs('validate-disabledRules', Object.keys(_disabledRules).join(',')); validator.validate(); }; diff --git a/modules/presets/index.js b/modules/presets/index.js index cb8e5c5f7..4bae2013c 100644 --- a/modules/presets/index.js +++ b/modules/presets/index.js @@ -1,5 +1,6 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; +import { prefs } from '../core/preferences'; import { fileFetcher } from '../core/file_fetcher'; import { osmNodeGeometriesForTags, osmSetAreaKeys, osmSetPointTags, osmSetVertexTags } from '../osm/tags'; import { presetCategory } from './category'; @@ -378,7 +379,7 @@ export function presetIndex(context) { function setRecents(items) { _recents = items; const minifiedItems = items.map(d => d.minified()); - context.storage('preset_recents', JSON.stringify(minifiedItems)); + prefs('preset_recents', JSON.stringify(minifiedItems)); dispatch.call('recentsChange'); } @@ -386,7 +387,7 @@ export function presetIndex(context) { _this.getRecents = () => { if (!_recents) { // fetch from local storage - _recents = (JSON.parse(context.storage('preset_recents')) || []) + _recents = (JSON.parse(prefs('preset_recents')) || []) .reduce((acc, d) => { let item = ribbonItemForMinified(d, 'recent'); if (item && item.preset.addable()) acc.push(item); diff --git a/modules/renderer/background.js b/modules/renderer/background.js index 3cf7a52aa..1b1320b06 100644 --- a/modules/renderer/background.js +++ b/modules/renderer/background.js @@ -4,6 +4,7 @@ import { select as d3_select } from 'd3-selection'; import whichPolygon from 'which-polygon'; +import { prefs } from '../core/preferences'; import { fileFetcher } from '../core/file_fetcher'; import { geoExtent, geoMetersToOffset, geoOffsetToMeters} from '../geo'; import { rendererBackgroundSource } from './background_source'; @@ -76,7 +77,7 @@ export function rendererBackground(context) { _imageryIndex.backgrounds.unshift(rendererBackgroundSource.None()); // Add 'Custom' - let template = context.storage('background-custom-template') || ''; + let template = prefs('background-custom-template') || ''; const custom = rendererBackgroundSource.Custom(template); _imageryIndex.backgrounds.unshift(custom); @@ -467,12 +468,12 @@ export function rendererBackground(context) { const template = requested.replace(/^custom:/, ''); const custom = background.findSource('custom'); background.baseLayerSource(custom.template(template)); - context.storage('background-custom-template', template); + prefs('background-custom-template', template); } else { background.baseLayerSource( background.findSource(requested) || best || - background.findSource(context.storage('background-last-used')) || + background.findSource(prefs('background-last-used')) || background.findSource('Bing') || first || background.findSource('none') diff --git a/modules/renderer/features.js b/modules/renderer/features.js index e908df604..e3a8c27f5 100644 --- a/modules/renderer/features.js +++ b/modules/renderer/features.js @@ -1,5 +1,6 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; +import { prefs } from '../core/preferences'; import { osmEntity } from '../osm'; import { utilRebind } from '../util/rebind'; import { utilArrayGroupBy, utilArrayUnion, utilQsString, utilStringQs } from '../util'; @@ -72,7 +73,7 @@ export function rendererFeatures(context) { delete hash.disable_features; } window.location.replace('#' + utilQsString(hash, true)); - context.storage('disabled-features', disabled.join(',')); + prefs('disabled-features', disabled.join(',')); } _hidden = features.hidden(); dispatch.call('change'); @@ -573,7 +574,7 @@ export function rendererFeatures(context) { features.init = function() { - var storage = context.storage('disabled-features'); + var storage = prefs('disabled-features'); if (storage) { var storageDisabled = storage.replace(/;/g, ',').split(','); storageDisabled.forEach(features.disable); diff --git a/modules/renderer/map.js b/modules/renderer/map.js index e8ac58b62..fb89fa794 100644 --- a/modules/renderer/map.js +++ b/modules/renderer/map.js @@ -6,6 +6,7 @@ import { scaleLinear as d3_scaleLinear } from 'd3-scale'; import { event as d3_event, select as d3_select } from 'd3-selection'; import { zoom as d3_zoom, zoomIdentity as d3_zoomIdentity } from 'd3-zoom'; +import { prefs } from '../core/preferences'; import { geoExtent, geoRawMercator, geoScaleToZoom, geoZoomToScale } from '../geo'; import { modeBrowse } from '../modes/browse'; import { svgAreas, svgLabels, svgLayers, svgLines, svgMidpoints, svgPoints, svgVertices } from '../svg'; @@ -1046,11 +1047,11 @@ export function rendererMap(context) { map.areaFillOptions = ['wireframe', 'partial', 'full']; map.activeAreaFill = function(val) { - if (!arguments.length) return context.storage('area-fill') || 'partial'; + if (!arguments.length) return prefs('area-fill') || 'partial'; - context.storage('area-fill', val); + prefs('area-fill', val); if (val !== 'wireframe') { - context.storage('area-fill-toggle', val); + prefs('area-fill-toggle', val); } updateAreaFill(); map.pan([0,0]); // trigger a redraw @@ -1063,7 +1064,7 @@ export function rendererMap(context) { var activeFill = map.activeAreaFill(); if (activeFill === 'wireframe') { - activeFill = context.storage('area-fill-toggle') || 'partial'; + activeFill = prefs('area-fill-toggle') || 'partial'; } else { activeFill = 'wireframe'; } diff --git a/modules/ui/commit.js b/modules/ui/commit.js index 7ac863e0f..9fce57a94 100644 --- a/modules/ui/commit.js +++ b/modules/ui/commit.js @@ -2,6 +2,7 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; import { select as d3_select } from 'd3-selection'; import deepEqual from 'fast-deep-equal'; +import { prefs } from '../core/preferences'; import { t, localizer } from '../core/localizer'; import { osmChangeset } from '../osm'; import { svgIcon } from '../svg/icon'; @@ -59,13 +60,13 @@ export function uiCommit(context) { var tagCharLimit = context.maxCharsForTagValue(); // expire stored comment, hashtags, source after cutoff datetime - #3947 #4899 - var commentDate = +context.storage('commentDate') || 0; + var commentDate = +prefs('commentDate') || 0; var currDate = Date.now(); var cutoff = 2 * 86400 * 1000; // 2 days if (commentDate > currDate || currDate - commentDate > cutoff) { - context.storage('comment', null); - context.storage('hashtags', null); - context.storage('source', null); + prefs('comment', null); + prefs('hashtags', null); + prefs('source', null); } var tags; @@ -76,20 +77,20 @@ export function uiCommit(context) { // load in the URL hash values, if any var hash = context.ui().hash; if (hash.comment) { - context.storage('comment', hash.comment); - context.storage('commentDate', Date.now()); + prefs('comment', hash.comment); + prefs('commentDate', Date.now()); } if (hash.source) { - context.storage('source', hash.source); - context.storage('commentDate', Date.now()); + prefs('source', hash.source); + prefs('commentDate', Date.now()); } if (hash.hashtags) { - context.storage('hashtags', hash.hashtags); + prefs('hashtags', hash.hashtags); } var detected = utilDetect(); tags = { - comment: context.storage('comment') || '', + comment: prefs('comment') || '', created_by: ('iD ' + context.version).substr(0, tagCharLimit), host: detected.host.substr(0, tagCharLimit), locale: localizer.localeCode().substr(0, tagCharLimit) @@ -99,12 +100,12 @@ export function uiCommit(context) { // hashtags if any hashtags are found in the comment - #4304 findHashtags(tags, true); - var hashtags = context.storage('hashtags'); + var hashtags = prefs('hashtags'); if (hashtags) { tags.hashtags = hashtags; } - var source = context.storage('source'); + var source = prefs('source'); if (source) { tags.source = source; } @@ -450,16 +451,16 @@ export function uiCommit(context) { changed.comment = ''; } if (!onInput) { - context.storage('comment', changed.comment); - context.storage('commentDate', Date.now()); + prefs('comment', changed.comment); + prefs('commentDate', Date.now()); } } if (changed.hasOwnProperty('source')) { if (changed.source === undefined) { - context.storage('source', null); + prefs('source', null); } else if (!onInput) { - context.storage('source', changed.source); - context.storage('commentDate', Date.now()); + prefs('source', changed.source); + prefs('commentDate', Date.now()); } } @@ -476,7 +477,7 @@ export function uiCommit(context) { var inHashTags = hashTags(); if (inComment !== null) { // when hashtags are detected in comment... - context.storage('hashtags', null); // always remove stored hashtags - #4304 + prefs('hashtags', null); // always remove stored hashtags - #4304 if (commentOnly) { inHashTags = []; } // optionally override hashtags field } @@ -555,10 +556,10 @@ export function uiCommit(context) { var arr = findHashtags(tags, commentOnly); if (arr.length) { tags.hashtags = arr.join(';').substr(0, tagCharLimit); - context.storage('hashtags', tags.hashtags); + prefs('hashtags', tags.hashtags); } else { delete tags.hashtags; - context.storage('hashtags', null); + prefs('hashtags', null); } } @@ -570,17 +571,17 @@ export function uiCommit(context) { // first 100 edits - new user if (changesetsCount <= 100) { var s; - s = context.storage('walkthrough_completed'); + s = prefs('walkthrough_completed'); if (s) { tags['ideditor:walkthrough_completed'] = s; } - s = context.storage('walkthrough_progress'); + s = prefs('walkthrough_progress'); if (s) { tags['ideditor:walkthrough_progress'] = s; } - s = context.storage('walkthrough_started'); + s = prefs('walkthrough_started'); if (s) { tags['ideditor:walkthrough_started'] = s; } diff --git a/modules/ui/disclosure.js b/modules/ui/disclosure.js index ffbec3ea4..7294a58a1 100644 --- a/modules/ui/disclosure.js +++ b/modules/ui/disclosure.js @@ -1,6 +1,7 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; import { event as d3_event } from 'd3-selection'; +import { prefs } from '../core/preferences'; import { svgIcon } from '../svg/icon'; import { utilFunctor } from '../util'; import { utilRebind } from '../util/rebind'; @@ -21,7 +22,7 @@ export function uiDisclosure(context, key, expandedDefault) { if (_expanded === undefined || _expanded === null) { // loading _expanded here allows it to be reset by calling `disclosure.expanded(null)` - var preference = context.storage('disclosure.' + key + '.expanded'); + var preference = prefs('disclosure.' + key + '.expanded'); _expanded = preference === null ? !!expandedDefault : (preference === 'true'); } @@ -78,7 +79,7 @@ export function uiDisclosure(context, key, expandedDefault) { _expanded = !_expanded; if (_updatePreference) { - context.storage('disclosure.' + key + '.expanded', _expanded); + prefs('disclosure.' + key + '.expanded', _expanded); } hideToggle diff --git a/modules/ui/fields/restrictions.js b/modules/ui/fields/restrictions.js index 5e3d1f1d7..fd4c99fbb 100644 --- a/modules/ui/fields/restrictions.js +++ b/modules/ui/fields/restrictions.js @@ -1,6 +1,7 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; import { select as d3_select, event as d3_event } from 'd3-selection'; +import { prefs } from '../../core/preferences'; import { t, localizer } from '../../core/localizer'; import { actionRestrictTurn } from '../../actions/restrict_turn'; import { actionUnrestrictTurn } from '../../actions/unrestrict_turn'; @@ -16,9 +17,9 @@ export function uiFieldRestrictions(field, context) { var dispatch = d3_dispatch('change'); var breathe = behaviorBreathe(context); - context.storage('turn-restriction-via-way', null); // remove old key - var storedViaWay = context.storage('turn-restriction-via-way0'); // use new key #6922 - var storedDistance = context.storage('turn-restriction-distance'); + prefs('turn-restriction-via-way', null); // remove old key + var storedViaWay = prefs('turn-restriction-via-way0'); // use new key #6922 + var storedDistance = prefs('turn-restriction-distance'); var _maxViaWay = storedViaWay !== null ? (+storedViaWay) : 0; var _maxDistance = storedDistance ? (+storedDistance) : 30; @@ -144,7 +145,7 @@ export function uiFieldRestrictions(field, context) { _maxDistance = +val; _intersection = null; _container.selectAll('.layer-osm .layer-turns *').remove(); - context.storage('turn-restriction-distance', _maxDistance); + prefs('turn-restriction-distance', _maxDistance); _parent.call(restrictions); }); @@ -186,7 +187,7 @@ export function uiFieldRestrictions(field, context) { var val = d3_select(this).property('value'); _maxViaWay = +val; _container.selectAll('.layer-osm .layer-turns *').remove(); - context.storage('turn-restriction-via-way0', _maxViaWay); + prefs('turn-restriction-via-way0', _maxViaWay); _parent.call(restrictions); }); diff --git a/modules/ui/init.js b/modules/ui/init.js index ed1097a3f..c218f4179 100644 --- a/modules/ui/init.js +++ b/modules/ui/init.js @@ -3,6 +3,7 @@ import { select as d3_select } from 'd3-selection'; +import { prefs } from '../core/preferences'; import { t, localizer } from '../core/localizer'; import { behaviorHash } from '../behavior'; @@ -326,11 +327,11 @@ export function uiInit(context) { d3_event.stopImmediatePropagation(); d3_event.preventDefault(); } - var previousBackground = context.background().findSource(context.storage('background-last-used-toggle')); + var previousBackground = context.background().findSource(prefs('background-last-used-toggle')); if (previousBackground) { var currentBackground = context.background().baseLayerSource(); - context.storage('background-last-used-toggle', currentBackground.id); - context.storage('background-last-used', previousBackground.id); + prefs('background-last-used-toggle', currentBackground.id); + prefs('background-last-used', previousBackground.id); context.background().baseLayerSource(previousBackground); } }) diff --git a/modules/ui/intro/intro.js b/modules/ui/intro/intro.js index 677232b59..b89fa40f4 100644 --- a/modules/ui/intro/intro.js +++ b/modules/ui/intro/intro.js @@ -1,6 +1,7 @@ import { t, localizer } from '../../core/localizer'; import { localize } from './helper'; +import { prefs } from '../../core/preferences'; import { fileFetcher } from '../../core/file_fetcher'; import { coreGraph } from '../../core/graph'; import { modeBrowse } from '../../modes/browse'; @@ -114,10 +115,10 @@ export function uiIntro(context) { selection.call(curtain); // Store that the user started the walkthrough.. - context.storage('walkthrough_started', 'yes'); + prefs('walkthrough_started', 'yes'); // Restore previous walkthrough progress.. - let storedProgress = context.storage('walkthrough_progress') || ''; + let storedProgress = prefs('walkthrough_progress') || ''; let progress = storedProgress.split(';').filter(Boolean); let chapters = chapterFlow.map((chapter, i) => { @@ -137,7 +138,7 @@ export function uiIntro(context) { // Store walkthrough progress.. progress.push(chapter); - context.storage('walkthrough_progress', utilArrayUniq(progress).join(';')); + prefs('walkthrough_progress', utilArrayUniq(progress).join(';')); }); return s; }); @@ -145,12 +146,12 @@ export function uiIntro(context) { chapters[chapters.length - 1].on('startEditing', () => { // Store walkthrough progress.. progress.push('startEditing'); - context.storage('walkthrough_progress', utilArrayUniq(progress).join(';')); + prefs('walkthrough_progress', utilArrayUniq(progress).join(';')); // Store if walkthrough is completed.. let incomplete = utilArrayDifference(chapterFlow, progress); if (!incomplete.length) { - context.storage('walkthrough_completed', 'yes'); + prefs('walkthrough_completed', 'yes'); } curtain.remove(); diff --git a/modules/ui/issues_info.js b/modules/ui/issues_info.js index 22ef05119..147aba79d 100644 --- a/modules/ui/issues_info.js +++ b/modules/ui/issues_info.js @@ -1,5 +1,6 @@ import { event as d3_event, select as d3_select } from 'd3-selection'; +import { prefs } from '../core/preferences'; import { svgIcon } from '../svg/icon'; import { t } from '../core/localizer'; import { uiTooltip } from './tooltip'; @@ -26,15 +27,15 @@ export function uiIssuesInfo(context) { var shownItems = []; var liveIssues = context.validator().getIssues({ - what: context.storage('validate-what') || 'edited', - where: context.storage('validate-where') || 'all' + what: prefs('validate-what') || 'edited', + where: prefs('validate-where') || 'all' }); if (liveIssues.length) { warningsItem.count = liveIssues.length; shownItems.push(warningsItem); } - if (context.storage('validate-what') === 'all') { + if (prefs('validate-what') === 'all') { var resolvedIssues = context.validator().getResolvedIssues(); if (resolvedIssues.length) { resolvedItem.count = resolvedIssues.length; diff --git a/modules/ui/note_comments.js b/modules/ui/note_comments.js index 1e32c86f9..4ace9a2cb 100644 --- a/modules/ui/note_comments.js +++ b/modules/ui/note_comments.js @@ -1,11 +1,12 @@ import { select as d3_select } from 'd3-selection'; +import { prefs } from '../core/preferences'; import { t, localizer } from '../core/localizer'; import { svgIcon } from '../svg/icon'; import { services } from '../services'; -export function uiNoteComments(context) { +export function uiNoteComments() { var _note; @@ -75,7 +76,7 @@ export function uiNoteComments(context) { function replaceAvatars(selection) { - var showThirdPartyIcons = context.storage('preferences.privacy.thirdpartyicons') || 'true'; + var showThirdPartyIcons = prefs('preferences.privacy.thirdpartyicons') || 'true'; var osm = services.osm; if (showThirdPartyIcons !== 'true' || !osm) return; diff --git a/modules/ui/preset_icon.js b/modules/ui/preset_icon.js index 2b42cc263..5c1aedbb1 100644 --- a/modules/ui/preset_icon.js +++ b/modules/ui/preset_icon.js @@ -1,5 +1,6 @@ import { select as d3_select } from 'd3-selection'; +import { prefs } from '../core/preferences'; import { svgIcon, svgTagClasses } from '../svg'; import { utilFunctor } from '../util'; @@ -232,7 +233,7 @@ export function uiPresetIcon(context) { geom = 'route'; } - const showThirdPartyIcons = context.storage('preferences.privacy.thirdpartyicons') || 'true'; + const showThirdPartyIcons = prefs('preferences.privacy.thirdpartyicons') || 'true'; const isFallback = isSmall() && p.isFallback && p.isFallback(); const imageURL = (showThirdPartyIcons === 'true') && p.imageURL; const picon = getIcon(p, geom); diff --git a/modules/ui/sections/background_display_options.js b/modules/ui/sections/background_display_options.js index 430ce7a43..5dc132037 100644 --- a/modules/ui/sections/background_display_options.js +++ b/modules/ui/sections/background_display_options.js @@ -3,6 +3,7 @@ import { select as d3_select } from 'd3-selection'; +import { prefs } from '../../core/preferences'; import { t, localizer } from '../../core/localizer'; import { svgIcon } from '../../svg/icon'; import { uiSection } from '../section'; @@ -16,7 +17,7 @@ export function uiSectionBackgroundDisplayOptions(context) { .disclosureContent(renderDisclosureContent); var _detected = utilDetect(); - var _storedOpacity = context.storage('background-opacity'); + var _storedOpacity = prefs('background-opacity'); var _minVal = 0.25; var _maxVal = _detected.cssfilters ? 2 : 1; @@ -46,7 +47,7 @@ export function uiSectionBackgroundDisplayOptions(context) { context.background()[d](val); if (d === 'brightness') { - context.storage('background-opacity', val); + prefs('background-opacity', val); } section.reRender(); diff --git a/modules/ui/sections/background_list.js b/modules/ui/sections/background_list.js index 2c6747f8b..441a02dc8 100644 --- a/modules/ui/sections/background_list.js +++ b/modules/ui/sections/background_list.js @@ -5,6 +5,7 @@ import { select as d3_select } from 'd3-selection'; +import { prefs } from '../../core/preferences'; import { t, localizer } from '../../core/localizer'; import { uiTooltip } from '../tooltip'; import { svgIcon } from '../../svg/icon'; @@ -27,7 +28,7 @@ export function uiSectionBackgroundList(context) { .disclosureContent(renderDisclosureContent); function previousBackgroundID() { - return context.storage('background-last-used-toggle'); + return prefs('background-last-used-toggle'); } function renderDisclosureContent(selection) { @@ -223,8 +224,8 @@ export function uiSectionBackgroundList(context) { d3_event.preventDefault(); var previousBackground = context.background().baseLayerSource(); - context.storage('background-last-used-toggle', previousBackground.id); - context.storage('background-last-used', d.id); + prefs('background-last-used-toggle', previousBackground.id); + prefs('background-last-used', d.id); context.background().baseLayerSource(d); document.activeElement.blur(); } diff --git a/modules/ui/sections/data_layers.js b/modules/ui/sections/data_layers.js index 5122d1cf2..cab83c8b4 100644 --- a/modules/ui/sections/data_layers.js +++ b/modules/ui/sections/data_layers.js @@ -4,6 +4,7 @@ import { select as d3_select } from 'd3-selection'; +import { prefs } from '../../core/preferences'; import { t, localizer } from '../../core/localizer'; import { uiTooltip } from '../tooltip'; import { svgIcon } from '../../svg/icon'; @@ -280,7 +281,7 @@ export function uiSectionDataLayers(context) { } function selectVTLayer(d) { - context.storage('settings-custom-data-url', d.template); + prefs('settings-custom-data-url', d.template); if (dataLayer) { dataLayer.template(d.template, d.src); dataLayer.enabled(true); diff --git a/modules/ui/sections/privacy.js b/modules/ui/sections/privacy.js index 9f9880bfc..bfe3f12b6 100644 --- a/modules/ui/sections/privacy.js +++ b/modules/ui/sections/privacy.js @@ -2,6 +2,7 @@ import { event as d3_event } from 'd3-selection'; +import { prefs } from '../../core/preferences'; import { t } from '../../core/localizer'; import { uiTooltip } from '../tooltip'; import { svgIcon } from '../../svg/icon'; @@ -13,7 +14,7 @@ export function uiSectionPrivacy(context) { .title(t('preferences.privacy.title')) .disclosureContent(renderDisclosureContent); - let _showThirdPartyIcons = context.storage('preferences.privacy.thirdpartyicons') || 'true'; + let _showThirdPartyIcons = prefs('preferences.privacy.thirdpartyicons') || 'true'; function renderDisclosureContent(selection) { // enter @@ -38,7 +39,7 @@ export function uiSectionPrivacy(context) { .on('change', () => { d3_event.preventDefault(); _showThirdPartyIcons = (_showThirdPartyIcons === 'true') ? 'false' : 'true'; - context.storage('preferences.privacy.thirdpartyicons', _showThirdPartyIcons); + prefs('preferences.privacy.thirdpartyicons', _showThirdPartyIcons); update(); }); diff --git a/modules/ui/sections/raw_tag_editor.js b/modules/ui/sections/raw_tag_editor.js index d646b3f8b..ea3a3a6b8 100644 --- a/modules/ui/sections/raw_tag_editor.js +++ b/modules/ui/sections/raw_tag_editor.js @@ -6,6 +6,7 @@ import { svgIcon } from '../../svg/icon'; import { uiCombobox } from '../combobox'; import { uiSection } from '../section'; import { uiTagReference } from '../tag_reference'; +import { prefs } from '../../core/preferences'; import { t } from '../../core/localizer'; import { utilArrayDifference, utilArrayIdentical } from '../../util/array'; import { utilGetSetValue, utilNoAuto, utilRebind, utilTagDiff } from '../../util'; @@ -28,7 +29,7 @@ export function uiSectionRawTagEditor(id, context) { { id: 'list', icon: '#fas-th-list' } ]; - var _tagView = (context.storage('raw-tag-editor-view') || 'list'); // 'list, 'text' + var _tagView = (prefs('raw-tag-editor-view') || 'list'); // 'list, 'text' var _readOnlyTags = []; // the keys in the order we want them to display var _orderedKeys = []; @@ -91,7 +92,7 @@ export function uiSectionRawTagEditor(id, context) { .attr('title', function(d) { return t('icons.' + d.id); }) .on('click', function(d) { _tagView = d.id; - context.storage('raw-tag-editor-view', d.id); + prefs('raw-tag-editor-view', d.id); wrap.selectAll('.raw-tag-option') .classed('selected', function(datum) { return datum === d; }); diff --git a/modules/ui/sections/validation_issues.js b/modules/ui/sections/validation_issues.js index c57d03140..870e8a2b5 100644 --- a/modules/ui/sections/validation_issues.js +++ b/modules/ui/sections/validation_issues.js @@ -6,6 +6,7 @@ import { //import { actionNoop } from '../actions/noop'; import { geoSphericalDistance } from '../../geo'; import { svgIcon } from '../../svg/icon'; +import { prefs } from '../../core/preferences'; import { t } from '../../core/localizer'; import { utilHighlightEntities } from '../../util'; import { uiSection } from '../section'; @@ -27,8 +28,8 @@ export function uiSectionValidationIssues(id, severity, context) { function getOptions() { return { - what: context.storage('validate-what') || 'edited', - where: context.storage('validate-where') || 'all' + what: prefs('validate-what') || 'edited', + where: prefs('validate-where') || 'all' }; } diff --git a/modules/ui/sections/validation_options.js b/modules/ui/sections/validation_options.js index dd8df0288..77fe5a4cf 100644 --- a/modules/ui/sections/validation_options.js +++ b/modules/ui/sections/validation_options.js @@ -2,6 +2,7 @@ import { event as d3_event } from 'd3-selection'; +import { prefs } from '../../core/preferences'; import { t } from '../../core/localizer'; import { uiSection } from '../section'; @@ -59,8 +60,8 @@ export function uiSectionValidationOptions(context) { function getOptions() { return { - what: context.storage('validate-what') || 'edited', // 'all', 'edited' - where: context.storage('validate-where') || 'all' // 'all', 'visible' + what: prefs('validate-what') || 'edited', // 'all', 'edited' + where: prefs('validate-where') || 'all' // 'all', 'visible' }; } @@ -69,7 +70,7 @@ export function uiSectionValidationOptions(context) { val = d3_event.target.value; } - context.storage('validate-' + d, val); + prefs('validate-' + d, val); context.validator().validate(); } diff --git a/modules/ui/sections/validation_rules.js b/modules/ui/sections/validation_rules.js index 1d459724e..2be50e261 100644 --- a/modules/ui/sections/validation_rules.js +++ b/modules/ui/sections/validation_rules.js @@ -3,6 +3,7 @@ import { select as d3_select } from 'd3-selection'; +import { prefs } from '../../core/preferences'; import { t } from '../../core/localizer'; import { utilGetSetValue, utilNoAuto } from '../../util'; import { uiTooltip } from '../tooltip'; @@ -119,7 +120,7 @@ export function uiSectionValidationRules(context) { // user-configurable square threshold - var degStr = context.storage('validate-square-degrees'); + var degStr = prefs('validate-square-degrees'); if (degStr === null) { degStr = '' + DEFAULTSQUARE; } @@ -172,7 +173,7 @@ export function uiSectionValidationRules(context) { input .property('value', degStr); - context.storage('validate-square-degrees', degStr); + prefs('validate-square-degrees', degStr); context.validator().reloadUnsquareIssues(); } diff --git a/modules/ui/sections/validation_status.js b/modules/ui/sections/validation_status.js index 65223029e..702b07b8f 100644 --- a/modules/ui/sections/validation_status.js +++ b/modules/ui/sections/validation_status.js @@ -1,6 +1,7 @@ import _debounce from 'lodash-es/debounce'; import { svgIcon } from '../../svg/icon'; +import { prefs } from '../../core/preferences'; import { t } from '../../core/localizer'; import { uiSection } from '../section'; @@ -15,8 +16,8 @@ export function uiSectionValidationStatus(context) { function getOptions() { return { - what: context.storage('validate-what') || 'edited', - where: context.storage('validate-where') || 'all' + what: prefs('validate-what') || 'edited', + where: prefs('validate-where') || 'all' }; } diff --git a/modules/ui/settings/custom_background.js b/modules/ui/settings/custom_background.js index 043cee1cb..e3b998251 100644 --- a/modules/ui/settings/custom_background.js +++ b/modules/ui/settings/custom_background.js @@ -1,20 +1,21 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; +import { prefs } from '../../core/preferences'; import { t } from '../../core/localizer'; import { uiConfirm } from '../confirm'; import { utilNoAuto, utilRebind } from '../../util'; -export function uiSettingsCustomBackground(context) { +export function uiSettingsCustomBackground() { var dispatch = d3_dispatch('change'); function render(selection) { // keep separate copies of original and current settings var _origSettings = { - template: context.storage('background-custom-template') + template: prefs('background-custom-template') }; var _currSettings = { - template: context.storage('background-custom-template') + template: prefs('background-custom-template') }; var example = 'https://{switch:a,b,c}.tile.openstreetmap.org/{zoom}/{x}/{y}.png'; @@ -68,7 +69,7 @@ export function uiSettingsCustomBackground(context) { // restore the original template function clickCancel() { textSection.select('.field-template').property('value', _origSettings.template); - context.storage('background-custom-template', _origSettings.template); + prefs('background-custom-template', _origSettings.template); this.blur(); modal.close(); } @@ -76,7 +77,7 @@ export function uiSettingsCustomBackground(context) { // accept the current template function clickSave() { _currSettings.template = textSection.select('.field-template').property('value'); - context.storage('background-custom-template', _currSettings.template); + prefs('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 7a1d8ca2d..923305928 100644 --- a/modules/ui/settings/custom_data.js +++ b/modules/ui/settings/custom_data.js @@ -1,6 +1,7 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; import { event as d3_event } from 'd3-selection'; +import { prefs } from '../../core/preferences'; import { t } from '../../core/localizer'; import { uiConfirm } from '../confirm'; import { utilNoAuto, utilRebind } from '../../util'; @@ -15,11 +16,11 @@ export function uiSettingsCustomData(context) { // keep separate copies of original and current settings var _origSettings = { fileList: (dataLayer && dataLayer.fileList()) || null, - url: context.storage('settings-custom-data-url') + url: prefs('settings-custom-data-url') }; var _currSettings = { fileList: (dataLayer && dataLayer.fileList()) || null, - url: context.storage('settings-custom-data-url') + url: prefs('settings-custom-data-url') }; // var example = 'https://{switch:a,b,c}.tile.openstreetmap.org/{zoom}/{x}/{y}.png'; @@ -98,7 +99,7 @@ export function uiSettingsCustomData(context) { // restore the original url function clickCancel() { textSection.select('.field-url').property('value', _origSettings.url); - context.storage('settings-custom-data-url', _origSettings.url); + prefs('settings-custom-data-url', _origSettings.url); this.blur(); modal.close(); } @@ -111,7 +112,7 @@ export function uiSettingsCustomData(context) { if (_currSettings.url) { _currSettings.fileList = null; } if (_currSettings.fileList) { _currSettings.url = ''; } - context.storage('settings-custom-data-url', _currSettings.url); + prefs('settings-custom-data-url', _currSettings.url); this.blur(); modal.close(); dispatch.call('change', this, _currSettings); diff --git a/modules/ui/splash.js b/modules/ui/splash.js index 684b3dfc3..5d8fbca38 100644 --- a/modules/ui/splash.js +++ b/modules/ui/splash.js @@ -1,3 +1,4 @@ +import { prefs } from '../core/preferences'; import { fileFetcher } from '../core/file_fetcher'; import { t } from '../core/localizer'; import { uiIntro } from './intro'; @@ -13,8 +14,8 @@ export function uiSplash(context) { // If user has not seen this version of the privacy policy, show the splash again. let updateMessage = ''; - const sawPrivacyVersion = context.storage('sawPrivacyVersion'); - let showSplash = !context.storage('sawSplash'); + const sawPrivacyVersion = prefs('sawPrivacyVersion'); + let showSplash = !prefs('sawSplash'); if (sawPrivacyVersion !== context.privacyVersion) { updateMessage = t('splash.privacy_update'); showSplash = true; @@ -22,8 +23,8 @@ export function uiSplash(context) { if (!showSplash) return; - context.storage('sawSplash', true); - context.storage('sawPrivacyVersion', context.privacyVersion); + prefs('sawSplash', true); + prefs('sawPrivacyVersion', context.privacyVersion); // fetch intro graph data now, while user is looking at the splash screen fileFetcher.get('intro_graph'); diff --git a/modules/ui/version.js b/modules/ui/version.js index a46f2e77c..31a18b9e3 100644 --- a/modules/ui/version.js +++ b/modules/ui/version.js @@ -1,3 +1,4 @@ +import { prefs } from '../core/preferences'; import { t } from '../core/localizer'; import { svgIcon } from '../svg/icon'; import { uiTooltip } from './tooltip'; @@ -15,14 +16,14 @@ export function uiVersion(context) { var matchedVersion = currVersion.match(/\d+\.\d+\.\d+.*/); if (sawVersion === null && matchedVersion !== null) { - if (context.storage('sawVersion')) { + if (prefs('sawVersion')) { isNewUser = false; - isNewVersion = context.storage('sawVersion') !== currVersion; + isNewVersion = prefs('sawVersion') !== currVersion; } else { isNewUser = true; isNewVersion = true; } - context.storage('sawVersion', currVersion); + prefs('sawVersion', currVersion); sawVersion = currVersion; } diff --git a/modules/validations/unsquare_way.js b/modules/validations/unsquare_way.js index bd5318f12..270c87488 100644 --- a/modules/validations/unsquare_way.js +++ b/modules/validations/unsquare_way.js @@ -1,3 +1,4 @@ +import { prefs } from '../core/preferences'; import { t } from '../core/localizer'; //import { actionChangeTags } from '../actions/change_tags'; import { actionOrthogonalize } from '../actions/orthogonalize'; @@ -54,7 +55,7 @@ export function validationUnsquareWay(context) { // user-configurable square threshold - var storedDegreeThreshold = context.storage('validate-square-degrees'); + var storedDegreeThreshold = prefs('validate-square-degrees'); var degreeThreshold = isNaN(storedDegreeThreshold) ? DEFAULT_DEG_THRESHOLD : parseFloat(storedDegreeThreshold); var points = nodes.map(function(node) { return context.projection(node.loc); }); diff --git a/test/spec/core/history.js b/test/spec/core/history.js index 686108afa..1bffa491a 100644 --- a/test/spec/core/history.js +++ b/test/spec/core/history.js @@ -12,7 +12,7 @@ describe('iD.coreHistory', function () { history = context.history(); spy = sinon.spy(); // clear lock - context.storage(history._getKey('lock'), null); + iD.prefs(history._getKey('lock'), null); }); describe('#graph', function () {