From 2b4e260953a3e71025296f14e3e5f8ba6bbd0ac9 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Wed, 27 Mar 2013 11:52:50 -0400 Subject: [PATCH] walkthrough now runnable in the middle of editing history.toJSON and .fromJSON are now split out of. history.save and .restore. --- data/core.yaml | 2 +- js/id/connection.js | 6 +++ js/id/core/history.js | 81 +++++++++++++++++++++------------------ js/id/ui/help.js | 8 ++++ js/id/ui/intro.js | 19 ++++++--- js/id/ui/restore.js | 2 +- test/spec/core/history.js | 12 +++--- 7 files changed, 79 insertions(+), 51 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index 953642857..8271b9bcf 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -151,7 +151,7 @@ en: reset: reset restore: heading: You have unsaved changes - description: "Do you wish to restore changes from a previous editing session?" + description: "Do you wish to restore unsaved changes from a previous editing session?" restore: Restore reset: Reset save: diff --git a/js/id/connection.js b/js/id/connection.js index de84601f0..8f690e127 100644 --- a/js/id/connection.js +++ b/js/id/connection.js @@ -316,6 +316,12 @@ iD.Connection = function(context) { return connection; }; + connection.loadedTiles = function(_) { + if (!arguments.length) return loadedTiles; + loadedTiles = _; + return connection; + }; + connection.logout = function() { oauth.logout(); event.auth(); diff --git a/js/id/core/history.js b/js/id/core/history.js index b95334eca..65078835c 100644 --- a/js/id/core/history.js +++ b/js/id/core/history.js @@ -183,34 +183,54 @@ iD.History = function(context) { index = 0; tree = iD.Tree(stack[0].graph); dispatch.change(); + return history; + }, + + toJSON: function() { + if (stack.length <= 1) return; + + var s = stack.map(function(i) { + var x = { entities: i.graph.entities }; + if (i.imagery_used) x.imagery_used = i.imagery_used; + if (i.annotation) x.annotation = i.annotation; + return x; + }); + + return JSON.stringify({ + stack: s, + nextIDs: iD.Entity.id.next, + index: index + }, function includeUndefined(key, value) { + if (typeof value === 'undefined') return 'undefined'; + return value; + }); + }, + + fromJSON: function(json) { + + var h = JSON.parse(json); + + iD.Entity.id.next = h.nextIDs; + index = h.index; + stack = h.stack.map(function(d) { + d.graph = iD.Graph(stack[0].graph).load(d.entities); + return d; + }); + stack[0].graph.inherited = false; + dispatch.change(); + + return history; }, save: function() { if (!lock) return; context.storage(getKey('lock'), null); - - if (stack.length <= 1) return; - - var json = JSON.stringify(stack.map(function(i) { - var x = { entities: i.graph.entities }; - if (i.imagery_used) x.imagery_used = i.imagery_used; - if (i.annotation) x.annotation = i.annotation; - return x; - }), function includeUndefined(key, value) { - if (typeof value === 'undefined') return 'undefined'; - return value; - }); - - context.storage(getKey('history'), json); - context.storage(getKey('nextIDs'), JSON.stringify(iD.Entity.id.next)); - context.storage(getKey('index'), index); + context.storage(getKey('saved_history'), this.toJSON() || null); }, clearSaved: function() { if (!lock) return; - context.storage(getKey('history'), null); - context.storage(getKey('nextIDs'), null); - context.storage(getKey('index'), null); + context.storage(getKey('saved_history'), null); }, lock: function() { @@ -223,31 +243,18 @@ iD.History = function(context) { // is iD not open in another window and it detects that // there's a history stored in localStorage that's recoverable? restorableChanges: function() { - return lock && !!context.storage(getKey('history')); + return lock && !!context.storage(getKey('saved_history')); }, // load history from a version stored in localStorage - load: function() { + restore: function() { if (!lock) return; - var json = context.storage(getKey('history')), - nextIDs = context.storage(getKey('nextIDs')), - index_ = context.storage(getKey('index')); + var json = context.storage(getKey('saved_history')); + if (json) this.fromJSON(json); - if (!json) return; - if (nextIDs) iD.Entity.id.next = JSON.parse(nextIDs); - if (index_ !== null) index = parseInt(index_, 10); + context.storage(getKey('saved_history', null)); - context.storage(getKey('history', null)); - context.storage(getKey('nextIDs', null)); - context.storage(getKey('index', null)); - - stack = JSON.parse(json).map(function(d) { - d.graph = iD.Graph(stack[0].graph).load(d.entities); - return d; - }); - stack[0].graph.inherited = false; - dispatch.change(); }, _getKey: getKey diff --git a/js/id/ui/help.js b/js/id/ui/help.js index 6a4c1af3f..e4b1ed1bc 100644 --- a/js/id/ui/help.js +++ b/js/id/ui/help.js @@ -32,6 +32,14 @@ iD.ui.Help = function(context) { .text(function(d) { return d.title; }) .on('click', clickHelp); + toc.append('li') + .append('a') + .text(t('splash.walkthrough')) + .on('click', function() { + d3.select(document.body).call(iD.ui.intro(context)); + setVisible(false); + }); + var content = pane.append('div') .attr('class', 'left-content'), doctitle = content.append('h2') diff --git a/js/id/ui/intro.js b/js/id/ui/intro.js index e0293fe53..159d8ca02 100644 --- a/js/id/ui/intro.js +++ b/js/id/ui/intro.js @@ -4,8 +4,14 @@ iD.ui.intro = function(context) { function intro(selection) { - var originalCenter = context.map().center(), - originalZoom = context.map().zoom(); + context.enter(iD.modes.Browse(context)); + + // Save current map state + var history = context.history().toJSON(), + hash = window.location.hash, + opacity = d3.select('.layer-layer:first-child').style('opacity'), + loadedTiles = context.connection().loadedTiles(), + baseEntities = context.history().graph().base().entities; // Load semi-real data used in intro context.connection().toggle(false).flush(); @@ -33,10 +39,11 @@ iD.ui.intro = function(context) { enter: function() { curtain.remove(); navwrap.remove(); - d3.select('.layer-layer:first-child').style('opacity', 0.5); - context.connection().toggle(true).flush(); - context.history().reset(); - context.map().centerZoom(originalCenter, originalZoom); + d3.select('.layer-layer:first-child').style('opacity', opacity); + context.connection().toggle(false).flush().loadedTiles(loadedTiles); + context.history().reset().merge(baseEntities); + if (history) context.history().fromJSON(history); + window.location.replace(hash); } }); diff --git a/js/id/ui/restore.js b/js/id/ui/restore.js index d8f052cbe..9f66fbea7 100644 --- a/js/id/ui/restore.js +++ b/js/id/ui/restore.js @@ -29,7 +29,7 @@ iD.ui.Restore = function(context) { .attr('class', 'restore col6') .text(t('restore.restore')) .on('click', function() { - context.history().load(); + context.history().restore(); modal.remove(); }); diff --git a/test/spec/core/history.js b/test/spec/core/history.js index 0618f3ec3..699e244f8 100644 --- a/test/spec/core/history.js +++ b/test/spec/core/history.js @@ -260,7 +260,7 @@ describe("iD.History", function () { describe("#save", function() { it("doesn't do anything if it doesn't have the lock", function() { - var key = history._getKey('history'); + var key = history._getKey('saved_history'); context.storage(key, null); history.save(); expect(context.storage(key)).to.be.undefined; @@ -275,13 +275,13 @@ describe("iD.History", function () { history.lock(); history.perform(iD.actions.AddEntity(node)); history.save(); - var saved = JSON.parse(context.storage(history._getKey('history'))); - expect(saved[1].entities.n.id).to.eql('n'); + var saved = JSON.parse(context.storage(history._getKey('saved_history'))); + expect(saved.stack[1].entities.n.id).to.eql('n'); }); }); - describe("#load", function() { - it("saves and loads a created and deleted entities", function() { + describe("#restore", function() { + it("saves and restores a created and deleted entities", function() { var node = iD.Node({ id: 'n' }), node2 = iD.Node({ id: 'n2' }); history.lock(); @@ -291,7 +291,7 @@ describe("iD.History", function () { history.save(); history.reset(); expect(history.graph().entity('n')).to.be.undefined - history.load(); + history.restore(); expect(history.graph().entity('n').id).to.equal('n'); expect(history.graph().entity('n2')).to.be.undefined; });