Merge branch 'develop' into decouple-presets

This commit is contained in:
Quincy Morgan
2020-11-10 15:25:24 -05:00
47 changed files with 478 additions and 2045 deletions
+4
View File
@@ -19,12 +19,16 @@
"array-callback-return": "warn",
"arrow-spacing": "warn",
"block-scoped-var": "error",
"block-spacing": ["warn", "always"],
"brace-style": ["warn", "1tbs", { "allowSingleLine": true }],
"class-methods-use-this": "error",
"complexity": ["warn", 50],
"curly": ["warn", "multi-line"],
"default-case-last": "error",
"default-param-last": "error",
"dot-notation": "error",
"eqeqeq": ["error", "smart"],
"func-call-spacing": ["warn", "never"],
"grouped-accessor-pairs": "error",
"indent": ["off", 4],
"keyword-spacing": "error",
+29
View File
@@ -36,6 +36,35 @@ _Breaking developer changes, which may affect downstream projects or sites that
[@xxxx]: https://github.com/xxxx
-->
# 2.19.5
##### 2020-Nov-9
#### :sparkles: Usability & Accessibility
* Enable loading iD with a feature selected even when zoomed out ([#8122])
[#8122]: https://github.com/openstreetmap/iD/issues/8122
#### :bug: Bugfixes
* Fix an issue where some fields that allow multiple values would not show existing tags ([#8155])
* Fix a bug where points could move back unexpectedly when changing their tags after dragging them ([#7606])
* Fix rare instances where iD could add an invalid localized name tag ([#8165])
[#8155]: https://github.com/openstreetmap/iD/issues/8155
[#7606]: https://github.com/openstreetmap/iD/issues/7606
[#8165]: https://github.com/openstreetmap/iD/issues/8165
#### :earth_asia: Localization
* Support dozens of additional languages in the Multilingual Name field ([#8165])
[#8165]: https://github.com/openstreetmap/iD/issues/8165
#### :rocket: Presets
* Indicate the units for the Capacity field on storage tank presets ([#8078], [#8112], thanks [@karmanya007])
[#8078]: https://github.com/openstreetmap/iD/issues/8078
[#8112]: https://github.com/openstreetmap/iD/issues/8112
[@karmanya007]: https://github.com/karmanya007
# 2.19.4
##### 2020-Nov-2
+152 -1852
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+2 -1
View File
@@ -8,8 +8,9 @@ export function actionDeleteMember(relationId, memberIndex) {
graph = graph.replace(relation);
if (relation.isDegenerate())
if (relation.isDegenerate()) {
graph = actionDeleteRelation(relation.id)(graph);
}
return graph;
};
+2 -4
View File
@@ -80,8 +80,7 @@ export function actionDisconnect(nodeId, newNodeId) {
action.disabled = function(graph) {
var connections = action.connections(graph);
if (connections.length === 0)
return 'not_connected';
if (connections.length === 0) return 'not_connected';
var parentWays = graph.parentWays(graph.entity(nodeId));
var seenRelationIds = {};
@@ -105,8 +104,7 @@ export function actionDisconnect(nodeId, newNodeId) {
});
});
if (sharedRelation)
return 'relation';
if (sharedRelation) return 'relation';
};
+7 -5
View File
@@ -256,11 +256,13 @@ export function behaviorSelect(context) {
var datum = pointerInfo.firstEvent.target.__data__;
var entity = (datum && datum.properties && datum.properties.entity) || datum;
if (context.graph().hasEntity(entity.id)) return {
pointerId: pointerId,
entityId: entity.id,
selected: selectedIDs.indexOf(entity.id) !== -1
};
if (context.graph().hasEntity(entity.id)) {
return {
pointerId: pointerId,
entityId: entity.id,
selected: selectedIDs.indexOf(entity.id) !== -1
};
}
}
return null;
}
+4 -1
View File
@@ -26,7 +26,7 @@ export function coreContext() {
let context = utilRebind({}, dispatch, 'on');
let _deferred = new Set();
context.version = '2.19.5-dev';
context.version = '2.20.0-dev';
context.privacyVersion = '20200407';
// iD will alter the hash so cache the parameters intended to setup the session
@@ -177,10 +177,13 @@ export function coreContext() {
_deferred.add(handle);
};
// Download the full entity and its parent relations. The callback may be called multiple times.
context.loadEntity = (entityID, callback) => {
if (_connection) {
const cid = _connection.getConnectionId();
_connection.loadEntity(entityID, afterLoad(cid, callback));
// We need to fetch the parent relations separately.
_connection.loadEntityRelations(entityID, afterLoad(cid, callback));
}
};
+2 -1
View File
@@ -213,8 +213,9 @@ export function coreDifference(base, head) {
if (extent &&
(!h || !h.intersects(extent, head)) &&
(!b || !b.intersects(extent, base)))
(!b || !b.intersects(extent, base))) {
continue;
}
result[id] = h;
+1 -2
View File
@@ -143,8 +143,7 @@ coreGraph.prototype = {
for (i = 0; i < entities.length; i++) {
var entity = entities[i];
if (!entity.visible || (!force && base.entities[entity.id]))
continue;
if (!entity.visible || (!force && base.entities[entity.id])) continue;
// Merging data into the base graph
base.entities[entity.id] = entity;
+8 -4
View File
@@ -326,14 +326,18 @@ export function geoViewportEdge(point, dimensions) {
var x = 0;
var y = 0;
if (point[0] > dimensions[0] - pad[1])
if (point[0] > dimensions[0] - pad[1]) {
x = -10;
if (point[0] < pad[3])
}
if (point[0] < pad[3]) {
x = 10;
if (point[1] > dimensions[1] - pad[2])
}
if (point[1] > dimensions[1] - pad[2]) {
y = -10;
if (point[1] < pad[0])
}
if (point[1] < pad[0]) {
y = 10;
}
if (x || y) {
return [x, y];
+1 -2
View File
@@ -114,8 +114,7 @@ osmEntity.prototype = {
copy: function(resolver, copies) {
if (copies[this.id])
return copies[this.id];
if (copies[this.id]) return copies[this.id];
var copy = osmEntity(this, { id: undefined, user: undefined, version: undefined });
copies[this.id] = copy;
+13 -8
View File
@@ -441,8 +441,7 @@ export function osmIntersection(graph, startVertexId, maxDistance) {
}
// stop looking if we find a "direct" restriction (matching FROM, VIA, TO)
if (restrict && restrict.direct)
break;
if (restrict && restrict.direct) break;
}
nextWays.push({ way: way, restrict: restrict });
@@ -607,19 +606,25 @@ export function osmInferRestriction(graph, turn, projection) {
var angle = (geoAngle(fromVertex, fromNode, projection) -
geoAngle(toVertex, toNode, projection)) * 180 / Math.PI;
while (angle < 0)
while (angle < 0) {
angle += 360;
}
if (fromNode === toNode)
if (fromNode === toNode) {
return 'no_u_turn';
if ((angle < 23 || angle > 336) && fromOneWay && toOneWay)
}
if ((angle < 23 || angle > 336) && fromOneWay && toOneWay) {
return 'no_u_turn'; // wider tolerance for u-turn if both ways are oneway
if ((angle < 40 || angle > 319) && fromOneWay && toOneWay && turn.from.vertex !== turn.to.vertex)
}
if ((angle < 40 || angle > 319) && fromOneWay && toOneWay && turn.from.vertex !== turn.to.vertex) {
return 'no_u_turn'; // even wider tolerance for u-turn if there is a via way (from !== to)
if (angle < 158)
}
if (angle < 158) {
return 'no_right_turn';
if (angle > 202)
}
if (angle > 202) {
return 'no_left_turn';
}
return 'no_straight_on';
}
+22 -20
View File
@@ -136,23 +136,19 @@ function parseLaneDirections(tags, isOneWay, laneCount) {
forward = 0;
bothways = 0;
backward = laneCount;
}
else if (isOneWay) {
} else if (isOneWay) {
forward = laneCount;
bothways = 0;
backward = 0;
}
else if (isNaN(forward) && isNaN(backward)) {
} else if (isNaN(forward) && isNaN(backward)) {
backward = Math.floor((laneCount - bothways) / 2);
forward = laneCount - bothways - backward;
}
else if (isNaN(forward)) {
} else if (isNaN(forward)) {
if (backward > laneCount - bothways) {
backward = laneCount - bothways;
}
forward = laneCount - bothways - backward;
}
else if (isNaN(backward)) {
} else if (isNaN(backward)) {
if (forward > laneCount - bothways) {
forward = laneCount - bothways;
}
@@ -229,16 +225,22 @@ function parseBicycleWay(tag) {
function mapToLanesObj(lanesObj, data, key) {
if (data.forward) data.forward.forEach(function(l, i) {
if (!lanesObj.forward[i]) lanesObj.forward[i] = {};
lanesObj.forward[i][key] = l;
});
if (data.backward) data.backward.forEach(function(l, i) {
if (!lanesObj.backward[i]) lanesObj.backward[i] = {};
lanesObj.backward[i][key] = l;
});
if (data.unspecified) data.unspecified.forEach(function(l, i) {
if (!lanesObj.unspecified[i]) lanesObj.unspecified[i] = {};
lanesObj.unspecified[i][key] = l;
});
if (data.forward) {
data.forward.forEach(function(l, i) {
if (!lanesObj.forward[i]) lanesObj.forward[i] = {};
lanesObj.forward[i][key] = l;
});
}
if (data.backward) {
data.backward.forEach(function(l, i) {
if (!lanesObj.backward[i]) lanesObj.backward[i] = {};
lanesObj.backward[i][key] = l;
});
}
if (data.unspecified) {
data.unspecified.forEach(function(l, i) {
if (!lanesObj.unspecified[i]) lanesObj.unspecified[i] = {};
lanesObj.unspecified[i][key] = l;
});
}
}
+25 -18
View File
@@ -40,24 +40,31 @@ export function osmOldMultipolygonOuterMemberOfRelation(entity, graph) {
// For fixing up rendering of multipolygons with tags on the outer member.
// https://github.com/openstreetmap/iD/issues/613
export function osmIsOldMultipolygonOuterMember(entity, graph) {
if (entity.type !== 'way' || Object.keys(entity.tags).filter(osmIsInterestingTag).length === 0)
if (entity.type !== 'way' ||
Object.keys(entity.tags).filter(osmIsInterestingTag).length === 0) {
return false;
}
var parents = graph.parentRelations(entity);
if (parents.length !== 1)
return false;
if (parents.length !== 1) return false;
var parent = parents[0];
if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1)
if (!parent.isMultipolygon() ||
Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1) {
return false;
}
var members = parent.members, member;
for (var i = 0; i < members.length; i++) {
member = members[i];
if (member.id === entity.id && member.role && member.role !== 'outer')
return false; // Not outer member
if (member.id !== entity.id && (!member.role || member.role === 'outer'))
return false; // Not a simple multipolygon
if (member.id === entity.id && member.role && member.role !== 'outer') {
// Not outer member
return false;
}
if (member.id !== entity.id && (!member.role || member.role === 'outer')) {
// Not a simple multipolygon
return false;
}
}
return parent;
@@ -65,33 +72,33 @@ export function osmIsOldMultipolygonOuterMember(entity, graph) {
export function osmOldMultipolygonOuterMember(entity, graph) {
if (entity.type !== 'way')
return false;
if (entity.type !== 'way') return false;
var parents = graph.parentRelations(entity);
if (parents.length !== 1)
return false;
if (parents.length !== 1) return false;
var parent = parents[0];
if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1)
if (!parent.isMultipolygon() ||
Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1) {
return false;
}
var members = parent.members, member, outerMember;
for (var i = 0; i < members.length; i++) {
member = members[i];
if (!member.role || member.role === 'outer') {
if (outerMember)
return false; // Not a simple multipolygon
if (outerMember) return false; // Not a simple multipolygon
outerMember = member;
}
}
if (!outerMember)
return false;
if (!outerMember) return false;
var outerEntity = graph.hasEntity(outerMember.id);
if (!outerEntity || !Object.keys(outerEntity.tags).filter(osmIsInterestingTag).length)
if (!outerEntity ||
!Object.keys(outerEntity.tags).filter(osmIsInterestingTag).length) {
return false;
}
return outerEntity;
}
+4 -2
View File
@@ -330,14 +330,16 @@ Object.assign(osmRelation.prototype, {
for (o = 0; o < outers.length; o++) {
outer = outers[o];
if (geoPolygonContainsPolygon(outer, inner))
if (geoPolygonContainsPolygon(outer, inner)) {
return o;
}
}
for (o = 0; o < outers.length; o++) {
outer = outers[o];
if (geoPolygonIntersectsPolygon(outer, inner, false))
if (geoPolygonIntersectsPolygon(outer, inner, false)) {
return o;
}
}
}
+5 -5
View File
@@ -155,8 +155,10 @@ Object.assign(osmWay.prototype, {
// implied oneway tag..
for (var key in this.tags) {
if (key in osmOneWayTags && (this.tags[key] in osmOneWayTags[key]))
if (key in osmOneWayTags &&
(this.tags[key] in osmOneWayTags[key])) {
return true;
}
}
return false;
},
@@ -232,10 +234,8 @@ Object.assign(osmWay.prototype, {
},
isArea: function() {
if (this.tags.area === 'yes')
return true;
if (!this.isClosed() || this.tags.area === 'no')
return false;
if (this.tags.area === 'yes') return true;
if (!this.isClosed() || this.tags.area === 'no') return false;
return this.tagSuggestingArea() !== null;
},
+91 -33
View File
@@ -232,6 +232,17 @@ var jsonparsers = {
tags: obj.tags,
members: getMembersJSON(obj)
});
},
user: function parseUser(obj, uid) {
return {
id: uid,
display_name: obj.display_name,
account_created: obj.account_created,
image_url: obj.img && obj.img.href,
changesets_count: obj.changesets && obj.changesets.count && obj.changesets.count.toString() || '0',
active_blocks: obj.blocks && obj.blocks.received && obj.blocks.received.active && obj.blocks.received.active.toString() || '0'
};
}
};
@@ -242,11 +253,9 @@ function parseJSON(payload, callback, options) {
}
var json = payload;
if (typeof json !== 'object')
json = JSON.parse(payload);
if (typeof json !== 'object') json = JSON.parse(payload);
if (!json.elements)
return callback({ message: 'No JSON', status: -1 });
if (!json.elements) return callback({ message: 'No JSON', status: -1 });
var children = json.elements;
@@ -278,6 +287,46 @@ function parseJSON(payload, callback, options) {
}
}
function parseUserJSON(payload, callback, options) {
options = Object.assign({ skipSeen: true }, options);
if (!payload) {
return callback({ message: 'No JSON', status: -1 });
}
var json = payload;
if (typeof json !== 'object') json = JSON.parse(payload);
if (!json.elements) return callback({ message: 'No JSON', status: -1 });
if (!json.users && !json.user) return callback({ message: 'No JSON', status: -1 });
var objs = json.users || [json];
var handle = window.requestIdleCallback(function() {
var results = [];
var result;
for (var i = 0; i < objs.length; i++) {
result = parseObj(objs[i]);
if (result) results.push(result);
}
callback(null, results);
});
_deferred.add(handle);
function parseObj(obj) {
var uid = obj.user.id && obj.user.id.toString();
if (options.skipSeen && _userCache.user[uid]) {
delete _userCache.toLoad[uid];
return null;
}
var user = jsonparsers.user(obj.user, uid);
_userCache.user[uid] = user;
delete _userCache.toLoad[uid];
return user;
}
}
var parsers = {
node: function nodeData(obj, uid) {
var attrs = obj.attributes;
@@ -635,7 +684,8 @@ export default {
},
// Load a single entity by id (ways and relations use the `/full` call)
// Load a single entity by id (ways and relations use the `/full` call to include
// nodes and members). Parent relations are not included, see `loadEntityRelations`.
// GET /api/0.6/node/#id
// GET /api/0.6/[way|relation]/#id/full
loadEntity: function(id, callback) {
@@ -670,6 +720,23 @@ export default {
},
// Load the relations of a single entity with the given.
// GET /api/0.6/[node|way|relation]/#id/relations
loadEntityRelations: function(id, callback) {
var type = osmEntity.id.type(id);
var osmID = osmEntity.id.toOSM(id);
var options = { skipSeen: false };
this.loadFromAPI(
'/api/0.6/' + type + '/' + osmID + '/relations.json',
function(err, entities) {
if (callback) callback(err, { data: entities });
},
options
);
},
// Load multiple entities in chunks
// (note: callback may be called multiple times)
// Unlike `loadEntity`, child nodes and members are not fetched
@@ -790,21 +857,18 @@ export default {
utilArrayChunk(toLoad, 150).forEach(function(arr) {
oauth.xhr(
{ method: 'GET', path: '/api/0.6/users?users=' + arr.join() },
{ method: 'GET', path: '/api/0.6/users.json?users=' + arr.join() },
wrapcb(this, done, _connectionID)
);
}.bind(this));
function done(err, xml) {
if (err) { return callback(err); }
function done(err, payload) {
if (err) return callback(err);
var options = { skipSeen: true };
return parseXML(xml, function(err, results) {
if (err) {
return callback(err);
} else {
return callback(undefined, results);
}
return parseUserJSON(payload, function(err, results) {
if (err) return callback(err);
return callback(undefined, results);
}, options);
}
},
@@ -819,20 +883,17 @@ export default {
}
oauth.xhr(
{ method: 'GET', path: '/api/0.6/user/' + uid },
{ method: 'GET', path: '/api/0.6/user/' + uid + '.json' },
wrapcb(this, done, _connectionID)
);
function done(err, xml) {
if (err) { return callback(err); }
function done(err, payload) {
if (err) return callback(err);
var options = { skipSeen: true };
return parseXML(xml, function(err, results) {
if (err) {
return callback(err);
} else {
return callback(undefined, results[0]);
}
return parseUserJSON(payload, function(err, results) {
if (err) return callback(err);
return callback(undefined, results[0]);
}, options);
}
},
@@ -846,21 +907,18 @@ export default {
}
oauth.xhr(
{ method: 'GET', path: '/api/0.6/user/details' },
{ method: 'GET', path: '/api/0.6/user/details.json' },
wrapcb(this, done, _connectionID)
);
function done(err, xml) {
if (err) { return callback(err); }
function done(err, payload) {
if (err) return callback(err);
var options = { skipSeen: false };
return parseXML(xml, function(err, results) {
if (err) {
return callback(err);
} else {
_userDetails = results[0];
return callback(undefined, _userDetails);
}
return parseUserJSON(payload, function(err, results) {
if (err) return callback(err);
_userDetails = results[0];
return callback(undefined, _userDetails);
}, options);
}
},
+1 -2
View File
@@ -315,8 +315,7 @@ export function svgLabels(projection, context) {
var preset = geometry === 'area' && presetManager.match(entity, graph);
var icon = preset && !shouldSkipIcon(preset) && preset.icon;
if (!icon && !utilDisplayName(entity))
continue;
if (!icon && !utilDisplayName(entity)) continue;
for (k = 0; k < labelStack.length; k++) {
var matchGeom = labelStack[k][0];
+3 -2
View File
@@ -185,10 +185,11 @@ export function svgLines(projection, context) {
var layer = this.parentNode.__data__;
var data = pathdata[layer] || [];
return data.filter(function(d) {
if (isSelected)
if (isSelected) {
return context.selectedIDs().indexOf(d.id) !== -1;
else
} else {
return context.selectedIDs().indexOf(d.id) === -1;
}
});
};
}
+2 -4
View File
@@ -83,8 +83,7 @@ export function svgMidpoints(projection, context) {
point = geoLineIntersection([a.loc, b.loc], [poly[k], poly[k + 1]]);
if (point &&
geoVecLength(projection(a.loc), projection(point)) > 20 &&
geoVecLength(projection(b.loc), projection(point)) > 20)
{
geoVecLength(projection(b.loc), projection(point)) > 20) {
loc = point;
break;
}
@@ -106,8 +105,7 @@ export function svgMidpoints(projection, context) {
function midpointFilter(d) {
if (midpoints[d.id])
return true;
if (midpoints[d.id]) return true;
for (var i = 0; i < d.parents.length; i++) {
if (filter(d.parents[i])) {
+1 -2
View File
@@ -118,8 +118,7 @@ export function svgTagClasses() {
if (v === 'yes') { // e.g. `railway=rail + abandoned=yes`
status = k;
}
else if (primary && primary === v) { // e.g. `railway=rail + abandoned=railway`
} else if (primary && primary === v) { // e.g. `railway=rail + abandoned=railway`
status = k;
} else if (!primary && primaries.indexOf(v) !== -1) { // e.g. `abandoned=railway`
status = k;
+2 -4
View File
@@ -193,8 +193,7 @@ export function uiCurtain(containerNode) {
if (tooltipBox.left + tooltipBox.width + tooltipArrow + tooltipWidth > w - 70) {
side = 'left';
pos = [tooltipBox.left - tooltipWidth - tooltipArrow, tipY];
}
else {
} else {
side = 'right';
pos = [tooltipBox.left + tooltipBox.width + tooltipArrow, tipY];
}
@@ -217,8 +216,7 @@ export function uiCurtain(containerNode) {
if (side === 'left' || side === 'right') {
if (pos[1] < 60) {
shiftY = 60 - pos[1];
}
else if (pos[1] + tip.height > h - 100) {
} else if (pos[1] + tip.height > h - 100) {
shiftY = h - pos[1] - tip.height - 100;
}
}
+6 -2
View File
@@ -270,11 +270,15 @@ export function uiEntityEditor(context) {
entityEditor.entityIDs = function(val) {
if (!arguments.length) return _entityIDs;
// always reload these even if the entityIDs are unchanged, since we
// could be reselecting after something like dragging a node
_base = context.graph();
_coalesceChanges = false;
if (val && _entityIDs && utilArrayIdentical(_entityIDs, val)) return entityEditor; // exit early if no change
_entityIDs = val;
_base = context.graph();
_coalesceChanges = false;
loadActivePresets(true);
+4 -8
View File
@@ -91,16 +91,12 @@ export function uiFieldAddress(field, context) {
function isAddressable(d) {
if (d.tags.name) {
if (d.tags.admin_level === '8' && d.tags.boundary === 'administrative')
return true;
if (d.tags.border_type === 'city')
return true;
if (d.tags.place === 'city' || d.tags.place === 'town' || d.tags.place === 'village')
return true;
if (d.tags.admin_level === '8' && d.tags.boundary === 'administrative') return true;
if (d.tags.border_type === 'city') return true;
if (d.tags.place === 'city' || d.tags.place === 'town' || d.tags.place === 'village') return true;
}
if (d.tags['addr:city'])
return true;
if (d.tags['addr:city']) return true;
return false;
}
+3 -1
View File
@@ -534,8 +534,10 @@ export function uiFieldRestrictions(field, context) {
for (var i = 0; i < datum.via.ways.length; i++) {
var prev = names[names.length - 1];
var curr = displayName(datum.via.ways[i], vgraph);
if (!prev || curr !== prev) // collapse identical names
if (!prev || curr !== prev) {
// collapse identical names
names.push(curr);
}
}
help
+4 -2
View File
@@ -86,8 +86,10 @@ export function uiImproveOsmDetails(context) {
if (entity) {
context.enter(modeSelect(context, [entityID]));
} else {
context.loadEntity(entityID, () => {
context.enter(modeSelect(context, [entityID]));
context.loadEntity(entityID, (err, result) => {
if (err) return;
const entity = result.data.find(e => e.id === entityID);
if (entity) context.enter(modeSelect(context, [entityID]));
});
}
});
+8 -5
View File
@@ -49,7 +49,8 @@ var helpStringReplacements;
// with custom `replacements`
export function helpHtml(id, replacements) {
// only load these the first time
if (!helpStringReplacements) helpStringReplacements = {
if (!helpStringReplacements) {
helpStringReplacements = {
// insert icons corresponding to various UI elements
point_icon: icon('#iD-icon-point', 'inline'),
line_icon: icon('#iD-icon-line', 'inline'),
@@ -144,7 +145,8 @@ export function helpHtml(id, replacements) {
start_the_walkthrough: t.html('splash.walkthrough'),
help: t.html('help.title'),
ok: t.html('intro.ok')
};
};
}
var reps;
if (replacements) {
@@ -255,10 +257,11 @@ export function selectMenuItem(context, operation) {
export function transitionTime(point1, point2) {
var distance = geoSphericalDistance(point1, point2);
if (distance === 0)
if (distance === 0) {
return 0;
else if (distance < 80)
} else if (distance < 80) {
return 500;
else
} else {
return 1000;
}
}
+4 -3
View File
@@ -211,12 +211,13 @@ export function uiIntroLine(context, reveal) {
reveal('.surface', continueLineText);
context.on('enter.intro', function(mode) {
if (mode.id === 'draw-line')
if (mode.id === 'draw-line') {
return;
else if (mode.id === 'select')
} else if (mode.id === 'select') {
return continueTo(chooseCategoryRoad);
else
} else {
return chapter.restart();
}
});
function continueTo(nextStep) {
+4 -2
View File
@@ -91,8 +91,10 @@ export function uiKeepRightDetails(context) {
if (entity) {
context.enter(modeSelect(context, [entityID]));
} else {
context.loadEntity(entityID, () => {
context.enter(modeSelect(context, [entityID]));
context.loadEntity(entityID, (err, result) => {
if (err) return;
const entity = result.data.find(e => e.id === entityID);
if (entity) context.enter(modeSelect(context, [entityID]));
});
}
});
+4 -2
View File
@@ -169,8 +169,10 @@ export function uiOsmoseDetails(context) {
if (entity) {
context.enter(modeSelect(context, [entityID]));
} else {
context.loadEntity(entityID, () => {
context.enter(modeSelect(context, [entityID]));
context.loadEntity(entityID, (err, result) => {
if (err) return;
const entity = result.data.find(e => e.id === entityID);
if (entity) context.enter(modeSelect(context, [entityID]));
});
}
});
+6 -12
View File
@@ -23,18 +23,12 @@ export function uiPresetIcon() {
function getIcon(p, geom) {
if (isSmall() && p.isFallback && p.isFallback())
return 'iD-icon-' + p.id;
else if (p.icon)
return p.icon;
else if (geom === 'line')
return 'iD-other-line';
else if (geom === 'vertex')
return p.isFallback() ? '' : 'temaki-vertex';
else if (isSmall() && geom === 'point')
return '';
else
return 'maki-marker-stroked';
if (isSmall() && p.isFallback && p.isFallback()) return 'iD-icon-' + p.id;
if (p.icon) return p.icon;
if (geom === 'line') return 'iD-other-line';
if (geom === 'vertex') return p.isFallback() ? '' : 'temaki-vertex';
if (isSmall() && geom === 'point') return '';
return 'maki-marker-stroked';
}
+10 -3
View File
@@ -31,9 +31,16 @@ export var JXON = new (function () {
if (bChildren) {
for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) {
oNode = oParentNode.childNodes.item(nItem);
if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is 'CDATASection' (4) */
else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is 'Text' (3) */
else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is 'Element' (1) */
if (oNode.nodeType === 4) {
/* nodeType is 'CDATASection' (4) */
sCollectedTxt += oNode.nodeValue;
} else if (oNode.nodeType === 3) {
/* nodeType is 'Text' (3) */
sCollectedTxt += oNode.nodeValue.trim();
} else if (oNode.nodeType === 1 && !oNode.prefix) {
/* nodeType is 'Element' (1) */
aCache.push(oNode);
}
}
}
+6 -2
View File
@@ -60,11 +60,15 @@ export function utilKeybinding(namespace) {
if (binding.event.key === undefined) {
isMatch = false;
} else if (Array.isArray(binding.event.key)) {
if (binding.event.key.map(function(s) { return s.toLowerCase(); }).indexOf(event.key.toLowerCase()) === -1)
if (binding.event.key.map(function(s) {
return s.toLowerCase();
}).indexOf(event.key.toLowerCase()) === -1) {
isMatch = false;
}
} else {
if (event.key.toLowerCase() !== binding.event.key.toLowerCase())
if (event.key.toLowerCase() !== binding.event.key.toLowerCase()) {
isMatch = false;
}
}
}
+1 -2
View File
@@ -365,8 +365,7 @@ export function utilPrefixDOMProperty(property) {
var n = prefixes.length;
var s = document.body;
if (property in s)
return property;
if (property in s) return property;
property = property.substr(0, 1).toUpperCase() + property.substr(1);
+13 -5
View File
@@ -152,8 +152,14 @@ export function utilZoomPan() {
b = typeof transform === 'function' ? transform.apply(that, args) : transform,
i = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k));
return function(t) {
if (t === 1) t = b; // Avoid rounding error on end.
else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); }
if (t === 1) {
// Avoid rounding error on end.
t = b;
} else {
var l = i(t);
var k = w / l[2];
t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k);
}
g.zoom(null, null, t);
};
});
@@ -297,8 +303,9 @@ export function utilZoomPan() {
} else if (g.pointer0) {
p = g.pointer0[0];
l = g.pointer0[1];
} else {
return;
}
else return;
g.zoom(d3_event, 'touch', constrain(translate(t, p, l), g.extent, translateExtent));
}
@@ -320,8 +327,9 @@ export function utilZoomPan() {
g.pointer0 = g.pointer1;
delete g.pointer1;
}
if (g.pointer0) g.pointer0[1] = _transform.invert(g.pointer0[0]);
else {
if (g.pointer0) {
g.pointer0[1] = _transform.invert(g.pointer0[0]);
} else {
g.end(d3_event);
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "iD",
"version": "2.19.5-dev",
"version": "2.20.0-dev",
"description": "A friendly editor for OpenStreetMap",
"main": "dist/iD.min.js",
"repository": "github:openstreetmap/iD",
+13 -13
View File
@@ -234,12 +234,12 @@ describe('maprules', function() {
});
});
describe('greaterThan', function() {
it ('is true when a tag value is greater than the selector value', function() {
it('is true when a tag value is greater than the selector value', function() {
var selectorTags = { lanes: 5 };
var tags = { lanes : 6 };
expect(_ruleChecks.greaterThan(selectorTags)(tags)).to.be.true;
});
it ('is false when a tag value is less than or equal to the selector value', function() {
it('is false when a tag value is less than or equal to the selector value', function() {
var selectorTags = { lanes: 5 };
[4, 5].forEach(function(val) {
expect(_ruleChecks.greaterThan(selectorTags)({ lanes: val })).to.be.false;
@@ -247,25 +247,25 @@ describe('maprules', function() {
});
});
describe('greaterThanEqual', function() {
it ('is true when a tag value is greater than or equal to the selector value', function() {
it('is true when a tag value is greater than or equal to the selector value', function() {
var selectorTags = { lanes: 5 };
[5, 6].forEach(function(val) {
expect(_ruleChecks.greaterThanEqual(selectorTags)({ lanes: val })).to.be.true;
});
});
it ('is false when a tag value is less than the selector value', function () {
it('is false when a tag value is less than the selector value', function () {
var selectorTags = { lanes: 5 };
var tags = { lanes: 4 };
expect(_ruleChecks.greaterThanEqual(selectorTags)(tags)).to.be.false;
});
});
describe('lessThan', function() {
it ('is true when a tag value is less than the selector value', function() {
it('is true when a tag value is less than the selector value', function() {
var selectorTags = { lanes: 5 };
var tags = { lanes: 4 };
expect(_ruleChecks.lessThan(selectorTags)(tags)).to.be.true;
});
it ('is false when a tag value is greater than or equal to the selector value', function() {
it('is false when a tag value is greater than or equal to the selector value', function() {
var selectorTags = { lanes: 5 };
[6, 7].forEach(function(val) {
expect(_ruleChecks.lessThan(selectorTags)({ lanes: val })).to.be.false;
@@ -273,13 +273,13 @@ describe('maprules', function() {
});
});
describe('lessThanEqual', function() {
it ('is true when a tag value is less than or equal to the selector value', function() {
it('is true when a tag value is less than or equal to the selector value', function() {
var selectorTags = { lanes: 5 };
[4, 5].forEach(function(val) {
expect(_ruleChecks.lessThanEqual(selectorTags)({ lanes: val })).to.be.true;
});
});
it ('is false when a tag value is greater than the selector value', function() {
it('is false when a tag value is greater than the selector value', function() {
var selectorTags = { lanes: 5 };
var tags = { lanes: 6 };
expect(_ruleChecks.lessThanEqual(selectorTags)(tags)).to.be.false;
@@ -287,22 +287,22 @@ describe('maprules', function() {
});
describe('positiveRegex', function() {
var positiveRegex = { amenity: ['^hospital$','^clinic$']};
it ('is true when tag value matches positiveRegex', function() {
it('is true when tag value matches positiveRegex', function() {
var tags = { amenity: 'hospital' };
expect(_ruleChecks.positiveRegex(positiveRegex)(tags)).to.be.true;
});
it ('is false when tag value does not match negative regex', function() {
it('is false when tag value does not match negative regex', function() {
var tags = { amenity: 'school' };
expect(_ruleChecks.positiveRegex(positiveRegex)(tags)).to.be.false;
});
});
describe('negativeRegex', function() {
var negativeRegex = { bicycle: [ 'use_path', 'designated' ] };
it ('is true when tag value does not match negativeRegex', function() {
it('is true when tag value does not match negativeRegex', function() {
var tags = { bicycle: 'yes' };
expect(_ruleChecks.negativeRegex(negativeRegex)(tags)).to.be.true;
});
it ('is false when tag value matches negativeRegex', function() {
it('is false when tag value matches negativeRegex', function() {
var tags = { bicycle: 'designated' };
expect(_ruleChecks.negativeRegex(negativeRegex)(tags)).to.be.false;
});
@@ -450,7 +450,7 @@ describe('maprules', function() {
expect(rule.matches(entities[i])).to.be.true;
});
});
it ('is true when at least one rule check is \'false\'', function() {
it('is true when at least one rule check is \'false\'', function() {
var selector = {
geometry: 'way',
equals: { highway: 'residential' },