From 8a66b3d892ca367264107dfd610f9a18000a8bae Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Fri, 9 Dec 2016 11:32:14 -0500 Subject: [PATCH] Don't enter iD.modeSelect without valid entities in selectedIDs --- modules/behavior/breathe.js | 4 +++- modules/modes/select.js | 28 ++++++++++++++++++++++++---- test/spec/behavior/select.js | 12 ++++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/modules/behavior/breathe.js b/modules/behavior/breathe.js index 85a494ea7..f95caa871 100644 --- a/modules/behavior/breathe.js +++ b/modules/behavior/breathe.js @@ -152,7 +152,9 @@ export function behaviorBreathe() { breathe.off = function() { done = true; - timer.stop(); + if (timer) { + timer.stop(); + } selected .interrupt() .call(reset); diff --git a/modules/modes/select.js b/modules/modes/select.js index fdfa54399..c7e9619f9 100644 --- a/modules/modes/select.js +++ b/modules/modes/select.js @@ -71,6 +71,23 @@ export function modeSelect(context, selectedIDs) { } + function checkSelectedIDs() { + var ids = []; + if (Array.isArray(selectedIDs)) { + ids = selectedIDs.filter(function(id) { + return context.hasEntity(id); + }); + } + + if (ids.length) { + selectedIDs = ids; + } else { + context.enter(modeBrowse(context)); + } + return !!ids.length; + } + + // find the common parent ways for nextVertex, previousVertex function commonParents() { var graph = context.graph(), @@ -171,6 +188,8 @@ export function modeSelect(context, selectedIDs) { mode.reselect = function() { + if (!checkSelectedIDs()) return; + var surfaceNode = context.surface().node(); if (surfaceNode.focus) { // FF doesn't support it surfaceNode.focus(); @@ -206,10 +225,7 @@ export function modeSelect(context, selectedIDs) { function update() { closeMenu(); - if (_.some(selectedIDs, function(id) { return !context.hasEntity(id); })) { - // Exit mode if selected entity gets undone - context.enter(modeBrowse(context)); - } + checkSelectedIDs(); } @@ -236,6 +252,8 @@ export function modeSelect(context, selectedIDs) { function selectElements(drawn) { + if (!checkSelectedIDs()) return; + var surface = context.surface(), entity = singular(); @@ -372,6 +390,8 @@ export function modeSelect(context, selectedIDs) { } + if (!checkSelectedIDs()) return; + behaviors.forEach(function(behavior) { context.install(behavior); }); diff --git a/test/spec/behavior/select.js b/test/spec/behavior/select.js index 3887c2773..5deddc548 100644 --- a/test/spec/behavior/select.js +++ b/test/spec/behavior/select.js @@ -31,6 +31,18 @@ describe('iD.behaviorSelect', function() { container.remove(); }); + specify('refuse to enter select mode with no ids', function() { + context.enter(iD.modeSelect(context, [])); + expect(context.mode().id, 'empty array').to.eql('browse'); + context.enter(iD.modeSelect(context, undefined)); + expect(context.mode().id, 'undefined').to.eql('browse'); + }); + + specify('refuse to enter select mode with nonexistent ids', function() { + context.enter(iD.modeSelect(context, ['w-1'])); + expect(context.mode().id).to.eql('browse'); + }); + specify('click on entity selects the entity', function() { happen.click(context.surface().selectAll('.' + a.id).node()); expect(context.selectedIDs()).to.eql([a.id]);