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.PanelWithSidebarTree}
44 WebInspector.ResourcesPanel = function(database)
46 WebInspector.PanelWithSidebarTree.call(this, "resources");
47 this.registerRequiredCSS("resourcesPanel.css");
49 WebInspector.settings.resourcesLastSelectedItem = WebInspector.settings.createSetting("resourcesLastSelectedItem", {});
51 this.sidebarElement().classList.add("filter-all", "children", "small", "outline-disclosure");
52 this.sidebarTree.element.classList.remove("sidebar-tree");
54 this.resourcesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Frames"), "Frames", ["frame-storage-tree-item"]);
55 this.sidebarTree.appendChild(this.resourcesListTreeElement);
57 this.databasesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Web SQL"), "Databases", ["database-storage-tree-item"]);
58 this.sidebarTree.appendChild(this.databasesListTreeElement);
60 this.indexedDBListTreeElement = new WebInspector.IndexedDBTreeElement(this);
61 this.sidebarTree.appendChild(this.indexedDBListTreeElement);
63 this.localStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Local Storage"), "LocalStorage", ["domstorage-storage-tree-item", "local-storage"]);
64 this.sidebarTree.appendChild(this.localStorageListTreeElement);
66 this.sessionStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Session Storage"), "SessionStorage", ["domstorage-storage-tree-item", "session-storage"]);
67 this.sidebarTree.appendChild(this.sessionStorageListTreeElement);
69 this.cookieListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Cookies"), "Cookies", ["cookie-storage-tree-item"]);
70 this.sidebarTree.appendChild(this.cookieListTreeElement);
72 this.applicationCacheListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Application Cache"), "ApplicationCache", ["application-cache-storage-tree-item"]);
73 this.sidebarTree.appendChild(this.applicationCacheListTreeElement);
75 if (WebInspector.experimentsSettings.fileSystemInspection.isEnabled()) {
76 this.fileSystemListTreeElement = new WebInspector.FileSystemListTreeElement(this);
77 this.sidebarTree.appendChild(this.fileSystemListTreeElement);
80 var mainView = new WebInspector.VBox();
81 this.storageViews = mainView.element.createChild("div", "resources-main diff-container");
82 var statusBarContainer = mainView.element.createChild("div", "resources-status-bar");
83 this.storageViewStatusBarItemsContainer = statusBarContainer.createChild("div", "status-bar");
84 mainView.show(this.mainElement());
86 /** @type {!Map.<!WebInspector.Database, !Object.<string, !WebInspector.DatabaseTableView>>} */
87 this._databaseTableViews = new Map();
88 /** @type {!Map.<!WebInspector.Database, !WebInspector.DatabaseQueryView>} */
89 this._databaseQueryViews = new Map();
90 /** @type {!Map.<!WebInspector.Database, !WebInspector.DatabaseTreeElement>} */
91 this._databaseTreeElements = new Map();
92 /** @type {!Map.<!WebInspector.DOMStorage, !WebInspector.DOMStorageItemsView>} */
93 this._domStorageViews = new Map();
94 /** @type {!Map.<!WebInspector.DOMStorage, !WebInspector.DOMStorageTreeElement>} */
95 this._domStorageTreeElements = new Map();
96 /** @type {!Object.<string, !WebInspector.CookieItemsView>} */
97 this._cookieViews = {};
98 /** @type {!Object.<string, boolean>} */
101 this.sidebarElement().addEventListener("mousemove", this._onmousemove.bind(this), false);
102 this.sidebarElement().addEventListener("mouseout", this._onmouseout.bind(this), false);
105 * @this {WebInspector.ResourcesPanel}
106 * @return {?WebInspector.SourceFrame}
108 function sourceFrameGetter()
110 var view = this.visibleView;
111 if (view && view instanceof WebInspector.SourceFrame)
112 return /** @type {!WebInspector.SourceFrame} */ (view);
115 WebInspector.GoToLineDialog.install(this, sourceFrameGetter.bind(this));
117 if (WebInspector.resourceTreeModel.cachedResourcesLoaded())
118 this._cachedResourcesLoaded();
120 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
121 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._cachedResourcesLoaded, this);
122 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources, this._resetWithFrames, this);
124 WebInspector.databaseModel.databases().forEach(this._addDatabase.bind(this));
125 WebInspector.databaseModel.addEventListener(WebInspector.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this);
128 WebInspector.ResourcesPanel.prototype = {
132 canSearch: function()
139 WebInspector.Panel.prototype.wasShown.call(this);
143 _initialize: function()
145 if (!this._initialized && this.isShowing() && this._cachedResourcesWereLoaded) {
146 this._populateResourceTree();
147 this._populateDOMStorageTree();
148 this._populateApplicationCacheTree();
149 this.indexedDBListTreeElement._initialize();
150 if (WebInspector.experimentsSettings.fileSystemInspection.isEnabled())
151 this.fileSystemListTreeElement._initialize();
152 this._initDefaultSelection();
153 this._initialized = true;
157 _loadEventFired: function()
159 this._initDefaultSelection();
162 _initDefaultSelection: function()
164 if (!this._initialized)
167 var itemURL = WebInspector.settings.resourcesLastSelectedItem.get();
169 for (var treeElement = this.sidebarTree.children[0]; treeElement; treeElement = treeElement.traverseNextTreeElement(false, this.sidebarTree, true)) {
170 if (treeElement.itemURL === itemURL) {
171 treeElement.revealAndSelect(true);
177 var mainResource = WebInspector.resourceTreeModel.inspectedPageURL() && this.resourcesListTreeElement && this.resourcesListTreeElement.expanded
178 ? WebInspector.resourceTreeModel.resourceForURL(WebInspector.resourceTreeModel.inspectedPageURL())
181 this.showResource(mainResource);
184 _resetWithFrames: function()
186 this.resourcesListTreeElement.removeChildren();
187 this._treeElementForFrameId = {};
194 var queryViews = this._databaseQueryViews.values();
195 for (var i = 0; i < queryViews.length; ++i)
196 queryViews[i].removeEventListener(WebInspector.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this);
197 this._databaseTableViews.clear();
198 this._databaseQueryViews.clear();
199 this._databaseTreeElements.clear();
200 this._domStorageViews.clear();
201 this._domStorageTreeElements.clear();
202 this._cookieViews = {};
204 this.databasesListTreeElement.removeChildren();
205 this.localStorageListTreeElement.removeChildren();
206 this.sessionStorageListTreeElement.removeChildren();
207 this.cookieListTreeElement.removeChildren();
209 if (this.visibleView && !(this.visibleView instanceof WebInspector.StorageCategoryView))
210 this.visibleView.detach();
212 this.storageViewStatusBarItemsContainer.removeChildren();
214 if (this.sidebarTree.selectedTreeElement)
215 this.sidebarTree.selectedTreeElement.deselect();
218 _populateResourceTree: function()
220 this._treeElementForFrameId = {};
221 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameAdded, this);
222 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
223 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
224 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
227 * @param {!WebInspector.ResourceTreeFrame} frame
228 * @this {WebInspector.ResourcesPanel}
230 function populateFrame(frame)
232 this._frameAdded({data:frame});
233 for (var i = 0; i < frame.childFrames.length; ++i)
234 populateFrame.call(this, frame.childFrames[i]);
236 var resources = frame.resources();
237 for (var i = 0; i < resources.length; ++i)
238 this._resourceAdded({data:resources[i]});
240 populateFrame.call(this, WebInspector.resourceTreeModel.mainFrame);
243 _frameAdded: function(event)
245 var frame = event.data;
246 var parentFrame = frame.parentFrame;
248 var parentTreeElement = parentFrame ? this._treeElementForFrameId[parentFrame.id] : this.resourcesListTreeElement;
249 if (!parentTreeElement) {
250 console.warn("No frame to route " + frame.url + " to.")
254 var frameTreeElement = new WebInspector.FrameTreeElement(this, frame);
255 this._treeElementForFrameId[frame.id] = frameTreeElement;
256 parentTreeElement.appendChild(frameTreeElement);
259 _frameDetached: function(event)
261 var frame = event.data;
262 var frameTreeElement = this._treeElementForFrameId[frame.id];
263 if (!frameTreeElement)
266 delete this._treeElementForFrameId[frame.id];
267 if (frameTreeElement.parent)
268 frameTreeElement.parent.removeChild(frameTreeElement);
271 _resourceAdded: function(event)
273 var resource = event.data;
274 var frameId = resource.frameId;
276 if (resource.statusCode >= 301 && resource.statusCode <= 303)
279 var frameTreeElement = this._treeElementForFrameId[frameId];
280 if (!frameTreeElement) {
281 // This is a frame's main resource, it will be retained
282 // and re-added by the resource manager;
286 frameTreeElement.appendResource(resource);
289 _frameNavigated: function(event)
291 var frame = event.data;
293 if (!frame.parentFrame)
296 var frameId = frame.id;
297 var frameTreeElement = this._treeElementForFrameId[frameId];
298 if (frameTreeElement)
299 frameTreeElement.frameNavigated(frame);
301 var applicationCacheFrameTreeElement = this._applicationCacheFrameElements[frameId];
302 if (applicationCacheFrameTreeElement)
303 applicationCacheFrameTreeElement.frameNavigated(frame);
306 _cachedResourcesLoaded: function()
308 this._cachedResourcesWereLoaded = true;
313 * @param {!WebInspector.Event} event
315 _databaseAdded: function(event)
317 var database = /** @type {!WebInspector.Database} */ (event.data);
318 this._addDatabase(database);
322 * @param {!WebInspector.Database} database
324 _addDatabase: function(database)
326 var databaseTreeElement = new WebInspector.DatabaseTreeElement(this, database);
327 this._databaseTreeElements.put(database, databaseTreeElement);
328 this.databasesListTreeElement.appendChild(databaseTreeElement);
331 addDocumentURL: function(url)
333 var parsedURL = url.asParsedURL();
337 var domain = parsedURL.host;
338 if (!this._domains[domain]) {
339 this._domains[domain] = true;
341 var cookieDomainTreeElement = new WebInspector.CookieTreeElement(this, domain);
342 this.cookieListTreeElement.appendChild(cookieDomainTreeElement);
347 * @param {!WebInspector.Event} event
349 _domStorageAdded: function(event)
351 var domStorage = /** @type {!WebInspector.DOMStorage} */ (event.data);
352 this._addDOMStorage(domStorage);
356 * @param {!WebInspector.DOMStorage} domStorage
358 _addDOMStorage: function(domStorage)
360 console.assert(!this._domStorageTreeElements.get(domStorage));
362 var domStorageTreeElement = new WebInspector.DOMStorageTreeElement(this, domStorage, (domStorage.isLocalStorage ? "local-storage" : "session-storage"));
363 this._domStorageTreeElements.put(domStorage, domStorageTreeElement);
364 if (domStorage.isLocalStorage)
365 this.localStorageListTreeElement.appendChild(domStorageTreeElement);
367 this.sessionStorageListTreeElement.appendChild(domStorageTreeElement);
371 * @param {!WebInspector.Event} event
373 _domStorageRemoved: function(event)
375 var domStorage = /** @type {!WebInspector.DOMStorage} */ (event.data);
376 this._removeDOMStorage(domStorage);
380 * @param {!WebInspector.DOMStorage} domStorage
382 _removeDOMStorage: function(domStorage)
384 var treeElement = this._domStorageTreeElements.get(domStorage);
387 var wasSelected = treeElement.selected;
388 var parentListTreeElement = treeElement.parent;
389 parentListTreeElement.removeChild(treeElement);
391 parentListTreeElement.select();
392 this._domStorageTreeElements.remove(treeElement);
393 this._domStorageViews.remove(domStorage);
397 * @param {!WebInspector.Database} database
399 selectDatabase: function(database)
402 this._showDatabase(database);
403 this._databaseTreeElements.get(database).select();
408 * @param {!WebInspector.DOMStorage} domStorage
410 selectDOMStorage: function(domStorage)
413 this._showDOMStorage(domStorage);
414 this._domStorageTreeElements.get(domStorage).select();
419 * @param {!WebInspector.Resource} resource
420 * @param {number=} line
421 * @param {number=} column
424 showResource: function(resource, line, column)
426 var resourceTreeElement = this._findTreeElementForResource(resource);
427 if (resourceTreeElement)
428 resourceTreeElement.revealAndSelect(true);
430 if (typeof line === "number") {
431 var resourceSourceFrame = this._resourceSourceFrameViewForResource(resource);
432 if (resourceSourceFrame)
433 resourceSourceFrame.revealPosition(line, column, true);
438 _showResourceView: function(resource)
440 var view = this._resourceViewForResource(resource);
442 this.visibleView.detach();
445 this._innerShowView(view);
449 * @param {!WebInspector.Resource} resource
450 * @return {?WebInspector.View}
452 _resourceViewForResource: function(resource)
454 if (WebInspector.ResourceView.hasTextContent(resource)) {
455 var treeElement = this._findTreeElementForResource(resource);
458 return treeElement.sourceView();
460 return WebInspector.ResourceView.nonSourceViewForResource(resource);
464 * @param {!WebInspector.Resource} resource
465 * @return {?WebInspector.ResourceSourceFrame}
467 _resourceSourceFrameViewForResource: function(resource)
469 var resourceView = this._resourceViewForResource(resource);
470 if (resourceView && resourceView instanceof WebInspector.ResourceSourceFrame)
471 return /** @type {!WebInspector.ResourceSourceFrame} */ (resourceView);
476 * @param {!WebInspector.Database} database
477 * @param {string=} tableName
479 _showDatabase: function(database, tableName)
486 var tableViews = this._databaseTableViews.get(database);
488 tableViews = /** @type {!Object.<string, !WebInspector.DatabaseTableView>} */ ({});
489 this._databaseTableViews.put(database, tableViews);
491 view = tableViews[tableName];
493 view = new WebInspector.DatabaseTableView(database, tableName);
494 tableViews[tableName] = view;
497 view = this._databaseQueryViews.get(database);
499 view = new WebInspector.DatabaseQueryView(database);
500 this._databaseQueryViews.put(database, view);
501 view.addEventListener(WebInspector.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this);
505 this._innerShowView(view);
509 * @param {!WebInspector.View} view
511 showIndexedDB: function(view)
513 this._innerShowView(view);
517 * @param {!WebInspector.DOMStorage} domStorage
519 _showDOMStorage: function(domStorage)
525 view = this._domStorageViews.get(domStorage);
527 view = new WebInspector.DOMStorageItemsView(domStorage);
528 this._domStorageViews.put(domStorage, view);
531 this._innerShowView(view);
535 * @param {!WebInspector.CookieTreeElement} treeElement
536 * @param {string} cookieDomain
538 showCookies: function(treeElement, cookieDomain)
540 var view = this._cookieViews[cookieDomain];
542 view = new WebInspector.CookieItemsView(treeElement, cookieDomain);
543 this._cookieViews[cookieDomain] = view;
546 this._innerShowView(view);
550 * @param {string} cookieDomain
552 clearCookies: function(cookieDomain)
554 this._cookieViews[cookieDomain].clear();
557 showApplicationCache: function(frameId)
559 if (!this._applicationCacheViews[frameId])
560 this._applicationCacheViews[frameId] = new WebInspector.ApplicationCacheItemsView(this._applicationCacheModel, frameId);
562 this._innerShowView(this._applicationCacheViews[frameId]);
566 * @param {!WebInspector.View} view
568 showFileSystem: function(view)
570 this._innerShowView(view);
573 showCategoryView: function(categoryName)
575 if (!this._categoryView)
576 this._categoryView = new WebInspector.StorageCategoryView();
577 this._categoryView.setText(categoryName);
578 this._innerShowView(this._categoryView);
581 _innerShowView: function(view)
583 if (this.visibleView === view)
586 if (this.visibleView)
587 this.visibleView.detach();
589 view.show(this.storageViews);
590 this.visibleView = view;
592 this.storageViewStatusBarItemsContainer.removeChildren();
593 var statusBarItems = view.statusBarItems || [];
594 for (var i = 0; i < statusBarItems.length; ++i)
595 this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
598 closeVisibleView: function()
600 if (!this.visibleView)
602 this.visibleView.detach();
603 delete this.visibleView;
606 _updateDatabaseTables: function(event)
608 var database = event.data;
613 var databasesTreeElement = this._databaseTreeElements.get(database);
614 if (!databasesTreeElement)
617 databasesTreeElement.shouldRefreshChildren = true;
618 var tableViews = this._databaseTableViews.get(database);
623 var tableNamesHash = {};
625 function tableNamesCallback(tableNames)
627 var tableNamesLength = tableNames.length;
628 for (var i = 0; i < tableNamesLength; ++i)
629 tableNamesHash[tableNames[i]] = true;
631 for (var tableName in tableViews) {
632 if (!(tableName in tableNamesHash)) {
633 if (self.visibleView === tableViews[tableName])
634 self.closeVisibleView();
635 delete tableViews[tableName];
639 database.getTableNames(tableNamesCallback);
642 _populateDOMStorageTree: function()
644 WebInspector.domStorageModel.storages().forEach(this._addDOMStorage.bind(this));
645 WebInspector.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this);
646 WebInspector.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this);
649 _populateApplicationCacheTree: function()
651 this._applicationCacheModel = new WebInspector.ApplicationCacheModel();
653 this._applicationCacheViews = {};
654 this._applicationCacheFrameElements = {};
655 this._applicationCacheManifestElements = {};
657 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded, this._applicationCacheFrameManifestAdded, this);
658 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved, this._applicationCacheFrameManifestRemoved, this);
660 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated, this._applicationCacheFrameManifestStatusChanged, this);
661 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged, this._applicationCacheNetworkStateChanged, this);
664 _applicationCacheFrameManifestAdded: function(event)
666 var frameId = event.data;
667 var manifestURL = this._applicationCacheModel.frameManifestURL(frameId);
668 var status = this._applicationCacheModel.frameManifestStatus(frameId)
670 var manifestTreeElement = this._applicationCacheManifestElements[manifestURL]
671 if (!manifestTreeElement) {
672 manifestTreeElement = new WebInspector.ApplicationCacheManifestTreeElement(this, manifestURL);
673 this.applicationCacheListTreeElement.appendChild(manifestTreeElement);
674 this._applicationCacheManifestElements[manifestURL] = manifestTreeElement;
677 var frameTreeElement = new WebInspector.ApplicationCacheFrameTreeElement(this, frameId, manifestURL);
678 manifestTreeElement.appendChild(frameTreeElement);
679 manifestTreeElement.expand();
680 this._applicationCacheFrameElements[frameId] = frameTreeElement;
683 _applicationCacheFrameManifestRemoved: function(event)
685 var frameId = event.data;
686 var frameTreeElement = this._applicationCacheFrameElements[frameId];
687 if (!frameTreeElement)
690 var manifestURL = frameTreeElement.manifestURL;
691 delete this._applicationCacheFrameElements[frameId];
692 delete this._applicationCacheViews[frameId];
693 frameTreeElement.parent.removeChild(frameTreeElement);
695 var manifestTreeElement = this._applicationCacheManifestElements[manifestURL];
696 if (manifestTreeElement.children.length !== 0)
699 delete this._applicationCacheManifestElements[manifestURL];
700 manifestTreeElement.parent.removeChild(manifestTreeElement);
703 _applicationCacheFrameManifestStatusChanged: function(event)
705 var frameId = event.data;
706 var status = this._applicationCacheModel.frameManifestStatus(frameId)
708 if (this._applicationCacheViews[frameId])
709 this._applicationCacheViews[frameId].updateStatus(status);
712 _applicationCacheNetworkStateChanged: function(event)
714 var isNowOnline = event.data;
716 for (var manifestURL in this._applicationCacheViews)
717 this._applicationCacheViews[manifestURL].updateNetworkState(isNowOnline);
720 _findTreeElementForResource: function(resource)
722 function isAncestor(ancestor, object)
724 // Redirects, XHRs do not belong to the tree, it is fine to silently return false here.
728 function getParent(object)
730 // Redirects, XHRs do not belong to the tree, it is fine to silently return false here.
734 return this.sidebarTree.findTreeElement(resource, isAncestor, getParent);
737 showView: function(view)
740 this.showResource(view.resource);
743 _onmousemove: function(event)
745 var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY);
749 var listNode = nodeUnderMouse.enclosingNodeOrSelfWithNodeName("li");
753 var element = listNode.treeElement;
754 if (this._previousHoveredElement === element)
757 if (this._previousHoveredElement) {
758 this._previousHoveredElement.hovered = false;
759 delete this._previousHoveredElement;
762 if (element instanceof WebInspector.FrameTreeElement) {
763 this._previousHoveredElement = element;
764 element.hovered = true;
768 _onmouseout: function(event)
770 if (this._previousHoveredElement) {
771 this._previousHoveredElement.hovered = false;
772 delete this._previousHoveredElement;
776 __proto__: WebInspector.PanelWithSidebarTree.prototype
781 * @implements {WebInspector.Revealer}
783 WebInspector.ResourcesPanel.ResourceRevealer = function()
787 WebInspector.ResourcesPanel.ResourceRevealer.prototype = {
789 * @param {!Object} resource
790 * @param {number=} lineNumber
792 reveal: function(resource, lineNumber)
794 if (resource instanceof WebInspector.Resource)
795 /** @type {!WebInspector.ResourcesPanel} */ (WebInspector.inspectorView.showPanel("resources")).showResource(resource, lineNumber);
801 * @extends {TreeElement}
802 * @param {boolean=} hasChildren
803 * @param {boolean=} noIcon
805 WebInspector.BaseStorageTreeElement = function(storagePanel, representedObject, title, iconClasses, hasChildren, noIcon)
807 TreeElement.call(this, "", representedObject, hasChildren);
808 this._storagePanel = storagePanel;
809 this._titleText = title;
810 this._iconClasses = iconClasses;
811 this._noIcon = noIcon;
814 WebInspector.BaseStorageTreeElement.prototype = {
817 this.listItemElement.removeChildren();
818 if (this._iconClasses) {
819 for (var i = 0; i < this._iconClasses.length; ++i)
820 this.listItemElement.classList.add(this._iconClasses[i]);
823 var selectionElement = document.createElement("div");
824 selectionElement.className = "selection";
825 this.listItemElement.appendChild(selectionElement);
828 this.imageElement = document.createElement("img");
829 this.imageElement.className = "icon";
830 this.listItemElement.appendChild(this.imageElement);
833 this.titleElement = document.createElement("div");
834 this.titleElement.className = "base-storage-tree-element-title";
835 this._titleTextNode = document.createTextNode("");
836 this.titleElement.appendChild(this._titleTextNode);
838 this._updateSubtitle();
839 this.listItemElement.appendChild(this.titleElement);
844 return this._displayName;
847 _updateDisplayName: function()
849 this._displayName = this._titleText || "";
850 if (this._subtitleText)
851 this._displayName += " (" + this._subtitleText + ")";
854 _updateTitle: function()
856 this._updateDisplayName();
858 if (!this.titleElement)
861 this._titleTextNode.textContent = this._titleText || "";
864 _updateSubtitle: function()
866 this._updateDisplayName();
868 if (!this.titleElement)
871 if (this._subtitleText) {
872 if (!this._subtitleElement) {
873 this._subtitleElement = document.createElement("span");
874 this._subtitleElement.className = "base-storage-tree-element-subtitle";
875 this.titleElement.appendChild(this._subtitleElement);
877 this._subtitleElement.textContent = "(" + this._subtitleText + ")";
878 } else if (this._subtitleElement) {
879 this.titleElement.removeChild(this._subtitleElement);
880 delete this._subtitleElement;
888 onselect: function(selectedByUser)
892 var itemURL = this.itemURL;
894 WebInspector.settings.resourcesLastSelectedItem.set(itemURL);
903 if (this.listItemElement)
904 this.listItemElement.scrollIntoViewIfNeeded(false);
909 return this._titleText;
912 set titleText(titleText)
914 this._titleText = titleText;
920 return this._subtitleText;
923 set subtitleText(subtitleText)
925 this._subtitleText = subtitleText;
926 this._updateSubtitle();
929 __proto__: TreeElement.prototype
934 * @extends {WebInspector.BaseStorageTreeElement}
935 * @param {boolean=} noIcon
937 WebInspector.StorageCategoryTreeElement = function(storagePanel, categoryName, settingsKey, iconClasses, noIcon)
939 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, categoryName, iconClasses, false, noIcon);
940 this._expandedSettingKey = "resources" + settingsKey + "Expanded";
941 WebInspector.settings[this._expandedSettingKey] = WebInspector.settings.createSetting(this._expandedSettingKey, settingsKey === "Frames");
942 this._categoryName = categoryName;
945 WebInspector.StorageCategoryTreeElement.prototype = {
948 return "category://" + this._categoryName;
955 onselect: function(selectedByUser)
957 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
958 this._storagePanel.showCategoryView(this._categoryName);
967 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
968 if (WebInspector.settings[this._expandedSettingKey].get())
977 WebInspector.settings[this._expandedSettingKey].set(true);
983 oncollapse: function()
985 WebInspector.settings[this._expandedSettingKey].set(false);
988 __proto__: WebInspector.BaseStorageTreeElement.prototype
993 * @extends {WebInspector.BaseStorageTreeElement}
995 WebInspector.FrameTreeElement = function(storagePanel, frame)
997 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, "", ["frame-storage-tree-item"]);
999 this.frameNavigated(frame);
1002 WebInspector.FrameTreeElement.prototype = {
1003 frameNavigated: function(frame)
1005 this.removeChildren();
1006 this._frameId = frame.id;
1008 this.titleText = frame.name;
1009 this.subtitleText = new WebInspector.ParsedURL(frame.url).displayName;
1011 this._categoryElements = {};
1012 this._treeElementForResource = {};
1014 this._storagePanel.addDocumentURL(frame.url);
1019 return "frame://" + encodeURI(this.displayName);
1026 onselect: function(selectedByUser)
1028 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1029 this._storagePanel.showCategoryView(this.displayName);
1031 this.listItemElement.classList.remove("hovered");
1032 DOMAgent.hideHighlight();
1036 set hovered(hovered)
1039 this.listItemElement.classList.add("hovered");
1040 DOMAgent.highlightFrame(this._frameId, WebInspector.Color.PageHighlight.Content.toProtocolRGBA(), WebInspector.Color.PageHighlight.ContentOutline.toProtocolRGBA());
1042 this.listItemElement.classList.remove("hovered");
1043 DOMAgent.hideHighlight();
1047 appendResource: function(resource)
1049 if (resource.isHidden())
1051 var categoryName = resource.type.name();
1052 var categoryElement = resource.type === WebInspector.resourceTypes.Document ? this : this._categoryElements[categoryName];
1053 if (!categoryElement) {
1054 categoryElement = new WebInspector.StorageCategoryTreeElement(this._storagePanel, resource.type.categoryTitle(), categoryName, null, true);
1055 this._categoryElements[resource.type.name()] = categoryElement;
1056 this._insertInPresentationOrder(this, categoryElement);
1058 var resourceTreeElement = new WebInspector.FrameResourceTreeElement(this._storagePanel, resource);
1059 this._insertInPresentationOrder(categoryElement, resourceTreeElement);
1060 this._treeElementForResource[resource.url] = resourceTreeElement;
1064 * @param {string} url
1065 * @return {?WebInspector.Resource}
1067 resourceByURL: function(url)
1069 var treeElement = this._treeElementForResource[url];
1070 return treeElement ? treeElement.representedObject : null;
1073 appendChild: function(treeElement)
1075 this._insertInPresentationOrder(this, treeElement);
1078 _insertInPresentationOrder: function(parentTreeElement, childTreeElement)
1080 // Insert in the alphabetical order, first frames, then resources. Document resource goes last.
1081 function typeWeight(treeElement)
1083 if (treeElement instanceof WebInspector.StorageCategoryTreeElement)
1085 if (treeElement instanceof WebInspector.FrameTreeElement)
1090 function compare(treeElement1, treeElement2)
1092 var typeWeight1 = typeWeight(treeElement1);
1093 var typeWeight2 = typeWeight(treeElement2);
1096 if (typeWeight1 > typeWeight2)
1098 else if (typeWeight1 < typeWeight2)
1101 var title1 = treeElement1.displayName || treeElement1.titleText;
1102 var title2 = treeElement2.displayName || treeElement2.titleText;
1103 result = title1.localeCompare(title2);
1108 var children = parentTreeElement.children;
1110 for (i = 0; i < children.length; ++i) {
1111 if (compare(childTreeElement, children[i]) < 0)
1114 parentTreeElement.insertChild(childTreeElement, i);
1117 __proto__: WebInspector.BaseStorageTreeElement.prototype
1122 * @extends {WebInspector.BaseStorageTreeElement}
1124 WebInspector.FrameResourceTreeElement = function(storagePanel, resource)
1126 WebInspector.BaseStorageTreeElement.call(this, storagePanel, resource, resource.displayName, ["resource-sidebar-tree-item", "resources-type-" + resource.type.name()]);
1127 this._resource = resource;
1128 this._resource.addEventListener(WebInspector.Resource.Events.MessageAdded, this._consoleMessageAdded, this);
1129 this._resource.addEventListener(WebInspector.Resource.Events.MessagesCleared, this._consoleMessagesCleared, this);
1130 this.tooltip = resource.url;
1133 WebInspector.FrameResourceTreeElement.prototype = {
1136 return this._resource.url;
1143 onselect: function(selectedByUser)
1145 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1146 this._storagePanel._showResourceView(this._resource);
1154 ondblclick: function(event)
1156 InspectorFrontendHost.openInNewTab(this._resource.url);
1163 onattach: function()
1165 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1167 if (this._resource.type === WebInspector.resourceTypes.Image) {
1168 var previewImage = document.createElement("img");
1169 previewImage.className = "image-resource-icon-preview";
1170 this._resource.populateImageSource(previewImage);
1172 var iconElement = document.createElement("div");
1173 iconElement.className = "icon";
1174 iconElement.appendChild(previewImage);
1175 this.listItemElement.replaceChild(iconElement, this.imageElement);
1178 this._statusElement = document.createElement("div");
1179 this._statusElement.className = "status";
1180 this.listItemElement.insertBefore(this._statusElement, this.titleElement);
1182 this.listItemElement.draggable = true;
1183 this.listItemElement.addEventListener("dragstart", this._ondragstart.bind(this), false);
1184 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1186 this._updateErrorsAndWarningsBubbles();
1190 * @param {!MouseEvent} event
1193 _ondragstart: function(event)
1195 event.dataTransfer.setData("text/plain", this._resource.content);
1196 event.dataTransfer.effectAllowed = "copy";
1200 _handleContextMenuEvent: function(event)
1202 var contextMenu = new WebInspector.ContextMenu(event);
1203 contextMenu.appendApplicableItems(this._resource);
1207 _setBubbleText: function(x)
1209 if (!this._bubbleElement) {
1210 this._bubbleElement = document.createElement("div");
1211 this._bubbleElement.className = "bubble";
1212 this._statusElement.appendChild(this._bubbleElement);
1215 this._bubbleElement.textContent = x;
1218 _resetBubble: function()
1220 if (this._bubbleElement) {
1221 this._bubbleElement.textContent = "";
1222 this._bubbleElement.classList.remove("warning");
1223 this._bubbleElement.classList.remove("error");
1227 _updateErrorsAndWarningsBubbles: function()
1229 if (this._storagePanel.currentQuery)
1232 this._resetBubble();
1234 if (this._resource.warnings || this._resource.errors)
1235 this._setBubbleText(this._resource.warnings + this._resource.errors);
1237 if (this._resource.warnings)
1238 this._bubbleElement.classList.add("warning");
1240 if (this._resource.errors)
1241 this._bubbleElement.classList.add("error");
1244 _consoleMessagesCleared: function()
1246 // FIXME: move to the SourceFrame.
1247 if (this._sourceView)
1248 this._sourceView.clearMessages();
1250 this._updateErrorsAndWarningsBubbles();
1253 _consoleMessageAdded: function(event)
1255 var msg = event.data;
1256 if (this._sourceView)
1257 this._sourceView.addMessage(msg);
1258 this._updateErrorsAndWarningsBubbles();
1262 * @return {!WebInspector.ResourceSourceFrame}
1264 sourceView: function()
1266 if (!this._sourceView) {
1267 var sourceFrame = new WebInspector.ResourceSourceFrame(this._resource);
1268 sourceFrame.setHighlighterType(this._resource.canonicalMimeType());
1269 this._sourceView = sourceFrame;
1270 if (this._resource.messages) {
1271 for (var i = 0; i < this._resource.messages.length; i++)
1272 this._sourceView.addMessage(this._resource.messages[i]);
1275 return this._sourceView;
1278 __proto__: WebInspector.BaseStorageTreeElement.prototype
1283 * @extends {WebInspector.BaseStorageTreeElement}
1284 * @param {!WebInspector.Database} database
1286 WebInspector.DatabaseTreeElement = function(storagePanel, database)
1288 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, database.name, ["database-storage-tree-item"], true);
1289 this._database = database;
1292 WebInspector.DatabaseTreeElement.prototype = {
1295 return "database://" + encodeURI(this._database.name);
1302 onselect: function(selectedByUser)
1304 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1305 this._storagePanel._showDatabase(this._database);
1312 onexpand: function()
1314 this._updateChildren();
1317 _updateChildren: function()
1319 this.removeChildren();
1322 * @param {!Array.<string>} tableNames
1323 * @this {WebInspector.DatabaseTreeElement}
1325 function tableNamesCallback(tableNames)
1327 var tableNamesLength = tableNames.length;
1328 for (var i = 0; i < tableNamesLength; ++i)
1329 this.appendChild(new WebInspector.DatabaseTableTreeElement(this._storagePanel, this._database, tableNames[i]));
1331 this._database.getTableNames(tableNamesCallback.bind(this));
1334 __proto__: WebInspector.BaseStorageTreeElement.prototype
1339 * @extends {WebInspector.BaseStorageTreeElement}
1341 WebInspector.DatabaseTableTreeElement = function(storagePanel, database, tableName)
1343 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, tableName, ["database-storage-tree-item"]);
1344 this._database = database;
1345 this._tableName = tableName;
1348 WebInspector.DatabaseTableTreeElement.prototype = {
1351 return "database://" + encodeURI(this._database.name) + "/" + encodeURI(this._tableName);
1358 onselect: function(selectedByUser)
1360 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1361 this._storagePanel._showDatabase(this._database, this._tableName);
1365 __proto__: WebInspector.BaseStorageTreeElement.prototype
1370 * @extends {WebInspector.StorageCategoryTreeElement}
1371 * @param {!WebInspector.ResourcesPanel} storagePanel
1373 WebInspector.IndexedDBTreeElement = function(storagePanel)
1375 WebInspector.StorageCategoryTreeElement.call(this, storagePanel, WebInspector.UIString("IndexedDB"), "IndexedDB", ["indexed-db-storage-tree-item"]);
1378 WebInspector.IndexedDBTreeElement.prototype = {
1379 _initialize: function()
1381 this._createIndexedDBModel();
1384 onattach: function()
1386 WebInspector.StorageCategoryTreeElement.prototype.onattach.call(this);
1387 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1390 _handleContextMenuEvent: function(event)
1392 var contextMenu = new WebInspector.ContextMenu(event);
1393 contextMenu.appendItem(WebInspector.UIString("Refresh IndexedDB"), this.refreshIndexedDB.bind(this));
1397 _createIndexedDBModel: function()
1399 this._indexedDBModel = new WebInspector.IndexedDBModel();
1400 this._idbDatabaseTreeElements = [];
1401 this._indexedDBModel.addEventListener(WebInspector.IndexedDBModel.EventTypes.DatabaseAdded, this._indexedDBAdded, this);
1402 this._indexedDBModel.addEventListener(WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved, this._indexedDBRemoved, this);
1403 this._indexedDBModel.addEventListener(WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded, this._indexedDBLoaded, this);
1406 refreshIndexedDB: function()
1408 if (!this._indexedDBModel) {
1409 this._createIndexedDBModel();
1413 this._indexedDBModel.refreshDatabaseNames();
1417 * @param {!WebInspector.Event} event
1419 _indexedDBAdded: function(event)
1421 var databaseId = /** @type {!WebInspector.IndexedDBModel.DatabaseId} */ (event.data);
1423 var idbDatabaseTreeElement = new WebInspector.IDBDatabaseTreeElement(this._storagePanel, this._indexedDBModel, databaseId);
1424 this._idbDatabaseTreeElements.push(idbDatabaseTreeElement);
1425 this.appendChild(idbDatabaseTreeElement);
1427 this._indexedDBModel.refreshDatabase(databaseId);
1431 * @param {!WebInspector.Event} event
1433 _indexedDBRemoved: function(event)
1435 var databaseId = /** @type {!WebInspector.IndexedDBModel.DatabaseId} */ (event.data);
1437 var idbDatabaseTreeElement = this._idbDatabaseTreeElement(databaseId)
1438 if (!idbDatabaseTreeElement)
1441 idbDatabaseTreeElement.clear();
1442 this.removeChild(idbDatabaseTreeElement);
1443 this._idbDatabaseTreeElements.remove(idbDatabaseTreeElement);
1447 * @param {!WebInspector.Event} event
1449 _indexedDBLoaded: function(event)
1451 var database = /** @type {!WebInspector.IndexedDBModel.Database} */ (event.data);
1453 var idbDatabaseTreeElement = this._idbDatabaseTreeElement(database.databaseId)
1454 if (!idbDatabaseTreeElement)
1457 idbDatabaseTreeElement.update(database);
1461 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1462 * @return {?WebInspector.IDBDatabaseTreeElement}
1464 _idbDatabaseTreeElement: function(databaseId)
1467 for (var i = 0; i < this._idbDatabaseTreeElements.length; ++i) {
1468 if (this._idbDatabaseTreeElements[i]._databaseId.equals(databaseId)) {
1474 return this._idbDatabaseTreeElements[i];
1478 __proto__: WebInspector.StorageCategoryTreeElement.prototype
1483 * @extends {WebInspector.StorageCategoryTreeElement}
1484 * @param {!WebInspector.ResourcesPanel} storagePanel
1486 WebInspector.FileSystemListTreeElement = function(storagePanel)
1488 WebInspector.StorageCategoryTreeElement.call(this, storagePanel, WebInspector.UIString("FileSystem"), "FileSystem", ["file-system-storage-tree-item"]);
1491 WebInspector.FileSystemListTreeElement.prototype = {
1492 _initialize: function()
1494 this._refreshFileSystem();
1497 onattach: function()
1499 WebInspector.StorageCategoryTreeElement.prototype.onattach.call(this);
1500 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1503 _handleContextMenuEvent: function(event)
1505 var contextMenu = new WebInspector.ContextMenu(event);
1506 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Refresh FileSystem list" : "Refresh FileSystem List"), this._refreshFileSystem.bind(this));
1510 _fileSystemAdded: function(event)
1512 var fileSystem = /** @type {!WebInspector.FileSystemModel.FileSystem} */ (event.data);
1513 var fileSystemTreeElement = new WebInspector.FileSystemTreeElement(this._storagePanel, fileSystem);
1514 this.appendChild(fileSystemTreeElement);
1517 _fileSystemRemoved: function(event)
1519 var fileSystem = /** @type {!WebInspector.FileSystemModel.FileSystem} */ (event.data);
1520 var fileSystemTreeElement = this._fileSystemTreeElementByName(fileSystem.name);
1521 if (!fileSystemTreeElement)
1523 fileSystemTreeElement.clear();
1524 this.removeChild(fileSystemTreeElement);
1527 _fileSystemTreeElementByName: function(fileSystemName)
1529 for (var i = 0; i < this.children.length; ++i) {
1530 var child = /** @type {!WebInspector.FileSystemTreeElement} */ (this.children[i]);
1531 if (child.fileSystemName === fileSystemName)
1532 return this.children[i];
1537 _refreshFileSystem: function()
1539 if (!this._fileSystemModel) {
1540 this._fileSystemModel = new WebInspector.FileSystemModel();
1541 this._fileSystemModel.addEventListener(WebInspector.FileSystemModel.EventTypes.FileSystemAdded, this._fileSystemAdded, this);
1542 this._fileSystemModel.addEventListener(WebInspector.FileSystemModel.EventTypes.FileSystemRemoved, this._fileSystemRemoved, this);
1545 this._fileSystemModel.refreshFileSystemList();
1548 __proto__: WebInspector.StorageCategoryTreeElement.prototype
1553 * @extends {WebInspector.BaseStorageTreeElement}
1554 * @param {!WebInspector.ResourcesPanel} storagePanel
1555 * @param {!WebInspector.IndexedDBModel} model
1556 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1558 WebInspector.IDBDatabaseTreeElement = function(storagePanel, model, databaseId)
1560 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, databaseId.name + " - " + databaseId.securityOrigin, ["indexed-db-storage-tree-item"]);
1561 this._model = model;
1562 this._databaseId = databaseId;
1563 this._idbObjectStoreTreeElements = {};
1566 WebInspector.IDBDatabaseTreeElement.prototype = {
1569 return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name;
1572 onattach: function()
1574 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1575 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1578 _handleContextMenuEvent: function(event)
1580 var contextMenu = new WebInspector.ContextMenu(event);
1581 contextMenu.appendItem(WebInspector.UIString("Refresh IndexedDB"), this._refreshIndexedDB.bind(this));
1585 _refreshIndexedDB: function()
1587 this._model.refreshDatabaseNames();
1591 * @param {!WebInspector.IndexedDBModel.Database} database
1593 update: function(database)
1595 this._database = database;
1596 var objectStoreNames = {};
1597 for (var objectStoreName in this._database.objectStores) {
1598 var objectStore = this._database.objectStores[objectStoreName];
1599 objectStoreNames[objectStore.name] = true;
1600 if (!this._idbObjectStoreTreeElements[objectStore.name]) {
1601 var idbObjectStoreTreeElement = new WebInspector.IDBObjectStoreTreeElement(this._storagePanel, this._model, this._databaseId, objectStore);
1602 this._idbObjectStoreTreeElements[objectStore.name] = idbObjectStoreTreeElement;
1603 this.appendChild(idbObjectStoreTreeElement);
1605 this._idbObjectStoreTreeElements[objectStore.name].update(objectStore);
1607 for (var objectStoreName in this._idbObjectStoreTreeElements) {
1608 if (!objectStoreNames[objectStoreName])
1609 this._objectStoreRemoved(objectStoreName);
1612 if (this.children.length) {
1613 this.hasChildren = true;
1618 this._view.update(database);
1620 this._updateTooltip();
1623 _updateTooltip: function()
1625 this.tooltip = WebInspector.UIString("Version") + ": " + this._database.version;
1632 onselect: function(selectedByUser)
1634 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1636 this._view = new WebInspector.IDBDatabaseView(this._database);
1638 this._storagePanel.showIndexedDB(this._view);
1643 * @param {string} objectStoreName
1645 _objectStoreRemoved: function(objectStoreName)
1647 var objectStoreTreeElement = this._idbObjectStoreTreeElements[objectStoreName];
1648 objectStoreTreeElement.clear();
1649 this.removeChild(objectStoreTreeElement);
1650 delete this._idbObjectStoreTreeElements[objectStoreName];
1655 for (var objectStoreName in this._idbObjectStoreTreeElements)
1656 this._objectStoreRemoved(objectStoreName);
1659 __proto__: WebInspector.BaseStorageTreeElement.prototype
1664 * @extends {WebInspector.BaseStorageTreeElement}
1665 * @param {!WebInspector.ResourcesPanel} storagePanel
1666 * @param {!WebInspector.IndexedDBModel} model
1667 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1668 * @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
1670 WebInspector.IDBObjectStoreTreeElement = function(storagePanel, model, databaseId, objectStore)
1672 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, objectStore.name, ["indexed-db-object-store-storage-tree-item"]);
1673 this._model = model;
1674 this._databaseId = databaseId;
1675 this._idbIndexTreeElements = {};
1678 WebInspector.IDBObjectStoreTreeElement.prototype = {
1681 return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name + "/" + this._objectStore.name;
1684 onattach: function()
1686 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1687 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1690 _handleContextMenuEvent: function(event)
1692 var contextMenu = new WebInspector.ContextMenu(event);
1693 contextMenu.appendItem(WebInspector.UIString("Clear"), this._clearObjectStore.bind(this));
1697 _clearObjectStore: function()
1700 * @this {WebInspector.IDBObjectStoreTreeElement}
1702 function callback() {
1703 this.update(this._objectStore);
1705 this._model.clearObjectStore(this._databaseId, this._objectStore.name, callback.bind(this));
1709 * @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
1711 update: function(objectStore)
1713 this._objectStore = objectStore;
1715 var indexNames = {};
1716 for (var indexName in this._objectStore.indexes) {
1717 var index = this._objectStore.indexes[indexName];
1718 indexNames[index.name] = true;
1719 if (!this._idbIndexTreeElements[index.name]) {
1720 var idbIndexTreeElement = new WebInspector.IDBIndexTreeElement(this._storagePanel, this._model, this._databaseId, this._objectStore, index);
1721 this._idbIndexTreeElements[index.name] = idbIndexTreeElement;
1722 this.appendChild(idbIndexTreeElement);
1724 this._idbIndexTreeElements[index.name].update(index);
1726 for (var indexName in this._idbIndexTreeElements) {
1727 if (!indexNames[indexName])
1728 this._indexRemoved(indexName);
1730 for (var indexName in this._idbIndexTreeElements) {
1731 if (!indexNames[indexName]) {
1732 this.removeChild(this._idbIndexTreeElements[indexName]);
1733 delete this._idbIndexTreeElements[indexName];
1737 if (this.children.length) {
1738 this.hasChildren = true;
1743 this._view.update(this._objectStore);
1745 this._updateTooltip();
1748 _updateTooltip: function()
1751 var keyPathString = this._objectStore.keyPathString;
1752 var tooltipString = keyPathString !== null ? (WebInspector.UIString("Key path: ") + keyPathString) : "";
1753 if (this._objectStore.autoIncrement)
1754 tooltipString += "\n" + WebInspector.UIString("autoIncrement");
1755 this.tooltip = tooltipString
1762 onselect: function(selectedByUser)
1764 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1766 this._view = new WebInspector.IDBDataView(this._model, this._databaseId, this._objectStore, null);
1768 this._storagePanel.showIndexedDB(this._view);
1773 * @param {string} indexName
1775 _indexRemoved: function(indexName)
1777 var indexTreeElement = this._idbIndexTreeElements[indexName];
1778 indexTreeElement.clear();
1779 this.removeChild(indexTreeElement);
1780 delete this._idbIndexTreeElements[indexName];
1785 for (var indexName in this._idbIndexTreeElements)
1786 this._indexRemoved(indexName);
1791 __proto__: WebInspector.BaseStorageTreeElement.prototype
1796 * @extends {WebInspector.BaseStorageTreeElement}
1797 * @param {!WebInspector.ResourcesPanel} storagePanel
1798 * @param {!WebInspector.IndexedDBModel} model
1799 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1800 * @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
1801 * @param {!WebInspector.IndexedDBModel.Index} index
1803 WebInspector.IDBIndexTreeElement = function(storagePanel, model, databaseId, objectStore, index)
1805 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, index.name, ["indexed-db-index-storage-tree-item"]);
1806 this._model = model;
1807 this._databaseId = databaseId;
1808 this._objectStore = objectStore;
1809 this._index = index;
1812 WebInspector.IDBIndexTreeElement.prototype = {
1815 return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name + "/" + this._objectStore.name + "/" + this._index.name;
1819 * @param {!WebInspector.IndexedDBModel.Index} index
1821 update: function(index)
1823 this._index = index;
1826 this._view.update(this._index);
1828 this._updateTooltip();
1831 _updateTooltip: function()
1833 var tooltipLines = [];
1834 var keyPathString = this._index.keyPathString;
1835 tooltipLines.push(WebInspector.UIString("Key path: ") + keyPathString);
1836 if (this._index.unique)
1837 tooltipLines.push(WebInspector.UIString("unique"));
1838 if (this._index.multiEntry)
1839 tooltipLines.push(WebInspector.UIString("multiEntry"));
1840 this.tooltip = tooltipLines.join("\n");
1847 onselect: function(selectedByUser)
1849 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1851 this._view = new WebInspector.IDBDataView(this._model, this._databaseId, this._objectStore, this._index);
1853 this._storagePanel.showIndexedDB(this._view);
1863 __proto__: WebInspector.BaseStorageTreeElement.prototype
1868 * @extends {WebInspector.BaseStorageTreeElement}
1870 WebInspector.DOMStorageTreeElement = function(storagePanel, domStorage, className)
1872 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, domStorage.securityOrigin ? domStorage.securityOrigin : WebInspector.UIString("Local Files"), ["domstorage-storage-tree-item", className]);
1873 this._domStorage = domStorage;
1876 WebInspector.DOMStorageTreeElement.prototype = {
1879 return "storage://" + this._domStorage.securityOrigin + "/" + (this._domStorage.isLocalStorage ? "local" : "session");
1886 onselect: function(selectedByUser)
1888 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1889 this._storagePanel._showDOMStorage(this._domStorage);
1893 __proto__: WebInspector.BaseStorageTreeElement.prototype
1898 * @extends {WebInspector.BaseStorageTreeElement}
1900 WebInspector.CookieTreeElement = function(storagePanel, cookieDomain)
1902 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, cookieDomain ? cookieDomain : WebInspector.UIString("Local Files"), ["cookie-storage-tree-item"]);
1903 this._cookieDomain = cookieDomain;
1906 WebInspector.CookieTreeElement.prototype = {
1909 return "cookies://" + this._cookieDomain;
1912 onattach: function()
1914 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1915 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1919 * @param {!Event} event
1921 _handleContextMenuEvent: function(event)
1923 var contextMenu = new WebInspector.ContextMenu(event);
1924 contextMenu.appendItem(WebInspector.UIString("Clear"), this._clearCookies.bind(this));
1929 * @param {string} domain
1931 _clearCookies: function(domain)
1933 this._storagePanel.clearCookies(this._cookieDomain);
1940 onselect: function(selectedByUser)
1942 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1943 this._storagePanel.showCookies(this, this._cookieDomain);
1947 __proto__: WebInspector.BaseStorageTreeElement.prototype
1952 * @extends {WebInspector.BaseStorageTreeElement}
1954 WebInspector.ApplicationCacheManifestTreeElement = function(storagePanel, manifestURL)
1956 var title = new WebInspector.ParsedURL(manifestURL).displayName;
1957 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, title, ["application-cache-storage-tree-item"]);
1958 this.tooltip = manifestURL;
1959 this._manifestURL = manifestURL;
1962 WebInspector.ApplicationCacheManifestTreeElement.prototype = {
1965 return "appcache://" + this._manifestURL;
1970 return this._manifestURL;
1977 onselect: function(selectedByUser)
1979 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1980 this._storagePanel.showCategoryView(this._manifestURL);
1984 __proto__: WebInspector.BaseStorageTreeElement.prototype
1989 * @extends {WebInspector.BaseStorageTreeElement}
1991 WebInspector.ApplicationCacheFrameTreeElement = function(storagePanel, frameId, manifestURL)
1993 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, "", ["frame-storage-tree-item"]);
1994 this._frameId = frameId;
1995 this._manifestURL = manifestURL;
1996 this._refreshTitles();
1999 WebInspector.ApplicationCacheFrameTreeElement.prototype = {
2002 return "appcache://" + this._manifestURL + "/" + encodeURI(this.displayName);
2007 return this._frameId;
2012 return this._manifestURL;
2015 _refreshTitles: function()
2017 var frame = WebInspector.resourceTreeModel.frameForId(this._frameId);
2019 this.subtitleText = WebInspector.UIString("new frame");
2022 this.titleText = frame.name;
2023 this.subtitleText = new WebInspector.ParsedURL(frame.url).displayName;
2026 frameNavigated: function()
2028 this._refreshTitles();
2035 onselect: function(selectedByUser)
2037 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
2038 this._storagePanel.showApplicationCache(this._frameId);
2042 __proto__: WebInspector.BaseStorageTreeElement.prototype
2047 * @extends {WebInspector.BaseStorageTreeElement}
2048 * @param {!WebInspector.ResourcesPanel} storagePanel
2049 * @param {!WebInspector.FileSystemModel.FileSystem} fileSystem
2051 WebInspector.FileSystemTreeElement = function(storagePanel, fileSystem)
2053 var displayName = fileSystem.type + " - " + fileSystem.origin;
2054 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, displayName, ["file-system-storage-tree-item"]);
2055 this._fileSystem = fileSystem;
2058 WebInspector.FileSystemTreeElement.prototype = {
2059 get fileSystemName()
2061 return this._fileSystem.name;
2066 return "filesystem://" + this._fileSystem.name;
2073 onselect: function(selectedByUser)
2075 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
2076 this._fileSystemView = new WebInspector.FileSystemView(this._fileSystem);
2077 this._storagePanel.showFileSystem(this._fileSystemView);
2083 if (this.fileSystemView && this._storagePanel.visibleView === this.fileSystemView)
2084 this._storagePanel.closeVisibleView();
2087 __proto__: WebInspector.BaseStorageTreeElement.prototype
2092 * @extends {WebInspector.VBox}
2094 WebInspector.StorageCategoryView = function()
2096 WebInspector.VBox.call(this);
2098 this.element.classList.add("storage-view");
2099 this._emptyView = new WebInspector.EmptyView("");
2100 this._emptyView.show(this.element);
2103 WebInspector.StorageCategoryView.prototype = {
2104 setText: function(text)
2106 this._emptyView.text = text;
2109 __proto__: WebInspector.VBox.prototype