Avoid resetting input values on every change

For some reason this invalidates and repaints the
entire page.
This commit is contained in:
John Firebaugh
2013-06-19 17:03:48 -07:00
parent 63d9b36355
commit d2e2d4fbed
11 changed files with 65 additions and 41 deletions

View File

@@ -26,6 +26,7 @@ dist/iD.js: \
js/lib/d3.trigger.js \
js/lib/d3.typeahead.js \
js/lib/d3.curtain.js \
js/lib/d3.value.js \
js/lib/jxon.js \
js/lib/lodash.js \
js/lib/osmauth.js \

View File

@@ -26,6 +26,7 @@
<script src='js/lib/d3.keybinding.js'></script>
<script src='js/lib/d3.curtain.js'></script>
<script src='js/lib/d3.one.js'></script>
<script src='js/lib/d3.value.js'></script>
<script src='js/lib/d3-compat.js'></script>
<script src='js/lib/bootstrap-tooltip.js'></script>
<script src='js/lib/rtree.js'></script>

View File

@@ -46,7 +46,7 @@ iD.ui.preset.access = function(field, context) {
function change(d) {
var tag = {};
tag[d] = d3.select(this).property('value') || undefined;
tag[d] = d3.select(this).value() || undefined;
event.change(tag);
}
@@ -73,8 +73,7 @@ iD.ui.preset.access = function(field, context) {
access.tags = function(tags) {
items.selectAll('.preset-input-access')
.property('value', function(d) { return tags[d] || ''; });
return access;
.value(function(d) { return tags[d] || ''; });
};
access.focus = function() {

View File

@@ -90,11 +90,11 @@ iD.ui.preset.address = function(field, context) {
function change() {
event.change({
'addr:housename': housename.property('value') || undefined,
'addr:housenumber': housenumber.property('value') || undefined,
'addr:street': street.property('value') || undefined,
'addr:city': city.property('value') || undefined,
'addr:postcode': postcode.property('value') || undefined
'addr:housename': housename.value() || undefined,
'addr:housenumber': housenumber.value() || undefined,
'addr:street': street.value() || undefined,
'addr:city': city.value() || undefined,
'addr:postcode': postcode.value() || undefined
});
}
@@ -105,12 +105,11 @@ iD.ui.preset.address = function(field, context) {
};
address.tags = function(tags) {
housename.property('value', tags['addr:housename'] || '');
housenumber.property('value', tags['addr:housenumber'] || '');
street.property('value', tags['addr:street'] || '');
city.property('value', tags['addr:city'] || '');
postcode.property('value', tags['addr:postcode'] || '');
return address;
housename.value(tags['addr:housename'] || '');
housenumber.value(tags['addr:housenumber'] || '');
street.value(tags['addr:street'] || '');
city.value(tags['addr:city'] || '');
postcode.value(tags['addr:postcode'] || '');
};
address.focus = function() {

View File

@@ -44,12 +44,12 @@ iD.ui.preset.combo = function(field) {
function change() {
var t = {};
t[field.key] = input.property('value').replace(' ', '_') || undefined;
t[field.key] = input.value().replace(' ', '_') || undefined;
event.change(t);
}
combo.tags = function(tags) {
input.property('value', tags[field.key] || '');
input.value(tags[field.key] || '');
};
combo.focus = function() {

View File

@@ -49,12 +49,12 @@ iD.ui.preset.url = function(field) {
function change() {
var t = {};
t[field.key] = input.property('value') || undefined;
t[field.key] = input.value() || undefined;
event.change(t);
}
i.tags = function(tags) {
input.property('value', tags[field.key] || '');
input.value(tags[field.key] || '');
};
i.focus = function() {

View File

@@ -48,14 +48,14 @@ iD.ui.preset.localized = function(field, context) {
function change() {
var t = {};
t[field.key] = d3.select(this).property('value') || undefined;
t[field.key] = d3.select(this).value() || undefined;
event.change(t);
}
function key(lang) { return field.key + ':' + lang; }
function changeLang(d) {
var value = d3.select(this).property('value'),
var value = d3.select(this).value(),
t = {},
language = _.find(iD.data.wikipedia, function(d) {
return d[0].toLowerCase() === value.toLowerCase() ||
@@ -79,7 +79,7 @@ iD.ui.preset.localized = function(field, context) {
function changeValue(d) {
var t = {};
t[key(d.lang)] = d3.select(this).property('value') || '';
t[key(d.lang)] = d3.select(this).value() || '';
event.change(t);
}
@@ -173,18 +173,16 @@ iD.ui.preset.localized = function(field, context) {
.style('top','-10px')
.remove();
selection.selectAll('.entry').select('.localized-lang').property('value', function(d) {
selection.selectAll('.entry').select('.localized-lang').value(function(d) {
var lang = _.find(iD.data.wikipedia, function(lang) {
return lang[2] === d.lang;
});
return lang ? lang[1] : d.lang;
});
selection.selectAll('.entry').select('.localized-value').property('value', function(d) {
selection.selectAll('.entry').select('.localized-value').value(function(d) {
return d.value;
});
}
i.tags = function(tags) {
@@ -200,7 +198,7 @@ iD.ui.preset.localized = function(field, context) {
}
}
input.property('value', tags[field.key] || '');
input.value(tags[field.key] || '');
var postfixed = [];
for (var i in tags) {

View File

@@ -49,8 +49,8 @@ iD.ui.preset.maxspeed = function(field, context) {
.call(unitCombobox);
function changeUnits() {
imperial = unitInput.property('value') === 'mph';
unitInput.property('value', imperial ? 'mph' : 'km/h');
imperial = unitInput.value() === 'mph';
unitInput.value(imperial ? 'mph' : 'km/h');
setSuggestions();
change();
}
@@ -59,7 +59,7 @@ iD.ui.preset.maxspeed = function(field, context) {
function setSuggestions() {
combobox.data((imperial ? imperialValues : metricValues).map(comboValues));
unitInput.property('value', imperial ? 'mph' : 'km/h');
unitInput.value(imperial ? 'mph' : 'km/h');
}
function comboValues(d) {
@@ -71,7 +71,7 @@ iD.ui.preset.maxspeed = function(field, context) {
function change() {
var tag = {},
value = input.property('value');
value = input.value();
if (!value) {
tag[field.key] = undefined;
@@ -96,7 +96,7 @@ iD.ui.preset.maxspeed = function(field, context) {
setSuggestions();
input.property('value', value || '');
input.value(value || '');
};
maxspeed.focus = function() {

View File

@@ -19,12 +19,12 @@ iD.ui.preset.textarea = function(field) {
function change() {
var t = {};
t[field.key] = input.property('value') || undefined;
t[field.key] = input.value() || undefined;
event.change(t);
}
i.tags = function(tags) {
input.property('value', tags[field.key] || '');
input.value(tags[field.key] || '');
};
i.focus = function() {

View File

@@ -69,7 +69,7 @@ iD.ui.preset.wikipedia = function(field, context) {
}
function changeLang() {
var value = lang.property('value').toLowerCase();
var value = lang.value().toLowerCase();
language = _.find(iD.data.wikipedia, function(d) {
return d[0].toLowerCase() === value ||
d[1].toLowerCase() === value ||
@@ -77,7 +77,7 @@ iD.ui.preset.wikipedia = function(field, context) {
}) || iD.data.wikipedia[0];
if (value !== language[0]) {
lang.property('value', language[1]);
lang.value(language[1]);
}
change();
@@ -86,7 +86,7 @@ iD.ui.preset.wikipedia = function(field, context) {
function change() {
var t = {};
var value = title.property('value');
var value = title.value();
var m = value.match('http://([a-z]+)\\.wikipedia.org/wiki/(.*)'),
newlanguage = m && m[1] && m[2] && _.find(iD.data.wikipedia, function(d) {
@@ -98,7 +98,7 @@ iD.ui.preset.wikipedia = function(field, context) {
value = m[2].replace(/_/g, ' ');
value = value.slice(0, 1).toUpperCase() + value.slice(1);
language = newlanguage;
lang.property('value', language[0]);
lang.value(language[0]);
}
t[field.key] = value ? language[2] + ':' + value : undefined;
@@ -115,14 +115,14 @@ iD.ui.preset.wikipedia = function(field, context) {
// value in correct format
if (language) {
lang.property('value', language[1]);
title.property('value', m[2]);
lang.value(language[1]);
title.value(m[2]);
link.attr('href', 'http://' + m[1] + '.wikipedia.org/wiki/' + m[2]);
// unrecognized value format
} else {
lang.property('value', 'English');
title.property('value', tags[field.key] || '');
lang.value('English');
title.value(tags[field.key] || '');
language = iD.data.wikipedia[0];
link.attr('href', 'http://en.wikipedia.org/wiki/Special:Search?search=' + tags[field.key]);
}

26
js/lib/d3.value.js Normal file
View File

@@ -0,0 +1,26 @@
// Like selection.property('value', ...), but avoids no-op value sets,
// which can result in layout/repaint thrashing in some situations.
d3.selection.prototype.value = function(value) {
function d3_selection_value(value) {
function valueNull() {
delete this.value;
}
function valueConstant() {
if (this.value !== value) this.value = value;
}
function valueFunction() {
var x = value.apply(this, arguments);
if (x == null) delete this.value;
else if (this.value !== x) this.value = x;
}
return value == null
? valueNull : (typeof value === "function"
? valueFunction : valueConstant);
}
if (!arguments.length) return this.property('value');
return this.each(d3_selection_value(value));
};