Skip to content

Commit

Permalink
Enable save as soon as user starts typing (closes #2342)
Browse files Browse the repository at this point in the history
  • Loading branch information
bhousel committed Dec 17, 2015
1 parent 07fae18 commit 2bbe968
Show file tree
Hide file tree
Showing 13 changed files with 95 additions and 83 deletions.
27 changes: 16 additions & 11 deletions js/id/ui/entity_editor.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
iD.ui.EntityEditor = function(context) {
var event = d3.dispatch('choose'),
var dispatch = d3.dispatch('choose'),
state = 'select',
coalesceChanges = false,
modified = false,
base,
id,
Expand All @@ -20,7 +21,6 @@ iD.ui.EntityEditor = function(context) {
.data([0]);

// Enter

var $enter = $header.enter().append('div')
.attr('class', 'header fillL cf');

Expand All @@ -31,7 +31,6 @@ iD.ui.EntityEditor = function(context) {
$enter.append('h3');

// Update

$header.select('h3')
.text(t('inspector.edit'));

Expand All @@ -44,7 +43,6 @@ iD.ui.EntityEditor = function(context) {
.data([0]);

// Enter

$enter = $body.enter().append('div')
.attr('class', 'inspector-body');

Expand Down Expand Up @@ -80,11 +78,10 @@ iD.ui.EntityEditor = function(context) {

selection.selectAll('.preset-reset')
.on('click', function() {
event.choose(preset);
dispatch.choose(preset);
});

// Update

$body.select('.preset-list-item button')
.call(iD.ui.PresetIcon()
.geometry(context.geometry(id))
Expand Down Expand Up @@ -183,15 +180,22 @@ iD.ui.EntityEditor = function(context) {
return out;
}

function changeTags(changed) {
// Tag changes that fire on input can all get coalesced into a single
// history operation when the user leaves the field. #2342
function changeTags(changed, onInput) {
var entity = context.entity(id),
annotation = t('operations.change_tags.annotation'),
tags = clean(_.extend({}, entity.tags, changed));

if (!_.isEqual(entity.tags, tags)) {
context.perform(
iD.actions.ChangeTags(id, tags),
t('operations.change_tags.annotation'));
if (coalesceChanges) {
context.overwrite(iD.actions.ChangeTags(id, tags), annotation);
} else {
context.perform(iD.actions.ChangeTags(id, tags), annotation);
}
}

coalesceChanges = !!onInput;
}

entityEditor.modified = function(_) {
Expand All @@ -213,6 +217,7 @@ iD.ui.EntityEditor = function(context) {
entityEditor.preset(context.presets().match(context.entity(id), context.graph()));
entityEditor.modified(false);
base = context.history().difference();
coalesceChanges = false;
return entityEditor;
};

Expand All @@ -226,5 +231,5 @@ iD.ui.EntityEditor = function(context) {
return entityEditor;
};

return d3.rebind(entityEditor, event, 'on');
return d3.rebind(entityEditor, dispatch, 'on');
};
6 changes: 3 additions & 3 deletions js/id/ui/preset/access.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
iD.ui.preset.access = function(field) {
var event = d3.dispatch('change'),
var dispatch = d3.dispatch('change'),
items;

function access(selection) {
Expand Down Expand Up @@ -45,7 +45,7 @@ iD.ui.preset.access = function(field) {
function change(d) {
var tag = {};
tag[d] = d3.select(this).value() || undefined;
event.change(tag);
dispatch.change(tag);
}

access.options = function(type) {
Expand Down Expand Up @@ -192,5 +192,5 @@ iD.ui.preset.access = function(field) {
.node().focus();
};

return d3.rebind(access, event, 'on');
return d3.rebind(access, dispatch, 'on');
};
33 changes: 19 additions & 14 deletions js/id/ui/preset/address.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
iD.ui.preset.address = function(field, context) {
var event = d3.dispatch('init', 'change'),
var dispatch = d3.dispatch('init', 'change'),
wrap,
entity,
isInitialized;
Expand Down Expand Up @@ -96,7 +96,7 @@ iD.ui.preset.address = function(field, context) {

function address(selection) {
isInitialized = false;

selection.selectAll('.preset-input-wrap')
.remove();

Expand Down Expand Up @@ -162,23 +162,28 @@ iD.ui.preset.address = function(field, context) {
}));

wrap.selectAll('input')
.on('blur', change)
.on('change', change);
.on('blur', change())
.on('change', change());

wrap.selectAll('input:not(.combobox-input)')
.on('input', change(true));

event.init();
dispatch.init();
isInitialized = true;
});
}

function change() {
var tags = {};
function change(onInput) {
return function() {
var tags = {};

wrap.selectAll('input')
.each(function (field) {
tags['addr:' + field.id] = this.value || undefined;
});
wrap.selectAll('input')
.each(function (field) {
tags['addr:' + field.id] = this.value || undefined;
});

event.change(tags);
dispatch.change(tags, onInput);
};
}

function updateTags(tags) {
Expand All @@ -198,7 +203,7 @@ iD.ui.preset.address = function(field, context) {
if (isInitialized) {
updateTags(tags);
} else {
event.on('init', function () {
dispatch.on('init', function () {
updateTags(tags);
});
}
Expand All @@ -209,5 +214,5 @@ iD.ui.preset.address = function(field, context) {
if (node) node.focus();
};

return d3.rebind(address, event, 'on');
return d3.rebind(address, dispatch, 'on');
};
6 changes: 3 additions & 3 deletions js/id/ui/preset/check.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
iD.ui.preset.check =
iD.ui.preset.defaultcheck = function(field) {
var event = d3.dispatch('change'),
var dispatch = d3.dispatch('change'),
options = field.strings && field.strings.options,
values = [],
texts = [],
Expand Down Expand Up @@ -53,7 +53,7 @@ iD.ui.preset.defaultcheck = function(field) {
.on('click', function() {
var t = {};
t[field.key] = values[(values.indexOf(value) + 1) % values.length];
event.change(t);
dispatch.change(t);
d3.event.stopPropagation();
});

Expand All @@ -78,5 +78,5 @@ iD.ui.preset.defaultcheck = function(field) {
box.node().focus();
};

return d3.rebind(check, event, 'on');
return d3.rebind(check, dispatch, 'on');
};
6 changes: 3 additions & 3 deletions js/id/ui/preset/combo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
iD.ui.preset.combo =
iD.ui.preset.typeCombo = function(field, context) {
var event = d3.dispatch('change'),
var dispatch = d3.dispatch('change'),
optstrings = field.strings && field.strings.options,
optarray = field.options,
snake_case = (field.snake_case || (field.snake_case === undefined)),
Expand Down Expand Up @@ -98,7 +98,7 @@ iD.ui.preset.typeCombo = function(field, context) {

var t = {};
t[field.key] = value || undefined;
event.change(t);
dispatch.change(t);
}

combo.tags = function(tags) {
Expand All @@ -119,5 +119,5 @@ iD.ui.preset.typeCombo = function(field, context) {
input.node().focus();
};

return d3.rebind(combo, event, 'on');
return d3.rebind(combo, dispatch, 'on');
};
6 changes: 3 additions & 3 deletions js/id/ui/preset/cycleway.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
iD.ui.preset.cycleway = function(field) {
var event = d3.dispatch('change'),
var dispatch = d3.dispatch('change'),
items;

function cycleway(selection) {
Expand Down Expand Up @@ -67,7 +67,7 @@ iD.ui.preset.cycleway = function(field) {
};
}

event.change(tag);
dispatch.change(tag);
}

cycleway.options = function() {
Expand Down Expand Up @@ -96,5 +96,5 @@ iD.ui.preset.cycleway = function(field) {
.node().focus();
};

return d3.rebind(cycleway, event, 'on');
return d3.rebind(cycleway, dispatch, 'on');
};
21 changes: 12 additions & 9 deletions js/id/ui/preset/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ iD.ui.preset.tel =
iD.ui.preset.email =
iD.ui.preset.url = function(field) {

var event = d3.dispatch('change'),
var dispatch = d3.dispatch('change'),
input;

function i(selection) {
Expand All @@ -17,8 +17,9 @@ iD.ui.preset.url = function(field) {
.attr('placeholder', field.placeholder() || t('inspector.unknown'));

input
.on('blur', change)
.on('change', change);
.on('input', change(true))
.on('blur', change())
.on('change', change());

if (field.type === 'number') {
input.attr('type', 'text');
Expand All @@ -42,15 +43,17 @@ iD.ui.preset.url = function(field) {
d3.event.preventDefault();
var num = parseInt(input.node().value || 0, 10);
if (!isNaN(num)) input.node().value = num + d;
change();
change()();
});
}
}

function change() {
var t = {};
t[field.key] = input.value() || undefined;
event.change(t);
function change(onInput) {
return function() {
var t = {};
t[field.key] = input.value() || undefined;
dispatch.change(t, onInput);
};
}

i.tags = function(tags) {
Expand All @@ -61,5 +64,5 @@ iD.ui.preset.url = function(field) {
input.node().focus();
};

return d3.rebind(i, event, 'on');
return d3.rebind(i, dispatch, 'on');
};
27 changes: 14 additions & 13 deletions js/id/ui/preset/localized.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
iD.ui.preset.localized = function(field, context) {

var event = d3.dispatch('change'),
var dispatch = d3.dispatch('change', 'input'),
wikipedia = iD.wikipedia(),
input, localizedInputs, wikiTitles,
entity;
Expand All @@ -23,8 +22,9 @@ iD.ui.preset.localized = function(field, context) {
}

input
.on('blur', change)
.on('change', change);
.on('input', change(true))
.on('blur', change())
.on('change', change());

var translateButton = selection.selectAll('.localized-add')
.data([0]);
Expand Down Expand Up @@ -54,10 +54,12 @@ iD.ui.preset.localized = function(field, context) {
localizedInputs.call(render, data);
}

function change() {
var t = {};
t[field.key] = d3.select(this).value() || undefined;
event.change(t);
function change(onInput) {
return function() {
var t = {};
t[field.key] = d3.select(this).value() || undefined;
dispatch.change(t, onInput);
};
}

function key(lang) { return field.key + ':' + lang; }
Expand Down Expand Up @@ -87,14 +89,14 @@ iD.ui.preset.localized = function(field, context) {
}

d.lang = lang;
event.change(t);
dispatch.change(t);
}

function changeValue(d) {
if (!d.lang) return;
var t = {};
t[key(d.lang)] = d3.select(this).value() || undefined;
event.change(t);
dispatch.change(t);
}

function fetcher(value, cb) {
Expand Down Expand Up @@ -132,7 +134,7 @@ iD.ui.preset.localized = function(field, context) {
d3.event.preventDefault();
var t = {};
t[key(d.lang)] = undefined;
event.change(t);
dispatch.change(t);
d3.select(this.parentNode.parentNode)
.style('top','0')
.style('max-height','240px')
Expand Down Expand Up @@ -195,7 +197,6 @@ iD.ui.preset.localized = function(field, context) {
}

i.tags = function(tags) {

// Fetch translations from wikipedia
if (tags.wikipedia && !wikiTitles) {
wikiTitles = {};
Expand Down Expand Up @@ -228,5 +229,5 @@ iD.ui.preset.localized = function(field, context) {
entity = _;
};

return d3.rebind(i, event, 'on');
return d3.rebind(i, dispatch, 'on');
};
Loading

0 comments on commit 2bbe968

Please sign in to comment.