diff --git a/css/app.css b/css/app.css
index 65c2fc5bd..27ca56b71 100644
--- a/css/app.css
+++ b/css/app.css
@@ -293,6 +293,10 @@ button.save {
background-color: #6bc641;
}
+button.save[disabled] {
+ background-color: #92BB7F;
+}
+
button.save:hover {
background-color: #59ac33;
}
diff --git a/js/id/id.js b/js/id/id.js
index 005e508f4..413b45e72 100644
--- a/js/id/id.js
+++ b/js/id/id.js
@@ -107,10 +107,11 @@ window.iD = function(container) {
.append('div')
.attr('class', 'hello');
- bar.append('button')
+ 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() {
@@ -157,6 +158,17 @@ window.iD = function(container) {
}
});
+ 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.select('span.count').text(num_changes === 0 ? '' : num_changes);
+ });
+
bar.append('div')
.attr('class', 'messages');
diff --git a/js/id/oauth.js b/js/id/oauth.js
index 5e29517e0..c310004e5 100644
--- a/js/id/oauth.js
+++ b/js/id/oauth.js
@@ -66,6 +66,10 @@ iD.OAuth = function() {
var l = iD.loading('contacting openstreetmap...');
+ // it would make more sense to have this code within the callback
+ // to oauth.xhr below. however, it needs to be directly within a
+ // browser event handler in order to open a popup without it being
+ // blocked.
var w = 600, h = 550,
settings = [
['width', w], ['height', h],