Defer processing clicks in behaviorSelect

(closes #6028) (I hope?)

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!)
This commit is contained in:
Bryan Housel
2019-05-01 14:47:29 -04:00
parent d3f767d6f4
commit 37557a7c98
2 changed files with 42 additions and 17 deletions
+12 -5
View File
@@ -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;
+30 -12
View File
@@ -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);
});
});