diff --git a/modules/actions/add_midpoint.js b/modules/actions/add_midpoint.js index 35f060916..7674a9506 100644 --- a/modules/actions/add_midpoint.js +++ b/modules/actions/add_midpoint.js @@ -1,14 +1,15 @@ -import _intersection from 'lodash-es/intersection'; import { geoEdgeEqual } from '../geo'; +import { utilArrayIntersection } from '../util'; export function actionAddMidpoint(midpoint, node) { return function(graph) { graph = graph.replace(node.move(midpoint.loc)); - var parents = _intersection( + var parents = utilArrayIntersection( graph.parentWays(graph.entity(midpoint.edge[0])), - graph.parentWays(graph.entity(midpoint.edge[1]))); + graph.parentWays(graph.entity(midpoint.edge[1])) + ); parents.forEach(function(way) { for (var i = 0; i < way.nodes.length - 1; i++) { diff --git a/modules/actions/join.js b/modules/actions/join.js index f3dc4daea..34fd6f918 100644 --- a/modules/actions/join.js +++ b/modules/actions/join.js @@ -1,9 +1,9 @@ import _groupBy from 'lodash-es/groupBy'; -import _intersection from 'lodash-es/intersection'; import { actionDeleteWay } from './delete_way'; import { osmIsInterestingTag, osmJoinWays } from '../osm'; import { geoPathIntersections } from '../geo'; +import { utilArrayIntersection } from '../util'; // Join ways at the end node they share. @@ -76,31 +76,34 @@ export function actionJoin(ids) { action.disabled = function(graph) { var geometries = groupEntitiesByGeometry(graph); - if (ids.length < 2 || ids.length !== geometries.line.length) + if (ids.length < 2 || ids.length !== geometries.line.length) { return 'not_eligible'; + } var joined = osmJoinWays(ids.map(graph.entity, graph), graph); - if (joined.length > 1) + if (joined.length > 1) { return 'not_adjacent'; + } - // Loop through all combinations of path-pairs to check potential intersections - // between all pairs - for (var i = 0; i < ids.length-1; i++) { - for (var j = i+1; j < ids.length; j++) { - var path1 = graph.childNodes(graph.entity(ids[i])).map(function(e) { - return e.loc; - }); - var path2 = graph.childNodes(graph.entity(ids[j])).map(function(e) { - return e.loc; - }); + // Loop through all combinations of path-pairs + // to check potential intersections between all pairs + for (var i = 0; i < ids.length - 1; i++) { + for (var j = i + 1; j < ids.length; j++) { + var path1 = graph.childNodes(graph.entity(ids[i])) + .map(function(e) { return e.loc; }); + var path2 = graph.childNodes(graph.entity(ids[j])) + .map(function(e) { return e.loc; }); var intersections = geoPathIntersections(path1, path2); - // Check if intersections are just nodes lying on top of each other/the line, - // as opposed to crossing it - if (_intersection( - joined[0].nodes.map(function(n) { return n.loc.toString(); }), - intersections.map(function(n) { return n.toString(); }) - ).length !== intersections.length) return 'paths_intersect'; + // Check if intersections are just nodes lying on top of + // each other/the line, as opposed to crossing it + var common = utilArrayIntersection( + joined[0].nodes.map(function(n) { return n.loc.toString(); }), + intersections.map(function(n) { return n.toString(); }) + ); + if (common.length !== intersections.length) { + return 'paths_intersect'; + } } } @@ -112,8 +115,9 @@ export function actionJoin(ids) { joined[0].forEach(function(way) { var parents = graph.parentRelations(way); parents.forEach(function(parent) { - if (parent.isRestriction() && parent.members.some(function(m) { return nodeIds.indexOf(m.id) >= 0; })) + if (parent.isRestriction() && parent.members.some(function(m) { return nodeIds.indexOf(m.id) >= 0; })) { relation = parent; + } }); for (var k in way.tags) { @@ -125,11 +129,13 @@ export function actionJoin(ids) { } }); - if (relation) + if (relation) { return 'restriction'; + } - if (conflicting) + if (conflicting) { return 'conflicting_tags'; + } }; diff --git a/modules/actions/merge_remote_changes.js b/modules/actions/merge_remote_changes.js index 35660a3d2..e36453f0f 100644 --- a/modules/actions/merge_remote_changes.js +++ b/modules/actions/merge_remote_changes.js @@ -1,13 +1,11 @@ import _isEqual from 'lodash-es/isEqual'; -import _isFunction from 'lodash-es/isFunction'; -import _union from 'lodash-es/union'; -import _uniq from 'lodash-es/uniq'; import { diff3Merge } from 'node-diff3'; import { t } from '../util/locale'; import { actionDeleteMultiple } from './delete_multiple'; import { osmEntity } from '../osm'; import { dataDiscarded } from '../../data'; +import { utilArrayUnion, utilArrayUniq } from '../util'; export function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser) { @@ -16,7 +14,7 @@ export function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser function user(d) { - return _isFunction(formatUser) ? formatUser(d) : d; + return (typeof formatUser === 'function') ? formatUser(d) : d; } @@ -168,7 +166,7 @@ export function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser var o = base.tags || {}; var a = target.tags || {}; var b = remote.tags || {}; - var keys = _union(Object.keys(o), Object.keys(a), Object.keys(b)) + var keys = utilArrayUnion(utilArrayUnion(Object.keys(o), Object.keys(a)), Object.keys(b)) .filter(function(k) { return !dataDiscarded[k]; }); var tags = Object.assign({}, a); // shallow copy var changed = false; @@ -220,7 +218,7 @@ export function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser } else if (_option === 'force_local') { if (target.type === 'way') { - target = mergeChildren(target, _uniq(local.nodes), updates, graph); + target = mergeChildren(target, utilArrayUniq(local.nodes), updates, graph); graph = updateChildren(updates, graph); } return graph.replace(target); @@ -239,7 +237,7 @@ export function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser // pull in any child nodes that may not be present locally.. graph.rebase(remoteGraph.childNodes(remote), [graph], false); target = mergeNodes(base, remote, target); - target = mergeChildren(target, _union(local.nodes, remote.nodes), updates, graph); + target = mergeChildren(target, utilArrayUnion(local.nodes, remote.nodes), updates, graph); } else if (target.type === 'relation') { target = mergeMembers(remote, target); diff --git a/modules/actions/move.js b/modules/actions/move.js index f5ffa81b3..d6964a94a 100644 --- a/modules/actions/move.js +++ b/modules/actions/move.js @@ -1,9 +1,6 @@ -import _intersection from 'lodash-es/intersection'; import _isEqual from 'lodash-es/isEqual'; import _map from 'lodash-es/map'; -import { osmNode } from '../osm'; - import { geoAngle, geoChooseEdge, @@ -15,6 +12,9 @@ import { geoVecSubtract } from '../geo'; +import { osmNode } from '../osm'; +import { utilArrayIntersection } from '../util'; + // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as @@ -87,7 +87,7 @@ export function actionMove(moveIds, tryDelta, projection, cache) { if (!unmoved) continue; // exclude ways that are overly connected.. - if (_intersection(moved.nodes, unmoved.nodes).length > 2) continue; + if (utilArrayIntersection(moved.nodes, unmoved.nodes).length > 2) continue; if (moved.isArea() || unmoved.isArea()) continue; cache.intersections.push({ diff --git a/modules/actions/split.js b/modules/actions/split.js index 15cd767bd..f5ac77660 100644 --- a/modules/actions/split.js +++ b/modules/actions/split.js @@ -1,10 +1,9 @@ import _indexOf from 'lodash-es/indexOf'; -import _intersection from 'lodash-es/intersection'; import { actionAddMember } from './add_member'; import { geoSphericalDistance } from '../geo'; import { osmIsOldMultipolygonOuterMember, osmRelation, osmWay } from '../osm'; -import { utilWrap } from '../util'; +import { utilArrayIntersection, utilWrap } from '../util'; // Split a way at the given node. @@ -80,7 +79,7 @@ export function actionSplit(nodeId, newWayIds) { function split(graph, wayA, newWayId) { - var wayB = osmWay({id: newWayId, tags: wayA.tags}); // `wayB` is the NEW way + var wayB = osmWay({ id: newWayId, tags: wayA.tags }); // `wayB` is the NEW way var origNodes = wayA.nodes.slice(); var nodesA; var nodesB; @@ -133,7 +132,7 @@ export function actionSplit(nodeId, newWayIds) { for (i = 0; i < v.length; i++) { if (v[i].type === 'way') { var wayVia = graph.hasEntity(v[i].id); - if (wayVia && _intersection(wayB.nodes, wayVia.nodes).length) { + if (wayVia && utilArrayIntersection(wayB.nodes, wayVia.nodes).length) { keepB = true; break; } diff --git a/modules/actions/straighten.js b/modules/actions/straighten.js index 506f032a9..f4237d213 100644 --- a/modules/actions/straighten.js +++ b/modules/actions/straighten.js @@ -1,7 +1,6 @@ -import _difference from 'lodash-es/difference'; - import { actionDeleteNode } from './delete_node'; import { geoVecDot, geoVecInterp, geoVecLength } from '../geo'; +import { utilArrayDifference } from '../util'; /* @@ -35,7 +34,7 @@ export function actionStraighten(selectedIDs, projection) { } // Remove duplicate end/startNodes (duplicate nodes cannot be at the line end, - // and need to be removed so currNode _difference calculation below works) + // and need to be removed so currNode difference calculation below works) // i.e. ["n-1", "n-1", "n-2"] => ["n-2"] startNodes = startNodes.filter(function(n) { return startNodes.indexOf(n) === startNodes.lastIndexOf(n); @@ -45,7 +44,8 @@ export function actionStraighten(selectedIDs, projection) { }); // Choose the initial endpoint to start from - var currNode = _difference(startNodes, endNodes).concat(_difference(endNodes, startNodes))[0]; + var currNode = utilArrayDifference(startNodes, endNodes) + .concat(utilArrayDifference(endNodes, startNodes))[0]; var nextWay = []; nodes = []; @@ -59,7 +59,7 @@ export function actionStraighten(selectedIDs, projection) { // Add nodes to end of nodes array, until all ways are added while (remainingWays.length) { nextWay = getNextWay(currNode, remainingWays); - remainingWays = _difference(remainingWays, [nextWay]); + remainingWays = utilArrayDifference(remainingWays, [nextWay]); if (nextWay[0] !== currNode) { nextWay.reverse(); diff --git a/modules/core/difference.js b/modules/core/difference.js index 46f7fa895..e781950a5 100644 --- a/modules/core/difference.js +++ b/modules/core/difference.js @@ -1,7 +1,7 @@ -import _difference from 'lodash-es/difference'; -import _each from 'lodash-es/each'; import _isEqual from 'lodash-es/isEqual'; +import { utilArrayDifference } from '../util'; + /* iD.coreDifference represents the difference between two graphs. @@ -41,7 +41,7 @@ export function coreDifference(base, head) { h = head.entities[k]; b = base.entities[k]; if (changed(h, b)) { - _changes[k] = {base: b, head: h}; + _changes[k] = { base: b, head: h }; _length++; } } @@ -52,7 +52,7 @@ export function coreDifference(base, head) { h = head.entities[k]; b = base.entities[k]; if (!_changes[k] && changed(h, b)) { - _changes[k] = {base: b, head: h}; + _changes[k] = { base: b, head: h }; _length++; } } @@ -83,8 +83,10 @@ export function coreDifference(base, head) { _diff.extantIDs = function extantIDs() { var result = []; - _each(_changes, function(change, id) { - if (change.head) result.push(id); + Object.keys(_changes).forEach(function(id) { + if (_changes[id].head) { + result.push(id); + } }); return result; }; @@ -92,8 +94,10 @@ export function coreDifference(base, head) { _diff.modified = function modified() { var result = []; - _each(_changes, function(change) { - if (change.base && change.head) result.push(change.head); + Object.values(_changes).forEach(function(change) { + if (change.base && change.head) { + result.push(change.head); + } }); return result; }; @@ -101,7 +105,7 @@ export function coreDifference(base, head) { _diff.created = function created() { var result = []; - _each(_changes, function(change) { + Object.values(_changes).forEach(function(change) { if (!change.base && change.head) result.push(change.head); }); return result; @@ -110,7 +114,7 @@ export function coreDifference(base, head) { _diff.deleted = function deleted() { var result = []; - _each(_changes, function(change) { + Object.values(_changes).forEach(function(change) { if (change.base && !change.head) result.push(change.base); }); return result; @@ -193,12 +197,12 @@ export function coreDifference(base, head) { var nb = b ? b.nodes : []; var diff, i; - diff = _difference(nh, nb); + diff = utilArrayDifference(nh, nb); for (i = 0; i < diff.length; i++) { result[diff[i]] = head.hasEntity(diff[i]); } - diff = _difference(nb, nh); + diff = utilArrayDifference(nb, nh); for (i = 0; i < diff.length; i++) { result[diff[i]] = head.hasEntity(diff[i]); } diff --git a/modules/core/graph.js b/modules/core/graph.js index d83745aaa..a696252cc 100644 --- a/modules/core/graph.js +++ b/modules/core/graph.js @@ -1,6 +1,5 @@ -import _difference from 'lodash-es/difference'; - import { debug } from '../index'; +import { utilArrayDifference } from '../util'; export function coreGraph(other, mutable) { @@ -206,8 +205,8 @@ coreGraph.prototype = { if (type === 'way') { // Update parentWays if (oldentity && entity) { - removed = _difference(oldentity.nodes, entity.nodes); - added = _difference(entity.nodes, oldentity.nodes); + removed = utilArrayDifference(oldentity.nodes, entity.nodes); + added = utilArrayDifference(entity.nodes, oldentity.nodes); } else if (oldentity) { removed = oldentity.nodes; added = []; @@ -228,8 +227,8 @@ coreGraph.prototype = { } else if (type === 'relation') { // Update parentRels if (oldentity && entity) { - removed = _difference(oldentity.members, entity.members); - added = _difference(entity.members, oldentity); + removed = utilArrayDifference(oldentity.members, entity.members); + added = utilArrayDifference(entity.members, oldentity.members); } else if (oldentity) { removed = oldentity.members; added = []; diff --git a/modules/core/history.js b/modules/core/history.js index 84735e774..0ead591c7 100644 --- a/modules/core/history.js +++ b/modules/core/history.js @@ -1,9 +1,7 @@ import _cloneDeep from 'lodash-es/cloneDeep'; import _cloneDeepWith from 'lodash-es/cloneDeepWith'; -import _difference from 'lodash-es/difference'; import _flatten from 'lodash-es/flatten'; import _groupBy from 'lodash-es/groupBy'; -import _isFunction from 'lodash-es/isFunction'; import _isEmpty from 'lodash-es/isEmpty'; import _forEach from 'lodash-es/forEach'; import _map from 'lodash-es/map'; @@ -18,7 +16,7 @@ import { coreGraph } from './graph'; import { coreTree } from './tree'; import { osmEntity } from '../osm/entity'; import { uiLoading } from '../ui'; -import { utilObjectOmit, utilRebind, utilSessionMutex } from '../util'; +import { utilArrayDifference, utilObjectOmit, utilRebind, utilSessionMutex } from '../util'; export function coreHistory(context) { @@ -38,7 +36,7 @@ export function coreHistory(context) { actions = Array.prototype.slice.call(actions); var annotation; - if (!_isFunction(actions[actions.length - 1])) { + if (typeof actions[actions.length - 1] !== 'function') { annotation = actions.pop(); } @@ -148,7 +146,7 @@ export function coreHistory(context) { var action0 = arguments[0]; if (arguments.length === 1 || - arguments.length === 2 && !_isFunction(arguments[1])) { + (arguments.length === 2 && (typeof arguments[1] !== 'function'))) { transitionable = !!action0.transitionable; } @@ -520,7 +518,7 @@ export function coreHistory(context) { if (!err) { var visible = _groupBy(result.data, 'visible'); if (!_isEmpty(visible.true)) { - missing = _difference(missing, _map(visible.true, 'id')); + missing = utilArrayDifference(missing, _map(visible.true, 'id')); _stack[0].graph.rebase(visible.true, _map(_stack, 'graph'), true); _tree.rebase(visible.true, true); } diff --git a/modules/modes/drag_node.js b/modules/modes/drag_node.js index 3d482313d..0dac1444f 100644 --- a/modules/modes/drag_node.js +++ b/modules/modes/drag_node.js @@ -1,5 +1,3 @@ -import _intersection from 'lodash-es/intersection'; - import { event as d3_event, select as d3_select @@ -31,7 +29,7 @@ import { import { modeBrowse, modeSelect } from './index'; import { osmJoinWays, osmNode } from '../osm'; import { uiFlash } from '../ui'; -import { utilKeybinding } from '../util'; +import { utilArrayIntersection, utilKeybinding } from '../util'; @@ -81,7 +79,7 @@ export function modeDragNode(context) { if (nodeGeometry === 'vertex' && targetGeometry === 'vertex') { var nodeParentWayIDs = context.graph().parentWays(nodeEntity); var targetParentWayIDs = context.graph().parentWays(targetEntity); - var sharedParentWays = _intersection(nodeParentWayIDs, targetParentWayIDs); + var sharedParentWays = utilArrayIntersection(nodeParentWayIDs, targetParentWayIDs); // if both vertices are part of the same way if (sharedParentWays.length !== 0) { // if the nodes are next to each other, they are merged diff --git a/modules/modes/save.js b/modules/modes/save.js index cf26f0c26..04d52e211 100644 --- a/modules/modes/save.js +++ b/modules/modes/save.js @@ -1,7 +1,5 @@ import _map from 'lodash-es/map'; import _reduce from 'lodash-es/reduce'; -import _union from 'lodash-es/union'; -import _uniq from 'lodash-es/uniq'; import { event as d3_event, @@ -10,35 +8,12 @@ import { import { t } from '../util/locale'; -import { - actionDiscardTags, - actionMergeRemoteChanges, - actionNoop, - actionRevert -} from '../actions'; - +import { actionDiscardTags, actionMergeRemoteChanges, actionNoop, actionRevert } from '../actions'; import { coreGraph } from '../core'; - -import { - modeBrowse, - modeSelect -} from './index'; - +import { modeBrowse, modeSelect } from './index'; import { services } from '../services'; - -import { - uiConflicts, - uiConfirm, - uiCommit, - uiLoading, - uiSuccess -} from '../ui'; - -import { - utilDisplayName, - utilDisplayType, - utilKeybinding -} from '../util'; +import { uiConflicts, uiConfirm, uiCommit, uiLoading, uiSuccess } from '../ui'; +import { utilArrayUnion, utilArrayUniq, utilDisplayName, utilDisplayType, utilKeybinding } from '../util'; var _isSaving = false; @@ -157,7 +132,7 @@ export function modeSave(context) { function withChildNodes(ids, graph) { - return _uniq(_reduce(ids, function(result, id) { + return utilArrayUniq(_reduce(ids, function(result, id) { var entity = graph.entity(id); if (entity.type === 'way') { try { @@ -250,7 +225,7 @@ export function modeSave(context) { if (local.version !== remote.version) return false; if (local.type === 'way') { - var children = _union(local.nodes, remote.nodes); + var children = utilArrayUnion(local.nodes, remote.nodes); for (var i = 0; i < children.length; i++) { var a = localGraph.hasEntity(children[i]); var b = remoteGraph.hasEntity(children[i]); @@ -390,7 +365,7 @@ export function modeSave(context) { if (_conflicts[i].chosen === 1) { // user chose "keep theirs" var entity = context.hasEntity(_conflicts[i].id); if (entity && entity.type === 'way') { - var children = _uniq(entity.nodes); + var children = utilArrayUniq(entity.nodes); for (var j = 0; j < children.length; j++) { history.replace(actionRevert(children[j])); } diff --git a/modules/modes/select.js b/modules/modes/select.js index ff4854ef8..11962bbb7 100644 --- a/modules/modes/select.js +++ b/modules/modes/select.js @@ -1,4 +1,3 @@ -import _intersection from 'lodash-es/intersection'; import _map from 'lodash-es/map'; import _uniq from 'lodash-es/uniq'; @@ -28,7 +27,7 @@ import { osmNode, osmWay } from '../osm'; import * as Operations from '../operations/index'; import { uiEditMenu, uiSelectionList } from '../ui'; import { uiCmd } from '../ui/cmd'; -import { utilEntityOrMemberSelector, utilEntitySelector, utilKeybinding } from '../util'; +import { utilArrayIntersection, utilEntityOrMemberSelector, utilEntitySelector, utilKeybinding } from '../util'; // deprecation warning - Radial Menu to be removed in iD v3 import { uiRadialMenu } from '../ui'; @@ -107,7 +106,7 @@ export function modeSelect(context, selectedIDs) { continue; } - commonParents = _intersection(commonParents, currParents); + commonParents = utilArrayIntersection(commonParents, currParents); if (!commonParents.length) { return []; } diff --git a/modules/operations/straighten.js b/modules/operations/straighten.js index e26572096..bd78388c0 100644 --- a/modules/operations/straighten.js +++ b/modules/operations/straighten.js @@ -1,9 +1,9 @@ import _uniq from 'lodash-es/uniq'; -import _difference from 'lodash-es/difference'; import { t } from '../util/locale'; import { actionStraighten } from '../actions/index'; import { behaviorOperation } from '../behavior/index'; +import { utilArrayDifference } from '../util/index'; export function operationStraighten(selectedIDs, context) { @@ -53,7 +53,8 @@ export function operationStraighten(selectedIDs, context) { if (!(selectedNodes.length === 0 || selectedNodes.length === 2)) return false; // Ensure all ways are connected (i.e. only 2 unique endpoints/startpoints) - if (_difference(startNodes, endNodes).length + _difference(endNodes, startNodes).length !== 2) return false; + if (utilArrayDifference(startNodes, endNodes).length + + utilArrayDifference(endNodes, startNodes).length !== 2) return false; // Ensure both start/end selected nodes lie on the selected path if (selectedNodes.length === 2 && ( diff --git a/modules/osm/entity.js b/modules/osm/entity.js index 4eff53137..9eae58d55 100644 --- a/modules/osm/entity.js +++ b/modules/osm/entity.js @@ -1,8 +1,7 @@ -import _union from 'lodash-es/union'; - import { debug } from '../index'; import { osmIsInterestingTag } from './tags'; import { dataDeprecated } from '../../data/index'; +import { utilArrayUnion } from '../util'; export function osmEntity(attrs) { @@ -128,7 +127,7 @@ osmEntity.prototype = { merged[k] = t2; } else if (t1 !== t2) { changed = true; - merged[k] = _union(t1.split(/;\s*/), t2.split(/;\s*/)).join(';'); + merged[k] = utilArrayUnion(t1.split(/;\s*/), t2.split(/;\s*/)).join(';'); } } return changed ? this.update({ tags: merged }) : this; diff --git a/modules/osm/intersection.js b/modules/osm/intersection.js index a3dc734be..dce7f0600 100644 --- a/modules/osm/intersection.js +++ b/modules/osm/intersection.js @@ -1,10 +1,10 @@ -import _difference from 'lodash-es/difference'; import _uniq from 'lodash-es/uniq'; import { actionDeleteRelation, actionReverse, actionSplit } from '../actions'; import { coreGraph } from '../core'; import { geoAngle, geoSphericalDistance } from '../geo'; import { osmEntity } from './entity'; +import { utilArrayDifference } from '../util'; export function osmTurn(turn) { @@ -413,7 +413,7 @@ export function osmIntersection(graph, startVertexId, maxDistance) { restrictionVias.push(v[k].id); } } - var diff = _difference(pathVias, restrictionVias); + var diff = utilArrayDifference(pathVias, restrictionVias); matchesViaTo = !diff.length; } diff --git a/modules/renderer/features.js b/modules/renderer/features.js index 2bae2d44b..4c5613b06 100644 --- a/modules/renderer/features.js +++ b/modules/renderer/features.js @@ -1,12 +1,10 @@ import _groupBy from 'lodash-es/groupBy'; -import _reduce from 'lodash-es/reduce'; -import _union from 'lodash-es/union'; import { dispatch as d3_dispatch } from 'd3-dispatch'; import { osmEntity } from '../osm'; import { utilRebind } from '../util/rebind'; -import { utilQsString, utilStringQs } from '../util'; +import { utilArrayUnion, utilQsString, utilStringQs } from '../util'; export function rendererFeatures(context) { @@ -471,8 +469,8 @@ export function rendererFeatures(context) { } // gather ways connected to child nodes.. - connections = _reduce(childNodes, function(result, e) { - return resolver.isShared(e) ? _union(result, resolver.parentWays(e)) : result; + connections = childNodes.reduce(function(result, e) { + return resolver.isShared(e) ? utilArrayUnion(result, resolver.parentWays(e)) : result; }, connections); return connections.some(function(e) { diff --git a/modules/services/mapillary.js b/modules/services/mapillary.js index c5c6888b2..0762e3db2 100644 --- a/modules/services/mapillary.js +++ b/modules/services/mapillary.js @@ -1,6 +1,5 @@ /* global Mapillary:false */ import _forEach from 'lodash-es/forEach'; -import _union from 'lodash-es/union'; import { dispatch as d3_dispatch } from 'd3-dispatch'; import { request as d3_request } from 'd3-request'; @@ -13,7 +12,7 @@ import rbush from 'rbush'; import { geoExtent, geoScaleToZoom } from '../geo'; import { svgDefs } from '../svg'; -import { utilQsString, utilRebind, utilTiler } from '../util'; +import { utilArrayUnion, utilQsString, utilRebind, utilTiler } from '../util'; var apibase = 'https://a.mapillary.com/v3/'; @@ -586,7 +585,7 @@ export default { var selectedImageKeys = (selectedLineString && selectedLineString.properties.coordinateProperties.image_keys) || []; // highlight sibling viewfields on either the selected or the hovered sequences - var highlightedImageKeys = _union(hoveredImageKeys, selectedImageKeys); + var highlightedImageKeys = utilArrayUnion(hoveredImageKeys, selectedImageKeys); d3_selectAll('.layer-mapillary .viewfield-group') .classed('highlighted', function(d) { return highlightedImageKeys.indexOf(d.key) !== -1; }) diff --git a/modules/services/maprules.js b/modules/services/maprules.js index de176d36c..37544046d 100644 --- a/modules/services/maprules.js +++ b/modules/services/maprules.js @@ -1,11 +1,10 @@ import _isMatch from 'lodash-es/isMatch'; -import _intersection from 'lodash-es/intersection'; import _reduce from 'lodash-es/reduce'; -import { areaKeys } from '../core/context'; -import { - validationIssue -} from '../core/validator'; +import { areaKeys } from '../core/context'; +import { utilArrayIntersection } from '../util'; +import { validationIssue } from '../core/validator'; + var buildRuleChecks = function() { return { @@ -166,10 +165,10 @@ export default { var _areaKeys = this._areaKeys; var isAreaKeyBlackList = function(key) { - return _intersection(tagMap[key], Object.keys(_areaKeys[key])).length > 0; + return utilArrayIntersection(tagMap[key], Object.keys(_areaKeys[key])).length > 0; }; var isLineKeysWhiteList = function(key) { - return _intersection(tagMap[key], Object.keys(_lineKeys[key])).length > 0; + return utilArrayIntersection(tagMap[key], Object.keys(_lineKeys[key])).length > 0; }; if (tagMap.hasOwnProperty('area')) { diff --git a/modules/services/openstreetcam.js b/modules/services/openstreetcam.js index fe73507ae..eb84c7672 100644 --- a/modules/services/openstreetcam.js +++ b/modules/services/openstreetcam.js @@ -1,5 +1,4 @@ import _forEach from 'lodash-es/forEach'; -import _union from 'lodash-es/union'; import { dispatch as d3_dispatch } from 'd3-dispatch'; import { request as d3_request } from 'd3-request'; @@ -19,7 +18,7 @@ import rbush from 'rbush'; import { geoExtent, geoScaleToZoom } from '../geo'; import { utilDetect } from '../util/detect'; -import { utilQsString, utilRebind, utilSetTransform, utilTiler } from '../util'; +import { utilArrayUnion, utilQsString, utilRebind, utilSetTransform, utilTiler } from '../util'; var apibase = 'https://openstreetcam.org'; @@ -512,7 +511,7 @@ export default { var selectedImageKeys = (selectedSequence && selectedSequence.images.map(function (d) { return d.key; })) || []; // highlight sibling viewfields on either the selected or the hovered sequences - var highlightedImageKeys = _union(hoveredImageKeys, selectedImageKeys); + var highlightedImageKeys = utilArrayUnion(hoveredImageKeys, selectedImageKeys); d3_selectAll('.layer-openstreetcam .viewfield-group') .classed('highlighted', function(d) { return highlightedImageKeys.indexOf(d.key) !== -1; }) diff --git a/modules/services/streetside.js b/modules/services/streetside.js index bf112ca41..4031c2c0d 100644 --- a/modules/services/streetside.js +++ b/modules/services/streetside.js @@ -1,5 +1,4 @@ import _forEach from 'lodash-es/forEach'; -import _union from 'lodash-es/union'; import { dispatch as d3_dispatch } from 'd3-dispatch'; import { timer as d3_timer } from 'd3-timer'; @@ -25,7 +24,7 @@ import { } from '../geo'; import { utilDetect } from '../util/detect'; -import { utilQsString, utilRebind, utilTiler } from '../util'; +import { utilArrayUnion, utilQsString, utilRebind, utilTiler } from '../util'; import Q from 'q'; @@ -950,7 +949,7 @@ export default { var selectedBubbleKeys = (selectedSequence && selectedSequence.bubbles.map(function (d) { return d.key; })) || []; // highlight sibling viewfields on either the selected or the hovered sequences - var highlightedBubbleKeys = _union(hoveredBubbleKeys, selectedBubbleKeys); + var highlightedBubbleKeys = utilArrayUnion(hoveredBubbleKeys, selectedBubbleKeys); d3_selectAll('.layer-streetside-images .viewfield-group') .classed('highlighted', function (d) { return highlightedBubbleKeys.indexOf(d.key) !== -1; }) diff --git a/modules/svg/data.js b/modules/svg/data.js index 57330d993..5f2886e16 100644 --- a/modules/svg/data.js +++ b/modules/svg/data.js @@ -1,7 +1,5 @@ import _flatten from 'lodash-es/flatten'; import _isEmpty from 'lodash-es/isEmpty'; -import _reduce from 'lodash-es/reduce'; -import _union from 'lodash-es/union'; import _throttle from 'lodash-es/throttle'; import { @@ -23,7 +21,7 @@ import { geoExtent, geoPolygonIntersectsPolygon } from '../geo'; import { services } from '../services'; import { svgPath } from './index'; import { utilDetect } from '../util/detect'; -import { utilHashcode } from '../util'; +import { utilArrayUnion, utilHashcode } from '../util'; var _initialized = false; @@ -504,7 +502,7 @@ export function svgData(projection, context, dispatch) { var map = context.map(); var viewport = map.trimmedExtent().polygon(); - var coords = _reduce(features, function(coords, feature) { + var coords = features.reduce(function(coords, feature) { var c = feature.geometry.coordinates; /* eslint-disable no-fallthrough */ @@ -524,7 +522,7 @@ export function svgData(projection, context, dispatch) { } /* eslint-enable no-fallthrough */ - return _union(coords, c); + return utilArrayUnion(coords, c); }, []); if (!geoPolygonIntersectsPolygon(viewport, coords, true)) { diff --git a/modules/svg/layers.js b/modules/svg/layers.js index a892111fd..2389118b3 100644 --- a/modules/svg/layers.js +++ b/modules/svg/layers.js @@ -1,6 +1,3 @@ -import _difference from 'lodash-es/difference'; -import _map from 'lodash-es/map'; - import { dispatch as d3_dispatch } from 'd3-dispatch'; import { select as d3_select } from 'd3-selection'; @@ -16,14 +13,14 @@ import { svgOpenstreetcamImages } from './openstreetcam_images'; import { svgOsm } from './osm'; import { svgNotes } from './notes'; import { svgTouch } from './touch'; -import { utilRebind } from '../util/rebind'; +import { utilArrayDifference, utilRebind } from '../util'; import { utilGetDimensions, utilSetDimensions } from '../util/dimensions'; export function svgLayers(projection, context) { var dispatch = d3_dispatch('change'); var svg = d3_select(null); - var layers = [ + var _layers = [ { id: 'osm', layer: svgOsm(projection, context, dispatch) }, { id: 'notes', layer: svgNotes(projection, context, dispatch) }, { id: 'data', layer: svgData(projection, context, dispatch) }, @@ -56,7 +53,7 @@ export function svgLayers(projection, context) { .attr('class', 'surface-defs'); var groups = svg.selectAll('.data-layer') - .data(layers); + .data(_layers); groups.exit() .remove(); @@ -70,27 +67,27 @@ export function svgLayers(projection, context) { drawLayers.all = function() { - return layers; + return _layers; }; drawLayers.layer = function(id) { - var obj = layers.find(function(o) {return o.id === id;}); + var obj = _layers.find(function(o) { return o.id === id; }); return obj && obj.layer; }; drawLayers.only = function(what) { var arr = [].concat(what); - drawLayers.remove(_difference(_map(layers, 'id'), arr)); - return this; + var all = _layers.map(function(layer) { return layer.id; }); + return drawLayers.remove(utilArrayDifference(all, arr)); }; drawLayers.remove = function(what) { var arr = [].concat(what); arr.forEach(function(id) { - layers = layers.filter(function(o) { return o.id !== id; }); + _layers = _layers.filter(function(o) { return o.id !== id; }); }); dispatch.call('change'); return this; @@ -101,7 +98,7 @@ export function svgLayers(projection, context) { var arr = [].concat(what); arr.forEach(function(obj) { if ('id' in obj && 'layer' in obj) { - layers.push(obj); + _layers.push(obj); } }); dispatch.call('change'); @@ -109,9 +106,9 @@ export function svgLayers(projection, context) { }; - drawLayers.dimensions = function(_) { + drawLayers.dimensions = function(val) { if (!arguments.length) return utilGetDimensions(svg); - utilSetDimensions(svg, _); + utilSetDimensions(svg, val); return this; }; diff --git a/modules/ui/commit.js b/modules/ui/commit.js index 7dca6bbaa..c3a042e41 100644 --- a/modules/ui/commit.js +++ b/modules/ui/commit.js @@ -1,6 +1,4 @@ -import _forEach from 'lodash-es/forEach'; import _isEqual from 'lodash-es/isEqual'; -import _unionBy from 'lodash-es/unionBy'; import { dispatch as d3_dispatch } from 'd3-dispatch'; import { select as d3_select } from 'd3-selection'; @@ -389,9 +387,22 @@ export function uiCommit(context) { context.storage('hashtags', null); // always remove stored hashtags - #4304 if (commentOnly) { inHashTags = null; } // optionally override hashtags field } - return _unionBy(inComment, inHashTags, function (s) { - return s.toLowerCase(); - }); + + // keep only one copy of the tags + var all = new Set(); + var keepTags = []; + inComment.forEach(checkTag); + inHashTags.forEach(checkTag); + return keepTags; + + // Compare tags as lowercase strings, but keep original case tags + function checkTag(s) { + var compare = s.toLowerCase(); + if (!all.has(compare)) { + all.add(compare); + keepTags.push(s); + } + } // Extract hashtags from `comment` function commentTags() { @@ -425,7 +436,8 @@ export function uiCommit(context) { function updateChangeset(changed, onInput) { var tags = Object.assign({}, _changeset.tags); // shallow copy - _forEach(changed, function(v, k) { + Object.keys(changed).forEach(function(k) { + var v = changed[k]; k = k.trim().substr(0, 255); if (readOnlyTags.indexOf(k) !== -1) return; diff --git a/modules/ui/fields/radio.js b/modules/ui/fields/radio.js index 320594533..04413dce1 100644 --- a/modules/ui/fields/radio.js +++ b/modules/ui/fields/radio.js @@ -1,11 +1,9 @@ -import _union from 'lodash-es/union'; - import { dispatch as d3_dispatch } from 'd3-dispatch'; import { select as d3_select } from 'd3-selection'; import { t } from '../../util/locale'; import { uiField } from '../field'; -import { utilRebind } from '../../util'; +import { utilArrayUnion, utilRebind } from '../../util'; export { uiFieldRadio as uiFieldStructureRadio }; @@ -153,7 +151,7 @@ export function uiFieldRadio(field, context) { .on('change', changeLayer); } layerField.tags(tags); - field.keys = _union(field.keys, ['layer']); + field.keys = utilArrayUnion(field.keys, ['layer']); } else { layerField = null; field.keys = field.keys.filter(function(k) { return k !== 'layer'; }); diff --git a/modules/ui/intro/intro.js b/modules/ui/intro/intro.js index 7f0bcb406..d8013c80b 100644 --- a/modules/ui/intro/intro.js +++ b/modules/ui/intro/intro.js @@ -1,4 +1,3 @@ -import _difference from 'lodash-es/difference'; import _uniq from 'lodash-es/uniq'; import { @@ -16,6 +15,7 @@ import { osmEntity } from '../../osm/entity'; import { services } from '../../services'; import { svgIcon } from '../../svg/icon'; import { uiCurtain } from '../curtain'; +import { utilArrayDifference } from '../../util'; import { uiIntroWelcome } from './welcome'; import { uiIntroNavigation } from './navigation'; @@ -154,7 +154,7 @@ export function uiIntro(context) { context.storage('walkthrough_progress', _uniq(progress).join(';')); // Store if walkthrough is completed.. - var incomplete = _difference(chapterFlow, progress); + var incomplete = utilArrayDifference(chapterFlow, progress); if (!incomplete.length) { context.storage('walkthrough_completed', 'yes'); } diff --git a/modules/ui/preset_editor.js b/modules/ui/preset_editor.js index 508692449..ab85f090f 100644 --- a/modules/ui/preset_editor.js +++ b/modules/ui/preset_editor.js @@ -1,5 +1,5 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; -import _union from 'lodash-es/union'; + import { event as d3_event, select as d3_select @@ -10,7 +10,7 @@ import { modeBrowse } from '../modes'; import { uiDisclosure } from './disclosure'; import { uiField } from './field'; import { uiFormFields } from './form_fields'; -import { utilRebind } from '../util'; +import { utilArrayUnion, utilRebind } from '../util'; export function uiPresetEditor(context) { @@ -53,7 +53,7 @@ export function uiPresetEditor(context) { ); } - var additionalFields = _union(_preset.moreFields, presets.universal()); + var additionalFields = utilArrayUnion(_preset.moreFields, presets.universal()); additionalFields.sort(function(field1, field2) { return field1.label() > field2.label(); });