1/* 2 * Copyright (C) 2008 Nokia Inc. All rights reserved. 3 * Copyright (C) 2013 Samsung Electronics. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27/** 28 * @constructor 29 * @extends {WebInspector.View} 30 */ 31WebInspector.DOMStorageItemsView = function(domStorage, domStorageModel) 32{ 33 WebInspector.View.call(this); 34 35 this.domStorage = domStorage; 36 this.domStorageModel = domStorageModel; 37 38 this.element.addStyleClass("storage-view"); 39 this.element.addStyleClass("table"); 40 41 this.deleteButton = new WebInspector.StatusBarButton(WebInspector.UIString("Delete"), "delete-storage-status-bar-item"); 42 this.deleteButton.visible = false; 43 this.deleteButton.addEventListener("click", this._deleteButtonClicked, this); 44 45 this.refreshButton = new WebInspector.StatusBarButton(WebInspector.UIString("Refresh"), "refresh-storage-status-bar-item"); 46 this.refreshButton.addEventListener("click", this._refreshButtonClicked, this); 47 48 this.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageItemsCleared, this._domStorageItemsCleared, this); 49 this.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageItemRemoved, this._domStorageItemRemoved, this); 50 this.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageItemAdded, this._domStorageItemAdded, this); 51 this.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageItemUpdated, this._domStorageItemUpdated, this); 52} 53 54WebInspector.DOMStorageItemsView.prototype = { 55 statusBarItems: function() 56 { 57 return [this.refreshButton.element, this.deleteButton.element]; 58 }, 59 60 wasShown: function() 61 { 62 this._update(); 63 }, 64 65 willHide: function() 66 { 67 this.deleteButton.visible = false; 68 }, 69 70 /** 71 * @param {WebInspector.Event} event 72 */ 73 _domStorageItemsCleared: function(event) 74 { 75 if (!this.isShowing()) 76 return; 77 78 this._dataGrid.rootNode().removeChildren(); 79 this._dataGrid.addCreationNode(false); 80 this.deleteButton.visible = false; 81 event.consume(true); 82 }, 83 84 /** 85 * @param {WebInspector.Event} event 86 */ 87 _domStorageItemRemoved: function(event) 88 { 89 if (!this.isShowing()) 90 return; 91 92 var storageData = event.data; 93 var rootNode = this._dataGrid.rootNode(); 94 var children = rootNode.children; 95 96 event.consume(true); 97 98 for (var i = 0; i < children.length; ++i) { 99 var childNode = children[i]; 100 if (childNode.data.key === storageData.key) { 101 rootNode.removeChild(childNode); 102 this.deleteButton.visible = (children.length > 1); 103 return; 104 } 105 } 106 }, 107 108 /** 109 * @param {WebInspector.Event} event 110 */ 111 _domStorageItemAdded: function(event) 112 { 113 if (!this.isShowing()) 114 return; 115 116 var storageData = event.data; 117 var rootNode = this._dataGrid.rootNode(); 118 var children = rootNode.children; 119 120 event.consume(true); 121 this.deleteButton.visible = true; 122 123 for (var i = 0; i < children.length; ++i) 124 if (children[i].data.key === storageData.key) 125 return; 126 127 var childNode = new WebInspector.DataGridNode({key: storageData.key, value: storageData.newValue}, false); 128 rootNode.insertChild(childNode, children.length - 1); 129 }, 130 131 /** 132 * @param {WebInspector.Event} event 133 */ 134 _domStorageItemUpdated: function(event) 135 { 136 if (!this.isShowing()) 137 return; 138 139 var storageData = event.data; 140 var rootNode = this._dataGrid.rootNode(); 141 var children = rootNode.children; 142 143 event.consume(true); 144 145 var keyFound = false; 146 for (var i = 0; i < children.length; ++i) { 147 var childNode = children[i]; 148 if (childNode.data.key === storageData.key) { 149 if (keyFound) { 150 rootNode.removeChild(childNode); 151 return; 152 } 153 keyFound = true; 154 if (childNode.data.value !== storageData.newValue) { 155 childNode.data.value = storageData.newValue; 156 childNode.refresh(); 157 childNode.select(); 158 childNode.reveal(); 159 } 160 this.deleteButton.visible = true; 161 } 162 } 163 }, 164 165 _update: function() 166 { 167 this.detachChildViews(); 168 this.domStorage.getItems(this._showDOMStorageItems.bind(this)); 169 }, 170 171 _showDOMStorageItems: function(error, items) 172 { 173 if (error) 174 return; 175 176 this._dataGrid = this._dataGridForDOMStorageItems(items); 177 this._dataGrid.show(this.element); 178 this._dataGrid.autoSizeColumns(10); 179 this.deleteButton.visible = (this._dataGrid.rootNode().children.length > 1); 180 }, 181 182 _dataGridForDOMStorageItems: function(items) 183 { 184 var columns = [ 185 {id: "key", title: WebInspector.UIString("Key"), editable: true}, 186 {id: "value", title: WebInspector.UIString("Value"), editable: true} 187 ]; 188 189 var nodes = []; 190 191 var keys = []; 192 var length = items.length; 193 for (var i = 0; i < items.length; i++) { 194 var key = items[i][0]; 195 var value = items[i][1]; 196 var node = new WebInspector.DataGridNode({key: key, value: value}, false); 197 node.selectable = true; 198 nodes.push(node); 199 keys.push(key); 200 } 201 202 var dataGrid = new WebInspector.DataGrid(columns, this._editingCallback.bind(this), this._deleteCallback.bind(this)); 203 length = nodes.length; 204 for (var i = 0; i < length; ++i) 205 dataGrid.rootNode().appendChild(nodes[i]); 206 dataGrid.addCreationNode(false); 207 if (length > 0) 208 nodes[0].selected = true; 209 return dataGrid; 210 }, 211 212 _deleteButtonClicked: function(event) 213 { 214 if (!this._dataGrid || !this._dataGrid.selectedNode) 215 return; 216 217 this._deleteCallback(this._dataGrid.selectedNode); 218 this._dataGrid.changeNodeAfterDeletion(); 219 }, 220 221 _refreshButtonClicked: function(event) 222 { 223 this._update(); 224 }, 225 226 _editingCallback: function(editingNode, columnIdentifier, oldText, newText) 227 { 228 var domStorage = this.domStorage; 229 if ("key" === columnIdentifier) { 230 if (oldText) 231 domStorage.removeItem(oldText); 232 domStorage.setItem(newText, editingNode.data.value); 233 this._removeDupes(editingNode); 234 } else 235 domStorage.setItem(editingNode.data.key, newText); 236 }, 237 238 /** 239 * @param {!WebInspector.DataGridNode} masterNode 240 */ 241 _removeDupes: function(masterNode) 242 { 243 var rootNode = this._dataGrid.rootNode(); 244 var children = rootNode.children; 245 for (var i = children.length - 1; i >= 0; --i) { 246 var childNode = children[i]; 247 if ((childNode.data.key === masterNode.data.key) && (masterNode !== childNode)) 248 rootNode.removeChild(childNode); 249 } 250 }, 251 252 _deleteCallback: function(node) 253 { 254 if (!node || node.isCreationNode) 255 return; 256 257 if (this.domStorage) 258 this.domStorage.removeItem(node.data.key); 259 }, 260 261 __proto__: WebInspector.View.prototype 262} 263