2 * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Joseph Pecoraro
4 * Copyright (C) 2013 Samsung Electronics. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 importScript("ApplicationCacheItemsView.js");
32 importScript("DOMStorageItemsView.js");
33 importScript("DatabaseQueryView.js");
34 importScript("DatabaseTableView.js");
35 importScript("DirectoryContentView.js");
36 importScript("IndexedDBViews.js");
37 importScript("FileContentView.js");
38 importScript("FileSystemView.js");
42 * @extends {WebInspector.Panel}
44 WebInspector.ResourcesPanel = function(database)
46 WebInspector.Panel.call(this, "resources");
47 this.registerRequiredCSS("resourcesPanel.css");
49 WebInspector.settings.resourcesLastSelectedItem = WebInspector.settings.createSetting("resourcesLastSelectedItem", {});
51 this.createSidebarViewWithTree();
52 this.splitView.sidebarElement().classList.add("outline-disclosure", "filter-all", "children", "small");
54 this.sidebarTreeElement.classList.remove("sidebar-tree");
56 this.resourcesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Frames"), "Frames", ["frame-storage-tree-item"]);
57 this.sidebarTree.appendChild(this.resourcesListTreeElement);
59 this.databasesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Web SQL"), "Databases", ["database-storage-tree-item"]);
60 this.sidebarTree.appendChild(this.databasesListTreeElement);
62 this.indexedDBListTreeElement = new WebInspector.IndexedDBTreeElement(this);
63 this.sidebarTree.appendChild(this.indexedDBListTreeElement);
65 this.localStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Local Storage"), "LocalStorage", ["domstorage-storage-tree-item", "local-storage"]);
66 this.sidebarTree.appendChild(this.localStorageListTreeElement);
68 this.sessionStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Session Storage"), "SessionStorage", ["domstorage-storage-tree-item", "session-storage"]);
69 this.sidebarTree.appendChild(this.sessionStorageListTreeElement);
71 this.cookieListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Cookies"), "Cookies", ["cookie-storage-tree-item"]);
72 this.sidebarTree.appendChild(this.cookieListTreeElement);
74 this.applicationCacheListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Application Cache"), "ApplicationCache", ["application-cache-storage-tree-item"]);
75 this.sidebarTree.appendChild(this.applicationCacheListTreeElement);
77 if (WebInspector.experimentsSettings.fileSystemInspection.isEnabled()) {
78 this.fileSystemListTreeElement = new WebInspector.FileSystemListTreeElement(this);
79 this.sidebarTree.appendChild(this.fileSystemListTreeElement);
82 var mainElement = this.splitView.mainElement();
83 this.storageViews = mainElement.createChild("div", "resources-main");
84 var statusBarContainer = mainElement.createChild("div", "resources-status-bar");
85 this.storageViewStatusBarItemsContainer = statusBarContainer.createChild("div", "status-bar");
86 this.storageViews.classList.add("diff-container");
88 /** @type {!Map.<!WebInspector.Database, !Object.<string, !WebInspector.DatabaseTableView>>} */
89 this._databaseTableViews = new Map();
90 /** @type {!Map.<!WebInspector.Database, !WebInspector.DatabaseQueryView>} */
91 this._databaseQueryViews = new Map();
92 /** @type {!Map.<!WebInspector.Database, !WebInspector.DatabaseTreeElement>} */
93 this._databaseTreeElements = new Map();
94 /** @type {!Map.<!WebInspector.DOMStorage, !WebInspector.DOMStorageItemsView>} */
95 this._domStorageViews = new Map();
96 /** @type {!Map.<!WebInspector.DOMStorage, !WebInspector.DOMStorageTreeElement>} */
97 this._domStorageTreeElements = new Map();
98 /** @type {!Object.<string, !WebInspector.CookieItemsView>} */
99 this._cookieViews = {};
100 /** @type {!Object.<string, boolean>} */
103 this.splitView.sidebarElement().addEventListener("mousemove", this._onmousemove.bind(this), false);
104 this.splitView.sidebarElement().addEventListener("mouseout", this._onmouseout.bind(this), false);
107 * @return {!WebInspector.View}
108 * @this {WebInspector.ResourcesPanel}
110 function viewGetter()
112 return this.visibleView;
114 WebInspector.GoToLineDialog.install(this, viewGetter.bind(this));
116 if (WebInspector.resourceTreeModel.cachedResourcesLoaded())
117 this._cachedResourcesLoaded();
119 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
120 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._cachedResourcesLoaded, this);
121 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources, this._resetWithFrames, this);
123 WebInspector.databaseModel.databases().forEach(this._addDatabase.bind(this));
124 WebInspector.databaseModel.addEventListener(WebInspector.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this);
127 WebInspector.ResourcesPanel.prototype = {
131 canSearch: function()
138 WebInspector.Panel.prototype.wasShown.call(this);
142 _initialize: function()
144 if (!this._initialized && this.isShowing() && this._cachedResourcesWereLoaded) {
145 this._populateResourceTree();
146 this._populateDOMStorageTree();
147 this._populateApplicationCacheTree();
148 this.indexedDBListTreeElement._initialize();
149 if (WebInspector.experimentsSettings.fileSystemInspection.isEnabled())
150 this.fileSystemListTreeElement._initialize();
151 this._initDefaultSelection();
152 this._initialized = true;
156 _loadEventFired: function()
158 this._initDefaultSelection();
161 _initDefaultSelection: function()
163 if (!this._initialized)
166 var itemURL = WebInspector.settings.resourcesLastSelectedItem.get();
168 for (var treeElement = this.sidebarTree.children[0]; treeElement; treeElement = treeElement.traverseNextTreeElement(false, this.sidebarTree, true)) {
169 if (treeElement.itemURL === itemURL) {
170 treeElement.revealAndSelect(true);
176 var mainResource = WebInspector.inspectedPageURL && this.resourcesListTreeElement && this.resourcesListTreeElement.expanded && WebInspector.resourceTreeModel.resourceForURL(WebInspector.inspectedPageURL);
178 this.showResource(mainResource);
181 _resetWithFrames: function()
183 this.resourcesListTreeElement.removeChildren();
184 this._treeElementForFrameId = {};
191 var queryViews = this._databaseQueryViews.values();
192 for (var i = 0; i < queryViews.length; ++i)
193 queryViews[i].removeEventListener(WebInspector.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this);
194 this._databaseTableViews.clear();
195 this._databaseQueryViews.clear();
196 this._databaseTreeElements.clear();
197 this._domStorageViews.clear();
198 this._domStorageTreeElements.clear();
199 this._cookieViews = {};
201 this.databasesListTreeElement.removeChildren();
202 this.localStorageListTreeElement.removeChildren();
203 this.sessionStorageListTreeElement.removeChildren();
204 this.cookieListTreeElement.removeChildren();
206 if (this.visibleView && !(this.visibleView instanceof WebInspector.StorageCategoryView))
207 this.visibleView.detach();
209 this.storageViewStatusBarItemsContainer.removeChildren();
211 if (this.sidebarTree.selectedTreeElement)
212 this.sidebarTree.selectedTreeElement.deselect();
215 _populateResourceTree: function()
217 this._treeElementForFrameId = {};
218 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameAdded, this);
219 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
220 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
221 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
224 * @param {!WebInspector.ResourceTreeFrame} frame
225 * @this {WebInspector.ResourcesPanel}
227 function populateFrame(frame)
229 this._frameAdded({data:frame});
230 for (var i = 0; i < frame.childFrames.length; ++i)
231 populateFrame.call(this, frame.childFrames[i]);
233 var resources = frame.resources();
234 for (var i = 0; i < resources.length; ++i)
235 this._resourceAdded({data:resources[i]});
237 populateFrame.call(this, WebInspector.resourceTreeModel.mainFrame);
240 _frameAdded: function(event)
242 var frame = event.data;
243 var parentFrame = frame.parentFrame;
245 var parentTreeElement = parentFrame ? this._treeElementForFrameId[parentFrame.id] : this.resourcesListTreeElement;
246 if (!parentTreeElement) {
247 console.warn("No frame to route " + frame.url + " to.")
251 var frameTreeElement = new WebInspector.FrameTreeElement(this, frame);
252 this._treeElementForFrameId[frame.id] = frameTreeElement;
253 parentTreeElement.appendChild(frameTreeElement);
256 _frameDetached: function(event)
258 var frame = event.data;
259 var frameTreeElement = this._treeElementForFrameId[frame.id];
260 if (!frameTreeElement)
263 delete this._treeElementForFrameId[frame.id];
264 if (frameTreeElement.parent)
265 frameTreeElement.parent.removeChild(frameTreeElement);
268 _resourceAdded: function(event)
270 var resource = event.data;
271 var frameId = resource.frameId;
273 if (resource.statusCode >= 301 && resource.statusCode <= 303)
276 var frameTreeElement = this._treeElementForFrameId[frameId];
277 if (!frameTreeElement) {
278 // This is a frame's main resource, it will be retained
279 // and re-added by the resource manager;
283 frameTreeElement.appendResource(resource);
286 _frameNavigated: function(event)
288 var frame = event.data;
290 if (!frame.parentFrame)
293 var frameId = frame.id;
294 var frameTreeElement = this._treeElementForFrameId[frameId];
295 if (frameTreeElement)
296 frameTreeElement.frameNavigated(frame);
298 var applicationCacheFrameTreeElement = this._applicationCacheFrameElements[frameId];
299 if (applicationCacheFrameTreeElement)
300 applicationCacheFrameTreeElement.frameNavigated(frame);
303 _cachedResourcesLoaded: function()
305 this._cachedResourcesWereLoaded = true;
310 * @param {!WebInspector.Event} event
312 _databaseAdded: function(event)
314 var database = /** @type {!WebInspector.Database} */ (event.data);
315 this._addDatabase(database);
319 * @param {!WebInspector.Database} database
321 _addDatabase: function(database)
323 var databaseTreeElement = new WebInspector.DatabaseTreeElement(this, database);
324 this._databaseTreeElements.put(database, databaseTreeElement);
325 this.databasesListTreeElement.appendChild(databaseTreeElement);
328 addDocumentURL: function(url)
330 var parsedURL = url.asParsedURL();
334 var domain = parsedURL.host;
335 if (!this._domains[domain]) {
336 this._domains[domain] = true;
338 var cookieDomainTreeElement = new WebInspector.CookieTreeElement(this, domain);
339 this.cookieListTreeElement.appendChild(cookieDomainTreeElement);
344 * @param {!WebInspector.Event} event
346 _domStorageAdded: function(event)
348 var domStorage = /** @type {!WebInspector.DOMStorage} */ (event.data);
349 this._addDOMStorage(domStorage);
353 * @param {!WebInspector.DOMStorage} domStorage
355 _addDOMStorage: function(domStorage)
357 console.assert(!this._domStorageTreeElements.get(domStorage));
359 var domStorageTreeElement = new WebInspector.DOMStorageTreeElement(this, domStorage, (domStorage.isLocalStorage ? "local-storage" : "session-storage"));
360 this._domStorageTreeElements.put(domStorage, domStorageTreeElement);
361 if (domStorage.isLocalStorage)
362 this.localStorageListTreeElement.appendChild(domStorageTreeElement);
364 this.sessionStorageListTreeElement.appendChild(domStorageTreeElement);
368 * @param {!WebInspector.Event} event
370 _domStorageRemoved: function(event)
372 var domStorage = /** @type {!WebInspector.DOMStorage} */ (event.data);
373 this._removeDOMStorage(domStorage);
377 * @param {!WebInspector.DOMStorage} domStorage
379 _removeDOMStorage: function(domStorage)
381 var treeElement = this._domStorageTreeElements.get(domStorage);
384 var wasSelected = treeElement.selected;
385 var parentListTreeElement = treeElement.parent;
386 parentListTreeElement.removeChild(treeElement);
388 parentListTreeElement.select();
389 this._domStorageTreeElements.remove(treeElement);
390 this._domStorageViews.remove(domStorage);
394 * @param {!WebInspector.Database} database
396 selectDatabase: function(database)
399 this._showDatabase(database);
400 this._databaseTreeElements.get(database).select();
405 * @param {!WebInspector.DOMStorage} domStorage
407 selectDOMStorage: function(domStorage)
410 this._showDOMStorage(domStorage);
411 this._domStorageTreeElements.get(domStorage).select();
416 * @param {!Element} anchor
419 showAnchorLocation: function(anchor)
421 var resource = WebInspector.resourceForURL(anchor.href);
424 WebInspector.inspectorView.setCurrentPanel(this);
425 this.showResource(resource, anchor.lineNumber);
430 * @param {!WebInspector.Resource} resource
431 * @param {number=} line
432 * @param {number=} column
435 showResource: function(resource, line, column)
437 var resourceTreeElement = this._findTreeElementForResource(resource);
438 if (resourceTreeElement)
439 resourceTreeElement.revealAndSelect(true);
441 if (typeof line === "number") {
442 var view = this._resourceViewForResource(resource);
443 if (view.canHighlightPosition())
444 view.highlightPosition(line, column);
449 _showResourceView: function(resource)
451 var view = this._resourceViewForResource(resource);
453 this.visibleView.detach();
456 this._innerShowView(view);
459 _resourceViewForResource: function(resource)
461 if (WebInspector.ResourceView.hasTextContent(resource)) {
462 var treeElement = this._findTreeElementForResource(resource);
465 return treeElement.sourceView();
467 return WebInspector.ResourceView.nonSourceViewForResource(resource);
471 * @param {!WebInspector.Database} database
472 * @param {string=} tableName
474 _showDatabase: function(database, tableName)
481 var tableViews = this._databaseTableViews.get(database);
483 tableViews = /** @type {!Object.<string, !WebInspector.DatabaseTableView>} */ ({});
484 this._databaseTableViews.put(database, tableViews);
486 view = tableViews[tableName];
488 view = new WebInspector.DatabaseTableView(database, tableName);
489 tableViews[tableName] = view;
492 view = this._databaseQueryViews.get(database);
494 view = new WebInspector.DatabaseQueryView(database);
495 this._databaseQueryViews.put(database, view);
496 view.addEventListener(WebInspector.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this);
500 this._innerShowView(view);
504 * @param {!WebInspector.View} view
506 showIndexedDB: function(view)
508 this._innerShowView(view);
512 * @param {!WebInspector.DOMStorage} domStorage
514 _showDOMStorage: function(domStorage)
520 view = this._domStorageViews.get(domStorage);
522 view = new WebInspector.DOMStorageItemsView(domStorage);
523 this._domStorageViews.put(domStorage, view);
526 this._innerShowView(view);
530 * @param {!WebInspector.CookieTreeElement} treeElement
531 * @param {string} cookieDomain
533 showCookies: function(treeElement, cookieDomain)
535 var view = this._cookieViews[cookieDomain];
537 view = new WebInspector.CookieItemsView(treeElement, cookieDomain);
538 this._cookieViews[cookieDomain] = view;
541 this._innerShowView(view);
545 * @param {string} cookieDomain
547 clearCookies: function(cookieDomain)
549 this._cookieViews[cookieDomain].clear();
552 showApplicationCache: function(frameId)
554 if (!this._applicationCacheViews[frameId])
555 this._applicationCacheViews[frameId] = new WebInspector.ApplicationCacheItemsView(this._applicationCacheModel, frameId);
557 this._innerShowView(this._applicationCacheViews[frameId]);
561 * @param {!WebInspector.View} view
563 showFileSystem: function(view)
565 this._innerShowView(view);
568 showCategoryView: function(categoryName)
570 if (!this._categoryView)
571 this._categoryView = new WebInspector.StorageCategoryView();
572 this._categoryView.setText(categoryName);
573 this._innerShowView(this._categoryView);
576 _innerShowView: function(view)
578 if (this.visibleView === view)
581 if (this.visibleView)
582 this.visibleView.detach();
584 view.show(this.storageViews);
585 this.visibleView = view;
587 this.storageViewStatusBarItemsContainer.removeChildren();
588 var statusBarItems = view.statusBarItems || [];
589 for (var i = 0; i < statusBarItems.length; ++i)
590 this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
593 closeVisibleView: function()
595 if (!this.visibleView)
597 this.visibleView.detach();
598 delete this.visibleView;
601 _updateDatabaseTables: function(event)
603 var database = event.data;
608 var databasesTreeElement = this._databaseTreeElements.get(database);
609 if (!databasesTreeElement)
612 databasesTreeElement.shouldRefreshChildren = true;
613 var tableViews = this._databaseTableViews.get(database);
618 var tableNamesHash = {};
620 function tableNamesCallback(tableNames)
622 var tableNamesLength = tableNames.length;
623 for (var i = 0; i < tableNamesLength; ++i)
624 tableNamesHash[tableNames[i]] = true;
626 for (var tableName in tableViews) {
627 if (!(tableName in tableNamesHash)) {
628 if (self.visibleView === tableViews[tableName])
629 self.closeVisibleView();
630 delete tableViews[tableName];
634 database.getTableNames(tableNamesCallback);
637 _populateDOMStorageTree: function()
639 WebInspector.domStorageModel.storages().forEach(this._addDOMStorage.bind(this));
640 WebInspector.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this);
641 WebInspector.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this);
644 _populateApplicationCacheTree: function()
646 this._applicationCacheModel = new WebInspector.ApplicationCacheModel();
648 this._applicationCacheViews = {};
649 this._applicationCacheFrameElements = {};
650 this._applicationCacheManifestElements = {};
652 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded, this._applicationCacheFrameManifestAdded, this);
653 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved, this._applicationCacheFrameManifestRemoved, this);
655 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated, this._applicationCacheFrameManifestStatusChanged, this);
656 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged, this._applicationCacheNetworkStateChanged, this);
659 _applicationCacheFrameManifestAdded: function(event)
661 var frameId = event.data;
662 var manifestURL = this._applicationCacheModel.frameManifestURL(frameId);
663 var status = this._applicationCacheModel.frameManifestStatus(frameId)
665 var manifestTreeElement = this._applicationCacheManifestElements[manifestURL]
666 if (!manifestTreeElement) {
667 manifestTreeElement = new WebInspector.ApplicationCacheManifestTreeElement(this, manifestURL);
668 this.applicationCacheListTreeElement.appendChild(manifestTreeElement);
669 this._applicationCacheManifestElements[manifestURL] = manifestTreeElement;
672 var frameTreeElement = new WebInspector.ApplicationCacheFrameTreeElement(this, frameId, manifestURL);
673 manifestTreeElement.appendChild(frameTreeElement);
674 manifestTreeElement.expand();
675 this._applicationCacheFrameElements[frameId] = frameTreeElement;
678 _applicationCacheFrameManifestRemoved: function(event)
680 var frameId = event.data;
681 var frameTreeElement = this._applicationCacheFrameElements[frameId];
682 if (!frameTreeElement)
685 var manifestURL = frameTreeElement.manifestURL;
686 delete this._applicationCacheFrameElements[frameId];
687 delete this._applicationCacheViews[frameId];
688 frameTreeElement.parent.removeChild(frameTreeElement);
690 var manifestTreeElement = this._applicationCacheManifestElements[manifestURL];
691 if (manifestTreeElement.children.length !== 0)
694 delete this._applicationCacheManifestElements[manifestURL];
695 manifestTreeElement.parent.removeChild(manifestTreeElement);
698 _applicationCacheFrameManifestStatusChanged: function(event)
700 var frameId = event.data;
701 var status = this._applicationCacheModel.frameManifestStatus(frameId)
703 if (this._applicationCacheViews[frameId])
704 this._applicationCacheViews[frameId].updateStatus(status);
707 _applicationCacheNetworkStateChanged: function(event)
709 var isNowOnline = event.data;
711 for (var manifestURL in this._applicationCacheViews)
712 this._applicationCacheViews[manifestURL].updateNetworkState(isNowOnline);
715 _forAllResourceTreeElements: function(callback)
718 for (var treeElement = this.resourcesListTreeElement; !stop && treeElement; treeElement = treeElement.traverseNextTreeElement(false, this.resourcesListTreeElement, true)) {
719 if (treeElement instanceof WebInspector.FrameResourceTreeElement)
720 stop = callback(treeElement);
724 _findTreeElementForResource: function(resource)
726 function isAncestor(ancestor, object)
728 // Redirects, XHRs do not belong to the tree, it is fine to silently return false here.
732 function getParent(object)
734 // Redirects, XHRs do not belong to the tree, it is fine to silently return false here.
738 return this.sidebarTree.findTreeElement(resource, isAncestor, getParent);
741 showView: function(view)
744 this.showResource(view.resource);
747 _onmousemove: function(event)
749 var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY);
753 var listNode = nodeUnderMouse.enclosingNodeOrSelfWithNodeName("li");
757 var element = listNode.treeElement;
758 if (this._previousHoveredElement === element)
761 if (this._previousHoveredElement) {
762 this._previousHoveredElement.hovered = false;
763 delete this._previousHoveredElement;
766 if (element instanceof WebInspector.FrameTreeElement) {
767 this._previousHoveredElement = element;
768 element.hovered = true;
772 _onmouseout: function(event)
774 if (this._previousHoveredElement) {
775 this._previousHoveredElement.hovered = false;
776 delete this._previousHoveredElement;
780 __proto__: WebInspector.Panel.prototype
785 * @extends {TreeElement}
786 * @param {boolean=} hasChildren
787 * @param {boolean=} noIcon
789 WebInspector.BaseStorageTreeElement = function(storagePanel, representedObject, title, iconClasses, hasChildren, noIcon)
791 TreeElement.call(this, "", representedObject, hasChildren);
792 this._storagePanel = storagePanel;
793 this._titleText = title;
794 this._iconClasses = iconClasses;
795 this._noIcon = noIcon;
798 WebInspector.BaseStorageTreeElement.prototype = {
801 this.listItemElement.removeChildren();
802 if (this._iconClasses) {
803 for (var i = 0; i < this._iconClasses.length; ++i)
804 this.listItemElement.classList.add(this._iconClasses[i]);
807 var selectionElement = document.createElement("div");
808 selectionElement.className = "selection";
809 this.listItemElement.appendChild(selectionElement);
812 this.imageElement = document.createElement("img");
813 this.imageElement.className = "icon";
814 this.listItemElement.appendChild(this.imageElement);
817 this.titleElement = document.createElement("div");
818 this.titleElement.className = "base-storage-tree-element-title";
819 this._titleTextNode = document.createTextNode("");
820 this.titleElement.appendChild(this._titleTextNode);
822 this._updateSubtitle();
823 this.listItemElement.appendChild(this.titleElement);
828 return this._displayName;
831 _updateDisplayName: function()
833 this._displayName = this._titleText || "";
834 if (this._subtitleText)
835 this._displayName += " (" + this._subtitleText + ")";
838 _updateTitle: function()
840 this._updateDisplayName();
842 if (!this.titleElement)
845 this._titleTextNode.textContent = this._titleText || "";
848 _updateSubtitle: function()
850 this._updateDisplayName();
852 if (!this.titleElement)
855 if (this._subtitleText) {
856 if (!this._subtitleElement) {
857 this._subtitleElement = document.createElement("span");
858 this._subtitleElement.className = "base-storage-tree-element-subtitle";
859 this.titleElement.appendChild(this._subtitleElement);
861 this._subtitleElement.textContent = "(" + this._subtitleText + ")";
862 } else if (this._subtitleElement) {
863 this.titleElement.removeChild(this._subtitleElement);
864 delete this._subtitleElement;
872 onselect: function(selectedByUser)
876 var itemURL = this.itemURL;
878 WebInspector.settings.resourcesLastSelectedItem.set(itemURL);
887 if (this.listItemElement)
888 this.listItemElement.scrollIntoViewIfNeeded(false);
893 return this._titleText;
896 set titleText(titleText)
898 this._titleText = titleText;
904 return this._subtitleText;
907 set subtitleText(subtitleText)
909 this._subtitleText = subtitleText;
910 this._updateSubtitle();
913 __proto__: TreeElement.prototype
918 * @extends {WebInspector.BaseStorageTreeElement}
919 * @param {boolean=} noIcon
921 WebInspector.StorageCategoryTreeElement = function(storagePanel, categoryName, settingsKey, iconClasses, noIcon)
923 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, categoryName, iconClasses, false, noIcon);
924 this._expandedSettingKey = "resources" + settingsKey + "Expanded";
925 WebInspector.settings[this._expandedSettingKey] = WebInspector.settings.createSetting(this._expandedSettingKey, settingsKey === "Frames");
926 this._categoryName = categoryName;
929 WebInspector.StorageCategoryTreeElement.prototype = {
932 return "category://" + this._categoryName;
939 onselect: function(selectedByUser)
941 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
942 this._storagePanel.showCategoryView(this._categoryName);
951 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
952 if (WebInspector.settings[this._expandedSettingKey].get())
961 WebInspector.settings[this._expandedSettingKey].set(true);
967 oncollapse: function()
969 WebInspector.settings[this._expandedSettingKey].set(false);
972 __proto__: WebInspector.BaseStorageTreeElement.prototype
977 * @extends {WebInspector.BaseStorageTreeElement}
979 WebInspector.FrameTreeElement = function(storagePanel, frame)
981 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, "", ["frame-storage-tree-item"]);
983 this.frameNavigated(frame);
986 WebInspector.FrameTreeElement.prototype = {
987 frameNavigated: function(frame)
989 this.removeChildren();
990 this._frameId = frame.id;
992 this.titleText = frame.name;
993 this.subtitleText = new WebInspector.ParsedURL(frame.url).displayName;
995 this._categoryElements = {};
996 this._treeElementForResource = {};
998 this._storagePanel.addDocumentURL(frame.url);
1003 return "frame://" + encodeURI(this.displayName);
1010 onselect: function(selectedByUser)
1012 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1013 this._storagePanel.showCategoryView(this.displayName);
1015 this.listItemElement.classList.remove("hovered");
1016 DOMAgent.hideHighlight();
1020 set hovered(hovered)
1023 this.listItemElement.classList.add("hovered");
1024 DOMAgent.highlightFrame(this._frameId, WebInspector.Color.PageHighlight.Content.toProtocolRGBA(), WebInspector.Color.PageHighlight.ContentOutline.toProtocolRGBA());
1026 this.listItemElement.classList.remove("hovered");
1027 DOMAgent.hideHighlight();
1031 appendResource: function(resource)
1033 if (resource.isHidden())
1035 var categoryName = resource.type.name();
1036 var categoryElement = resource.type === WebInspector.resourceTypes.Document ? this : this._categoryElements[categoryName];
1037 if (!categoryElement) {
1038 categoryElement = new WebInspector.StorageCategoryTreeElement(this._storagePanel, resource.type.categoryTitle(), categoryName, null, true);
1039 this._categoryElements[resource.type.name()] = categoryElement;
1040 this._insertInPresentationOrder(this, categoryElement);
1042 var resourceTreeElement = new WebInspector.FrameResourceTreeElement(this._storagePanel, resource);
1043 this._insertInPresentationOrder(categoryElement, resourceTreeElement);
1044 this._treeElementForResource[resource.url] = resourceTreeElement;
1048 * @param {string} url
1049 * @return {?WebInspector.Resource}
1051 resourceByURL: function(url)
1053 var treeElement = this._treeElementForResource[url];
1054 return treeElement ? treeElement.representedObject : null;
1057 appendChild: function(treeElement)
1059 this._insertInPresentationOrder(this, treeElement);
1062 _insertInPresentationOrder: function(parentTreeElement, childTreeElement)
1064 // Insert in the alphabetical order, first frames, then resources. Document resource goes last.
1065 function typeWeight(treeElement)
1067 if (treeElement instanceof WebInspector.StorageCategoryTreeElement)
1069 if (treeElement instanceof WebInspector.FrameTreeElement)
1074 function compare(treeElement1, treeElement2)
1076 var typeWeight1 = typeWeight(treeElement1);
1077 var typeWeight2 = typeWeight(treeElement2);
1080 if (typeWeight1 > typeWeight2)
1082 else if (typeWeight1 < typeWeight2)
1085 var title1 = treeElement1.displayName || treeElement1.titleText;
1086 var title2 = treeElement2.displayName || treeElement2.titleText;
1087 result = title1.localeCompare(title2);
1092 var children = parentTreeElement.children;
1094 for (i = 0; i < children.length; ++i) {
1095 if (compare(childTreeElement, children[i]) < 0)
1098 parentTreeElement.insertChild(childTreeElement, i);
1101 __proto__: WebInspector.BaseStorageTreeElement.prototype
1106 * @extends {WebInspector.BaseStorageTreeElement}
1108 WebInspector.FrameResourceTreeElement = function(storagePanel, resource)
1110 WebInspector.BaseStorageTreeElement.call(this, storagePanel, resource, resource.displayName, ["resource-sidebar-tree-item", "resources-type-" + resource.type.name()]);
1111 this._resource = resource;
1112 this._resource.addEventListener(WebInspector.Resource.Events.MessageAdded, this._consoleMessageAdded, this);
1113 this._resource.addEventListener(WebInspector.Resource.Events.MessagesCleared, this._consoleMessagesCleared, this);
1114 this.tooltip = resource.url;
1117 WebInspector.FrameResourceTreeElement.prototype = {
1120 return this._resource.url;
1127 onselect: function(selectedByUser)
1129 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1130 this._storagePanel._showResourceView(this._resource);
1138 ondblclick: function(event)
1140 InspectorFrontendHost.openInNewTab(this._resource.url);
1147 onattach: function()
1149 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1151 if (this._resource.type === WebInspector.resourceTypes.Image) {
1152 var previewImage = document.createElement("img");
1153 previewImage.className = "image-resource-icon-preview";
1154 this._resource.populateImageSource(previewImage);
1156 var iconElement = document.createElement("div");
1157 iconElement.className = "icon";
1158 iconElement.appendChild(previewImage);
1159 this.listItemElement.replaceChild(iconElement, this.imageElement);
1162 this._statusElement = document.createElement("div");
1163 this._statusElement.className = "status";
1164 this.listItemElement.insertBefore(this._statusElement, this.titleElement);
1166 this.listItemElement.draggable = true;
1167 this.listItemElement.addEventListener("dragstart", this._ondragstart.bind(this), false);
1168 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1170 this._updateErrorsAndWarningsBubbles();
1174 * @param {!MouseEvent} event
1177 _ondragstart: function(event)
1179 event.dataTransfer.setData("text/plain", this._resource.content);
1180 event.dataTransfer.effectAllowed = "copy";
1184 _handleContextMenuEvent: function(event)
1186 var contextMenu = new WebInspector.ContextMenu(event);
1187 contextMenu.appendApplicableItems(this._resource);
1191 _setBubbleText: function(x)
1193 if (!this._bubbleElement) {
1194 this._bubbleElement = document.createElement("div");
1195 this._bubbleElement.className = "bubble";
1196 this._statusElement.appendChild(this._bubbleElement);
1199 this._bubbleElement.textContent = x;
1202 _resetBubble: function()
1204 if (this._bubbleElement) {
1205 this._bubbleElement.textContent = "";
1206 this._bubbleElement.classList.remove("warning");
1207 this._bubbleElement.classList.remove("error");
1211 _updateErrorsAndWarningsBubbles: function()
1213 if (this._storagePanel.currentQuery)
1216 this._resetBubble();
1218 if (this._resource.warnings || this._resource.errors)
1219 this._setBubbleText(this._resource.warnings + this._resource.errors);
1221 if (this._resource.warnings)
1222 this._bubbleElement.classList.add("warning");
1224 if (this._resource.errors)
1225 this._bubbleElement.classList.add("error");
1228 _consoleMessagesCleared: function()
1230 // FIXME: move to the SourceFrame.
1231 if (this._sourceView)
1232 this._sourceView.clearMessages();
1234 this._updateErrorsAndWarningsBubbles();
1237 _consoleMessageAdded: function(event)
1239 var msg = event.data;
1240 if (this._sourceView)
1241 this._sourceView.addMessage(msg);
1242 this._updateErrorsAndWarningsBubbles();
1246 * @return {!WebInspector.ResourceSourceFrame}
1248 sourceView: function()
1250 if (!this._sourceView) {
1251 var sourceFrame = new WebInspector.ResourceSourceFrame(this._resource);
1252 sourceFrame.setHighlighterType(this._resource.canonicalMimeType());
1253 this._sourceView = sourceFrame;
1254 if (this._resource.messages) {
1255 for (var i = 0; i < this._resource.messages.length; i++)
1256 this._sourceView.addMessage(this._resource.messages[i]);
1259 return this._sourceView;
1262 __proto__: WebInspector.BaseStorageTreeElement.prototype
1267 * @extends {WebInspector.BaseStorageTreeElement}
1268 * @param {!WebInspector.Database} database
1270 WebInspector.DatabaseTreeElement = function(storagePanel, database)
1272 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, database.name, ["database-storage-tree-item"], true);
1273 this._database = database;
1276 WebInspector.DatabaseTreeElement.prototype = {
1279 return "database://" + encodeURI(this._database.name);
1286 onselect: function(selectedByUser)
1288 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1289 this._storagePanel._showDatabase(this._database);
1296 onexpand: function()
1298 this._updateChildren();
1301 _updateChildren: function()
1303 this.removeChildren();
1306 * @param {!Array.<string>} tableNames
1307 * @this {WebInspector.DatabaseTreeElement}
1309 function tableNamesCallback(tableNames)
1311 var tableNamesLength = tableNames.length;
1312 for (var i = 0; i < tableNamesLength; ++i)
1313 this.appendChild(new WebInspector.DatabaseTableTreeElement(this._storagePanel, this._database, tableNames[i]));
1315 this._database.getTableNames(tableNamesCallback.bind(this));
1318 __proto__: WebInspector.BaseStorageTreeElement.prototype
1323 * @extends {WebInspector.BaseStorageTreeElement}
1325 WebInspector.DatabaseTableTreeElement = function(storagePanel, database, tableName)
1327 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, tableName, ["database-storage-tree-item"]);
1328 this._database = database;
1329 this._tableName = tableName;
1332 WebInspector.DatabaseTableTreeElement.prototype = {
1335 return "database://" + encodeURI(this._database.name) + "/" + encodeURI(this._tableName);
1342 onselect: function(selectedByUser)
1344 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1345 this._storagePanel._showDatabase(this._database, this._tableName);
1349 __proto__: WebInspector.BaseStorageTreeElement.prototype
1354 * @extends {WebInspector.StorageCategoryTreeElement}
1355 * @param {!WebInspector.ResourcesPanel} storagePanel
1357 WebInspector.IndexedDBTreeElement = function(storagePanel)
1359 WebInspector.StorageCategoryTreeElement.call(this, storagePanel, WebInspector.UIString("IndexedDB"), "IndexedDB", ["indexed-db-storage-tree-item"]);
1362 WebInspector.IndexedDBTreeElement.prototype = {
1363 _initialize: function()
1365 this._createIndexedDBModel();
1368 onattach: function()
1370 WebInspector.StorageCategoryTreeElement.prototype.onattach.call(this);
1371 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1374 _handleContextMenuEvent: function(event)
1376 var contextMenu = new WebInspector.ContextMenu(event);
1377 contextMenu.appendItem(WebInspector.UIString("Refresh IndexedDB"), this.refreshIndexedDB.bind(this));
1381 _createIndexedDBModel: function()
1383 this._indexedDBModel = new WebInspector.IndexedDBModel();
1384 this._idbDatabaseTreeElements = [];
1385 this._indexedDBModel.addEventListener(WebInspector.IndexedDBModel.EventTypes.DatabaseAdded, this._indexedDBAdded, this);
1386 this._indexedDBModel.addEventListener(WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved, this._indexedDBRemoved, this);
1387 this._indexedDBModel.addEventListener(WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded, this._indexedDBLoaded, this);
1390 refreshIndexedDB: function()
1392 if (!this._indexedDBModel) {
1393 this._createIndexedDBModel();
1397 this._indexedDBModel.refreshDatabaseNames();
1401 * @param {!WebInspector.Event} event
1403 _indexedDBAdded: function(event)
1405 var databaseId = /** @type {!WebInspector.IndexedDBModel.DatabaseId} */ (event.data);
1407 var idbDatabaseTreeElement = new WebInspector.IDBDatabaseTreeElement(this._storagePanel, this._indexedDBModel, databaseId);
1408 this._idbDatabaseTreeElements.push(idbDatabaseTreeElement);
1409 this.appendChild(idbDatabaseTreeElement);
1411 this._indexedDBModel.refreshDatabase(databaseId);
1415 * @param {!WebInspector.Event} event
1417 _indexedDBRemoved: function(event)
1419 var databaseId = /** @type {!WebInspector.IndexedDBModel.DatabaseId} */ (event.data);
1421 var idbDatabaseTreeElement = this._idbDatabaseTreeElement(databaseId)
1422 if (!idbDatabaseTreeElement)
1425 idbDatabaseTreeElement.clear();
1426 this.removeChild(idbDatabaseTreeElement);
1427 this._idbDatabaseTreeElements.remove(idbDatabaseTreeElement);
1431 * @param {!WebInspector.Event} event
1433 _indexedDBLoaded: function(event)
1435 var database = /** @type {!WebInspector.IndexedDBModel.Database} */ (event.data);
1437 var idbDatabaseTreeElement = this._idbDatabaseTreeElement(database.databaseId)
1438 if (!idbDatabaseTreeElement)
1441 idbDatabaseTreeElement.update(database);
1445 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1446 * @return {?WebInspector.IDBDatabaseTreeElement}
1448 _idbDatabaseTreeElement: function(databaseId)
1451 for (var i = 0; i < this._idbDatabaseTreeElements.length; ++i) {
1452 if (this._idbDatabaseTreeElements[i]._databaseId.equals(databaseId)) {
1458 return this._idbDatabaseTreeElements[i];
1462 __proto__: WebInspector.StorageCategoryTreeElement.prototype
1467 * @extends {WebInspector.StorageCategoryTreeElement}
1468 * @param {!WebInspector.ResourcesPanel} storagePanel
1470 WebInspector.FileSystemListTreeElement = function(storagePanel)
1472 WebInspector.StorageCategoryTreeElement.call(this, storagePanel, WebInspector.UIString("FileSystem"), "FileSystem", ["file-system-storage-tree-item"]);
1475 WebInspector.FileSystemListTreeElement.prototype = {
1476 _initialize: function()
1478 this._refreshFileSystem();
1481 onattach: function()
1483 WebInspector.StorageCategoryTreeElement.prototype.onattach.call(this);
1484 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1487 _handleContextMenuEvent: function(event)
1489 var contextMenu = new WebInspector.ContextMenu(event);
1490 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Refresh FileSystem list" : "Refresh FileSystem List"), this._refreshFileSystem.bind(this));
1494 _fileSystemAdded: function(event)
1496 var fileSystem = /** @type {!WebInspector.FileSystemModel.FileSystem} */ (event.data);
1497 var fileSystemTreeElement = new WebInspector.FileSystemTreeElement(this._storagePanel, fileSystem);
1498 this.appendChild(fileSystemTreeElement);
1501 _fileSystemRemoved: function(event)
1503 var fileSystem = /** @type {!WebInspector.FileSystemModel.FileSystem} */ (event.data);
1504 var fileSystemTreeElement = this._fileSystemTreeElementByName(fileSystem.name);
1505 if (!fileSystemTreeElement)
1507 fileSystemTreeElement.clear();
1508 this.removeChild(fileSystemTreeElement);
1511 _fileSystemTreeElementByName: function(fileSystemName)
1513 for (var i = 0; i < this.children.length; ++i) {
1514 var child = /** @type {!WebInspector.FileSystemTreeElement} */ (this.children[i]);
1515 if (child.fileSystemName === fileSystemName)
1516 return this.children[i];
1521 _refreshFileSystem: function()
1523 if (!this._fileSystemModel) {
1524 this._fileSystemModel = new WebInspector.FileSystemModel();
1525 this._fileSystemModel.addEventListener(WebInspector.FileSystemModel.EventTypes.FileSystemAdded, this._fileSystemAdded, this);
1526 this._fileSystemModel.addEventListener(WebInspector.FileSystemModel.EventTypes.FileSystemRemoved, this._fileSystemRemoved, this);
1529 this._fileSystemModel.refreshFileSystemList();
1532 __proto__: WebInspector.StorageCategoryTreeElement.prototype
1537 * @extends {WebInspector.BaseStorageTreeElement}
1538 * @param {!WebInspector.ResourcesPanel} storagePanel
1539 * @param {!WebInspector.IndexedDBModel} model
1540 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1542 WebInspector.IDBDatabaseTreeElement = function(storagePanel, model, databaseId)
1544 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, databaseId.name + " - " + databaseId.securityOrigin, ["indexed-db-storage-tree-item"]);
1545 this._model = model;
1546 this._databaseId = databaseId;
1547 this._idbObjectStoreTreeElements = {};
1550 WebInspector.IDBDatabaseTreeElement.prototype = {
1553 return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name;
1556 onattach: function()
1558 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1559 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1562 _handleContextMenuEvent: function(event)
1564 var contextMenu = new WebInspector.ContextMenu(event);
1565 contextMenu.appendItem(WebInspector.UIString("Refresh IndexedDB"), this._refreshIndexedDB.bind(this));
1569 _refreshIndexedDB: function()
1571 this._model.refreshDatabaseNames();
1575 * @param {!WebInspector.IndexedDBModel.Database} database
1577 update: function(database)
1579 this._database = database;
1580 var objectStoreNames = {};
1581 for (var objectStoreName in this._database.objectStores) {
1582 var objectStore = this._database.objectStores[objectStoreName];
1583 objectStoreNames[objectStore.name] = true;
1584 if (!this._idbObjectStoreTreeElements[objectStore.name]) {
1585 var idbObjectStoreTreeElement = new WebInspector.IDBObjectStoreTreeElement(this._storagePanel, this._model, this._databaseId, objectStore);
1586 this._idbObjectStoreTreeElements[objectStore.name] = idbObjectStoreTreeElement;
1587 this.appendChild(idbObjectStoreTreeElement);
1589 this._idbObjectStoreTreeElements[objectStore.name].update(objectStore);
1591 for (var objectStoreName in this._idbObjectStoreTreeElements) {
1592 if (!objectStoreNames[objectStoreName])
1593 this._objectStoreRemoved(objectStoreName);
1596 if (this.children.length) {
1597 this.hasChildren = true;
1602 this._view.update(database);
1604 this._updateTooltip();
1607 _updateTooltip: function()
1609 this.tooltip = WebInspector.UIString("Version") + ": " + this._database.version;
1616 onselect: function(selectedByUser)
1618 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1620 this._view = new WebInspector.IDBDatabaseView(this._database);
1622 this._storagePanel.showIndexedDB(this._view);
1627 * @param {string} objectStoreName
1629 _objectStoreRemoved: function(objectStoreName)
1631 var objectStoreTreeElement = this._idbObjectStoreTreeElements[objectStoreName];
1632 objectStoreTreeElement.clear();
1633 this.removeChild(objectStoreTreeElement);
1634 delete this._idbObjectStoreTreeElements[objectStoreName];
1639 for (var objectStoreName in this._idbObjectStoreTreeElements)
1640 this._objectStoreRemoved(objectStoreName);
1643 __proto__: WebInspector.BaseStorageTreeElement.prototype
1648 * @extends {WebInspector.BaseStorageTreeElement}
1649 * @param {!WebInspector.ResourcesPanel} storagePanel
1650 * @param {!WebInspector.IndexedDBModel} model
1651 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1652 * @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
1654 WebInspector.IDBObjectStoreTreeElement = function(storagePanel, model, databaseId, objectStore)
1656 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, objectStore.name, ["indexed-db-object-store-storage-tree-item"]);
1657 this._model = model;
1658 this._databaseId = databaseId;
1659 this._idbIndexTreeElements = {};
1662 WebInspector.IDBObjectStoreTreeElement.prototype = {
1665 return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name + "/" + this._objectStore.name;
1668 onattach: function()
1670 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1671 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1674 _handleContextMenuEvent: function(event)
1676 var contextMenu = new WebInspector.ContextMenu(event);
1677 contextMenu.appendItem(WebInspector.UIString("Clear"), this._clearObjectStore.bind(this));
1681 _clearObjectStore: function()
1684 * @this {WebInspector.IDBObjectStoreTreeElement}
1686 function callback() {
1687 this.update(this._objectStore);
1689 this._model.clearObjectStore(this._databaseId, this._objectStore.name, callback.bind(this));
1693 * @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
1695 update: function(objectStore)
1697 this._objectStore = objectStore;
1699 var indexNames = {};
1700 for (var indexName in this._objectStore.indexes) {
1701 var index = this._objectStore.indexes[indexName];
1702 indexNames[index.name] = true;
1703 if (!this._idbIndexTreeElements[index.name]) {
1704 var idbIndexTreeElement = new WebInspector.IDBIndexTreeElement(this._storagePanel, this._model, this._databaseId, this._objectStore, index);
1705 this._idbIndexTreeElements[index.name] = idbIndexTreeElement;
1706 this.appendChild(idbIndexTreeElement);
1708 this._idbIndexTreeElements[index.name].update(index);
1710 for (var indexName in this._idbIndexTreeElements) {
1711 if (!indexNames[indexName])
1712 this._indexRemoved(indexName);
1714 for (var indexName in this._idbIndexTreeElements) {
1715 if (!indexNames[indexName]) {
1716 this.removeChild(this._idbIndexTreeElements[indexName]);
1717 delete this._idbIndexTreeElements[indexName];
1721 if (this.children.length) {
1722 this.hasChildren = true;
1727 this._view.update(this._objectStore);
1729 this._updateTooltip();
1732 _updateTooltip: function()
1735 var keyPathString = this._objectStore.keyPathString;
1736 var tooltipString = keyPathString !== null ? (WebInspector.UIString("Key path: ") + keyPathString) : "";
1737 if (this._objectStore.autoIncrement)
1738 tooltipString += "\n" + WebInspector.UIString("autoIncrement");
1739 this.tooltip = tooltipString
1746 onselect: function(selectedByUser)
1748 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1750 this._view = new WebInspector.IDBDataView(this._model, this._databaseId, this._objectStore, null);
1752 this._storagePanel.showIndexedDB(this._view);
1757 * @param {string} indexName
1759 _indexRemoved: function(indexName)
1761 var indexTreeElement = this._idbIndexTreeElements[indexName];
1762 indexTreeElement.clear();
1763 this.removeChild(indexTreeElement);
1764 delete this._idbIndexTreeElements[indexName];
1769 for (var indexName in this._idbIndexTreeElements)
1770 this._indexRemoved(indexName);
1775 __proto__: WebInspector.BaseStorageTreeElement.prototype
1780 * @extends {WebInspector.BaseStorageTreeElement}
1781 * @param {!WebInspector.ResourcesPanel} storagePanel
1782 * @param {!WebInspector.IndexedDBModel} model
1783 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1784 * @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
1785 * @param {!WebInspector.IndexedDBModel.Index} index
1787 WebInspector.IDBIndexTreeElement = function(storagePanel, model, databaseId, objectStore, index)
1789 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, index.name, ["indexed-db-index-storage-tree-item"]);
1790 this._model = model;
1791 this._databaseId = databaseId;
1792 this._objectStore = objectStore;
1793 this._index = index;
1796 WebInspector.IDBIndexTreeElement.prototype = {
1799 return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name + "/" + this._objectStore.name + "/" + this._index.name;
1803 * @param {!WebInspector.IndexedDBModel.Index} index
1805 update: function(index)
1807 this._index = index;
1810 this._view.update(this._index);
1812 this._updateTooltip();
1815 _updateTooltip: function()
1817 var tooltipLines = [];
1818 var keyPathString = this._index.keyPathString;
1819 tooltipLines.push(WebInspector.UIString("Key path: ") + keyPathString);
1820 if (this._index.unique)
1821 tooltipLines.push(WebInspector.UIString("unique"));
1822 if (this._index.multiEntry)
1823 tooltipLines.push(WebInspector.UIString("multiEntry"));
1824 this.tooltip = tooltipLines.join("\n");
1831 onselect: function(selectedByUser)
1833 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1835 this._view = new WebInspector.IDBDataView(this._model, this._databaseId, this._objectStore, this._index);
1837 this._storagePanel.showIndexedDB(this._view);
1847 __proto__: WebInspector.BaseStorageTreeElement.prototype
1852 * @extends {WebInspector.BaseStorageTreeElement}
1854 WebInspector.DOMStorageTreeElement = function(storagePanel, domStorage, className)
1856 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, domStorage.securityOrigin ? domStorage.securityOrigin : WebInspector.UIString("Local Files"), ["domstorage-storage-tree-item", className]);
1857 this._domStorage = domStorage;
1860 WebInspector.DOMStorageTreeElement.prototype = {
1863 return "storage://" + this._domStorage.securityOrigin + "/" + (this._domStorage.isLocalStorage ? "local" : "session");
1870 onselect: function(selectedByUser)
1872 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1873 this._storagePanel._showDOMStorage(this._domStorage);
1877 __proto__: WebInspector.BaseStorageTreeElement.prototype
1882 * @extends {WebInspector.BaseStorageTreeElement}
1884 WebInspector.CookieTreeElement = function(storagePanel, cookieDomain)
1886 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, cookieDomain ? cookieDomain : WebInspector.UIString("Local Files"), ["cookie-storage-tree-item"]);
1887 this._cookieDomain = cookieDomain;
1890 WebInspector.CookieTreeElement.prototype = {
1893 return "cookies://" + this._cookieDomain;
1896 onattach: function()
1898 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1899 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1903 * @param {!Event} event
1905 _handleContextMenuEvent: function(event)
1907 var contextMenu = new WebInspector.ContextMenu(event);
1908 contextMenu.appendItem(WebInspector.UIString("Clear"), this._clearCookies.bind(this));
1913 * @param {string} domain
1915 _clearCookies: function(domain)
1917 this._storagePanel.clearCookies(this._cookieDomain);
1924 onselect: function(selectedByUser)
1926 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1927 this._storagePanel.showCookies(this, this._cookieDomain);
1931 __proto__: WebInspector.BaseStorageTreeElement.prototype
1936 * @extends {WebInspector.BaseStorageTreeElement}
1938 WebInspector.ApplicationCacheManifestTreeElement = function(storagePanel, manifestURL)
1940 var title = new WebInspector.ParsedURL(manifestURL).displayName;
1941 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, title, ["application-cache-storage-tree-item"]);
1942 this.tooltip = manifestURL;
1943 this._manifestURL = manifestURL;
1946 WebInspector.ApplicationCacheManifestTreeElement.prototype = {
1949 return "appcache://" + this._manifestURL;
1954 return this._manifestURL;
1961 onselect: function(selectedByUser)
1963 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1964 this._storagePanel.showCategoryView(this._manifestURL);
1968 __proto__: WebInspector.BaseStorageTreeElement.prototype
1973 * @extends {WebInspector.BaseStorageTreeElement}
1975 WebInspector.ApplicationCacheFrameTreeElement = function(storagePanel, frameId, manifestURL)
1977 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, "", ["frame-storage-tree-item"]);
1978 this._frameId = frameId;
1979 this._manifestURL = manifestURL;
1980 this._refreshTitles();
1983 WebInspector.ApplicationCacheFrameTreeElement.prototype = {
1986 return "appcache://" + this._manifestURL + "/" + encodeURI(this.displayName);
1991 return this._frameId;
1996 return this._manifestURL;
1999 _refreshTitles: function()
2001 var frame = WebInspector.resourceTreeModel.frameForId(this._frameId);
2003 this.subtitleText = WebInspector.UIString("new frame");
2006 this.titleText = frame.name;
2007 this.subtitleText = new WebInspector.ParsedURL(frame.url).displayName;
2010 frameNavigated: function()
2012 this._refreshTitles();
2019 onselect: function(selectedByUser)
2021 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
2022 this._storagePanel.showApplicationCache(this._frameId);
2026 __proto__: WebInspector.BaseStorageTreeElement.prototype
2031 * @extends {WebInspector.BaseStorageTreeElement}
2032 * @param {!WebInspector.ResourcesPanel} storagePanel
2033 * @param {!WebInspector.FileSystemModel.FileSystem} fileSystem
2035 WebInspector.FileSystemTreeElement = function(storagePanel, fileSystem)
2037 var displayName = fileSystem.type + " - " + fileSystem.origin;
2038 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, displayName, ["file-system-storage-tree-item"]);
2039 this._fileSystem = fileSystem;
2042 WebInspector.FileSystemTreeElement.prototype = {
2043 get fileSystemName()
2045 return this._fileSystem.name;
2050 return "filesystem://" + this._fileSystem.name;
2057 onselect: function(selectedByUser)
2059 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
2060 this._fileSystemView = new WebInspector.FileSystemView(this._fileSystem);
2061 this._storagePanel.showFileSystem(this._fileSystemView);
2067 if (this.fileSystemView && this._storagePanel.visibleView === this.fileSystemView)
2068 this._storagePanel.closeVisibleView();
2071 __proto__: WebInspector.BaseStorageTreeElement.prototype
2076 * @extends {WebInspector.View}
2078 WebInspector.StorageCategoryView = function()
2080 WebInspector.View.call(this);
2082 this.element.classList.add("storage-view");
2083 this._emptyView = new WebInspector.EmptyView("");
2084 this._emptyView.show(this.element);
2087 WebInspector.StorageCategoryView.prototype = {
2088 setText: function(text)
2090 this._emptyView.text = text;
2093 __proto__: WebInspector.View.prototype