diff --git a/index.html b/index.html
index 62eb33d30..5286c84b0 100644
--- a/index.html
+++ b/index.html
@@ -50,6 +50,7 @@
+
diff --git a/js/id/id.js b/js/id/id.js
index 46d6acbd6..7c3e91129 100644
--- a/js/id/id.js
+++ b/js/id/id.js
@@ -96,82 +96,7 @@ window.iD = function(container) {
var save_button = bar.append('button')
.attr('class', 'save action wide')
- .html("Save")
- .attr('title', 'Save changes to OpenStreetMap, making them visible to other users')
- .property('disabled', true)
- .call(bootstrap.tooltip()
- .placement('bottom'))
- .on('click', function() {
- function save(e) {
- d3.select('.shaded').remove();
- var l = iD.loading('Uploading changes to OpenStreetMap.');
- connection.putChangeset(history.changes(), e.comment, history.imagery_used(), function(err, changeset_id) {
- l.remove();
- history.reset();
- map.flush().redraw();
- if (err) {
- var desc = iD.confirm()
- .select('.description');
- desc.append('h2')
- .text('An error occurred while trying to save');
- desc.append('p').text(err.responseText);
- } else {
- var modal = iD.modal();
- modal.select('.content')
- .classed('success-modal', true)
- .datum({
- id: changeset_id,
- comment: e.comment
- })
- .call(iD.success()
- .on('cancel', function() {
- modal.remove();
- }));
- }
- });
- }
- var changes = history.changes();
- var has_changes = d3.sum(d3.values(changes).map(function(c) {
- return c.length;
- })) > 0;
-
- if (has_changes) {
- connection.authenticate(function(err) {
- var modal = iD.modal();
- var changes = history.changes();
- changes.connection = connection;
- modal.select('.content')
- .classed('commit-modal', true)
- .datum(changes)
- .call(iD.commit()
- .on('cancel', function() {
- modal.remove();
- })
- .on('save', save));
- });
- } else {
- iD.confirm().select('.description')
- .append('h3').text('You don\'t have any changes to save.');
- }
- });
-
- save_button.append('span')
- .attr('class', 'count');
-
- history.on('change.save-button', function() {
- var changes = history.changes(),
- num_changes = d3.sum(d3.values(changes).map(function(c) {
- return c.length;
- }));
-
- save_button.property('disabled', num_changes === 0);
-
- save_button
- .classed('has-count', num_changes > 0);
-
- save_button.select('span.count')
- .text(num_changes);
- });
+ .call(iD.save().map(map));
history.on('change.warn-unload', function() {
var changes = history.changes(),
diff --git a/js/id/ui/save.js b/js/id/ui/save.js
new file mode 100644
index 000000000..4e49f26de
--- /dev/null
+++ b/js/id/ui/save.js
@@ -0,0 +1,95 @@
+iD.save = function() {
+
+ var map;
+
+ function save(selection) {
+
+ var history = map.history(),
+ connection = map.connection();
+
+ selection.html("Save")
+ .attr('title', 'Save changes to OpenStreetMap, making them visible to other users')
+ .property('disabled', true)
+ .call(bootstrap.tooltip()
+ .placement('bottom'))
+ .on('click', function() {
+
+ function commit(e) {
+ d3.select('.shaded').remove();
+ var l = iD.loading('Uploading changes to OpenStreetMap.');
+ connection.putChangeset(history.changes(), e.comment, history.imagery_used(), function(err, changeset_id) {
+ l.remove();
+ history.reset();
+ map.flush().redraw();
+ if (err) {
+ var desc = iD.confirm()
+ .select('.description');
+ desc.append('h2')
+ .text('An error occurred while trying to save');
+ desc.append('p').text(err.responseText);
+ } else {
+ var modal = iD.modal();
+ modal.select('.content')
+ .classed('success-modal', true)
+ .datum({
+ id: changeset_id,
+ comment: e.comment
+ })
+ .call(iD.success()
+ .on('cancel', function() {
+ modal.remove();
+ }));
+ }
+ });
+ }
+ var changes = history.changes();
+ var has_changes = d3.sum(d3.values(changes).map(function(c) {
+ return c.length;
+ })) > 0;
+
+ if (has_changes) {
+ connection.authenticate(function(err) {
+ var modal = iD.modal();
+ var changes = history.changes();
+ changes.connection = connection;
+ modal.select('.content')
+ .classed('commit-modal', true)
+ .datum(changes)
+ .call(iD.commit()
+ .on('cancel', function() {
+ modal.remove();
+ })
+ .on('save', commit));
+ });
+ } else {
+ iD.confirm().select('.description')
+ .append('h3').text('You don\'t have any changes to save.');
+ }
+ });
+
+ selection.append('span')
+ .attr('class', 'count');
+
+ history.on('change.save-button', function() {
+ var changes = history.changes(),
+ num_changes = d3.sum(d3.values(changes).map(function(c) {
+ return c.length;
+ }));
+
+ selection
+ .property('disabled', num_changes === 0)
+ .classed('has-count', num_changes > 0)
+ .select('span.count')
+ .text(num_changes);
+ });
+
+ }
+
+ save.map = function(_) {
+ if (!arguments.length) return map;
+ map = _;
+ return save;
+ };
+
+ return save;
+};