From 58e31bc45a0585686e66a5b2e6669a249afd64a0 Mon Sep 17 00:00:00 2001 From: Max Grossman Date: Fri, 1 Feb 2019 17:34:40 -0500 Subject: [PATCH] initial update to draw modes and hover behavior ref #5811 --- modules/behavior/draw.js | 8 ++++++-- modules/behavior/draw_way.js | 6 +++++- modules/behavior/hover.js | 13 +++++++++++-- modules/modes/drag_node.js | 1 - modules/presets/index.js | 33 ++++++++++++++++++++++++++++++++- 5 files changed, 54 insertions(+), 7 deletions(-) diff --git a/modules/behavior/draw.js b/modules/behavior/draw.js index 3081d2153..dd6b9e0a0 100644 --- a/modules/behavior/draw.js +++ b/modules/behavior/draw.js @@ -13,6 +13,7 @@ import { behaviorTail } from './tail'; import { geoChooseEdge, geoVecLength } from '../geo'; import { utilKeybinding, utilRebind } from '../util'; +import _isEmpty from 'lodash-es/isEmpty'; var _usedTails = {}; var _disableSpace = false; @@ -26,7 +27,7 @@ export function behaviorDraw(context) { var keybinding = utilKeybinding('draw'); - var hover = behaviorHover(context).altDisables(true) + var hover = behaviorHover(context).altDisables(true).ignoreVertex(true) .on('hover', context.ui().sidebar.hover); var tail = behaviorTail(); var edit = behaviorEdit(context); @@ -116,6 +117,9 @@ export function behaviorDraw(context) { _mouseLeave = true; } + function allowsVertex(d) { + return _isEmpty(d.tags) || context.presets().allowsVertex(d, context.graph()); + } // related code // - `mode/drag_node.js` `doMode()` @@ -125,7 +129,7 @@ export function behaviorDraw(context) { var d = datum(); var target = d && d.properties && d.properties.entity; - if (target && target.type === 'node') { // Snap to a node + if (target && target.type === 'node' && allowsVertex(target)) { // Snap to a node dispatch.call('clickNode', this, target, d); return; diff --git a/modules/behavior/draw_way.js b/modules/behavior/draw_way.js index d980bc26b..93846eb0b 100644 --- a/modules/behavior/draw_way.js +++ b/modules/behavior/draw_way.js @@ -17,6 +17,7 @@ import { modeBrowse, modeSelect } from '../modes'; import { osmNode } from '../osm'; import { utilKeybinding } from '../util'; +import _isEmpty from 'lodash-es/isEmpty'; export function behaviorDrawWay(context, wayId, index, mode, startGraph) { var origWay = context.entity(wayId); @@ -65,6 +66,9 @@ export function behaviorDrawWay(context, wayId, index, mode, startGraph) { } } + function allowsVertex(d) { + return _isEmpty(d.tags) || context.presets().allowsVertex(d, context.graph()); + } // related code // - `mode/drag_node.js` `doMode()` @@ -73,7 +77,7 @@ export function behaviorDrawWay(context, wayId, index, mode, startGraph) { function move(datum) { context.surface().classed('nope-disabled', d3_event.altKey); - var targetLoc = datum && datum.properties && datum.properties.entity && datum.properties.entity.loc; + var targetLoc = datum && datum.properties && datum.properties.entity && allowsVertex(datum.properties.entity) && datum.properties.entity.loc; var targetNodes = datum && datum.properties && datum.properties.nodes; var loc = context.map().mouseCoordinates(); diff --git a/modules/behavior/hover.js b/modules/behavior/hover.js index 58b9187a9..d13c5d77e 100644 --- a/modules/behavior/hover.js +++ b/modules/behavior/hover.js @@ -8,6 +8,7 @@ import { import { osmEntity, osmNote, krError } from '../osm'; import { utilKeybinding, utilRebind } from '../util'; +import _isEmpty from 'lodash-es/isEmpty'; /* The hover behavior adds the `.hover` class on mouseover to all elements to which @@ -24,6 +25,7 @@ export function behaviorHover(context) { var _newId = null; var _buttonDown; var _altDisables; + var _vertex; var _target; @@ -96,6 +98,9 @@ export function behaviorHover(context) { .on('mouseup.hover', null, true); } + function allowsVertex(d) { + return _isEmpty(d.tags) || context.presets().allowsVertex(d, context.graph()); + } function enter(datum) { if (datum === _target) return; @@ -126,7 +131,6 @@ export function behaviorHover(context) { if (entity.type === 'relation') { entity.members.forEach(function(member) { selector += ', .' + member.id; }); } - } else if (datum && datum.properties && (datum.properties.entity instanceof osmEntity)) { entity = datum.properties.entity; selector = '.' + entity.id; @@ -144,7 +148,7 @@ export function behaviorHover(context) { return; } - var suppressed = _altDisables && d3_event && d3_event.altKey; + var suppressed = (_altDisables && d3_event && d3_event.altKey) || (_vertex && !allowsVertex(entity, context.graph())); _selection.selectAll(selector) .classed(suppressed ? 'hover-suppressed' : 'hover', true); @@ -182,6 +186,11 @@ export function behaviorHover(context) { return behavior; }; + behavior.ignoreVertex = function(val) { + if (!arguments.length) return _vertex; + _vertex = val; + return behavior; + }; return utilRebind(behavior, dispatch, 'on'); } diff --git a/modules/modes/drag_node.js b/modules/modes/drag_node.js index 9753f8e1e..cd121d920 100644 --- a/modules/modes/drag_node.js +++ b/modules/modes/drag_node.js @@ -355,7 +355,6 @@ export function modeDragNode(context) { } } - function end(entity) { if (_isCancelled) return; diff --git a/modules/presets/index.js b/modules/presets/index.js index ff346eacf..12a939470 100644 --- a/modules/presets/index.js +++ b/modules/presets/index.js @@ -53,7 +53,7 @@ export function presetIndex() { for (var k in entity.tags) { // If any part of an address is present, // allow fallback to "Address" preset - #4353 - if (k.match(/^addr:/) !== null && geometryMatches['addr:*']) { + if (/^addr:/.test(k) && geometryMatches['addr:*']) { address = geometryMatches['addr:*'][0]; } @@ -67,6 +67,7 @@ export function presetIndex() { match = keyMatches[i]; } } + } if (address && (!match || match.isFallback())) { @@ -76,6 +77,36 @@ export function presetIndex() { }); }; + all.allowsVertex = function(entity, resolver) { + return resolver.transient(entity, 'vertexMatch', function() { + var vertexPresets = _index.vertex; + var match; + + for (var k in entity.tags) { + var keyMatches = vertexPresets[k]; + if (!keyMatches) continue; + for (var i = 0; i < keyMatches.length; i++) { + var preset = keyMatches[i]; + if (preset.searchable !== false) { + if (preset.matchScore(entity) > -1) { + match = preset; + break; + } + } + } + + if (!match && /^addr:/.test(k) && vertexPresets['addr:*']) { + match = true; + } + + if (match) break; + + } + + return match; + }); + }; + // Because of the open nature of tagging, iD will never have a complete // list of tags used in OSM, so we want it to have logic like "assume