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]);