diff --git a/modules/behavior/select.js b/modules/behavior/select.js index 50390c094..311db7da0 100644 --- a/modules/behavior/select.js +++ b/modules/behavior/select.js @@ -107,14 +107,21 @@ export function behaviorSelect(context) { _p1 = null; if (dist > tolerance) return; - var e = d3_event; - processClick(e); // todo defer for 6028? + // Defer processing the click, + // because this click may trigger a blur event, + // and the blur event may trigger a tag change, + // and we really want that tag change to go to the already selected entity + // and not the one that we are about to select with the click #6028, #5878 + // (Be very careful entering modeSelect anywhere that might also blur a field!) + var datum = d3_event.target.__data__ || (_lastMouse && _lastMouse.target.__data__); + var isMultiselect = d3_event.shiftKey || d3_select('#surface .lasso').node(); + window.setTimeout(function() { + processClick(datum, isMultiselect); + }, 20); // delay > whatever raw_tag_editor.js `scheduleChange` does (10ms). } - function processClick(e) { - var isMultiselect = e.shiftKey || d3_select('#surface .lasso').node(); - var datum = e.target.__data__ || (_lastMouse && _lastMouse.target.__data__); + function processClick(datum, isMultiselect) { var mode = context.mode(); var entity = datum && datum.properties && datum.properties.entity; diff --git a/test/spec/behavior/select.js b/test/spec/behavior/select.js index 4994ca01b..ef42baa0e 100644 --- a/test/spec/behavior/select.js +++ b/test/spec/behavior/select.js @@ -43,50 +43,68 @@ describe('iD.behaviorSelect', function() { expect(context.mode().id).to.eql('browse'); }); - specify('click on entity selects the entity', function() { + specify('click on entity selects the entity', function(done) { var el = context.surface().selectAll('.' + a.id).node(); happen.mousedown(el); happen.mouseup(el); - expect(context.selectedIDs()).to.eql([a.id]); + window.setTimeout(function() { + expect(context.selectedIDs()).to.eql([a.id]); + done(); + }, 50); }); - specify('click on empty space clears the selection', function() { + specify('click on empty space clears the selection', function(done) { context.enter(iD.modeSelect(context, [a.id])); var el = context.surface().node(); happen.mousedown(el); happen.mouseup(el); - expect(context.mode().id).to.eql('browse'); + window.setTimeout(function() { + expect(context.mode().id).to.eql('browse'); + done(); + }, 50); }); - specify('shift-click on unselected entity adds it to the selection', function() { + specify('shift-click on unselected entity adds it to the selection', function(done) { context.enter(iD.modeSelect(context, [a.id])); var el = context.surface().selectAll('.' + b.id).node(); happen.mousedown(el, { shiftKey: true }); happen.mouseup(el, { shiftKey: true }); - expect(context.selectedIDs()).to.eql([a.id, b.id]); + window.setTimeout(function() { + expect(context.selectedIDs()).to.eql([a.id, b.id]); + done(); + }, 50); }); - specify('shift-click on selected entity removes it from the selection', function() { + specify('shift-click on selected entity removes it from the selection', function(done) { context.enter(iD.modeSelect(context, [a.id, b.id])); var el = context.surface().selectAll('.' + b.id).node(); happen.mousedown(el, { shiftKey: true }); happen.mouseup(el, { shiftKey: true }); - expect(context.selectedIDs()).to.eql([a.id]); + window.setTimeout(function() { + expect(context.selectedIDs()).to.eql([a.id]); + done(); + }, 50); }); - specify('shift-click on last selected entity clears the selection', function() { + specify('shift-click on last selected entity clears the selection', function(done) { context.enter(iD.modeSelect(context, [a.id])); var el = context.surface().selectAll('.' + a.id).node(); happen.mousedown(el, { shiftKey: true }); happen.mouseup(el, { shiftKey: true }); - expect(context.mode().id).to.eql('browse'); + window.setTimeout(function() { + expect(context.mode().id).to.eql('browse'); + done(); + }, 50); }); - specify('shift-click on empty space leaves the selection unchanged', function() { + specify('shift-click on empty space leaves the selection unchanged', function(done) { context.enter(iD.modeSelect(context, [a.id])); var el = context.surface().node(); happen.mousedown(el, { shiftKey: true }); happen.mouseup(el, { shiftKey: true }); - expect(context.selectedIDs()).to.eql([a.id]); + window.setTimeout(function() { + expect(context.selectedIDs()).to.eql([a.id]); + done(); + }, 50); }); });