From f309e925d8a9db2dd53899cb8cc68dbed34c20f1 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Wed, 10 Apr 2019 11:28:41 -0400 Subject: [PATCH] Memoize disabled for all the other operations too see 81127d71f --- modules/operations/circularize.js | 36 +++++++++++++++++++++-------- modules/operations/continue.js | 10 +++++--- modules/operations/delete.js | 34 +++++++++++++++++++-------- modules/operations/detach_node.js | 15 ++++++++---- modules/operations/disconnect.js | 15 ++++++++---- modules/operations/downgrade.js | 10 ++++---- modules/operations/merge.js | 7 ++---- modules/operations/move.js | 30 ++++++++++++++++++------ modules/operations/orthogonalize.js | 35 ++++++++++++++++++++-------- modules/operations/reflect.js | 30 ++++++++++++++++++------ modules/operations/rotate.js | 30 ++++++++++++++++++------ modules/operations/split.js | 14 +++++++---- modules/operations/straighten.js | 11 ++++----- 13 files changed, 193 insertions(+), 84 deletions(-) diff --git a/modules/operations/circularize.js b/modules/operations/circularize.js index 7698fb05b..1b217dd58 100644 --- a/modules/operations/circularize.js +++ b/modules/operations/circularize.js @@ -12,6 +12,7 @@ export function operationCircularize(selectedIDs, context) { var action = actionCircularize(entityID, context.projection); var nodes = utilGetAllNodes(selectedIDs, context.graph()); var coords = nodes.map(function(n) { return n.loc; }); + var _disabled; var operation = function() { context.perform(action, operation.annotation()); @@ -26,18 +27,33 @@ export function operationCircularize(selectedIDs, context) { operation.disabled = function() { - var osm = context.connection(); - var reason = action.disabled(context.graph()); - if (reason) { - return reason; + if (_disabled !== undefined) return _disabled; + + _disabled = action.disabled(context.graph()); + if (_disabled) { + return _disabled; } else if (extent.percentContainedIn(context.extent()) < 0.8) { - return 'too_large'; - } else if (osm && !coords.every(osm.isDataLoaded)) { - return 'not_downloaded'; - } else if (context.hasHiddenConnections(entityID)) { - return 'connected_to_hidden'; + return _disabled = 'too_large'; + } else if (someMissing()) { + return _disabled = 'not_downloaded'; + } else if (selectedIDs.some(context.hasHiddenConnections)) { + return _disabled = 'connected_to_hidden'; + } + + return _disabled = false; + + + function someMissing() { + var osm = context.connection(); + if (osm) { + var missing = coords.filter(function(loc) { return !osm.isDataLoaded(loc); }); + if (missing.length) { + missing.forEach(function(loc) { context.loadTileAtLoc(loc); }); + return true; + } + } + return false; } - return false; }; diff --git a/modules/operations/continue.js b/modules/operations/continue.js index 37a467469..eb4dcd595 100644 --- a/modules/operations/continue.js +++ b/modules/operations/continue.js @@ -12,6 +12,7 @@ export function operationContinue(selectedIDs, context) { utilArrayGroupBy(entities, function(entity) { return entity.geometry(graph); }) ); var vertex = geometries.vertex[0]; + var _disabled; function candidateWays() { @@ -40,13 +41,16 @@ export function operationContinue(selectedIDs, context) { operation.disabled = function() { + if (_disabled !== undefined) return _disabled; + var candidates = candidateWays(); if (candidates.length === 0) { - return 'not_eligible'; + return _disabled = 'not_eligible'; } else if (candidates.length > 1) { - return 'multiple'; + return _disabled = 'multiple'; } - return false; + + return _disabled = false; }; diff --git a/modules/operations/delete.js b/modules/operations/delete.js index 2dd00a57c..81d12ca2c 100644 --- a/modules/operations/delete.js +++ b/modules/operations/delete.js @@ -15,6 +15,7 @@ export function operationDelete(selectedIDs, context) { var extent = nodes.reduce(function(extent, node) { return extent.extend(node.extent(context.graph())); }, geoExtent()); + var _disabled; var operation = function() { @@ -70,21 +71,36 @@ export function operationDelete(selectedIDs, context) { operation.disabled = function() { - var osm = context.connection(); + if (_disabled !== undefined) return _disabled; + if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) { - return 'too_large'; - } else if (osm && !coords.every(osm.isDataLoaded)) { - return 'not_downloaded'; + return _disabled = 'too_large'; + } else if (someMissing()) { + return _disabled = 'not_downloaded'; } else if (selectedIDs.some(context.hasHiddenConnections)) { - return 'connected_to_hidden'; + return _disabled = 'connected_to_hidden'; } else if (selectedIDs.some(protectedMember)) { - return 'part_of_relation'; + return _disabled = 'part_of_relation'; } else if (selectedIDs.some(incompleteRelation)) { - return 'incomplete_relation'; + return _disabled = 'incomplete_relation'; } else if (selectedIDs.some(hasWikidataTag)) { - return 'has_wikidata_tag'; + return _disabled = 'has_wikidata_tag'; + } + + return _disabled = false; + + + function someMissing() { + var osm = context.connection(); + if (osm) { + var missing = coords.filter(function(loc) { return !osm.isDataLoaded(loc); }); + if (missing.length) { + missing.forEach(function(loc) { context.loadTileAtLoc(loc); }); + return true; + } + } + return false; } - return false; function hasWikidataTag(id) { var entity = context.entity(id); diff --git a/modules/operations/detach_node.js b/modules/operations/detach_node.js index a578ed211..f0aec3b6d 100644 --- a/modules/operations/detach_node.js +++ b/modules/operations/detach_node.js @@ -7,6 +7,8 @@ import { t } from '../util/locale'; export function operationDetachNode(selectedIDs, context) { var nodeID = selectedIDs.length && selectedIDs[0]; var action = actionDetachNode(nodeID); + var _disabled; + var operation = function () { context.perform(action); // do the detach @@ -48,13 +50,16 @@ export function operationDetachNode(selectedIDs, context) { operation.disabled = function () { - var reason = action.disabled(context.graph()); - if (reason) { - return reason; + if (_disabled !== undefined) return _disabled; + + _disabled = action.disabled(context.graph()); + if (_disabled) { + return _disabled; } else if (selectedIDs.some(context.hasHiddenConnections)) { - return 'connected_to_hidden'; + return _disabled = 'connected_to_hidden'; } - return false; + + return _disabled = false; }; diff --git a/modules/operations/disconnect.js b/modules/operations/disconnect.js index 62d526a93..573d3d286 100644 --- a/modules/operations/disconnect.js +++ b/modules/operations/disconnect.js @@ -8,6 +8,8 @@ export function operationDisconnect(selectedIDs, context) { .filter(function(id) { return context.geometry(id) === 'vertex'; }); var entityID = vertices[0]; var action = actionDisconnect(entityID); + var _disabled; + if (entityID && selectedIDs.length > 1) { var ids = selectedIDs.filter(function(id) { return id !== entityID; }); @@ -26,13 +28,16 @@ export function operationDisconnect(selectedIDs, context) { operation.disabled = function() { - var reason = action.disabled(context.graph()); - if (reason) { - return reason; + if (_disabled !== undefined) return _disabled; + + _disabled = action.disabled(context.graph()); + if (_disabled) { + return _disabled; } else if (selectedIDs.some(context.hasHiddenConnections)) { - return 'connected_to_hidden'; + return _disabled = 'connected_to_hidden'; } - return false; + + return _disabled = false; }; diff --git a/modules/operations/downgrade.js b/modules/operations/downgrade.js index 13a69c49d..87fc79a34 100644 --- a/modules/operations/downgrade.js +++ b/modules/operations/downgrade.js @@ -6,9 +6,9 @@ import { uiCmd } from '../ui'; export function operationDowngrade(selectedIDs, context) { - var affectedFeatureCount = 0; var downgradeType; + var _disabled; setDowngradeTypeForEntityIDs(); @@ -94,15 +94,17 @@ export function operationDowngrade(selectedIDs, context) { operation.disabled = function () { - var reason; + if (_disabled !== undefined) return _disabled; + if (selectedIDs.some(hasWikidataTag)) { - reason = 'has_wikidata_tag'; + return _disabled = 'has_wikidata_tag'; } + return _disabled = false; + function hasWikidataTag(id) { var entity = context.entity(id); return entity.tags.wikidata && entity.tags.wikidata.trim().length > 0; } - return reason; }; diff --git a/modules/operations/merge.js b/modules/operations/merge.js index 20728b75f..49154134b 100644 --- a/modules/operations/merge.js +++ b/modules/operations/merge.js @@ -1,11 +1,8 @@ import { t } from '../util/locale'; import { - actionChangePreset, - actionJoin, - actionMerge, - actionMergeNodes, - actionMergePolygon + actionChangePreset, actionJoin, actionMerge, + actionMergeNodes, actionMergePolygon } from '../actions'; import { behaviorOperation } from '../behavior'; diff --git a/modules/operations/move.js b/modules/operations/move.js index d9506b806..f79b0a4ce 100644 --- a/modules/operations/move.js +++ b/modules/operations/move.js @@ -12,6 +12,7 @@ export function operationMove(selectedIDs, context) { var extent = nodes.reduce(function(extent, node) { return extent.extend(node.extent(context.graph())); }, geoExtent()); + var _disabled; var operation = function() { @@ -26,17 +27,32 @@ export function operationMove(selectedIDs, context) { operation.disabled = function() { - var osm = context.connection(); + if (_disabled !== undefined) return _disabled; + if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) { - return 'too_large'; - } else if (osm && !coords.every(osm.isDataLoaded)) { - return 'not_downloaded'; + return _disabled = 'too_large'; + } else if (someMissing()) { + return _disabled = 'not_downloaded'; } else if (selectedIDs.some(context.hasHiddenConnections)) { - return 'connected_to_hidden'; + return _disabled = 'connected_to_hidden'; } else if (selectedIDs.some(incompleteRelation)) { - return 'incomplete_relation'; + return _disabled = 'incomplete_relation'; + } + + return _disabled = false; + + + function someMissing() { + var osm = context.connection(); + if (osm) { + var missing = coords.filter(function(loc) { return !osm.isDataLoaded(loc); }); + if (missing.length) { + missing.forEach(function(loc) { context.loadTileAtLoc(loc); }); + return true; + } + } + return false; } - return false; function incompleteRelation(id) { var entity = context.entity(id); diff --git a/modules/operations/orthogonalize.js b/modules/operations/orthogonalize.js index 7935d439b..82eccf33a 100644 --- a/modules/operations/orthogonalize.js +++ b/modules/operations/orthogonalize.js @@ -8,6 +8,7 @@ export function operationOrthogonalize(selectedIDs, context) { var _entityID; var _entity; var _geometry; + var _disabled; var action = chooseAction(); var nodes = utilGetAllNodes(selectedIDs, context.graph()); var coords = nodes.map(function(n) { return n.loc; }); @@ -53,21 +54,35 @@ export function operationOrthogonalize(selectedIDs, context) { operation.disabled = function() { if (!action) return ''; + if (_disabled !== undefined) return _disabled; - var osm = context.connection(); var extent = _entity.extent(context.graph()); - var reason = action.disabled(context.graph()); + _disabled = action.disabled(context.graph()); - if (reason) { - return reason; + if (_disabled) { + return _disabled; } else if (_geometry !== 'vertex' && extent.percentContainedIn(context.extent()) < 0.8) { - return 'too_large'; - } else if (osm && !coords.every(osm.isDataLoaded)) { - return 'not_downloaded'; - } else if (context.hasHiddenConnections(_entityID)) { - return 'connected_to_hidden'; + return _disabled = 'too_large'; + } else if (someMissing()) { + return _disabled = 'not_downloaded'; + } else if (selectedIDs.some(context.hasHiddenConnections)) { + return _disabled = 'connected_to_hidden'; + } + + return _disabled = false; + + + function someMissing() { + var osm = context.connection(); + if (osm) { + var missing = coords.filter(function(loc) { return !osm.isDataLoaded(loc); }); + if (missing.length) { + missing.forEach(function(loc) { context.loadTileAtLoc(loc); }); + return true; + } + } + return false; } - return false; }; diff --git a/modules/operations/reflect.js b/modules/operations/reflect.js index 8f9fe5a3f..4fd8cdb92 100644 --- a/modules/operations/reflect.js +++ b/modules/operations/reflect.js @@ -23,6 +23,7 @@ export function operationReflect(selectedIDs, context, axis) { var extent = nodes.reduce(function(extent, node) { return extent.extend(node.extent(context.graph())); }, geoExtent()); + var _disabled; var operation = function() { @@ -38,17 +39,32 @@ export function operationReflect(selectedIDs, context, axis) { operation.disabled = function() { - var osm = context.connection(); + if (_disabled !== undefined) return _disabled; + if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) { - return 'too_large'; - } else if (osm && !coords.every(osm.isDataLoaded)) { - return 'not_downloaded'; + return _disabled = 'too_large'; + } else if (someMissing()) { + return _disabled = 'not_downloaded'; } else if (selectedIDs.some(context.hasHiddenConnections)) { - return 'connected_to_hidden'; + return _disabled = 'connected_to_hidden'; } else if (selectedIDs.some(incompleteRelation)) { - return 'incomplete_relation'; + return _disabled = 'incomplete_relation'; + } + + return _disabled = false; + + + function someMissing() { + var osm = context.connection(); + if (osm) { + var missing = coords.filter(function(loc) { return !osm.isDataLoaded(loc); }); + if (missing.length) { + missing.forEach(function(loc) { context.loadTileAtLoc(loc); }); + return true; + } + } + return false; } - return false; function incompleteRelation(id) { var entity = context.entity(id); diff --git a/modules/operations/rotate.js b/modules/operations/rotate.js index 2371dfcbf..699663cad 100644 --- a/modules/operations/rotate.js +++ b/modules/operations/rotate.js @@ -12,6 +12,7 @@ export function operationRotate(selectedIDs, context) { var extent = nodes.reduce(function(extent, node) { return extent.extend(node.extent(context.graph())); }, geoExtent()); + var _disabled; var operation = function() { @@ -25,17 +26,32 @@ export function operationRotate(selectedIDs, context) { operation.disabled = function() { - var osm = context.connection(); + if (_disabled !== undefined) return _disabled; + if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) { - return 'too_large'; - } else if (osm && !coords.every(osm.isDataLoaded)) { - return 'not_downloaded'; + return _disabled = 'too_large'; + } else if (someMissing()) { + return _disabled = 'not_downloaded'; } else if (selectedIDs.some(context.hasHiddenConnections)) { - return 'connected_to_hidden'; + return _disabled = 'connected_to_hidden'; } else if (selectedIDs.some(incompleteRelation)) { - return 'incomplete_relation'; + return _disabled = 'incomplete_relation'; + } + + return _disabled = false; + + + function someMissing() { + var osm = context.connection(); + if (osm) { + var missing = coords.filter(function(loc) { return !osm.isDataLoaded(loc); }); + if (missing.length) { + missing.forEach(function(loc) { context.loadTileAtLoc(loc); }); + return true; + } + } + return false; } - return false; function incompleteRelation(id) { var entity = context.entity(id); diff --git a/modules/operations/split.js b/modules/operations/split.js index d7ca65806..b2c583107 100644 --- a/modules/operations/split.js +++ b/modules/operations/split.js @@ -10,6 +10,7 @@ export function operationSplit(selectedIDs, context) { var entityID = vertices[0]; var action = actionSplit(entityID); var ways = []; + var _disabled; if (vertices.length === 1) { if (entityID && selectedIDs.length > 1) { @@ -32,13 +33,16 @@ export function operationSplit(selectedIDs, context) { operation.disabled = function() { - var reason = action.disabled(context.graph()); - if (reason) { - return reason; + if (_disabled !== undefined) return _disabled; + + _disabled = action.disabled(context.graph()); + if (_disabled) { + return _disabled; } else if (selectedIDs.some(context.hasHiddenConnections)) { - return 'connected_to_hidden'; + return _disabled = 'connected_to_hidden'; } - return false; + + return _disabled = false; }; diff --git a/modules/operations/straighten.js b/modules/operations/straighten.js index 548701339..046e93a28 100644 --- a/modules/operations/straighten.js +++ b/modules/operations/straighten.js @@ -5,11 +5,11 @@ import { utilArrayDifference, utilGetAllNodes } from '../util/index'; export function operationStraighten(selectedIDs, context) { - var _disabled; var action = actionStraighten(selectedIDs, context.projection); var wayIDs = selectedIDs.filter(function(id) { return id.charAt(0) === 'w'; }); var nodes = utilGetAllNodes(wayIDs, context.graph()); var coords = nodes.map(function(n) { return n.loc; }); + var _disabled; function operation() { @@ -70,15 +70,12 @@ export function operationStraighten(selectedIDs, context) { if (_disabled) { return _disabled; } else if (someMissing()) { - _disabled = 'not_downloaded'; - return _disabled; + return _disabled = 'not_downloaded'; } else if (selectedIDs.some(context.hasHiddenConnections)) { - _disabled = 'connected_to_hidden'; - return _disabled; + return _disabled = 'connected_to_hidden'; } - _disabled = false; - return _disabled; + return _disabled = false; function someMissing() {