Commit cb71e903 authored by Bryan Housel's avatar Bryan Housel Committed by Tom MacWright

Module for iD.Detect() (#3243)

* convert iD.Detect() iife to a module

* iD.Detect() should return loaded locale (except for 'en')

(The previous code was a hack to replace the detected locale with the loaded
locale.  Now that Detect is a module, we can not replace the detected locale
from external code, but we can have Detect() return the locale we really want)
parent 0aeacc32
js/id/start.js
js/id/end.js
......@@ -62,10 +62,8 @@ dist/iD.js: \
js/lib/d3.curtain.js \
js/lib/d3.value.js \
js/lib/lodash.js \
js/id/start.js \
js/id/id.js \
$(MODULE_TARGETS) \
js/id/end.js \
js/lib/locale.js \
data/introGraph.js
......
......@@ -35,7 +35,7 @@
a.src=document.location.protocol+'//dnn506yrbagrg.cloudfront.net/pages/scripts/0013/6714.js?'+Math.floor(new Date().getTime()/3600000);
a.async=true;a.type='text/javascript';b.parentNode.insertBefore(a,b)}, 1);
if (typeof iD == 'undefined' || !iD.detect().support) {
if (typeof iD == 'undefined' || !iD.Detect().support) {
document.getElementById('id-container').innerHTML = 'Sorry, your browser is not currently supported. Please use Potlatch 2 to edit the map.';
document.getElementById('id-container').className = 'unsupported';
} else {
......
......@@ -27,13 +27,10 @@
<script src='js/lib/bootstrap-tooltip.js'></script>
<script src='js/id/id.js'></script>
<script src='js/lib/id/index.js'></script>
<script src='data/data_dev.js'></script>
<script src='js/lib/locale.js'></script>
<script src='data/data_dev.js'></script>
<script src='data/introGraph.js'></script>
</head>
<body>
......
(function () {
/*global iD*/
window.iD = function () {
window.locale.en = iD.data.en;
......@@ -305,14 +307,9 @@ window.iD = function () {
var locale, localePath;
context.locale = function(loc, path) {
if (!arguments.length) return locale;
locale = loc;
localePath = path;
// Also set iD.detect().locale (unless we detected 'en-us' and openstreetmap wants 'en')..
if (!(loc.toLowerCase() === 'en' && iD.detect().locale.toLowerCase() === 'en-us')) {
iD.detect().locale = loc;
}
return context;
};
......@@ -334,7 +331,7 @@ window.iD = function () {
context.projection = iD.geo.RawMercator();
locale = iD.detect().locale;
locale = iD.Detect().locale;
if (locale && iD.data.locales.indexOf(locale) === -1) {
locale = locale.split('-')[0];
}
......@@ -385,88 +382,6 @@ window.iD = function () {
return d3.rebind(context, dispatch, 'on');
};
iD.version = '1.9.6';
(function() {
var detected = {};
var ua = navigator.userAgent,
m = null;
m = ua.match(/(edge)\/?\s*(\.?\d+(\.\d+)*)/i); // Edge
if (m !== null) {
detected.browser = m[1];
detected.version = m[2];
}
if (!detected.browser) {
m = ua.match(/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/i); // IE11
if (m !== null) {
detected.browser = 'msie';
detected.version = m[1];
}
}
if (!detected.browser) {
m = ua.match(/(opr)\/?\s*(\.?\d+(\.\d+)*)/i); // Opera 15+
if (m !== null) {
detected.browser = 'Opera';
detected.version = m[2];
}
}
if (!detected.browser) {
m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
if (m !== null) {
detected.browser = m[1];
detected.version = m[2];
m = ua.match(/version\/([\.\d]+)/i);
if (m !== null) detected.version = m[1];
}
}
if (!detected.browser) {
detected.browser = navigator.appName;
detected.version = navigator.appVersion;
}
// keep major.minor version only..
detected.version = detected.version.split(/\W/).slice(0,2).join('.');
if (detected.browser.toLowerCase() === 'msie') {
detected.ie = true;
detected.browser = 'Internet Explorer';
detected.support = parseFloat(detected.version) >= 11;
} else {
detected.ie = false;
detected.support = true;
}
// Added due to incomplete svg style support. See #715
detected.opera = (detected.browser.toLowerCase() === 'opera' && parseFloat(detected.version) < 15 );
detected.locale = (navigator.languages && navigator.languages.length)
? navigator.languages[0] : (navigator.language || navigator.userLanguage || 'en-US');
detected.filedrop = (window.FileReader && 'ondrop' in window);
function nav(x) {
return navigator.userAgent.indexOf(x) !== -1;
}
if (nav('Win')) {
detected.os = 'win';
detected.platform = 'Windows';
}
else if (nav('Mac')) {
detected.os = 'mac';
detected.platform = 'Macintosh';
}
else if (nav('X11') || nav('Linux')) {
detected.os = 'linux';
detected.platform = 'Linux';
}
else {
detected.os = 'win';
detected.platform = 'Unknown';
}
iD.detect = function() { return detected; };
})();
import { Detect } from '../util/detect';
import { Entity } from './entity';
import { Extent } from '../geo/index';
import { JXON } from '../util/jxon';
......@@ -258,7 +259,7 @@ export function Connection(useHttps) {
};
connection.changesetTags = function(comment, imageryUsed) {
var detected = iD.detect(),
var detected = Detect(),
tags = {
created_by: 'iD ' + iD.version,
imagery_used: imageryUsed.join(';').substr(0, 255),
......
......@@ -10,6 +10,9 @@ import * as ui from './ui/index';
import * as util from './util/index';
import * as validations from './validations/index';
// detect
export { Detect } from './util/detect';
// core
export { Connection } from './core/connection';
export { Difference } from './core/difference';
......
import { Detect } from '../util/detect';
import { Extent } from '../geo/index';
import { Icon } from '../svg/index';
import { qsString } from '../util/index';
......@@ -279,7 +280,7 @@ export function init() {
};
mapillary.signsSupported = function() {
var detected = iD.detect();
var detected = Detect();
return (!(detected.ie || detected.browser.toLowerCase() === 'safari'));
};
......
import { Extent, polygonIntersectsPolygon } from '../geo/index';
import { Detect } from '../util/detect';
import toGeoJSON from 'togeojson';
export function Gpx(projection, context, dispatch) {
......@@ -22,7 +23,7 @@ export function Gpx(projection, context, dispatch) {
.on('drop.localgpx', function() {
d3.event.stopPropagation();
d3.event.preventDefault();
if (!iD.detect().filedrop) return;
if (!Detect().filedrop) return;
drawGpx.files(d3.event.dataTransfer.files);
})
.on('dragenter.localgpx', over)
......
import { OneWaySegments, Path, RelationMemberTags, TagClasses } from './index';
import { Detect } from '../util/detect';
import { Entity } from '../core/index';
import { simpleMultipolygonOuterMember } from '../geo/index';
......@@ -121,7 +122,7 @@ export function Lines(projection) {
oneways
.attr('d', function(d) { return d.d; });
if (iD.detect().ie) {
if (Detect().ie) {
oneways.each(function() { this.parentNode.insertBefore(this, this); });
}
......
import { metersToOffset, offsetToMeters } from '../geo/index';
import { BackgroundSource } from '../renderer/index';
import { Detect } from '../util/detect';
import { Icon } from '../svg/index';
import { MapInMap } from './map_in_map';
import { cmd } from './cmd';
......@@ -37,7 +38,7 @@ export function Background(context) {
.style('opacity', d)
.attr('data-opacity', d);
if (!iD.detect().opera) {
if (!Detect().opera) {
setTransform(bg, 0, 0);
}
......
import { Detect } from '../util/detect';
// Translate a MacOS key command into the appropriate Windows/Linux equivalent.
// For example, ⌘Z -> Ctrl+Z
export function cmd(code) {
if (iD.detect().os === 'mac') {
var detected = Detect();
if (detected.os === 'mac') {
return code;
}
if (iD.detect().os === 'win') {
if (detected.os === 'win') {
if (code === '⌘⇧Z') return 'Ctrl+Y';
}
......
export { check as defaultcheck };
import { oneWayTags } from '../../core/index';
export { check as defaultcheck };
export function check(field) {
var dispatch = d3.dispatch('change'),
options = field.strings && field.strings.options,
......
export { combo as typeCombo, combo as multiCombo };
export {
combo as typeCombo,
combo as multiCombo
};
export function combo(field, context) {
var dispatch = d3.dispatch('change'),
isMulti = (field.type === 'multiCombo'),
......
import { Detect } from '../../util/detect';
import { Icon } from '../../svg/index';
import { SuggestNames } from '../../util/index';
export function localized(field, context) {
var dispatch = d3.dispatch('change', 'input'),
wikipedia = iD.services.wikipedia.init(),
......@@ -53,7 +55,7 @@ export function localized(field, context) {
function addNew() {
d3.event.preventDefault();
var data = localizedInputs.selectAll('div.entry').data();
var defaultLang = iD.detect().locale.toLowerCase().split('-')[0];
var defaultLang = Detect().locale.toLowerCase().split('-')[0];
var langExists = _.find(data, function(datum) { return datum.lang === defaultLang;});
var isLangEn = defaultLang.indexOf('en') > -1;
if (isLangEn || langExists) {
......
import { pointInPolygon } from '../../geo/index';
export function maxspeed(field, context) {
var dispatch = d3.dispatch('change'),
entity,
......
import { ChangeTags } from '../../actions/index';
import { Detect } from '../../util/detect';
import { Icon } from '../../svg/index';
export function wikipedia(field, context) {
......@@ -73,7 +74,7 @@ export function wikipedia(field, context) {
function language() {
var value = lang.value().toLowerCase();
var locale = iD.detect().locale.toLowerCase();
var locale = Detect().locale.toLowerCase();
var localeLanguage;
return _.find(iD.data.wikipedia, function(d) {
if (d[2] === locale) localeLanguage = d;
......
import { Detect } from '../util/detect';
import { Extent } from '../geo/index';
import { cmd } from './cmd';
export function Info(context) {
var key = cmd('⌘I'),
imperial = (iD.detect().locale.toLowerCase() === 'en-us'),
imperial = (Detect().locale.toLowerCase() === 'en-us'),
hidden = true;
function info(selection) {
......
......@@ -4,6 +4,7 @@ import { Attribution } from './attribution';
import { Background } from './background';
import { Browse } from '../modes/index';
import { Contributors } from './contributors';
import { Detect } from '../util/detect';
import { FeatureInfo } from './feature_info';
import { FullScreen } from './full_screen';
import { Geolocate } from './geolocate';
......@@ -29,7 +30,7 @@ export function init(context) {
function render(container) {
var map = context.map();
if (iD.detect().opera) container.classed('opera', true);
if (Detect().opera) container.classed('opera', true);
var hash = Hash(context);
......
import { lonToMeters, metersToLon } from '../geo/index';
import { Detect } from '../util/detect';
export function Scale(context) {
var projection = context.projection,
imperial = (iD.detect().locale.toLowerCase() === 'en-us'),
imperial = (Detect().locale.toLowerCase() === 'en-us'),
maxLength = 180,
tickHeight = 8;
......
import { Detect } from '../util/detect';
import { Icon } from '../svg/index';
export function TagReference(tag, context) {
var tagReference = {},
button,
......@@ -7,7 +9,7 @@ export function TagReference(tag, context) {
showing;
function findLocal(data) {
var locale = iD.detect().locale.toLowerCase(),
var locale = Detect().locale.toLowerCase(),
localized;
localized = _.find(data, function(d) {
......
export function Detect() {
var detected = {};
var ua = navigator.userAgent,
m = null;
m = ua.match(/(edge)\/?\s*(\.?\d+(\.\d+)*)/i); // Edge
if (m !== null) {
detected.browser = m[1];
detected.version = m[2];
}
if (!detected.browser) {
m = ua.match(/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/i); // IE11
if (m !== null) {
detected.browser = 'msie';
detected.version = m[1];
}
}
if (!detected.browser) {
m = ua.match(/(opr)\/?\s*(\.?\d+(\.\d+)*)/i); // Opera 15+
if (m !== null) {
detected.browser = 'Opera';
detected.version = m[2];
}
}
if (!detected.browser) {
m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
if (m !== null) {
detected.browser = m[1];
detected.version = m[2];
m = ua.match(/version\/([\.\d]+)/i);
if (m !== null) detected.version = m[1];
}
}
if (!detected.browser) {
detected.browser = navigator.appName;
detected.version = navigator.appVersion;
}
// keep major.minor version only..
detected.version = detected.version.split(/\W/).slice(0,2).join('.');
if (detected.browser.toLowerCase() === 'msie') {
detected.ie = true;
detected.browser = 'Internet Explorer';
detected.support = parseFloat(detected.version) >= 11;
} else {
detected.ie = false;
detected.support = true;
}
// Added due to incomplete svg style support. See #715
detected.opera = (detected.browser.toLowerCase() === 'opera' && parseFloat(detected.version) < 15 );
detected.locale = (navigator.languages && navigator.languages.length)
? navigator.languages[0] : (navigator.language || navigator.userLanguage || 'en-US');
// Loaded locale is stored in window.locale.current()
// return that instead (except in the situation where 'en' might override 'en-US')
var loadedLocale = (window.locale && window.locale.current()) || 'en';
if (loadedLocale !== 'en') {
detected.locale = loadedLocale;
}
detected.filedrop = (window.FileReader && 'ondrop' in window);
function nav(x) {
return navigator.userAgent.indexOf(x) !== -1;
}
if (nav('Win')) {
detected.os = 'win';
detected.platform = 'Windows';
}
else if (nav('Mac')) {
detected.os = 'mac';
detected.platform = 'Macintosh';
}
else if (nav('X11') || nav('Linux')) {
detected.os = 'linux';
detected.platform = 'Linux';
}
else {
detected.os = 'win';
detected.platform = 'Unknown';
}
return detected;
}
import { Detect } from './detect';
import { remove as removeDiacritics } from 'diacritics';
export function tagText(entity) {
......@@ -26,7 +27,7 @@ export function entityOrMemberSelector(ids, graph) {
}
export function displayName(entity) {
var localeName = 'name:' + iD.detect().locale.toLowerCase().split('-')[0];
var localeName = 'name:' + Detect().locale.toLowerCase().split('-')[0];
return entity.tags[localeName] || entity.tags.name || entity.tags.ref;
}
......@@ -98,7 +99,7 @@ export function prefixCSSProperty(property) {
var transformProperty;
export function setTransform(el, x, y, scale) {
var prop = transformProperty = transformProperty || prefixCSSProperty('Transform'),
translate = iD.detect().opera ?
translate = Detect().opera ?
'translate(' + x + 'px,' + y + 'px)' :
'translate3d(' + x + 'px,' + y + 'px,0)';
return el.style(prop, translate + (scale ? ' scale(' + scale + ')' : ''));
......
describe('iD.ui.cmd', function () {
var detect, os;
var origNavigator, ua;
beforeEach(function() {
detect = iD.detect;
iD.detect = function() {
return { os: os };
};
/* eslint-disable no-native-reassign */
origNavigator = navigator;
navigator = Object.create(origNavigator, {
userAgent: { get: function() { return ua; } }
});
});
afterEach(function() {
iD.detect = detect;
navigator = origNavigator;
/* eslint-enable no-native-reassign */
});
it('does not overwrite mac keybindings', function () {
os = 'mac';
ua = 'Mac';
expect(iD.ui.cmd('⌘A')).to.eql('⌘A');
});
it('changes keys to linux versions', function () {
os = 'linux';
ua = 'Linux';
expect(iD.ui.cmd('⌘A')).to.eql('Ctrl+A');
expect(iD.ui.cmd('⇧A')).to.eql('Shift+A');
expect(iD.ui.cmd('⌘⇧A')).to.eql('Ctrl+Shift+A');
......@@ -26,7 +28,7 @@ describe('iD.ui.cmd', function () {
});
it('changes keys to win versions', function () {
os = 'win';
ua = 'Win';
expect(iD.ui.cmd('⌘A')).to.eql('Ctrl+A');
expect(iD.ui.cmd('⇧A')).to.eql('Shift+A');
expect(iD.ui.cmd('⌘⇧A')).to.eql('Ctrl+Shift+A');
......@@ -34,7 +36,7 @@ describe('iD.ui.cmd', function () {
});
it('handles multi-character keys', function () {
os = 'win';
ua = 'Win';
expect(iD.ui.cmd('f11')).to.eql('f11');
expect(iD.ui.cmd('⌘plus')).to.eql('Ctrl+plus');
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment