 Chromium Code Reviews
 Chromium Code Reviews Issue 21163003:
  DevTools: Implement undo, redo operations for the DOMStorage views.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/blink.git@master
    
  
    Issue 21163003:
  DevTools: Implement undo, redo operations for the DOMStorage views.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/blink.git@master| Index: Source/devtools/front_end/DOMStorage.js | 
| diff --git a/Source/devtools/front_end/DOMStorage.js b/Source/devtools/front_end/DOMStorage.js | 
| index 29094228273d83c168b18a6df240f0f1a201471c..662672b2ff9ff5a9fdfdb3cae8093b047c7687b3 100644 | 
| --- a/Source/devtools/front_end/DOMStorage.js | 
| +++ b/Source/devtools/front_end/DOMStorage.js | 
| @@ -36,6 +36,7 @@ WebInspector.DOMStorage = function(securityOrigin, isLocalStorage) | 
| { | 
| this._securityOrigin = securityOrigin; | 
| this._isLocalStorage = isLocalStorage; | 
| + this._storageHistory = new WebInspector.DOMStorageHistory(this); | 
| } | 
| /** | 
| @@ -82,7 +83,7 @@ WebInspector.DOMStorage.prototype = { | 
| */ | 
| setItem: function(key, value) | 
| { | 
| - DOMStorageAgent.setDOMStorageItem(this.id, key, value); | 
| + this._storageHistory.perform(new WebInspector.DOMStorageSetItemAction(this, key, value)); | 
| }, | 
| /** | 
| @@ -90,7 +91,219 @@ WebInspector.DOMStorage.prototype = { | 
| */ | 
| removeItem: function(key) | 
| { | 
| - DOMStorageAgent.removeDOMStorageItem(this.id, key); | 
| + this._storageHistory.perform(new WebInspector.DOMStorageRemoveItemAction(this, key)); | 
| + }, | 
| + | 
| + undo: function() | 
| + { | 
| + this._storageHistory.undo(); | 
| + }, | 
| + | 
| + redo: function() | 
| + { | 
| + this._storageHistory.redo(); | 
| + } | 
| +} | 
| + | 
| +/** | 
| + * @constructor | 
| + * @param {WebInspector.DOMStorage} domStorage | 
| + */ | 
| +WebInspector.DOMStorageAction = function(domStorage) | 
| +{ | 
| + this._domStorage = domStorage; | 
| +} | 
| + | 
| +WebInspector.DOMStorageAction.prototype = { | 
| + /** | 
| + * @param {function()} callback | 
| + */ | 
| + perform: function(callback) | 
| + { | 
| + }, | 
| + | 
| + undo: function() | 
| + { | 
| + }, | 
| + | 
| + redo: function() | 
| + { | 
| + } | 
| +} | 
| + | 
| +/** | 
| + * @constructor | 
| + * @extends {WebInspector.DOMStorageAction} | 
| + * @param {WebInspector.DOMStorage} domStorage | 
| + * @param {string} key | 
| + */ | 
| +WebInspector.DOMStorageRemoveItemAction = function(domStorage, key) | 
| +{ | 
| + WebInspector.DOMStorageAction.call(this, domStorage); | 
| + this._key = key; | 
| +} | 
| + | 
| +WebInspector.DOMStorageRemoveItemAction.prototype = { | 
| + /** | 
| + * @override | 
| + */ | 
| + perform: function(callback) | 
| + { | 
| + DOMStorageAgent.getDOMStorageItemValue(this._domStorage.id, this._key, valueReceived.bind(this)); | 
| + | 
| + /** | 
| + * @param {?Protocol.Error} error | 
| + * @param {string=} value | 
| + */ | 
| + function valueReceived(error, value) | 
| + { | 
| + this._value = value; | 
| + this.redo(); | 
| + callback(); | 
| + } | 
| + }, | 
| + | 
| + /** | 
| + * @override | 
| + */ | 
| + undo: function() | 
| + { | 
| + DOMStorageAgent.setDOMStorageItem(this._domStorage.id, this._key, this._value); | 
| + }, | 
| + | 
| + /** | 
| + * @override | 
| + */ | 
| + redo: function() | 
| + { | 
| + DOMStorageAgent.removeDOMStorageItem(this._domStorage.id, this._key); | 
| + }, | 
| + | 
| + __proto__: WebInspector.DOMStorageAction.prototype | 
| +} | 
| + | 
| +/** | 
| + * @constructor | 
| + * @extends {WebInspector.DOMStorageAction} | 
| + * @param {WebInspector.DOMStorage} domStorage | 
| + * @param {string} key | 
| + * @param {string} value | 
| + */ | 
| +WebInspector.DOMStorageSetItemAction = function(domStorage, key, value) | 
| +{ | 
| + WebInspector.DOMStorageAction.call(this, domStorage); | 
| + this._key = key; | 
| + this._value = value; | 
| +} | 
| + | 
| +WebInspector.DOMStorageSetItemAction.prototype = { | 
| + /** | 
| + * @override | 
| + */ | 
| + perform: function(callback) | 
| + { | 
| + DOMStorageAgent.getDOMStorageItemValue(this._domStorage.id, this._key, valueReceived.bind(this)); | 
| + | 
| + /** | 
| + * @param {?Protocol.Error} error | 
| + * @param {string=} value | 
| + */ | 
| + function valueReceived(error, value) | 
| + { | 
| + if (error) | 
| + return; | 
| + | 
| + if (typeof value === "undefined") | 
| + delete this._exists; | 
| + else { | 
| + this._exists = true; | 
| + this._oldValue = value; | 
| + } | 
| + this.redo(); | 
| + callback(); | 
| + } | 
| + }, | 
| + | 
| + /** | 
| + * @override | 
| + */ | 
| + undo: function() | 
| + { | 
| + if (!this._exists) | 
| + DOMStorageAgent.removeDOMStorageItem(this._domStorage.id, this._key); | 
| + else | 
| + DOMStorageAgent.setDOMStorageItem(this._domStorage.id, this._key, this._oldValue); | 
| + }, | 
| + | 
| + /** | 
| + * @override | 
| + */ | 
| + redo: function() | 
| + { | 
| + DOMStorageAgent.setDOMStorageItem(this._domStorage.id, this._key, this._value); | 
| + }, | 
| + | 
| + __proto__: WebInspector.DOMStorageAction.prototype | 
| +} | 
| + | 
| +/** | 
| + * @constructor | 
| + * @param {WebInspector.DOMStorage} domStorage | 
| + */ | 
| +WebInspector.DOMStorageHistory = function(domStorage) | 
| +{ | 
| + this._domStorage = domStorage; | 
| + | 
| + /** @type {!Array.<!WebInspector.DOMStorageAction>} */ | 
| + this._actions = []; | 
| + this._currentActionIndex = -1; | 
| +} | 
| + | 
| +WebInspector.DOMStorageHistory.MAX_UNDO_REDO_DEPTH = 20; | 
| 
apavlov
2013/08/05 09:07:15
MAX_UNDO_STACK_DEPTH (since the thing is called "u
 
vivekg_samsung
2013/08/05 09:39:49
Done.
 | 
| + | 
| +WebInspector.DOMStorageHistory.prototype = { | 
| + /** | 
| + * @param {WebInspector.DOMStorageAction} action | 
| + */ | 
| + perform: function(action) | 
| + { | 
| + if (!action) | 
| + return; | 
| + | 
| + action.perform(actionCompleted.bind(this)); | 
| + function actionCompleted() | 
| + { | 
| + if (this._currentActionIndex + 1 === WebInspector.DOMStorageHistory.MAX_UNDO_REDO_DEPTH) { | 
| + this._actions.shift(); | 
| + this._currentActionIndex--; | 
| 
apavlov
2013/08/05 09:07:15
We always use the prefix form: ++this._currentActi
 
apavlov
2013/08/05 09:11:04
Sorry, looked at the wrong place. Of course, it sh
 
vivekg_samsung
2013/08/05 09:39:49
Done.
 | 
| + } | 
| + | 
| + if (this._currentActionIndex + 1 < this._actions.length) | 
| 
apavlov
2013/08/05 09:11:04
this can become an "else if", I guess...
 
vivekg_samsung
2013/08/05 09:39:49
Done.
 | 
| + this._actions.splice(this._currentActionIndex + 1); | 
| + this._actions.push(action); | 
| + ++this._currentActionIndex; | 
| + } | 
| + }, | 
| + | 
| + undo: function() | 
| + { | 
| + if (this._currentActionIndex < 0) | 
| + return; | 
| + | 
| + var action = this._actions[this._currentActionIndex]; | 
| + console.assert(action); | 
| + action.undo(); | 
| + --this._currentActionIndex; | 
| + }, | 
| + | 
| + redo: function() | 
| + { | 
| + if (this._currentActionIndex >= this._actions.length - 1) | 
| + return; | 
| + | 
| + var action = this._actions[++this._currentActionIndex]; | 
| + console.assert(action); | 
| + action.redo(); | 
| } | 
| } |