diff --git a/css/app.css b/css/app.css
index 6b1bb5a36..3399fe70b 100644
--- a/css/app.css
+++ b/css/app.css
@@ -2287,6 +2287,11 @@ img.wiki-image {
/* Commit Modal
------------------------------------------------------- */
+.commit-modal {
+ width: 100%;
+ height: 100%;
+}
+
.commit-modal a.user-info {
display: inline-block;
}
diff --git a/index.html b/index.html
index cd1177efb..348e9a2c1 100644
--- a/index.html
+++ b/index.html
@@ -167,6 +167,7 @@
+
diff --git a/js/id/id.js b/js/id/id.js
index 909ead40b..eb85ed275 100644
--- a/js/id/id.js
+++ b/js/id/id.js
@@ -45,26 +45,21 @@ window.iD = function () {
return context;
};
- context.ui = function() {
- return function(container) {
- context.container(container);
-
- if (locale && locale !== 'en' && iD.data.locales.indexOf(locale) !== -1) {
- localePath = localePath || context.assetPath() + 'locales/' + locale + '.json';
- d3.json(localePath, function(err, result) {
- window.locale[locale] = result;
- window.locale.current(locale);
- container.call(ui);
- });
- } else {
- container.call(ui);
- }
-
- return ui;
+ context.loadLocale = function(cb) {
+ if (locale && locale !== 'en' && iD.data.locales.indexOf(locale) !== -1) {
+ localePath = localePath || context.assetPath() + 'locales/' + locale + '.json';
+ d3.json(localePath, function(err, result) {
+ window.locale[locale] = result;
+ window.locale.current(locale);
+ cb();
+ });
+ } else {
+ cb();
}
};
/* Straight accessors. Avoid using these if you can. */
+ context.ui = function() { return ui; };
context.connection = function() { return connection; };
context.history = function() { return history; };
context.map = function() { return map; };
diff --git a/js/id/modes/add_point.js b/js/id/modes/add_point.js
index 12eadef37..1973f542d 100644
--- a/js/id/modes/add_point.js
+++ b/js/id/modes/add_point.js
@@ -1,6 +1,7 @@
iD.modes.AddPoint = function(context) {
var mode = {
id: 'add-point',
+ button: 'point',
title: t('modes.add_point.title'),
description: t('modes.add_point.description'),
key: '1'
diff --git a/js/id/modes/save.js b/js/id/modes/save.js
new file mode 100644
index 000000000..f46c00bec
--- /dev/null
+++ b/js/id/modes/save.js
@@ -0,0 +1,95 @@
+iD.modes.Save = function(context) {
+ var ui = iD.ui.Commit(context)
+ .on('cancel', cancel)
+ .on('fix', fix)
+ .on('save', save);
+
+ function cancel() {
+ context.enter(iD.modes.Browse(context));
+ }
+
+ function fix(d) {
+ context.map().zoomTo(d.entity);
+ context.enter(iD.modes.Select(context, [d.entity.id]));
+ }
+
+ function save(e) {
+ var loading = iD.ui.Loading(context)
+ .message(t('save.uploading'))
+ .blocking(true);
+
+ context.container()
+ .call(loading);
+
+ context.connection().putChangeset(
+ context.history().changes(iD.actions.DiscardTags(context.history().difference())),
+ e.comment,
+ context.history().imagery_used(),
+ function(err, changeset_id) {
+ loading.close();
+ if (err) {
+ var confirm = iD.ui.confirm(context.container());
+ confirm
+ .select('.modal-section.header')
+ .append('h3')
+ .text(t('save.error'));
+ confirm
+ .select('.modal-section.message-text')
+ .append('p')
+ .text(err.responseText);
+ } else {
+ context.flush();
+ success(e, changeset_id);
+ }
+ });
+ }
+
+ function success(e, changeset_id) {
+ context.ui().sidebar.hide(ui);
+
+ ui = iD.ui.Success(context)
+ .changeset({
+ id: changeset_id,
+ comment: e.comment
+ })
+ .on('cancel', cancel);
+
+ context.ui().sidebar.show(ui);
+ }
+
+ var mode = {
+ id: 'save'
+ };
+
+ var behaviors = [
+ iD.behavior.Hover(context),
+ iD.behavior.Select(context),
+ iD.behavior.Lasso(context),
+ iD.modes.DragNode(context).behavior];
+
+ mode.enter = function() {
+ context.container().selectAll('#bar button.save')
+ .classed('active', true);
+
+ behaviors.forEach(function(behavior) {
+ context.install(behavior);
+ });
+
+ context.connection().authenticate(function(err) {
+ context.ui().sidebar.show(ui);
+ });
+ };
+
+ mode.exit = function() {
+ context.container().selectAll('#bar button.save')
+ .classed('active', false);
+
+ behaviors.forEach(function(behavior) {
+ context.uninstall(behavior);
+ });
+
+ context.ui().sidebar.hide(ui);
+ };
+
+ return mode;
+};
diff --git a/js/id/ui.js b/js/id/ui.js
index 6d78251a2..acb64c830 100644
--- a/js/id/ui.js
+++ b/js/id/ui.js
@@ -1,5 +1,5 @@
iD.ui = function(context) {
- return function(container) {
+ function render(container) {
var history = context.history(),
map = context.map();
@@ -16,7 +16,7 @@ iD.ui = function(context) {
container.append('div')
.attr('id', 'sidebar')
.attr('class', 'col4')
- .call(iD.ui.Sidebar(context));
+ .call(ui.sidebar);
var content = container.append('div')
.attr('id', 'content');
@@ -171,7 +171,18 @@ iD.ui = function(context) {
.on('authenticated.ui', function() {
authenticating.close();
});
- };
+ }
+
+ function ui(container) {
+ context.container(container);
+ context.loadLocale(function() {
+ render(container);
+ });
+ }
+
+ ui.sidebar = iD.ui.Sidebar(context);
+
+ return ui;
};
iD.ui.tooltipHtml = function(text, key) {
diff --git a/js/id/ui/commit.js b/js/id/ui/commit.js
index 8d4f9e7bb..7da066b03 100644
--- a/js/id/ui/commit.js
+++ b/js/id/ui/commit.js
@@ -23,35 +23,39 @@ iD.ui.Commit = function(context) {
}
function commit(selection) {
+ var changes = context.history().changes(),
+ user = context.connection().user();
+
+ selection.classed('commit-modal', true);
function changesLength(d) { return changes[d].length; }
- var changes = selection.datum(),
- connection = changes.connection,
- user = connection.user(),
- header = selection.append('div').attr('class', 'header modal-section'),
- body = selection.append('div').attr('class', 'body');
+ var header = selection.append('div')
+ .attr('class', 'header');
header.append('h3')
.text(t('commit.title'));
+ var body = selection.append('div')
+ .attr('class', 'body');
+
// Comment Section
var commentSection = body.append('div')
.attr('class', 'modal-section form-field');
- commentSection.append('label')
- .attr('class','form-label')
- .text(t('commit.message_label'));
+ commentSection.append('label')
+ .attr('class', 'form-label')
+ .text(t('commit.message_label'));
- var commentField = commentSection
- .append('textarea')
- .attr('placeholder', t('commit.description_placeholder'))
- .property('value', context.storage('comment') || '');
+ var commentField = commentSection.append('textarea')
+ .attr('placeholder', t('commit.description_placeholder'))
+ .property('value', context.storage('comment') || '');
commentField.node().select();
// Save Section
- var saveSection = body.append('div').attr('class','modal-section cf');
+ var saveSection = body.append('div')
+ .attr('class','modal-section cf');
var userLink = d3.select(document.createElement('div'));
@@ -64,7 +68,7 @@ iD.ui.Commit = function(context) {
userLink.append('a')
.attr('class','user-info')
.text(user.display_name)
- .attr('href', connection.userURL(user.display_name))
+ .attr('href', context.connection().userURL(user.display_name))
.attr('tabindex', -1)
.attr('target', '_blank');
diff --git a/js/id/ui/save.js b/js/id/ui/save.js
index bb22685f8..48328802a 100644
--- a/js/id/ui/save.js
+++ b/js/id/ui/save.js
@@ -1,84 +1,11 @@
iD.ui.Save = function(context) {
- var map = context.map(),
- history = context.history(),
- connection = context.connection(),
- key = iD.ui.cmd('⌘S'),
- modal;
+ var history = context.history(),
+ key = iD.ui.cmd('⌘S');
function save() {
d3.event.preventDefault();
-
if (!history.hasChanges()) return;
-
- connection.authenticate(function(err) {
- modal = iD.ui.modal(context.container());
- var changes = history.changes();
- changes.connection = connection;
- modal.select('.content')
- .classed('commit-modal', true)
- .datum(changes)
- .call(iD.ui.Commit(context)
- .on('cancel', function() {
- modal.remove();
- })
- .on('fix', clickFix)
- .on('save', commit));
- });
- }
-
- function commit(e) {
- context.container().select('.shaded')
- .remove();
-
- var loading = iD.ui.Loading(context)
- .message(t('save.uploading'))
- .blocking(true);
-
- context.container()
- .call(loading);
-
- connection.putChangeset(
- history.changes(iD.actions.DiscardTags(history.difference())),
- e.comment,
- history.imagery_used(),
- function(err, changeset_id) {
- loading.close();
- if (err) {
- var confirm = iD.ui.confirm(context.container());
- confirm
- .select('.modal-section.header')
- .append('h3')
- .text(t('save.error'));
- confirm
- .select('.modal-section.message-text')
- .append('p')
- .text(err.responseText);
- } else {
- context.flush();
- success(e, changeset_id);
- }
- });
- }
-
- function success(e, changeset_id) {
- modal = iD.ui.modal(context.container());
- modal.select('.content')
- .classed('success-modal', true)
- .datum({
- id: changeset_id,
- comment: e.comment
- })
- .call(iD.ui.Success(context)
- .on('cancel', function() {
- modal.remove();
- }));
- }
-
- function clickFix(d) {
- var extent = d.entity.extent(context.graph());
- map.centerZoom(extent.center(), Math.min(19, map.extentZoom(extent)));
- context.enter(iD.modes.Select(context, [d.entity.id]));
- modal.remove();
+ context.enter(iD.modes.Save(context));
}
return function(selection) {
diff --git a/js/id/ui/sidebar.js b/js/id/ui/sidebar.js
index da5adebb8..dac928cee 100644
--- a/js/id/ui/sidebar.js
+++ b/js/id/ui/sidebar.js
@@ -1,12 +1,14 @@
iD.ui.Sidebar = function(context) {
- return function(selection) {
+ var current;
+
+ function sidebar(selection) {
var wrap = selection.append('div')
.attr('class', 'inspector-hidden inspector-wrap fr');
context.on('hover.sidebar', function(entity) {
if (context.selection().length === 1) return;
- if (entity) {
+ if (!current && entity) {
wrap.classed('inspector-hidden', false)
.classed('inspector-hover', true)
.call(iD.ui.Inspector(context)
@@ -18,7 +20,7 @@ iD.ui.Sidebar = function(context) {
});
context.on('select.sidebar', function(selection) {
- if (selection.length === 1) {
+ if (!current && selection.length === 1) {
wrap.classed('inspector-hidden', false)
.classed('inspector-hover', false)
.call(iD.ui.Inspector(context)
@@ -27,6 +29,20 @@ iD.ui.Sidebar = function(context) {
} else {
wrap.classed('inspector-hidden', true);
}
- })
+ });
+
+ sidebar.show = function(component) {
+ wrap.classed('inspector-hidden', true);
+ current = selection.append('div')
+ .attr('class', 'sidebar-component')
+ .call(component);
+ };
+
+ sidebar.hide = function() {
+ current.remove();
+ current = null;
+ };
}
+
+ return sidebar;
};
diff --git a/js/id/ui/success.js b/js/id/ui/success.js
index 4d5cd721b..5e5c02e4e 100644
--- a/js/id/ui/success.js
+++ b/js/id/ui/success.js
@@ -1,23 +1,25 @@
iD.ui.Success = function(context) {
- var event = d3.dispatch('cancel', 'save');
+ var event = d3.dispatch('cancel'),
+ changeset;
function success(selection) {
- var changeset = selection.datum(),
- header = selection.append('div').attr('class', 'header modal-section'),
- body = selection.append('div').attr('class', 'body');
+ var message = (changeset.comment || t('success.edited_osm')).substring(0, 130) +
+ ' ' + context.connection().changesetURL(changeset.id);
- header.append('h3').text(t('just_edited'));
+ var header = selection.append('div')
+ .attr('class', 'header');
- var m = changeset.comment ?
- changeset.comment.substring(0, 130) : '';
+ header.append('h3')
+ .text(t('just_edited'));
- var message = (m || t('success.edited_osm')) + ' ' +
- context.connection().changesetURL(changeset.id);
+ var body = selection.append('div')
+ .attr('class', 'body');
- var links = body.append('div').attr('class','modal-actions cf');
+ var links = body.append('div')
+ .attr('class', 'modal-actions cf');
links.append('a')
- .attr('class','col4 osm')
+ .attr('class', 'col4 osm')
.attr('target', '_blank')
.attr('href', function() {
return context.connection().changesetURL(changeset.id);
@@ -25,7 +27,7 @@ iD.ui.Success = function(context) {
.text(t('view_on_osm'));
links.append('a')
- .attr('class','col4 twitter')
+ .attr('class', 'col4 twitter')
.attr('target', '_blank')
.attr('href', function() {
return 'https://twitter.com/intent/tweet?source=webclient&text=' +
@@ -34,23 +36,29 @@ iD.ui.Success = function(context) {
.text(t('success.tweet'));
links.append('a')
- .attr('class','col4 facebook')
+ .attr('class', 'col4 facebook')
.attr('target', '_blank')
.attr('href', function() {
- return 'https://facebook.com/sharer/sharer.php?u=' + encodeURIComponent(message);
+ return 'https://facebook.com/sharer/sharer.php?u=' +
+ encodeURIComponent(message);
})
.text(t('success.facebook'));
- var section = body.append('div').attr('class','modal-section cf');
+ var section = body.append('div')
+ .attr('class', 'modal-section cf');
section.append('button')
.attr('class', 'action col2')
- .on('click.save', function() {
- event.cancel();
- })
+ .on('click', event.cancel)
.text(t('success.okay'))
.node().focus();
}
+ success.changeset = function(_) {
+ if (!arguments.length) return changeset;
+ changeset = _;
+ return success;
+ };
+
return d3.rebind(success, event, 'on');
};
diff --git a/test/index.html b/test/index.html
index ebca79ffd..15529d330 100644
--- a/test/index.html
+++ b/test/index.html
@@ -93,6 +93,7 @@
+