mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-15 05:30:35 +02:00
Work toward making inspector persistent
This commit is contained in:
+27
-23
@@ -1,47 +1,51 @@
|
||||
iD.ui.Disclosure = function() {
|
||||
var title,
|
||||
var dispatch = d3.dispatch('toggled'),
|
||||
title,
|
||||
expanded = false,
|
||||
content = function () {},
|
||||
dispatch = d3.dispatch('toggled'),
|
||||
link, container;
|
||||
|
||||
function toggle() {
|
||||
expanded = !expanded;
|
||||
link.classed('expanded', expanded);
|
||||
container.call(iD.ui.Toggle(expanded));
|
||||
dispatch.toggled(expanded);
|
||||
}
|
||||
content = function () {};
|
||||
|
||||
var disclosure = function(selection) {
|
||||
link = selection.append('a')
|
||||
var $link = selection.selectAll('.hide-toggle')
|
||||
.data([0]);
|
||||
|
||||
$link.enter().append('a')
|
||||
.attr('href', '#')
|
||||
.attr('class', 'hide-toggle')
|
||||
.text(title)
|
||||
.attr('class', 'hide-toggle');
|
||||
|
||||
$link.text(title)
|
||||
.on('click', toggle)
|
||||
.classed('expanded', expanded);
|
||||
|
||||
container = selection.append('div')
|
||||
.classed('hide', !expanded);
|
||||
var $body = selection.selectAll('div')
|
||||
.data([0]);
|
||||
|
||||
container.call(content);
|
||||
$body.enter().append('div');
|
||||
|
||||
$body.classed('hide', !expanded)
|
||||
.call(content);
|
||||
|
||||
function toggle() {
|
||||
expanded = !expanded;
|
||||
$link.classed('expanded', expanded);
|
||||
$body.call(iD.ui.Toggle(expanded));
|
||||
dispatch.toggled(expanded);
|
||||
}
|
||||
};
|
||||
|
||||
disclosure.title = function(_) {
|
||||
if (!arguments.length) return title;
|
||||
title = _;
|
||||
if (link) link.text(_);
|
||||
return disclosure;
|
||||
};
|
||||
|
||||
disclosure.expanded = function(_) {
|
||||
if (link && expanded !== _) {
|
||||
toggle();
|
||||
} else {
|
||||
expanded = _;
|
||||
}
|
||||
if (!arguments.length) return expanded;
|
||||
expanded = _;
|
||||
return disclosure;
|
||||
};
|
||||
|
||||
disclosure.content = function(_) {
|
||||
if (!arguments.length) return content;
|
||||
content = _;
|
||||
return disclosure;
|
||||
};
|
||||
|
||||
+119
-97
@@ -1,127 +1,124 @@
|
||||
iD.ui.EntityEditor = function(context, entity) {
|
||||
iD.ui.EntityEditor = function(context) {
|
||||
var event = d3.dispatch('choose'),
|
||||
presets = context.presets(),
|
||||
id = entity.id,
|
||||
tags = _.clone(entity.tags),
|
||||
preset,
|
||||
selection_,
|
||||
presetUI,
|
||||
rawTagEditor,
|
||||
rawMemberEditor,
|
||||
rawMembershipEditor;
|
||||
id,
|
||||
preset;
|
||||
|
||||
function browse() {
|
||||
context.enter(iD.modes.Browse(context));
|
||||
}
|
||||
function entityEditor(selection) {
|
||||
var entity = context.entity(id),
|
||||
tags = _.clone(entity.tags);
|
||||
|
||||
function update() {
|
||||
var entity = context.hasEntity(id);
|
||||
if (!entity) return;
|
||||
var $header = selection.selectAll('.header')
|
||||
.data([0]);
|
||||
|
||||
tags = _.clone(entity.tags);
|
||||
// Enter
|
||||
|
||||
// change preset if necessary (undos/redos)
|
||||
var newmatch = presets.match(entity, context.graph());
|
||||
if (newmatch !== preset) {
|
||||
entityEditor(selection_, newmatch);
|
||||
return;
|
||||
}
|
||||
|
||||
presetUI.change(tags);
|
||||
rawTagEditor.tags(tags);
|
||||
if (rawMemberEditor) rawMemberEditor.change();
|
||||
rawMembershipEditor.change();
|
||||
}
|
||||
|
||||
function entityEditor(selection, newpreset) {
|
||||
selection_ = selection;
|
||||
var geometry = entity.geometry(context.graph());
|
||||
|
||||
if (!preset) preset = presets.match(entity, context.graph());
|
||||
|
||||
// preset was explicitly chosen
|
||||
if (newpreset) {
|
||||
tags = preset.removeTags(tags, geometry);
|
||||
|
||||
newpreset.applyTags(tags, geometry);
|
||||
preset = newpreset;
|
||||
}
|
||||
|
||||
selection.html('');
|
||||
|
||||
var messagewrap = selection.append('div')
|
||||
var $enter = $header.enter().append('div')
|
||||
.attr('class', 'header fillL cf');
|
||||
|
||||
messagewrap.append('button')
|
||||
$enter.append('button')
|
||||
.attr('class', 'preset-reset fl ')
|
||||
.on('click', function() {
|
||||
event.choose(preset);
|
||||
})
|
||||
.append('span')
|
||||
.attr('class', 'icon back');
|
||||
|
||||
messagewrap.append('h3')
|
||||
.attr('class', 'inspector-inner')
|
||||
.text(t('inspector.editing_feature', { feature: preset.name() }));
|
||||
$enter.append('h3')
|
||||
.attr('class', 'inspector-inner');
|
||||
|
||||
messagewrap.append('button')
|
||||
$enter.append('button')
|
||||
.attr('class', 'preset-close fr')
|
||||
.on('click', browse)
|
||||
.append('span')
|
||||
.attr('class', 'icon close');
|
||||
|
||||
var editorwrap = selection.append('div')
|
||||
// Update
|
||||
|
||||
$header.select('h3')
|
||||
.text(t('inspector.editing_feature', {feature: preset.name()}));
|
||||
|
||||
$header.select('.preset-reset')
|
||||
.on('click', function() {
|
||||
event.choose(preset);
|
||||
});
|
||||
|
||||
$header.select('.preset-close')
|
||||
.on('click', function() {
|
||||
context.enter(iD.modes.Browse(context));
|
||||
});
|
||||
|
||||
var $body = selection.selectAll('.inspector-body')
|
||||
.data([0]);
|
||||
|
||||
// Enter
|
||||
|
||||
$enter = $body.enter().append('div')
|
||||
.attr('class', 'tag-wrap inspector-body fillL2');
|
||||
|
||||
editorwrap.append('div')
|
||||
.attr('class', 'col12 inspector-inner preset-icon-wrap')
|
||||
$enter.append('div')
|
||||
.attr('class', 'preset-icon-wrap inspector-inner col12')
|
||||
.append('div')
|
||||
.attr('class','fillL')
|
||||
.attr('class', 'fillL');
|
||||
|
||||
$enter.append('div')
|
||||
.attr('class', 'inspector-preset cf fillL col12');
|
||||
|
||||
$enter.append('div')
|
||||
.attr('class', 'raw-tag-editor inspector-inner col12');
|
||||
|
||||
$enter.append('div')
|
||||
.attr('class', 'raw-member-editor inspector-inner col12');
|
||||
|
||||
$enter.append('div')
|
||||
.attr('class', 'raw-membership-editor inspector-inner col12');
|
||||
|
||||
$enter.append('div')
|
||||
.attr('class', 'inspector-external-links inspector-inner col12');
|
||||
|
||||
// Update
|
||||
|
||||
$body.select('.preset-icon-wrap .fillL')
|
||||
.call(iD.ui.PresetIcon()
|
||||
.geometry(context.geometry(entity.id))
|
||||
.geometry(context.geometry(id))
|
||||
.preset(preset));
|
||||
|
||||
presetUI = iD.ui.preset(context, entity, preset)
|
||||
.on('change', changeTags);
|
||||
$body.select('.inspector-preset')
|
||||
.call(iD.ui.preset(context)
|
||||
.preset(preset)
|
||||
.entityID(id)
|
||||
.tags(tags)
|
||||
.on('change', changeTags));
|
||||
|
||||
var tageditorpreset = editorwrap.append('div')
|
||||
.attr('class', 'inspector-preset cf fillL col12')
|
||||
.call(presetUI);
|
||||
|
||||
rawTagEditor = iD.ui.RawTagEditor(context, entity)
|
||||
.on('change', changeTags);
|
||||
|
||||
editorwrap.append('div')
|
||||
.attr('class', 'inspector-inner raw-tag-editor col12')
|
||||
.call(rawTagEditor, preset.id === 'other');
|
||||
$body.select('.raw-tag-editor')
|
||||
.call(iD.ui.RawTagEditor(context)
|
||||
.preset(preset)
|
||||
.entityID(id)
|
||||
.tags(tags)
|
||||
.on('change', changeTags));
|
||||
|
||||
if (entity.type === 'relation') {
|
||||
rawMemberEditor = iD.ui.RawMemberEditor(context, entity);
|
||||
|
||||
editorwrap.append('div')
|
||||
.attr('class', 'inspector-inner raw-membership-editor col12')
|
||||
.call(rawMemberEditor);
|
||||
$body.select('.raw-member-editor')
|
||||
.style('display', 'block')
|
||||
.call(iD.ui.RawMemberEditor(context)
|
||||
.entityID(id));
|
||||
} else {
|
||||
$body.select('.raw-member-editor')
|
||||
.style('display', 'none')
|
||||
}
|
||||
|
||||
rawMembershipEditor = iD.ui.RawMembershipEditor(context, entity);
|
||||
$body.select('.raw-membership-editor')
|
||||
.call(iD.ui.RawMembershipEditor(context)
|
||||
.entityID(id));
|
||||
|
||||
editorwrap.append('div')
|
||||
.attr('class', 'inspector-inner raw-membership-editor col12')
|
||||
.call(rawMembershipEditor);
|
||||
$body.select('.inspector-external-links')
|
||||
.call(iD.ui.ViewOnOSM(context)
|
||||
.entityID(id));
|
||||
|
||||
var viewOnOSM = iD.ui.ViewOnOSM(context);
|
||||
|
||||
editorwrap.append('div')
|
||||
.attr('class', 'col12 inspector-inner inspector-external-links')
|
||||
.call(viewOnOSM, entity);
|
||||
|
||||
presetUI.change(tags);
|
||||
rawTagEditor.tags(tags);
|
||||
|
||||
changeTags();
|
||||
function historyChanged() {
|
||||
var entity = context.hasEntity(id);
|
||||
if (!entity) return;
|
||||
preset = context.presets().match(entity, context.graph());
|
||||
entityEditor(selection);
|
||||
}
|
||||
|
||||
context.history()
|
||||
.on('change.entity-editor', update);
|
||||
.on('change.entity-editor', historyChanged);
|
||||
}
|
||||
|
||||
function clean(o) {
|
||||
@@ -134,15 +131,40 @@ iD.ui.EntityEditor = function(context, entity) {
|
||||
}
|
||||
|
||||
function changeTags(changed) {
|
||||
tags = clean(_.extend(tags, changed));
|
||||
var entity = context.hasEntity(id);
|
||||
if (entity && !_.isEqual(entity.tags, tags)) {
|
||||
var entity = context.entity(id),
|
||||
tags = clean(_.extend({}, entity.tags, changed));
|
||||
|
||||
if (!_.isEqual(entity.tags, tags)) {
|
||||
context.perform(
|
||||
iD.actions.ChangeTags(entity.id, tags),
|
||||
iD.actions.ChangeTags(id, tags),
|
||||
t('operations.change_tags.annotation'));
|
||||
}
|
||||
}
|
||||
|
||||
entityEditor.entityID = function(_) {
|
||||
if (!arguments.length) return id;
|
||||
id = _;
|
||||
preset = context.presets().match(context.entity(id), context.graph());
|
||||
return entityEditor;
|
||||
};
|
||||
|
||||
entityEditor.preset = function(_) {
|
||||
if (!arguments.length) return preset;
|
||||
|
||||
var entity = context.entity(id),
|
||||
geometry = context.geometry(id),
|
||||
tags = preset.removeTags(entity.tags, geometry);
|
||||
|
||||
preset = _;
|
||||
tags = preset.applyTags(tags, geometry);
|
||||
|
||||
context.perform(
|
||||
iD.actions.ChangeTags(id, tags),
|
||||
t('operations.change_tags.annotation'));
|
||||
|
||||
return entityEditor;
|
||||
};
|
||||
|
||||
entityEditor.close = function() {
|
||||
// Blur focused element so that tag changes are dispatched
|
||||
// See #1295
|
||||
|
||||
+35
-46
@@ -1,70 +1,59 @@
|
||||
iD.ui.Inspector = function(context) {
|
||||
var presetList,
|
||||
entityEditor,
|
||||
var presetList = iD.ui.PresetList(context),
|
||||
entityEditor = iD.ui.EntityEditor(context),
|
||||
entityID,
|
||||
newFeature = false;
|
||||
|
||||
function inspector(selection) {
|
||||
selection.style('display', 'block');
|
||||
|
||||
var reselect = selection.html(),
|
||||
entity = context.entity(entityID);
|
||||
var $wrap = selection.selectAll('.panewrap')
|
||||
.data([0]);
|
||||
|
||||
selection
|
||||
.html('')
|
||||
.style('display', 'block')
|
||||
.style('right', '-500px')
|
||||
.style('opacity', 1)
|
||||
.transition()
|
||||
.duration(reselect ? 0 : 200)
|
||||
.style('right', '0px');
|
||||
var $enter = $wrap.enter().append('div')
|
||||
.attr('class', 'panewrap');
|
||||
|
||||
var panewrap = selection
|
||||
.append('div')
|
||||
.classed('panewrap', true);
|
||||
$enter.append('div')
|
||||
.attr('class', 'grid-pane pane');
|
||||
|
||||
var presetLayer = panewrap
|
||||
.append('div')
|
||||
.classed('pane grid-pane', true);
|
||||
$enter.append('div')
|
||||
.attr('class', 'tag-pane pane');
|
||||
|
||||
var tagLayer = panewrap
|
||||
.append('div')
|
||||
.classed('pane tag-pane', true);
|
||||
var $presetPane = $wrap.select('.grid-pane')
|
||||
.call(presetList
|
||||
.entityID(entityID)
|
||||
.autofocus(newFeature)
|
||||
.on('choose', setPreset));
|
||||
|
||||
presetList = iD.ui.PresetList(context, entity)
|
||||
.autofocus(newFeature)
|
||||
.on('choose', function(preset) {
|
||||
panewrap
|
||||
.transition()
|
||||
.style('right', '0%');
|
||||
var $editorPane = $wrap.select('.tag-pane')
|
||||
.call(entityEditor
|
||||
.entityID(entityID)
|
||||
.on('choose', showList));
|
||||
|
||||
tagLayer.call(entityEditor, preset);
|
||||
});
|
||||
$wrap.style('right', context.entity(entityID).isUsed(context.graph()) ? '-0%' : '-100%');
|
||||
|
||||
entityEditor = iD.ui.EntityEditor(context, entity)
|
||||
.on('choose', function(preset) {
|
||||
panewrap
|
||||
.transition()
|
||||
.style('right', '-100%');
|
||||
function showList(preset) {
|
||||
$wrap.transition()
|
||||
.style('right', '-100%');
|
||||
|
||||
presetList
|
||||
.current(preset)
|
||||
.autofocus(true);
|
||||
$presetPane.call(presetList
|
||||
.preset(preset)
|
||||
.autofocus(true));
|
||||
}
|
||||
|
||||
presetLayer.call(presetList);
|
||||
});
|
||||
function setPreset(preset) {
|
||||
$wrap.transition()
|
||||
.style('right', '0%');
|
||||
|
||||
if (entity.isUsed(context.graph())) {
|
||||
panewrap.style('right', '-0%');
|
||||
tagLayer.call(entityEditor);
|
||||
} else {
|
||||
panewrap.style('right', '-100%');
|
||||
presetLayer.call(presetList);
|
||||
$editorPane.call(entityEditor
|
||||
.preset(preset));
|
||||
}
|
||||
}
|
||||
|
||||
inspector.close = function(selection) {
|
||||
entityEditor.close();
|
||||
selection.html('');
|
||||
|
||||
selection.style('display', 'none');
|
||||
};
|
||||
|
||||
inspector.entityID = function(_) {
|
||||
|
||||
+98
-104
@@ -1,12 +1,11 @@
|
||||
iD.ui.preset = function(context, entity, preset) {
|
||||
var original = context.graph().base().entities[entity.id],
|
||||
event = d3.dispatch('change'),
|
||||
fields = [],
|
||||
tags = {},
|
||||
formwrap,
|
||||
formbuttonwrap;
|
||||
iD.ui.preset = function(context) {
|
||||
var event = d3.dispatch('change'),
|
||||
fields,
|
||||
preset,
|
||||
tags,
|
||||
id;
|
||||
|
||||
function UIField(field, show) {
|
||||
function UIField(field, entity, show) {
|
||||
field = _.clone(field);
|
||||
|
||||
field.input = iD.ui.preset[field.type](field, context)
|
||||
@@ -29,160 +28,155 @@ iD.ui.preset = function(context, entity, preset) {
|
||||
};
|
||||
|
||||
field.modified = function() {
|
||||
var original = context.graph().base().entities[entity.id];
|
||||
return _.any(field.keys, function(key) {
|
||||
return original ? tags[key] !== original.tags[key] : tags[key];
|
||||
});
|
||||
};
|
||||
|
||||
field.revert = function() {
|
||||
var original = context.graph().base().entities[entity.id],
|
||||
t = {};
|
||||
field.keys.forEach(function(key) {
|
||||
t[key] = original ? original.tags[key] : undefined;
|
||||
});
|
||||
return t;
|
||||
};
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
fields.push(UIField(context.presets().field('name')));
|
||||
|
||||
var geometry = entity.geometry(context.graph());
|
||||
preset.fields.forEach(function(field) {
|
||||
if (field.matchGeometry(geometry)) {
|
||||
fields.push(UIField(field, true));
|
||||
}
|
||||
});
|
||||
|
||||
context.presets().universal().forEach(function(field) {
|
||||
if (preset.fields.indexOf(field) < 0) {
|
||||
fields.push(UIField(field));
|
||||
}
|
||||
});
|
||||
|
||||
function fieldKey(field) {
|
||||
return field.id;
|
||||
}
|
||||
|
||||
function shown() {
|
||||
return fields.filter(function(field) { return field.shown(); });
|
||||
}
|
||||
function presets(selection) {
|
||||
if (!fields) {
|
||||
var entity = context.entity(id),
|
||||
geometry = context.geometry(id);
|
||||
|
||||
function notShown() {
|
||||
return fields.filter(function(field) { return !field.shown(); });
|
||||
}
|
||||
fields = [UIField(context.presets().field('name'), entity)];
|
||||
|
||||
function show(field) {
|
||||
field.show = true;
|
||||
render();
|
||||
field.input.focus();
|
||||
}
|
||||
preset.fields.forEach(function(field) {
|
||||
if (field.matchGeometry(geometry)) {
|
||||
fields.push(UIField(field, entity, true));
|
||||
}
|
||||
});
|
||||
|
||||
function revert(field) {
|
||||
d3.event.stopPropagation();
|
||||
d3.event.preventDefault();
|
||||
var t = {};
|
||||
field.keys.forEach(function(key) {
|
||||
t[key] = original ? original.tags[key] || '' : '';
|
||||
});
|
||||
event.change(t);
|
||||
}
|
||||
context.presets().universal().forEach(function(field) {
|
||||
if (preset.fields.indexOf(field) < 0) {
|
||||
fields.push(UIField(field, entity));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function render() {
|
||||
var selection = formwrap.selectAll('.form-field')
|
||||
.data(shown(), fieldKey);
|
||||
var shown = fields.filter(function(field) { return field.shown(); }),
|
||||
notShown = fields.filter(function(field) { return !field.shown(); });
|
||||
|
||||
var enter = selection.enter()
|
||||
var $fields = selection.selectAll('.form-field')
|
||||
.data(shown, fieldKey);
|
||||
|
||||
// Enter
|
||||
|
||||
var $enter = $fields.enter()
|
||||
.insert('div', '.more-buttons')
|
||||
.style('opacity', 0)
|
||||
.attr('class', function(field) {
|
||||
return 'form-field form-field-' + field.id + ' fillL col12';
|
||||
});
|
||||
|
||||
enter.transition()
|
||||
.style('max-height', '0px')
|
||||
.style('padding-top', '0px')
|
||||
.style('opacity', '0')
|
||||
.transition()
|
||||
.duration(200)
|
||||
.style('padding-top', '10px')
|
||||
.style('max-height', '240px')
|
||||
.style('opacity', '1')
|
||||
.each('end', function(d) {
|
||||
d3.select(this).style('max-height', '');
|
||||
});
|
||||
|
||||
var label = enter.append('label')
|
||||
var $label = $enter.append('label')
|
||||
.attr('class', 'form-label')
|
||||
.attr('for', function(field) { return 'preset-input-' + field.id; })
|
||||
.text(function(field) { return field.label(); });
|
||||
|
||||
label.each(function(field) {
|
||||
d3.select(this)
|
||||
.call(field.reference.button);
|
||||
});
|
||||
|
||||
label.append('button')
|
||||
$label.append('button')
|
||||
.attr('class', 'modified-icon minor')
|
||||
.attr('tabindex', -1)
|
||||
.on('click', revert)
|
||||
.append('div')
|
||||
.attr('class','icon undo');
|
||||
.attr('class', 'icon undo');
|
||||
|
||||
enter.each(function(field) {
|
||||
d3.select(this)
|
||||
.call(field.input)
|
||||
.call(field.reference.body);
|
||||
});
|
||||
// Update
|
||||
|
||||
selection
|
||||
$fields.select('.modified-icon')
|
||||
.on('click', revert);
|
||||
|
||||
$fields.select('.form-label')
|
||||
.each(function(field) {
|
||||
field.input.tags(tags);
|
||||
})
|
||||
.classed('modified', function(field) {
|
||||
return field.modified();
|
||||
d3.select(this)
|
||||
.call(field.reference.button);
|
||||
});
|
||||
|
||||
selection.exit()
|
||||
$fields
|
||||
.classed('modified', function(field) {
|
||||
return field.modified();
|
||||
})
|
||||
.each(function(field) {
|
||||
d3.select(this)
|
||||
.call(field.input)
|
||||
.call(field.reference.body);
|
||||
|
||||
field.input.tags(tags);
|
||||
});
|
||||
|
||||
$fields.exit()
|
||||
.remove();
|
||||
|
||||
var addFields = formbuttonwrap.selectAll('.preset-add-field')
|
||||
.data(notShown(), fieldKey);
|
||||
var $more = selection.selectAll('.more-buttons')
|
||||
.data([0]);
|
||||
|
||||
addFields.enter()
|
||||
$more.enter().append('div')
|
||||
.attr('class', 'more-buttons inspector-inner col12');
|
||||
|
||||
var $buttons = $more.selectAll('.preset-add-field')
|
||||
.data(notShown, fieldKey);
|
||||
|
||||
$buttons.enter()
|
||||
.append('button')
|
||||
.attr('class', 'preset-add-field')
|
||||
.on('click', show)
|
||||
.call(bootstrap.tooltip()
|
||||
.placement('top')
|
||||
.title(function(d) { return d.label(); }))
|
||||
.append('span')
|
||||
.attr('class', function(d) { return 'icon ' + d.icon; });
|
||||
|
||||
addFields.exit()
|
||||
$buttons.on('click', show);
|
||||
|
||||
$buttons.exit()
|
||||
.transition()
|
||||
.style('opacity', 0)
|
||||
.remove();
|
||||
|
||||
return selection;
|
||||
function show(field) {
|
||||
field.show = true;
|
||||
presets(selection);
|
||||
field.input.focus();
|
||||
}
|
||||
|
||||
function revert(field) {
|
||||
d3.event.stopPropagation();
|
||||
d3.event.preventDefault();
|
||||
event.change(field.revert());
|
||||
}
|
||||
}
|
||||
|
||||
function presets(selection) {
|
||||
selection.html('');
|
||||
|
||||
formwrap = selection;
|
||||
|
||||
formbuttonwrap = selection.append('div')
|
||||
.attr('class', 'col12 more-buttons inspector-inner');
|
||||
|
||||
render();
|
||||
}
|
||||
|
||||
presets.rendered = function() {
|
||||
return _.flatten(shown().map(function(field) { return field.keys; }));
|
||||
};
|
||||
|
||||
presets.preset = function(_) {
|
||||
if (!arguments.length) return preset;
|
||||
preset = _;
|
||||
fields = null;
|
||||
return presets;
|
||||
};
|
||||
|
||||
presets.change = function(_) {
|
||||
presets.tags = function(_) {
|
||||
if (!arguments.length) return tags;
|
||||
tags = _;
|
||||
render();
|
||||
// Don't reset fields here.
|
||||
return presets;
|
||||
};
|
||||
|
||||
presets.entityID = function(_) {
|
||||
if (!arguments.length) return id;
|
||||
id = _;
|
||||
fields = null;
|
||||
return presets;
|
||||
};
|
||||
|
||||
|
||||
@@ -4,14 +4,19 @@ iD.ui.preset.access = function(field, context) {
|
||||
items;
|
||||
|
||||
function access(selection) {
|
||||
var wrap = selection.append('div')
|
||||
.attr('class', 'cf preset-input-wrap');
|
||||
var wrap = selection.selectAll('.preset-input-wrap')
|
||||
.data([0]);
|
||||
|
||||
items = wrap.append('ul').selectAll('li')
|
||||
wrap.enter().append('div')
|
||||
.attr('class', 'cf preset-input-wrap')
|
||||
.append('ul');
|
||||
|
||||
items = wrap.select('ul').selectAll('li')
|
||||
.data(field.keys);
|
||||
|
||||
var enter = items.enter()
|
||||
.append('li')
|
||||
// Enter
|
||||
|
||||
var enter = items.enter().append('li')
|
||||
.attr('class', function(d) { return 'cf preset-access-' + d; });
|
||||
|
||||
enter.append('span')
|
||||
@@ -25,13 +30,17 @@ iD.ui.preset.access = function(field, context) {
|
||||
.attr('type', 'text')
|
||||
.attr('class', 'preset-input-access')
|
||||
.attr('id', function(d) { return 'preset-input-access-' + d; })
|
||||
.on('change', change)
|
||||
.on('blur', change)
|
||||
.each(function(d) {
|
||||
d3.select(this)
|
||||
.call(d3.combobox()
|
||||
.data(access.options(d)));
|
||||
});
|
||||
|
||||
// Update
|
||||
|
||||
wrap.selectAll('.preset-input-access')
|
||||
.on('change', change)
|
||||
.on('blur', change);
|
||||
}
|
||||
|
||||
function change(d) {
|
||||
|
||||
+31
-23
@@ -1,5 +1,4 @@
|
||||
iD.ui.preset.address = function(field, context) {
|
||||
|
||||
var event = d3.dispatch('change'),
|
||||
housename,
|
||||
housenumber,
|
||||
@@ -36,45 +35,54 @@ iD.ui.preset.address = function(field, context) {
|
||||
}
|
||||
|
||||
function address(selection) {
|
||||
var wrap = selection.append('div')
|
||||
var wrap = selection.selectAll('.preset-input-wrap')
|
||||
.data([0]);
|
||||
|
||||
// Enter
|
||||
|
||||
var enter = wrap.enter().append('div')
|
||||
.attr('class', 'preset-input-wrap');
|
||||
|
||||
housename = wrap.append('input')
|
||||
enter.append('input')
|
||||
.property('type', 'text')
|
||||
.attr('placeholder', field.t('placeholders.housename'))
|
||||
.attr('class', 'addr-housename')
|
||||
.attr('id', 'preset-input-' + field.id)
|
||||
.on('blur', change)
|
||||
.on('change', change);
|
||||
.attr('id', 'preset-input-' + field.id);
|
||||
|
||||
housenumber = wrap.append('input')
|
||||
enter.append('input')
|
||||
.property('type', 'text')
|
||||
.attr('placeholder', field.t('placeholders.number'))
|
||||
.attr('class', 'addr-number')
|
||||
.on('blur', change)
|
||||
.on('change', change);
|
||||
.attr('class', 'addr-number');
|
||||
|
||||
street = wrap.append('input')
|
||||
enter.append('input')
|
||||
.property('type', 'text')
|
||||
.attr('placeholder', field.t('placeholders.street'))
|
||||
.attr('class', 'addr-street')
|
||||
.on('blur', change)
|
||||
.on('change', change)
|
||||
.call(d3.combobox().data(getStreets()));
|
||||
.attr('class', 'addr-street');
|
||||
|
||||
city = wrap.append('input')
|
||||
enter.append('input')
|
||||
.property('type', 'text')
|
||||
.attr('placeholder', field.t('placeholders.city'))
|
||||
.attr('class', 'addr-city')
|
||||
.attr('class', 'addr-city');
|
||||
|
||||
enter.append('input')
|
||||
.property('type', 'text')
|
||||
.attr('placeholder', field.t('placeholders.postcode'))
|
||||
.attr('class', 'addr-postcode');
|
||||
|
||||
// Update
|
||||
|
||||
housename = wrap.select('.addr-housename');
|
||||
housenumber = wrap.select('.addr-number');
|
||||
street = wrap.select('.addr-street');
|
||||
city = wrap.select('.addr-city');
|
||||
postcode = wrap.select('.addr-postcode');
|
||||
|
||||
wrap.selectAll('input')
|
||||
.on('blur', change)
|
||||
.on('change', change);
|
||||
|
||||
postcode = wrap.append('input')
|
||||
.property('type', 'text')
|
||||
.attr('placeholder', field.t('placeholders.postcode'))
|
||||
.attr('class', 'addr-postcode')
|
||||
.on('blur', change)
|
||||
.on('change', change);
|
||||
street
|
||||
.call(d3.combobox().data(getStreets()));
|
||||
}
|
||||
|
||||
function change() {
|
||||
|
||||
+16
-12
@@ -1,5 +1,4 @@
|
||||
iD.ui.preset.check = function(field) {
|
||||
|
||||
var event = d3.dispatch('change'),
|
||||
values = ['', 'yes', 'no'],
|
||||
value = '',
|
||||
@@ -8,28 +7,33 @@ iD.ui.preset.check = function(field) {
|
||||
label;
|
||||
|
||||
var check = function(selection) {
|
||||
|
||||
selection.classed('checkselect', 'true');
|
||||
|
||||
label = selection.append('label')
|
||||
label = selection.selectAll('.preset-input-wrap')
|
||||
.data([0]);
|
||||
|
||||
var enter = label.enter().append('label')
|
||||
.attr('class', 'preset-input-wrap');
|
||||
|
||||
box = label.append('input')
|
||||
enter.append('input')
|
||||
.property('indeterminate', true)
|
||||
.attr('type', 'checkbox')
|
||||
.attr('id', 'preset-input-' + field.id);
|
||||
|
||||
text = label.append('span')
|
||||
enter.append('span')
|
||||
.text('unknown')
|
||||
.attr('class', 'value');
|
||||
|
||||
box.on('click', function() {
|
||||
var t = {};
|
||||
t[field.key] = values[(values.indexOf(value) + 1) % 3];
|
||||
check.tags(t);
|
||||
event.change(t);
|
||||
d3.event.stopPropagation();
|
||||
});
|
||||
box = label.select('input')
|
||||
.on('click', function() {
|
||||
var t = {};
|
||||
t[field.key] = values[(values.indexOf(value) + 1) % 3];
|
||||
check.tags(t);
|
||||
event.change(t);
|
||||
d3.event.stopPropagation();
|
||||
});
|
||||
|
||||
text = label.select('span.value');
|
||||
};
|
||||
|
||||
check.tags = function(tags) {
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
iD.ui.preset.combo = function(field) {
|
||||
|
||||
var event = d3.dispatch('change'),
|
||||
input;
|
||||
|
||||
function combo(selection) {
|
||||
var combobox = d3.combobox();
|
||||
|
||||
input = selection.append('input')
|
||||
input = selection.selectAll('input')
|
||||
.data([0]);
|
||||
|
||||
input.enter().append('input')
|
||||
.attr('type', 'text')
|
||||
.attr('id', 'preset-input-' + field.id)
|
||||
.attr('id', 'preset-input-' + field.id);
|
||||
|
||||
input
|
||||
.on('change', change)
|
||||
.on('blur', change)
|
||||
.call(combobox);
|
||||
@@ -37,7 +41,6 @@ iD.ui.preset.combo = function(field) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function change() {
|
||||
var t = {};
|
||||
t[field.key] = input.property('value').replace(' ', '_');
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
iD.ui.preset.defaultcheck = function(field) {
|
||||
|
||||
var event = d3.dispatch('change'),
|
||||
input;
|
||||
|
||||
var check = function(selection) {
|
||||
function check(selection) {
|
||||
input = selection.selectAll('input')
|
||||
.data([0]);
|
||||
|
||||
input = selection.append('input')
|
||||
input.enter().append('input')
|
||||
.attr('type', 'checkbox')
|
||||
.attr('id', 'preset-input-' + field.id)
|
||||
.attr('id', 'preset-input-' + field.id);
|
||||
|
||||
input
|
||||
.on('change', function() {
|
||||
var t = {};
|
||||
t[field.key] = input.property('checked') ? field.value || 'yes' : undefined;
|
||||
event.change(t);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
check.tags = function(tags) {
|
||||
input.property('checked', !!tags[field.key] && tags[field.key] !== 'no');
|
||||
|
||||
+22
-15
@@ -8,10 +8,15 @@ iD.ui.preset.url = function(field) {
|
||||
input;
|
||||
|
||||
function i(selection) {
|
||||
input = selection.append('input')
|
||||
input = selection.selectAll('input')
|
||||
.data([0]);
|
||||
|
||||
input.enter().append('input')
|
||||
.attr('type', field.type)
|
||||
.attr('id', 'preset-input-' + field.id)
|
||||
.attr('placeholder', field.placeholder || '')
|
||||
.attr('placeholder', field.placeholder || '');
|
||||
|
||||
input
|
||||
.on('blur', change)
|
||||
.on('change', change);
|
||||
|
||||
@@ -23,23 +28,25 @@ iD.ui.preset.url = function(field) {
|
||||
}
|
||||
|
||||
if (field.type == 'number') {
|
||||
|
||||
input.attr('type', 'text');
|
||||
|
||||
var numbercontrols = selection.append('div')
|
||||
var spinControl = selection.selectAll('.spin-control')
|
||||
.data([0]);
|
||||
|
||||
var enter = spinControl.enter().append('div')
|
||||
.attr('class', 'spin-control');
|
||||
|
||||
numbercontrols
|
||||
.append('button')
|
||||
.attr('class', 'increment')
|
||||
.on('click', function() {
|
||||
pm(input.node(), 1);
|
||||
});
|
||||
numbercontrols
|
||||
.append('button')
|
||||
.attr('class', 'decrement')
|
||||
.on('click', function() {
|
||||
pm(input.node(), -1);
|
||||
enter.append('button')
|
||||
.datum(1)
|
||||
.attr('class', 'increment');
|
||||
|
||||
enter.append('button')
|
||||
.datum(-1)
|
||||
.attr('class', 'decrement');
|
||||
|
||||
spinControl.selectAll('button')
|
||||
.on('click', function(d) {
|
||||
pm(input.node(), d);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,29 +5,38 @@ iD.ui.preset.localized = function(field, context) {
|
||||
input, localizedInputs, wikiTitles;
|
||||
|
||||
function i(selection) {
|
||||
input = selection.selectAll('.localized-main')
|
||||
.data([0]);
|
||||
|
||||
input = selection.append('input')
|
||||
input.enter().append('input')
|
||||
.attr('type', 'text')
|
||||
.attr('id', 'preset-input-' + field.id)
|
||||
.attr('class', 'localized-main')
|
||||
.attr('placeholder', field.placeholder || '')
|
||||
.attr('placeholder', field.placeholder || '');
|
||||
|
||||
input
|
||||
.on('blur', change)
|
||||
.on('change', change);
|
||||
|
||||
var translateButton = selection.append('button')
|
||||
.attr('class', 'button-input-action localized-add minor')
|
||||
.on('click', addBlank);
|
||||
var translateButton = selection.selectAll('.localized-add')
|
||||
.data([0]);
|
||||
|
||||
translateButton.append('span')
|
||||
translateButton.enter().append('button')
|
||||
.attr('class', 'button-input-action localized-add minor')
|
||||
.call(bootstrap.tooltip()
|
||||
.title(t('translate.translate'))
|
||||
.placement('left'))
|
||||
.append('span')
|
||||
.attr('class', 'icon plus');
|
||||
|
||||
translateButton.call(bootstrap.tooltip()
|
||||
.title(t('translate.translate'))
|
||||
.placement('left'));
|
||||
translateButton
|
||||
.on('click', addBlank);
|
||||
|
||||
localizedInputs = selection.append('div')
|
||||
localizedInputs = selection.selectAll('.localized-wrap')
|
||||
.data([0]);
|
||||
|
||||
localizedInputs.enter().append('div')
|
||||
.attr('class', 'localized-wrap');
|
||||
|
||||
}
|
||||
|
||||
function addBlank() {
|
||||
|
||||
@@ -14,9 +14,14 @@ iD.ui.preset.maxspeed = function(field, context) {
|
||||
combobox = d3.combobox();
|
||||
var unitCombobox = d3.combobox().data(['km/h', 'mph'].map(comboValues));
|
||||
|
||||
input = selection.append('input')
|
||||
input = selection.selectAll('#preset-input-' + field.id)
|
||||
.data([0]);
|
||||
|
||||
input.enter().append('input')
|
||||
.attr('type', 'text')
|
||||
.attr('id', 'preset-input-' + field.id)
|
||||
.attr('id', 'preset-input-' + field.id);
|
||||
|
||||
input
|
||||
.on('change', change)
|
||||
.on('blur', change)
|
||||
.call(combobox);
|
||||
@@ -30,9 +35,14 @@ iD.ui.preset.maxspeed = function(field, context) {
|
||||
});
|
||||
});
|
||||
|
||||
unitInput = selection.append('input')
|
||||
unitInput = selection.selectAll('input.maxspeed-unit')
|
||||
.data([0]);
|
||||
|
||||
unitInput.enter().append('input')
|
||||
.attr('type', 'text')
|
||||
.attr('class', 'maxspeed-unit')
|
||||
.attr('class', 'maxspeed-unit');
|
||||
|
||||
unitInput
|
||||
.on('blur', changeUnits)
|
||||
.on('change', changeUnits)
|
||||
.call(unitCombobox);
|
||||
|
||||
+22
-12
@@ -6,28 +6,38 @@ iD.ui.preset.radio = function(field) {
|
||||
function radio(selection) {
|
||||
selection.classed('preset-radio', true);
|
||||
|
||||
var buttonwrap = selection.append('div')
|
||||
var wrap = selection.selectAll('.preset-input-wrap')
|
||||
.data([0]);
|
||||
|
||||
wrap.enter().append('div')
|
||||
.attr('class', 'preset-input-wrap toggle-list radio-wrap');
|
||||
|
||||
buttons = buttonwrap.selectAll('button')
|
||||
.data(field.options || field.keys)
|
||||
.enter()
|
||||
.append('button')
|
||||
.text(function(d) { return field.t('options.' + d, { 'default': d }); })
|
||||
buttons = wrap.selectAll('button')
|
||||
.data(field.options || field.keys);
|
||||
|
||||
buttons.enter().append('button')
|
||||
.text(function(d) { return field.t('options.' + d, { 'default': d }); });
|
||||
|
||||
buttons
|
||||
.on('click', function(d) {
|
||||
buttons.classed('active', function(e) { return d === e; });
|
||||
change();
|
||||
});
|
||||
|
||||
buttonwrap.append('button')
|
||||
.attr('class','remove')
|
||||
.on('click', function() {
|
||||
buttons.classed('active', false);
|
||||
change();
|
||||
})
|
||||
var remove = wrap.selectAll('button.remove')
|
||||
.data([0]);
|
||||
|
||||
remove.enter().append('button')
|
||||
.attr('class', 'remove')
|
||||
.text(t('inspector.remove'))
|
||||
.append('span')
|
||||
.attr('class', 'icon remove');
|
||||
|
||||
remove
|
||||
.on('click', function() {
|
||||
buttons.classed('active', false);
|
||||
change();
|
||||
});
|
||||
}
|
||||
|
||||
function change() {
|
||||
|
||||
@@ -4,10 +4,15 @@ iD.ui.preset.textarea = function(field) {
|
||||
input;
|
||||
|
||||
function i(selection) {
|
||||
input = selection.append('textarea')
|
||||
input = selection.selectAll('textarea')
|
||||
.data([0]);
|
||||
|
||||
input.enter().append('textarea')
|
||||
.attr('id', 'preset-input-' + field.id)
|
||||
.attr('placeholder', field.placeholder || '')
|
||||
.attr('maxlength', 255)
|
||||
.attr('maxlength', 255);
|
||||
|
||||
input
|
||||
.on('blur', change)
|
||||
.on('change', change);
|
||||
}
|
||||
|
||||
@@ -33,26 +33,39 @@ iD.ui.preset.wikipedia = function(field, context) {
|
||||
});
|
||||
});
|
||||
|
||||
lang = selection.append('input')
|
||||
lang = selection.selectAll('input.wiki-lang')
|
||||
.data([0]);
|
||||
|
||||
lang.enter().append('input')
|
||||
.attr('type', 'text')
|
||||
.attr('class', 'wiki-lang')
|
||||
.attr('class', 'wiki-lang');
|
||||
|
||||
lang
|
||||
.on('blur', changeLang)
|
||||
.on('change', changeLang)
|
||||
.call(langcombo);
|
||||
|
||||
title = selection.append('input')
|
||||
title = selection.selectAll('input.wiki-title')
|
||||
.data([0]);
|
||||
|
||||
title.enter().append('input')
|
||||
.attr('type', 'text')
|
||||
.attr('class', 'wiki-title')
|
||||
.attr('id', 'preset-input-' + field.id)
|
||||
.attr('id', 'preset-input-' + field.id);
|
||||
|
||||
title
|
||||
.on('blur', change)
|
||||
.on('change', change)
|
||||
.call(titlecombo);
|
||||
|
||||
link = selection.append('a')
|
||||
link = selection.selectAll('a.wiki-link')
|
||||
.data([0]);
|
||||
|
||||
link.enter().append('a')
|
||||
.attr('class', 'wiki-link button-input-action minor')
|
||||
.attr('target', '_blank');
|
||||
link.append('span')
|
||||
.attr('class','icon out-link');
|
||||
.attr('target', '_blank')
|
||||
.append('span')
|
||||
.attr('class', 'icon out-link');
|
||||
}
|
||||
|
||||
function changeLang() {
|
||||
|
||||
+29
-21
@@ -2,32 +2,40 @@ iD.ui.PresetIcon = function() {
|
||||
var preset, geometry;
|
||||
|
||||
function presetIcon(selection) {
|
||||
selection.append('div')
|
||||
.attr('class', function() {
|
||||
var s = 'preset-icon-fill icon-' + geometry;
|
||||
for (var i in preset.tags) {
|
||||
s += ' tag-' + i + ' tag-' + i + '-' + preset.tags[i];
|
||||
}
|
||||
return s;
|
||||
});
|
||||
var $fill = selection.selectAll('.preset-icon-fill')
|
||||
.data([0]);
|
||||
|
||||
$fill.enter().append('div');
|
||||
|
||||
$fill.attr('class', function() {
|
||||
var s = 'preset-icon-fill icon-' + geometry;
|
||||
for (var i in preset.tags) {
|
||||
s += ' tag-' + i + ' tag-' + i + '-' + preset.tags[i];
|
||||
}
|
||||
return s;
|
||||
});
|
||||
|
||||
var fallbackIcon = geometry === 'line' ? 'other-line' : 'marker-stroked';
|
||||
|
||||
selection.append('div')
|
||||
.attr('class', function() {
|
||||
var icon = preset.icon || fallbackIcon,
|
||||
klass = 'feature-' + icon + ' preset-icon';
|
||||
var $icon = selection.selectAll('.preset-icon')
|
||||
.data([0]);
|
||||
|
||||
var featureicon = iD.data.featureIcons[icon];
|
||||
if (featureicon && featureicon[geometry]) {
|
||||
klass += ' preset-icon-' + geometry;
|
||||
} else if (icon === 'multipolygon') {
|
||||
// Special case (geometry === 'area')
|
||||
klass += ' preset-icon-relation';
|
||||
}
|
||||
$icon.enter().append('div');
|
||||
|
||||
return klass;
|
||||
});
|
||||
$icon.attr('class', function() {
|
||||
var icon = preset.icon || fallbackIcon,
|
||||
klass = 'feature-' + icon + ' preset-icon';
|
||||
|
||||
var featureicon = iD.data.featureIcons[icon];
|
||||
if (featureicon && featureicon[geometry]) {
|
||||
klass += ' preset-icon-' + geometry;
|
||||
} else if (icon === 'multipolygon') {
|
||||
// Special case (geometry === 'area')
|
||||
klass += ' preset-icon-relation';
|
||||
}
|
||||
|
||||
return klass;
|
||||
});
|
||||
}
|
||||
|
||||
presetIcon.preset = function(_) {
|
||||
|
||||
+22
-17
@@ -1,15 +1,12 @@
|
||||
iD.ui.PresetList = function(context, entity) {
|
||||
iD.ui.PresetList = function(context) {
|
||||
var event = d3.dispatch('choose'),
|
||||
presets, current,
|
||||
id,
|
||||
preset,
|
||||
autofocus = false;
|
||||
|
||||
function browse() {
|
||||
context.enter(iD.modes.Browse(context));
|
||||
}
|
||||
|
||||
function presetList(selection) {
|
||||
var geometry = entity.geometry(context.graph());
|
||||
presets = context.presets().matchGeometry(geometry);
|
||||
var geometry = context.geometry(id),
|
||||
presets = context.presets().matchGeometry(geometry);
|
||||
|
||||
selection.html('');
|
||||
|
||||
@@ -20,7 +17,7 @@ iD.ui.PresetList = function(context, entity) {
|
||||
.attr('class', 'inspector-inner')
|
||||
.text(t('inspector.choose'));
|
||||
|
||||
if (current) {
|
||||
if (preset) {
|
||||
messagewrap.append('button')
|
||||
.attr('class', 'preset-choose')
|
||||
.on('click', event.choose)
|
||||
@@ -29,7 +26,9 @@ iD.ui.PresetList = function(context, entity) {
|
||||
} else {
|
||||
messagewrap.append('button')
|
||||
.attr('class', 'close')
|
||||
.on('click', browse)
|
||||
.on('click', function() {
|
||||
context.enter(iD.modes.Browse(context));
|
||||
})
|
||||
.append('span')
|
||||
.attr('class', 'icon close');
|
||||
}
|
||||
@@ -41,7 +40,7 @@ iD.ui.PresetList = function(context, entity) {
|
||||
d3.event.keyCode === d3.keybinding.keyCodes['⌦'])) {
|
||||
d3.event.preventDefault();
|
||||
d3.event.stopPropagation();
|
||||
iD.operations.Delete([entity.id], context)();
|
||||
iD.operations.Delete([id], context)();
|
||||
} else if (search.property('value').length === 0 &&
|
||||
(d3.event.ctrlKey || d3.event.metaKey) &&
|
||||
d3.event.keyCode === d3.keybinding.keyCodes.z) {
|
||||
@@ -108,7 +107,7 @@ iD.ui.PresetList = function(context, entity) {
|
||||
|
||||
items.enter().append('div')
|
||||
.attr('class', function(item) { return 'preset-list-item preset-' + item.preset.id.replace('/', '-'); })
|
||||
.classed('current', function(item) { return item.preset === current; })
|
||||
.classed('current', function(item) { return item.preset === preset; })
|
||||
.each(function(item) {
|
||||
d3.select(this).call(item);
|
||||
})
|
||||
@@ -132,7 +131,7 @@ iD.ui.PresetList = function(context, entity) {
|
||||
wrap.append('button')
|
||||
.attr('class', 'preset-list-button')
|
||||
.call(iD.ui.PresetIcon()
|
||||
.geometry(context.geometry(entity.id))
|
||||
.geometry(context.geometry(id))
|
||||
.preset(preset))
|
||||
.on('click', item.choose)
|
||||
.append('div')
|
||||
@@ -182,7 +181,7 @@ iD.ui.PresetList = function(context, entity) {
|
||||
wrap.append('button')
|
||||
.attr('class', 'preset-list-button')
|
||||
.call(iD.ui.PresetIcon()
|
||||
.geometry(context.geometry(entity.id))
|
||||
.geometry(context.geometry(id))
|
||||
.preset(preset))
|
||||
.on('click', item.choose)
|
||||
.append('div')
|
||||
@@ -215,9 +214,15 @@ iD.ui.PresetList = function(context, entity) {
|
||||
return presetList;
|
||||
};
|
||||
|
||||
presetList.current = function(_) {
|
||||
if (!arguments.length) return current;
|
||||
current = _;
|
||||
presetList.entityID = function(_) {
|
||||
if (!arguments.length) return id;
|
||||
id = _;
|
||||
return presetList;
|
||||
};
|
||||
|
||||
presetList.preset = function(_) {
|
||||
if (!arguments.length) return preset;
|
||||
preset = _;
|
||||
return presetList;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,32 +1,5 @@
|
||||
iD.ui.RawMemberEditor = function(context, entity) {
|
||||
var list, disclosure;
|
||||
|
||||
var rawMemberEditor = function(selection) {
|
||||
function toggled(expanded) {
|
||||
if (expanded) {
|
||||
selection.node().parentNode.scrollTop += 200;
|
||||
}
|
||||
}
|
||||
|
||||
disclosure = iD.ui.Disclosure()
|
||||
.title(t('inspector.all_members'))
|
||||
.expanded(true)
|
||||
.on('toggled', toggled)
|
||||
.content(content);
|
||||
|
||||
selection.call(disclosure);
|
||||
};
|
||||
|
||||
rawMemberEditor.change = function() {
|
||||
drawMembers();
|
||||
};
|
||||
|
||||
function content(wrap) {
|
||||
list = wrap.append('ul')
|
||||
.attr('class', 'member-list');
|
||||
|
||||
drawMembers();
|
||||
}
|
||||
iD.ui.RawMemberEditor = function(context) {
|
||||
var id;
|
||||
|
||||
function selectMember(d) {
|
||||
context.enter(iD.modes.Select(context, [d.member.id]));
|
||||
@@ -35,75 +8,97 @@ iD.ui.RawMemberEditor = function(context, entity) {
|
||||
function changeRole(d) {
|
||||
var role = d3.select(this).property('value');
|
||||
context.perform(
|
||||
iD.actions.ChangeMember(entity.id, _.extend({}, d.member, {role: role}), d.index),
|
||||
iD.actions.ChangeMember(id, _.extend({}, d.member, {role: role}), d.index),
|
||||
t('operations.change_role.annotation'));
|
||||
}
|
||||
|
||||
function deleteMember(d) {
|
||||
context.perform(
|
||||
iD.actions.DeleteMember(entity.id, d.index),
|
||||
iD.actions.DeleteMember(id, d.index),
|
||||
t('operations.delete_member.annotation.' + context.geometry(d.member.id)));
|
||||
}
|
||||
|
||||
function drawMembers() {
|
||||
var memberships = [];
|
||||
|
||||
entity = context.hasEntity(entity.id);
|
||||
if (!entity) return;
|
||||
function rawMemberEditor(selection) {
|
||||
var entity = context.entity(id),
|
||||
memberships = [];
|
||||
|
||||
entity.members.forEach(function(member, index) {
|
||||
memberships.push({member: member, index: index, entity: context.hasEntity(member.id)});
|
||||
});
|
||||
|
||||
disclosure.title(t('inspector.all_members') + ' (' + memberships.length + ')');
|
||||
selection.call(iD.ui.Disclosure()
|
||||
.title(t('inspector.all_members') + ' (' + memberships.length + ')')
|
||||
.expanded(true)
|
||||
.on('toggled', toggled)
|
||||
.content(content));
|
||||
|
||||
var li = list.selectAll('li')
|
||||
.data(memberships, function(d) { return iD.Entity.key(entity) + ',' + d.index; });
|
||||
|
||||
var row = li.enter().append('li')
|
||||
.attr('class', 'member-row form-field');
|
||||
|
||||
row.each(function(d) {
|
||||
if (d.entity) {
|
||||
var member = d3.select(this).append('label')
|
||||
.attr('class', 'form-label')
|
||||
.append('a')
|
||||
.attr('href', '#')
|
||||
.on('click', selectMember);
|
||||
|
||||
member.append('span')
|
||||
.attr('class', 'member-entity-type')
|
||||
.text(function(d) { return context.presets().match(d.entity, context.graph()).name(); });
|
||||
|
||||
member.append('span')
|
||||
.attr('class', 'member-entity-name')
|
||||
.text(function(d) { return iD.util.localeName(d.entity); });
|
||||
|
||||
} else {
|
||||
d3.select(this).append('label')
|
||||
.attr('class', 'form-label member-incomplete')
|
||||
.text(t('inspector.incomplete'));
|
||||
function toggled(expanded) {
|
||||
if (expanded) {
|
||||
selection.node().parentNode.scrollTop += 200;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
row.append('input')
|
||||
.attr('class', 'member-role')
|
||||
.property('type', 'text')
|
||||
.attr('maxlength', 255)
|
||||
.attr('placeholder', t('inspector.role'))
|
||||
.property('value', function(d) { return d.member.role; })
|
||||
.on('change', changeRole);
|
||||
function content($wrap) {
|
||||
var $list = $wrap.selectAll('.member-list')
|
||||
.data([0]);
|
||||
|
||||
row.append('button')
|
||||
.attr('tabindex', -1)
|
||||
.attr('class', 'remove button-input-action member-delete minor')
|
||||
.on('click', deleteMember)
|
||||
.append('span')
|
||||
.attr('class', 'icon delete');
|
||||
$list.enter().append('ul')
|
||||
.attr('class', 'member-list');
|
||||
|
||||
li.exit()
|
||||
.remove();
|
||||
var $items = $list.selectAll('li')
|
||||
.data(memberships, function(d) { return iD.Entity.key(entity) + ',' + d.index; });
|
||||
|
||||
var $enter = $items.enter().append('li')
|
||||
.attr('class', 'member-row form-field');
|
||||
|
||||
$enter.each(function(d) {
|
||||
if (d.entity) {
|
||||
var $label = d3.select(this).append('label')
|
||||
.attr('class', 'form-label')
|
||||
.append('a')
|
||||
.attr('href', '#')
|
||||
.on('click', selectMember);
|
||||
|
||||
$label.append('span')
|
||||
.attr('class', 'member-entity-type')
|
||||
.text(function(d) { return context.presets().match(d.entity, context.graph()).name(); });
|
||||
|
||||
$label.append('span')
|
||||
.attr('class', 'member-entity-name')
|
||||
.text(function(d) { return iD.util.localeName(d.entity); });
|
||||
|
||||
} else {
|
||||
d3.select(this).append('label')
|
||||
.attr('class', 'form-label member-incomplete')
|
||||
.text(t('inspector.incomplete'));
|
||||
}
|
||||
});
|
||||
|
||||
$enter.append('input')
|
||||
.attr('class', 'member-role')
|
||||
.property('type', 'text')
|
||||
.attr('maxlength', 255)
|
||||
.attr('placeholder', t('inspector.role'))
|
||||
.property('value', function(d) { return d.member.role; })
|
||||
.on('change', changeRole);
|
||||
|
||||
$enter.append('button')
|
||||
.attr('tabindex', -1)
|
||||
.attr('class', 'remove button-input-action member-delete minor')
|
||||
.on('click', deleteMember)
|
||||
.append('span')
|
||||
.attr('class', 'icon delete');
|
||||
|
||||
$items.exit()
|
||||
.remove();
|
||||
}
|
||||
}
|
||||
|
||||
rawMemberEditor.entityID = function(_) {
|
||||
if (!arguments.length) return id;
|
||||
id = _;
|
||||
return rawMemberEditor;
|
||||
};
|
||||
|
||||
return rawMemberEditor;
|
||||
};
|
||||
|
||||
@@ -1,32 +1,5 @@
|
||||
iD.ui.RawMembershipEditor = function(context, entity) {
|
||||
var list, disclosure;
|
||||
|
||||
var rawMembershipEditor = function(selection) {
|
||||
function toggled(expanded) {
|
||||
if (expanded) {
|
||||
selection.node().parentNode.scrollTop += 200;
|
||||
}
|
||||
}
|
||||
|
||||
disclosure = iD.ui.Disclosure()
|
||||
.title(t('inspector.all_relations'))
|
||||
.expanded(true)
|
||||
.on('toggled', toggled)
|
||||
.content(content);
|
||||
|
||||
selection.call(disclosure);
|
||||
};
|
||||
|
||||
rawMembershipEditor.change = function() {
|
||||
drawMemberships();
|
||||
};
|
||||
|
||||
function content(wrap) {
|
||||
list = wrap.append('ul')
|
||||
.attr('class', 'member-list');
|
||||
|
||||
drawMemberships();
|
||||
}
|
||||
iD.ui.RawMembershipEditor = function(context) {
|
||||
var id;
|
||||
|
||||
function selectRelation(d) {
|
||||
context.enter(iD.modes.Select(context, [d.relation.id]));
|
||||
@@ -45,8 +18,9 @@ iD.ui.RawMembershipEditor = function(context, entity) {
|
||||
t('operations.delete_member.annotation.' + context.geometry(d.member.id)));
|
||||
}
|
||||
|
||||
function drawMemberships() {
|
||||
var memberships = [];
|
||||
function rawMembershipEditor(selection) {
|
||||
var entity = context.entity(id),
|
||||
memberships = [];
|
||||
|
||||
context.graph().parentRelations(entity).forEach(function(relation) {
|
||||
relation.members.forEach(function(member, index) {
|
||||
@@ -56,46 +30,70 @@ iD.ui.RawMembershipEditor = function(context, entity) {
|
||||
})
|
||||
});
|
||||
|
||||
disclosure.title(t('inspector.all_relations') + ' (' + memberships.length + ')');
|
||||
selection.call(iD.ui.Disclosure()
|
||||
.title(t('inspector.all_relations') + ' (' + memberships.length + ')')
|
||||
.expanded(true)
|
||||
.on('toggled', toggled)
|
||||
.content(content));
|
||||
|
||||
var li = list.selectAll('li')
|
||||
.data(memberships, function(d) { return iD.Entity.key(d.relation) + ',' + d.index; });
|
||||
function toggled(expanded) {
|
||||
if (expanded) {
|
||||
selection.node().parentNode.scrollTop += 200;
|
||||
}
|
||||
}
|
||||
|
||||
var row = li.enter().append('li')
|
||||
.attr('class', 'member-row form-field');
|
||||
function content($wrap) {
|
||||
var $list = $wrap.selectAll('.member-list')
|
||||
.data([0]);
|
||||
|
||||
relationLabel = row.append('label')
|
||||
.attr('class', 'form-label')
|
||||
.append('a')
|
||||
.attr('href', '#')
|
||||
.on('click', selectRelation);
|
||||
$list.enter().append('ul')
|
||||
.attr('class', 'member-list');
|
||||
|
||||
relationLabel.append('span')
|
||||
.attr('class','member-entity-type')
|
||||
.text(function(d) { return context.presets().match(d.relation, context.graph()).name(); });
|
||||
var $items = $list.selectAll('li')
|
||||
.data(memberships, function(d) { return iD.Entity.key(d.relation) + ',' + d.index; });
|
||||
|
||||
relationLabel.append('span')
|
||||
.attr('class', 'member-entity-name')
|
||||
.text(function(d) { return iD.util.localeName(d.relation); });
|
||||
var $enter = $items.enter().append('li')
|
||||
.attr('class', 'member-row form-field');
|
||||
|
||||
row.append('input')
|
||||
.attr('class', 'member-role')
|
||||
.property('type', 'text')
|
||||
.attr('maxlength', 255)
|
||||
.attr('placeholder', t('inspector.role'))
|
||||
.property('value', function(d) { return d.member.role; })
|
||||
.on('change', changeRole);
|
||||
var $label = $enter.append('label')
|
||||
.attr('class', 'form-label')
|
||||
.append('a')
|
||||
.attr('href', '#')
|
||||
.on('click', selectRelation);
|
||||
|
||||
row.append('button')
|
||||
.attr('tabindex', -1)
|
||||
.attr('class', 'remove button-input-action member-delete minor')
|
||||
.on('click', deleteMembership)
|
||||
.append('span')
|
||||
.attr('class', 'icon delete');
|
||||
$label.append('span')
|
||||
.attr('class','member-entity-type')
|
||||
.text(function(d) { return context.presets().match(d.relation, context.graph()).name(); });
|
||||
|
||||
li.exit()
|
||||
.remove();
|
||||
$label.append('span')
|
||||
.attr('class', 'member-entity-name')
|
||||
.text(function(d) { return iD.util.localeName(d.relation); });
|
||||
|
||||
$enter.append('input')
|
||||
.attr('class', 'member-role')
|
||||
.property('type', 'text')
|
||||
.attr('maxlength', 255)
|
||||
.attr('placeholder', t('inspector.role'))
|
||||
.property('value', function(d) { return d.member.role; })
|
||||
.on('change', changeRole);
|
||||
|
||||
$enter.append('button')
|
||||
.attr('tabindex', -1)
|
||||
.attr('class', 'remove button-input-action member-delete minor')
|
||||
.on('click', deleteMembership)
|
||||
.append('span')
|
||||
.attr('class', 'icon delete');
|
||||
|
||||
$items.exit()
|
||||
.remove();
|
||||
}
|
||||
}
|
||||
|
||||
rawMembershipEditor.entityID = function(_) {
|
||||
if (!arguments.length) return id;
|
||||
id = _;
|
||||
return rawMembershipEditor;
|
||||
};
|
||||
|
||||
return rawMembershipEditor;
|
||||
};
|
||||
|
||||
+158
-142
@@ -1,195 +1,211 @@
|
||||
iD.ui.RawTagEditor = function(context, entity) {
|
||||
iD.ui.RawTagEditor = function(context) {
|
||||
var event = d3.dispatch('change'),
|
||||
taginfo = iD.taginfo(),
|
||||
disclosure,
|
||||
list;
|
||||
preset,
|
||||
tags,
|
||||
id;
|
||||
|
||||
function rawTagEditor(selection) {
|
||||
var count = Object.keys(tags).filter(function(d) { return d; }).length;
|
||||
|
||||
selection.call(iD.ui.Disclosure()
|
||||
.title(t('inspector.all_tags') + ' (' + count + ')')
|
||||
.expanded(iD.ui.RawTagEditor.expanded || preset.isFallback())
|
||||
.on('toggled', toggled)
|
||||
.content(content));
|
||||
|
||||
function rawTagEditor(selection, other) {
|
||||
function toggled(expanded) {
|
||||
iD.ui.RawTagEditor.expanded = expanded;
|
||||
if (expanded) {
|
||||
selection.node().parentNode.scrollTop += 200;
|
||||
}
|
||||
}
|
||||
|
||||
disclosure = iD.ui.Disclosure()
|
||||
.title(t('inspector.all_tags'))
|
||||
.expanded(iD.ui.RawTagEditor.expanded || other)
|
||||
.on('toggled', toggled)
|
||||
.content(content);
|
||||
|
||||
selection.call(disclosure);
|
||||
}
|
||||
|
||||
function content(wrap) {
|
||||
list = wrap.append('ul')
|
||||
.attr('class', 'tag-list');
|
||||
function content($wrap) {
|
||||
var entries = d3.entries(tags);
|
||||
|
||||
var newTag = wrap.append('button')
|
||||
.attr('class', 'add-tag col6')
|
||||
.on('click', addTag);
|
||||
|
||||
newTag.append('span')
|
||||
.attr('class', 'icon plus light');
|
||||
|
||||
newTag.append('span')
|
||||
.attr('class', 'label')
|
||||
.text(t('inspector.new_tag'));
|
||||
}
|
||||
|
||||
function drawTags(tags) {
|
||||
|
||||
var count = Object.keys(tags).filter(function(d) { return d; }).length;
|
||||
disclosure.title(t('inspector.all_tags') + ' (' + count + ')');
|
||||
|
||||
tags = d3.entries(tags);
|
||||
|
||||
if (!tags.length) {
|
||||
tags = [{key: '', value: ''}];
|
||||
if (!entries.length) {
|
||||
entries = [{key: '', value: ''}];
|
||||
}
|
||||
|
||||
tags.forEach(function(tag) {
|
||||
tag.reference = iD.ui.TagReference({key: tag.key});
|
||||
entries.forEach(function(entry) {
|
||||
entry.reference = iD.ui.TagReference({key: entry.key});
|
||||
});
|
||||
|
||||
var li = list.html('')
|
||||
.selectAll('li')
|
||||
.data(tags, function(d) { return d.key; });
|
||||
var $list = $wrap.selectAll('.tag-list')
|
||||
.data([0]);
|
||||
|
||||
li.exit().remove();
|
||||
$list.enter().append('ul')
|
||||
.attr('class', 'tag-list');
|
||||
|
||||
var row = li.enter().append('li')
|
||||
var $newTag = $wrap.selectAll('.add-tag')
|
||||
.data([0]);
|
||||
|
||||
var $enter = $newTag.enter().append('button')
|
||||
.attr('class', 'add-tag col6');
|
||||
|
||||
$enter.append('span')
|
||||
.attr('class', 'icon plus light');
|
||||
|
||||
$enter.append('span')
|
||||
.attr('class', 'label')
|
||||
.text(t('inspector.new_tag'));
|
||||
|
||||
$newTag.on('click', addTag);
|
||||
|
||||
var $items = $list.selectAll('li')
|
||||
.data(entries, function(d) { return d.key; });
|
||||
|
||||
// Enter
|
||||
|
||||
$enter = $items.enter().append('li')
|
||||
.attr('class', 'tag-row cf');
|
||||
|
||||
row.append('div')
|
||||
$enter.append('div')
|
||||
.attr('class', 'key-wrap')
|
||||
.append('input')
|
||||
.property('type', 'text')
|
||||
.attr('class', 'key')
|
||||
.attr('maxlength', 255)
|
||||
.property('value', function(d) { return d.key; })
|
||||
.on('blur', keyChange)
|
||||
.on('change', keyChange);
|
||||
.attr('maxlength', 255);
|
||||
|
||||
function keyChange(d) {
|
||||
d.key = this.value;
|
||||
event.change(rawTagEditor.tags());
|
||||
}
|
||||
|
||||
row.append('div')
|
||||
$enter.append('div')
|
||||
.attr('class', 'input-wrap-position col6')
|
||||
.append('input')
|
||||
.property('type', 'text')
|
||||
.attr('class', 'value')
|
||||
.attr('maxlength', 255)
|
||||
.property('value', function(d) { return d.value; })
|
||||
.attr('maxlength', 255);
|
||||
|
||||
$enter.append('button')
|
||||
.attr('tabindex', -1)
|
||||
.attr('class', 'remove minor')
|
||||
.append('span')
|
||||
.attr('class', 'icon delete');
|
||||
|
||||
// Update
|
||||
|
||||
$items.order();
|
||||
|
||||
$items.select('input.key')
|
||||
.property('value', function(d) {
|
||||
return d.key;
|
||||
})
|
||||
.on('blur', keyChange)
|
||||
.on('change', keyChange);
|
||||
|
||||
$items.select('input.value')
|
||||
.property('value', function(d) {
|
||||
return d.value;
|
||||
})
|
||||
.on('blur', valueChange)
|
||||
.on('change', valueChange)
|
||||
.on('keydown.push-more', pushMore);
|
||||
|
||||
function valueChange(d) {
|
||||
d.value = this.value;
|
||||
event.change(rawTagEditor.tags());
|
||||
}
|
||||
$items.select('button.remove')
|
||||
.on('click', removeTag);
|
||||
|
||||
row.each(bindTypeahead);
|
||||
|
||||
row.append('button')
|
||||
.attr('tabindex', -1)
|
||||
.attr('class','remove minor')
|
||||
.on('click', removeTag)
|
||||
.append('span')
|
||||
.attr('class', 'icon delete');
|
||||
|
||||
row.each(function(tag) {
|
||||
$items.each(function(tag) {
|
||||
d3.select(this)
|
||||
.each(bindTypeahead)
|
||||
.call(tag.reference.button)
|
||||
.call(tag.reference.body);
|
||||
});
|
||||
|
||||
return li;
|
||||
}
|
||||
$items.exit()
|
||||
.remove();
|
||||
|
||||
function pushMore() {
|
||||
if (d3.event.keyCode === 9 &&
|
||||
list.selectAll('li:last-child input.value').node() === this &&
|
||||
!d3.event.shiftKey) {
|
||||
addTag();
|
||||
d3.event.preventDefault();
|
||||
function keyChange(d) {
|
||||
var tag = {};
|
||||
tag[this.value] = d.value;
|
||||
d.key = this.value; // Maintain DOM identity through the subsequent update.
|
||||
event.change(tag);
|
||||
}
|
||||
}
|
||||
|
||||
function bindTypeahead() {
|
||||
var geometry = entity.geometry(context.graph()),
|
||||
row = d3.select(this),
|
||||
key = row.selectAll('input.key'),
|
||||
value = row.selectAll('input.value');
|
||||
function valueChange(d) {
|
||||
var tag = {};
|
||||
tag[d.key] = this.value;
|
||||
event.change(tag);
|
||||
}
|
||||
|
||||
function sort(value, data) {
|
||||
var sameletter = [],
|
||||
other = [];
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (data[i].value.substring(0, value.length) === value) {
|
||||
sameletter.push(data[i]);
|
||||
} else {
|
||||
other.push(data[i]);
|
||||
}
|
||||
function pushMore() {
|
||||
if (d3.event.keyCode === 9 && !d3.event.shiftKey &&
|
||||
$list.selectAll('li:last-child input.value').node() === this) {
|
||||
addTag();
|
||||
d3.event.preventDefault();
|
||||
}
|
||||
return sameletter.concat(other);
|
||||
}
|
||||
|
||||
key.call(d3.combobox()
|
||||
.fetcher(function(value, __, callback) {
|
||||
taginfo.keys({
|
||||
debounce: true,
|
||||
geometry: geometry,
|
||||
query: value
|
||||
}, function(err, data) {
|
||||
if (!err) callback(sort(value, data));
|
||||
});
|
||||
}));
|
||||
function bindTypeahead() {
|
||||
var geometry = context.geometry(id),
|
||||
row = d3.select(this),
|
||||
key = row.selectAll('input.key'),
|
||||
value = row.selectAll('input.value');
|
||||
|
||||
value.call(d3.combobox()
|
||||
.fetcher(function(value, __, callback) {
|
||||
taginfo.values({
|
||||
debounce: true,
|
||||
key: key.property('value'),
|
||||
geometry: geometry,
|
||||
query: value
|
||||
}, function(err, data) {
|
||||
if (!err) callback(sort(value, data));
|
||||
});
|
||||
}));
|
||||
}
|
||||
function sort(value, data) {
|
||||
var sameletter = [],
|
||||
other = [];
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (data[i].value.substring(0, value.length) === value) {
|
||||
sameletter.push(data[i]);
|
||||
} else {
|
||||
other.push(data[i]);
|
||||
}
|
||||
}
|
||||
return sameletter.concat(other);
|
||||
}
|
||||
|
||||
function addTag() {
|
||||
var tags = rawTagEditor.tags();
|
||||
tags[''] = '';
|
||||
drawTags(tags);
|
||||
list.selectAll('li:last-child input.key').node().focus();
|
||||
}
|
||||
key.call(d3.combobox()
|
||||
.fetcher(function(value, __, callback) {
|
||||
taginfo.keys({
|
||||
debounce: true,
|
||||
geometry: geometry,
|
||||
query: value
|
||||
}, function(err, data) {
|
||||
if (!err) callback(sort(value, data));
|
||||
});
|
||||
}));
|
||||
|
||||
function removeTag(d) {
|
||||
var tags = rawTagEditor.tags();
|
||||
tags[d.key] = '';
|
||||
event.change(tags);
|
||||
delete tags[d.key];
|
||||
drawTags(tags);
|
||||
}
|
||||
|
||||
rawTagEditor.tags = function(tags) {
|
||||
if (!arguments.length) {
|
||||
tags = {};
|
||||
list.selectAll('li').each(function() {
|
||||
var row = d3.select(this),
|
||||
key = row.selectAll('.key').property('value'),
|
||||
value = row.selectAll('.value').property('value');
|
||||
if (key !== '') tags[key] = value;
|
||||
});
|
||||
return tags;
|
||||
} else {
|
||||
drawTags(tags);
|
||||
value.call(d3.combobox()
|
||||
.fetcher(function(value, __, callback) {
|
||||
taginfo.values({
|
||||
debounce: true,
|
||||
key: key.property('value'),
|
||||
geometry: geometry,
|
||||
query: value
|
||||
}, function(err, data) {
|
||||
if (!err) callback(sort(value, data));
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function addTag() {
|
||||
tags[''] = '';
|
||||
content($wrap);
|
||||
$list.selectAll('li:last-child input.key').node().focus();
|
||||
}
|
||||
|
||||
function removeTag(d) {
|
||||
tags[d.key] = '';
|
||||
event.change(tags);
|
||||
}
|
||||
}
|
||||
|
||||
rawTagEditor.preset = function(_) {
|
||||
if (!arguments.length) return preset;
|
||||
preset = _;
|
||||
return rawTagEditor;
|
||||
};
|
||||
|
||||
rawTagEditor.tags = function(_) {
|
||||
if (!arguments.length) return tags;
|
||||
tags = _;
|
||||
return rawTagEditor;
|
||||
};
|
||||
|
||||
rawTagEditor.entityID = function(_) {
|
||||
if (!arguments.length) return id;
|
||||
id = _;
|
||||
return rawTagEditor;
|
||||
};
|
||||
|
||||
return d3.rebind(rawTagEditor, event, 'on');
|
||||
|
||||
+23
-14
@@ -31,25 +31,32 @@ iD.ui.TagReference = function(tag) {
|
||||
}
|
||||
|
||||
tagReference.button = function(selection) {
|
||||
button = selection.append('button')
|
||||
.attr('tabindex', -1)
|
||||
.attr('class', 'tag-reference-button minor')
|
||||
.on('click', function() {
|
||||
d3.event.stopPropagation();
|
||||
d3.event.preventDefault();
|
||||
if (showing) {
|
||||
tagReference.hide();
|
||||
} else {
|
||||
tagReference.load();
|
||||
}
|
||||
});
|
||||
button = selection.selectAll('.tag-reference-button')
|
||||
.data([0]);
|
||||
|
||||
button.append('span')
|
||||
var enter = button.enter().append('button')
|
||||
.attr('tabindex', -1)
|
||||
.attr('class', 'tag-reference-button minor');
|
||||
|
||||
enter.append('span')
|
||||
.attr('class', 'icon inspect');
|
||||
|
||||
button.on('click', function () {
|
||||
d3.event.stopPropagation();
|
||||
d3.event.preventDefault();
|
||||
if (showing) {
|
||||
tagReference.hide();
|
||||
} else {
|
||||
tagReference.load();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
tagReference.body = function(selection) {
|
||||
body = selection.append('div')
|
||||
body = selection.selectAll('.tag-reference-body')
|
||||
.data([0]);
|
||||
|
||||
body.enter().append('div')
|
||||
.attr('class', 'tag-reference-body cf')
|
||||
.style('max-height', '0')
|
||||
.style('opacity', '0');
|
||||
@@ -68,6 +75,8 @@ iD.ui.TagReference = function(tag) {
|
||||
docs = findLocal(docs);
|
||||
}
|
||||
|
||||
body.html('');
|
||||
|
||||
if (!docs || !docs.description) {
|
||||
body.append('p').text(t('inspector.no_documentation_key'));
|
||||
tagReference.show();
|
||||
|
||||
+20
-7
@@ -1,19 +1,32 @@
|
||||
iD.ui.ViewOnOSM = function(context) {
|
||||
return function(selection, entity) {
|
||||
var id;
|
||||
|
||||
function viewOnOSM(selection) {
|
||||
var entity = context.entity(id);
|
||||
|
||||
selection.style('display', entity.isNew() ? 'none' : null);
|
||||
|
||||
var osmLink = selection.selectAll('.view-on-osm')
|
||||
.data([entity]);
|
||||
var $link = selection.selectAll('.view-on-osm')
|
||||
.data([0]);
|
||||
|
||||
var enter = osmLink.enter().append('a')
|
||||
var $enter = $link.enter().append('a')
|
||||
.attr('class', 'view-on-osm')
|
||||
.attr('target', '_blank');
|
||||
|
||||
enter.append('span')
|
||||
$enter.append('span')
|
||||
.attr('class', 'icon icon-pre-text out-link');
|
||||
enter.append('span')
|
||||
|
||||
$enter.append('span')
|
||||
.text(t('inspector.view_on_osm'));
|
||||
|
||||
osmLink.attr('href', context.connection().entityURL(entity));
|
||||
$link.attr('href', context.connection().entityURL(entity));
|
||||
}
|
||||
|
||||
viewOnOSM.entityID = function(_) {
|
||||
if (!arguments.length) return id;
|
||||
id = _;
|
||||
return viewOnOSM;
|
||||
};
|
||||
|
||||
return viewOnOSM;
|
||||
};
|
||||
|
||||
+22
-12
@@ -12,16 +12,25 @@ d3.combobox = function() {
|
||||
};
|
||||
|
||||
var combobox = function(input) {
|
||||
var idx = -1, container, shown = false;
|
||||
var idx = -1,
|
||||
container = d3.select(document.body)
|
||||
.selectAll('div.combobox')
|
||||
.filter(function(d) { return d === input.node(); }),
|
||||
shown = !container.empty();
|
||||
|
||||
input
|
||||
.classed('combobox-input', true)
|
||||
.each(function() {
|
||||
var parent = this.parentNode,
|
||||
sibling = this.nextSibling;
|
||||
d3.select(parent)
|
||||
.insert('div', function() { return sibling; })
|
||||
.attr('class', 'combobox-carat')
|
||||
|
||||
var carat = d3.select(parent).selectAll('.combobox-carat')
|
||||
.data([0]);
|
||||
|
||||
carat.enter().insert('div', function() { return sibling; })
|
||||
.attr('class', 'combobox-carat');
|
||||
|
||||
carat
|
||||
.on('mousedown', function () {
|
||||
// prevent the form element from blurring. it blurs
|
||||
// on mousedown
|
||||
@@ -50,6 +59,7 @@ d3.combobox = function() {
|
||||
if (!shown) {
|
||||
container = d3.select(document.body)
|
||||
.insert('div', ':first-child')
|
||||
.datum(input.node())
|
||||
.attr('class', 'combobox')
|
||||
.style({
|
||||
position: 'absolute',
|
||||
@@ -201,18 +211,18 @@ d3.combobox = function() {
|
||||
.selectAll('a.combobox-option')
|
||||
.data(data, function(d) { return d.value; });
|
||||
|
||||
options.enter()
|
||||
.append('a')
|
||||
.text(function(d) { return d.value; })
|
||||
options.enter().append('a')
|
||||
.attr('class', 'combobox-option')
|
||||
.attr('title', function(d) { return d.title; })
|
||||
.on('click', select);
|
||||
|
||||
options.exit().remove();
|
||||
.text(function(d) { return d.value; });
|
||||
|
||||
options
|
||||
.attr('title', function(d) { return d.title; })
|
||||
.classed('selected', function(d, i) { return i == idx; })
|
||||
.on('click', select)
|
||||
.order();
|
||||
|
||||
options.exit()
|
||||
.remove();
|
||||
}
|
||||
|
||||
fetcher.apply(input, [value, data, render]);
|
||||
@@ -234,7 +244,7 @@ d3.combobox = function() {
|
||||
input.node().focus();
|
||||
update('');
|
||||
|
||||
if (!container) return;
|
||||
if (container.empty()) return;
|
||||
|
||||
var entries = container.selectAll('a'),
|
||||
height = container.node().scrollHeight / entries[0].length,
|
||||
|
||||
Reference in New Issue
Block a user