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.
33 * @extends {WebInspector.PanelWithSidebarTree}
34 * @implements {WebInspector.TargetManager.Observer}
36 WebInspector.ResourcesPanel = function(database)
38 WebInspector.PanelWithSidebarTree.call(this, "resources");
39 this.registerRequiredCSS("resourcesPanel.css");
41 WebInspector.settings.resourcesLastSelectedItem = WebInspector.settings.createSetting("resourcesLastSelectedItem", {});
43 this.sidebarElement().classList.add("filter-all", "children", "small", "outline-disclosure");
44 this.sidebarTree.element.classList.remove("sidebar-tree");
46 this.resourcesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Frames"), "Frames", ["frame-storage-tree-item"]);
47 this.sidebarTree.appendChild(this.resourcesListTreeElement);
49 this.databasesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Web SQL"), "Databases", ["database-storage-tree-item"]);
50 this.sidebarTree.appendChild(this.databasesListTreeElement);
52 this.indexedDBListTreeElement = new WebInspector.IndexedDBTreeElement(this);
53 this.sidebarTree.appendChild(this.indexedDBListTreeElement);
55 this.localStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Local Storage"), "LocalStorage", ["domstorage-storage-tree-item", "local-storage"]);
56 this.sidebarTree.appendChild(this.localStorageListTreeElement);
58 this.sessionStorageListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Session Storage"), "SessionStorage", ["domstorage-storage-tree-item", "session-storage"]);
59 this.sidebarTree.appendChild(this.sessionStorageListTreeElement);
61 this.cookieListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Cookies"), "Cookies", ["cookie-storage-tree-item"]);
62 this.sidebarTree.appendChild(this.cookieListTreeElement);
64 this.applicationCacheListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Application Cache"), "ApplicationCache", ["application-cache-storage-tree-item"]);
65 this.sidebarTree.appendChild(this.applicationCacheListTreeElement);
67 if (Runtime.experiments.isEnabled("fileSystemInspection")) {
68 this.fileSystemListTreeElement = new WebInspector.FileSystemListTreeElement(this);
69 this.sidebarTree.appendChild(this.fileSystemListTreeElement);
72 var mainView = new WebInspector.VBox();
73 this.storageViews = mainView.element.createChild("div", "resources-main diff-container");
74 var statusBarContainer = mainView.element.createChild("div", "resources-status-bar");
75 this.storageViewStatusBarItemsContainer = statusBarContainer.createChild("div", "status-bar");
76 mainView.show(this.mainElement());
78 /** @type {!Map.<!WebInspector.Database, !Object.<string, !WebInspector.DatabaseTableView>>} */
79 this._databaseTableViews = new Map();
80 /** @type {!Map.<!WebInspector.Database, !WebInspector.DatabaseQueryView>} */
81 this._databaseQueryViews = new Map();
82 /** @type {!Map.<!WebInspector.Database, !WebInspector.DatabaseTreeElement>} */
83 this._databaseTreeElements = new Map();
84 /** @type {!Map.<!WebInspector.DOMStorage, !WebInspector.DOMStorageItemsView>} */
85 this._domStorageViews = new Map();
86 /** @type {!Map.<!WebInspector.DOMStorage, !WebInspector.DOMStorageTreeElement>} */
87 this._domStorageTreeElements = new Map();
88 /** @type {!Object.<string, !WebInspector.CookieItemsView>} */
89 this._cookieViews = {};
90 /** @type {!Object.<string, boolean>} */
93 this.sidebarElement().addEventListener("mousemove", this._onmousemove.bind(this), false);
94 this.sidebarElement().addEventListener("mouseout", this._onmouseout.bind(this), false);
97 * @this {WebInspector.ResourcesPanel}
98 * @return {?WebInspector.SourceFrame}
100 function sourceFrameGetter()
102 var view = this.visibleView;
103 if (view && view instanceof WebInspector.SourceFrame)
104 return /** @type {!WebInspector.SourceFrame} */ (view);
107 WebInspector.GoToLineDialog.install(this, sourceFrameGetter.bind(this));
109 WebInspector.targetManager.observeTargets(this);
112 WebInspector.ResourcesPanel.prototype = {
114 * @param {!WebInspector.Target} target
116 targetAdded: function(target)
121 if (target.resourceTreeModel.cachedResourcesLoaded())
122 this._cachedResourcesLoaded();
124 target.databaseModel.databases().forEach(this._addDatabase.bind(this));
126 target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
127 target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._cachedResourcesLoaded, this);
128 target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources, this._resetWithFrames, this);
129 target.databaseModel.addEventListener(WebInspector.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this);
131 this._target = target;
135 * @param {!WebInspector.Target} target
137 targetRemoved: function(target)
139 if (target !== this._target)
143 target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
144 target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._cachedResourcesLoaded, this);
145 target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources, this._resetWithFrames, this);
146 target.databaseModel.removeEventListener(WebInspector.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this);
148 this._resetWithFrames();
154 canSearch: function()
161 WebInspector.Panel.prototype.wasShown.call(this);
165 _initialize: function()
167 if (!this._initialized && this.isShowing() && this._cachedResourcesWereLoaded) {
168 var target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.mainTarget());
169 this._populateResourceTree();
170 this._populateDOMStorageTree();
171 this._populateApplicationCacheTree(target);
172 this.indexedDBListTreeElement._initialize();
173 if (Runtime.experiments.isEnabled("fileSystemInspection"))
174 this.fileSystemListTreeElement._initialize();
175 this._initDefaultSelection();
176 this._initialized = true;
180 _loadEventFired: function()
182 this._initDefaultSelection();
185 _initDefaultSelection: function()
187 if (!this._initialized)
190 var itemURL = WebInspector.settings.resourcesLastSelectedItem.get();
192 for (var treeElement = this.sidebarTree.children[0]; treeElement; treeElement = treeElement.traverseNextTreeElement(false, this.sidebarTree, true)) {
193 if (treeElement.itemURL === itemURL) {
194 treeElement.revealAndSelect(true);
200 var mainResource = WebInspector.resourceTreeModel.inspectedPageURL() && this.resourcesListTreeElement && this.resourcesListTreeElement.expanded
201 ? WebInspector.resourceTreeModel.resourceForURL(WebInspector.resourceTreeModel.inspectedPageURL())
204 this.showResource(mainResource);
207 _resetWithFrames: function()
209 this.resourcesListTreeElement.removeChildren();
210 this._treeElementForFrameId = {};
217 var queryViews = this._databaseQueryViews.values();
218 for (var i = 0; i < queryViews.length; ++i)
219 queryViews[i].removeEventListener(WebInspector.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this);
220 this._databaseTableViews.clear();
221 this._databaseQueryViews.clear();
222 this._databaseTreeElements.clear();
223 this._domStorageViews.clear();
224 this._domStorageTreeElements.clear();
225 this._cookieViews = {};
227 this.databasesListTreeElement.removeChildren();
228 this.localStorageListTreeElement.removeChildren();
229 this.sessionStorageListTreeElement.removeChildren();
230 this.cookieListTreeElement.removeChildren();
232 if (this.visibleView && !(this.visibleView instanceof WebInspector.StorageCategoryView))
233 this.visibleView.detach();
235 this.storageViewStatusBarItemsContainer.removeChildren();
237 if (this.sidebarTree.selectedTreeElement)
238 this.sidebarTree.selectedTreeElement.deselect();
241 _populateResourceTree: function()
243 this._treeElementForFrameId = {};
244 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameAdded, this);
245 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
246 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
247 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
250 * @param {!WebInspector.ResourceTreeFrame} frame
251 * @this {WebInspector.ResourcesPanel}
253 function populateFrame(frame)
255 this._frameAdded({data:frame});
256 for (var i = 0; i < frame.childFrames.length; ++i)
257 populateFrame.call(this, frame.childFrames[i]);
259 var resources = frame.resources();
260 for (var i = 0; i < resources.length; ++i)
261 this._resourceAdded({data:resources[i]});
263 populateFrame.call(this, WebInspector.resourceTreeModel.mainFrame);
266 _frameAdded: function(event)
268 var frame = event.data;
269 var parentFrame = frame.parentFrame;
271 var parentTreeElement = parentFrame ? this._treeElementForFrameId[parentFrame.id] : this.resourcesListTreeElement;
272 if (!parentTreeElement) {
273 console.warn("No frame to route " + frame.url + " to.")
277 var frameTreeElement = new WebInspector.FrameTreeElement(this, frame);
278 this._treeElementForFrameId[frame.id] = frameTreeElement;
279 parentTreeElement.appendChild(frameTreeElement);
282 _frameDetached: function(event)
284 var frame = event.data;
285 var frameTreeElement = this._treeElementForFrameId[frame.id];
286 if (!frameTreeElement)
289 delete this._treeElementForFrameId[frame.id];
290 if (frameTreeElement.parent)
291 frameTreeElement.parent.removeChild(frameTreeElement);
294 _resourceAdded: function(event)
296 var resource = event.data;
297 var frameId = resource.frameId;
299 if (resource.statusCode >= 301 && resource.statusCode <= 303)
302 var frameTreeElement = this._treeElementForFrameId[frameId];
303 if (!frameTreeElement) {
304 // This is a frame's main resource, it will be retained
305 // and re-added by the resource manager;
309 frameTreeElement.appendResource(resource);
312 _frameNavigated: function(event)
314 var frame = event.data;
316 if (!frame.parentFrame)
319 var frameId = frame.id;
320 var frameTreeElement = this._treeElementForFrameId[frameId];
321 if (frameTreeElement)
322 frameTreeElement.frameNavigated(frame);
324 var applicationCacheFrameTreeElement = this._applicationCacheFrameElements[frameId];
325 if (applicationCacheFrameTreeElement)
326 applicationCacheFrameTreeElement.frameNavigated(frame);
329 _cachedResourcesLoaded: function()
331 this._cachedResourcesWereLoaded = true;
336 * @param {!WebInspector.Event} event
338 _databaseAdded: function(event)
340 var database = /** @type {!WebInspector.Database} */ (event.data);
341 this._addDatabase(database);
345 * @param {!WebInspector.Database} database
347 _addDatabase: function(database)
349 var databaseTreeElement = new WebInspector.DatabaseTreeElement(this, database);
350 this._databaseTreeElements.set(database, databaseTreeElement);
351 this.databasesListTreeElement.appendChild(databaseTreeElement);
354 addDocumentURL: function(url)
356 var parsedURL = url.asParsedURL();
360 var domain = parsedURL.host;
361 if (!this._domains[domain]) {
362 this._domains[domain] = true;
364 var cookieDomainTreeElement = new WebInspector.CookieTreeElement(this, domain);
365 this.cookieListTreeElement.appendChild(cookieDomainTreeElement);
370 * @param {!WebInspector.Event} event
372 _domStorageAdded: function(event)
374 var domStorage = /** @type {!WebInspector.DOMStorage} */ (event.data);
375 this._addDOMStorage(domStorage);
379 * @param {!WebInspector.DOMStorage} domStorage
381 _addDOMStorage: function(domStorage)
383 console.assert(!this._domStorageTreeElements.get(domStorage));
385 var domStorageTreeElement = new WebInspector.DOMStorageTreeElement(this, domStorage, (domStorage.isLocalStorage ? "local-storage" : "session-storage"));
386 this._domStorageTreeElements.set(domStorage, domStorageTreeElement);
387 if (domStorage.isLocalStorage)
388 this.localStorageListTreeElement.appendChild(domStorageTreeElement);
390 this.sessionStorageListTreeElement.appendChild(domStorageTreeElement);
394 * @param {!WebInspector.Event} event
396 _domStorageRemoved: function(event)
398 var domStorage = /** @type {!WebInspector.DOMStorage} */ (event.data);
399 this._removeDOMStorage(domStorage);
403 * @param {!WebInspector.DOMStorage} domStorage
405 _removeDOMStorage: function(domStorage)
407 var treeElement = this._domStorageTreeElements.get(domStorage);
410 var wasSelected = treeElement.selected;
411 var parentListTreeElement = treeElement.parent;
412 parentListTreeElement.removeChild(treeElement);
414 parentListTreeElement.select();
415 this._domStorageTreeElements.remove(domStorage);
416 this._domStorageViews.remove(domStorage);
420 * @param {!WebInspector.Database} database
422 selectDatabase: function(database)
425 this._showDatabase(database);
426 this._databaseTreeElements.get(database).select();
431 * @param {!WebInspector.DOMStorage} domStorage
433 selectDOMStorage: function(domStorage)
436 this._showDOMStorage(domStorage);
437 this._domStorageTreeElements.get(domStorage).select();
442 * @param {!WebInspector.Resource} resource
443 * @param {number=} line
444 * @param {number=} column
447 showResource: function(resource, line, column)
449 var resourceTreeElement = this._findTreeElementForResource(resource);
450 if (resourceTreeElement)
451 resourceTreeElement.revealAndSelect(true);
453 if (typeof line === "number") {
454 var resourceSourceFrame = this._resourceSourceFrameViewForResource(resource);
455 if (resourceSourceFrame)
456 resourceSourceFrame.revealPosition(line, column, true);
461 _showResourceView: function(resource)
463 var view = this._resourceViewForResource(resource);
465 this.visibleView.detach();
468 this._innerShowView(view);
472 * @param {!WebInspector.Resource} resource
473 * @return {?WebInspector.View}
475 _resourceViewForResource: function(resource)
477 if (WebInspector.ResourceView.hasTextContent(resource)) {
478 var treeElement = this._findTreeElementForResource(resource);
481 return treeElement.sourceView();
483 return WebInspector.ResourceView.nonSourceViewForResource(resource);
487 * @param {!WebInspector.Resource} resource
488 * @return {?WebInspector.ResourceSourceFrame}
490 _resourceSourceFrameViewForResource: function(resource)
492 var resourceView = this._resourceViewForResource(resource);
493 if (resourceView && resourceView instanceof WebInspector.ResourceSourceFrame)
494 return /** @type {!WebInspector.ResourceSourceFrame} */ (resourceView);
499 * @param {!WebInspector.Database} database
500 * @param {string=} tableName
502 _showDatabase: function(database, tableName)
509 var tableViews = this._databaseTableViews.get(database);
511 tableViews = /** @type {!Object.<string, !WebInspector.DatabaseTableView>} */ ({});
512 this._databaseTableViews.set(database, tableViews);
514 view = tableViews[tableName];
516 view = new WebInspector.DatabaseTableView(database, tableName);
517 tableViews[tableName] = view;
520 view = this._databaseQueryViews.get(database);
522 view = new WebInspector.DatabaseQueryView(database);
523 this._databaseQueryViews.set(database, view);
524 view.addEventListener(WebInspector.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this);
528 this._innerShowView(view);
532 * @param {!WebInspector.View} view
534 showIndexedDB: function(view)
536 this._innerShowView(view);
540 * @param {!WebInspector.DOMStorage} domStorage
542 _showDOMStorage: function(domStorage)
548 view = this._domStorageViews.get(domStorage);
550 view = new WebInspector.DOMStorageItemsView(domStorage);
551 this._domStorageViews.set(domStorage, view);
554 this._innerShowView(view);
558 * @param {!WebInspector.CookieTreeElement} treeElement
559 * @param {string} cookieDomain
561 showCookies: function(treeElement, cookieDomain)
563 var view = this._cookieViews[cookieDomain];
565 view = new WebInspector.CookieItemsView(treeElement, cookieDomain);
566 this._cookieViews[cookieDomain] = view;
569 this._innerShowView(view);
573 * @param {string} cookieDomain
575 clearCookies: function(cookieDomain)
577 this._cookieViews[cookieDomain].clear();
580 showApplicationCache: function(frameId)
582 if (!this._applicationCacheViews[frameId])
583 this._applicationCacheViews[frameId] = new WebInspector.ApplicationCacheItemsView(this._applicationCacheModel, frameId);
585 this._innerShowView(this._applicationCacheViews[frameId]);
589 * @param {!WebInspector.View} view
591 showFileSystem: function(view)
593 this._innerShowView(view);
596 showCategoryView: function(categoryName)
598 if (!this._categoryView)
599 this._categoryView = new WebInspector.StorageCategoryView();
600 this._categoryView.setText(categoryName);
601 this._innerShowView(this._categoryView);
604 _innerShowView: function(view)
606 if (this.visibleView === view)
609 if (this.visibleView)
610 this.visibleView.detach();
612 view.show(this.storageViews);
613 this.visibleView = view;
615 this.storageViewStatusBarItemsContainer.removeChildren();
616 var statusBarItems = view.statusBarItems || [];
617 for (var i = 0; i < statusBarItems.length; ++i)
618 this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
621 closeVisibleView: function()
623 if (!this.visibleView)
625 this.visibleView.detach();
626 delete this.visibleView;
629 _updateDatabaseTables: function(event)
631 var database = event.data;
636 var databasesTreeElement = this._databaseTreeElements.get(database);
637 if (!databasesTreeElement)
640 databasesTreeElement.shouldRefreshChildren = true;
641 var tableViews = this._databaseTableViews.get(database);
646 var tableNamesHash = {};
648 function tableNamesCallback(tableNames)
650 var tableNamesLength = tableNames.length;
651 for (var i = 0; i < tableNamesLength; ++i)
652 tableNamesHash[tableNames[i]] = true;
654 for (var tableName in tableViews) {
655 if (!(tableName in tableNamesHash)) {
656 if (self.visibleView === tableViews[tableName])
657 self.closeVisibleView();
658 delete tableViews[tableName];
662 database.getTableNames(tableNamesCallback);
665 _populateDOMStorageTree: function()
667 WebInspector.domStorageModel.storages().forEach(this._addDOMStorage.bind(this));
668 WebInspector.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this);
669 WebInspector.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this);
673 * @param {!WebInspector.Target} target
675 _populateApplicationCacheTree: function(target)
677 this._applicationCacheModel = new WebInspector.ApplicationCacheModel(target);
679 this._applicationCacheViews = {};
680 this._applicationCacheFrameElements = {};
681 this._applicationCacheManifestElements = {};
683 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded, this._applicationCacheFrameManifestAdded, this);
684 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved, this._applicationCacheFrameManifestRemoved, this);
686 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated, this._applicationCacheFrameManifestStatusChanged, this);
687 this._applicationCacheModel.addEventListener(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged, this._applicationCacheNetworkStateChanged, this);
690 _applicationCacheFrameManifestAdded: function(event)
692 var frameId = event.data;
693 var manifestURL = this._applicationCacheModel.frameManifestURL(frameId);
694 var status = this._applicationCacheModel.frameManifestStatus(frameId)
696 var manifestTreeElement = this._applicationCacheManifestElements[manifestURL]
697 if (!manifestTreeElement) {
698 manifestTreeElement = new WebInspector.ApplicationCacheManifestTreeElement(this, manifestURL);
699 this.applicationCacheListTreeElement.appendChild(manifestTreeElement);
700 this._applicationCacheManifestElements[manifestURL] = manifestTreeElement;
703 var frameTreeElement = new WebInspector.ApplicationCacheFrameTreeElement(this, frameId, manifestURL);
704 manifestTreeElement.appendChild(frameTreeElement);
705 manifestTreeElement.expand();
706 this._applicationCacheFrameElements[frameId] = frameTreeElement;
709 _applicationCacheFrameManifestRemoved: function(event)
711 var frameId = event.data;
712 var frameTreeElement = this._applicationCacheFrameElements[frameId];
713 if (!frameTreeElement)
716 var manifestURL = frameTreeElement.manifestURL;
717 delete this._applicationCacheFrameElements[frameId];
718 delete this._applicationCacheViews[frameId];
719 frameTreeElement.parent.removeChild(frameTreeElement);
721 var manifestTreeElement = this._applicationCacheManifestElements[manifestURL];
722 if (manifestTreeElement.children.length !== 0)
725 delete this._applicationCacheManifestElements[manifestURL];
726 manifestTreeElement.parent.removeChild(manifestTreeElement);
729 _applicationCacheFrameManifestStatusChanged: function(event)
731 var frameId = event.data;
732 var status = this._applicationCacheModel.frameManifestStatus(frameId)
734 if (this._applicationCacheViews[frameId])
735 this._applicationCacheViews[frameId].updateStatus(status);
738 _applicationCacheNetworkStateChanged: function(event)
740 var isNowOnline = event.data;
742 for (var manifestURL in this._applicationCacheViews)
743 this._applicationCacheViews[manifestURL].updateNetworkState(isNowOnline);
746 _findTreeElementForResource: function(resource)
748 function getParent(object)
750 // Redirects, XHRs do not belong to the tree, it is fine to silently return false here.
754 return this.sidebarTree.findTreeElement(resource, getParent);
757 showView: function(view)
760 this.showResource(view.resource);
763 _onmousemove: function(event)
765 var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY);
769 var listNode = nodeUnderMouse.enclosingNodeOrSelfWithNodeName("li");
773 var element = listNode.treeElement;
774 if (this._previousHoveredElement === element)
777 if (this._previousHoveredElement) {
778 this._previousHoveredElement.hovered = false;
779 delete this._previousHoveredElement;
782 if (element instanceof WebInspector.FrameTreeElement) {
783 this._previousHoveredElement = element;
784 element.hovered = true;
788 _onmouseout: function(event)
790 if (this._previousHoveredElement) {
791 this._previousHoveredElement.hovered = false;
792 delete this._previousHoveredElement;
796 __proto__: WebInspector.PanelWithSidebarTree.prototype
801 * @implements {WebInspector.Revealer}
803 WebInspector.ResourcesPanel.ResourceRevealer = function()
807 WebInspector.ResourcesPanel.ResourceRevealer.prototype = {
809 * @param {!Object} resource
810 * @param {number=} lineNumber
812 reveal: function(resource, lineNumber)
814 if (resource instanceof WebInspector.Resource) {
815 var panel = /** @type {?WebInspector.ResourcesPanel} */ (WebInspector.inspectorView.showPanel("resources"));
817 panel.showResource(resource, lineNumber);
824 * @extends {TreeElement}
825 * @param {!WebInspector.ResourcesPanel} storagePanel
826 * @param {?Object} representedObject
827 * @param {string} title
828 * @param {?Array.<string>=} iconClasses
829 * @param {boolean=} hasChildren
830 * @param {boolean=} noIcon
832 WebInspector.BaseStorageTreeElement = function(storagePanel, representedObject, title, iconClasses, hasChildren, noIcon)
834 TreeElement.call(this, "", representedObject, hasChildren);
835 this._storagePanel = storagePanel;
836 this._titleText = title;
837 this._iconClasses = iconClasses;
838 this._noIcon = noIcon;
841 WebInspector.BaseStorageTreeElement.prototype = {
844 this.listItemElement.removeChildren();
845 if (this._iconClasses) {
846 for (var i = 0; i < this._iconClasses.length; ++i)
847 this.listItemElement.classList.add(this._iconClasses[i]);
850 this.listItemElement.createChild("div", "selection");
853 this.imageElement = this.listItemElement.createChild("img", "icon");
855 this.titleElement = this.listItemElement.createChild("div", "base-storage-tree-element-title");
856 this._titleTextNode = this.titleElement.createTextChild("");
858 this._updateSubtitle();
863 return this._displayName;
866 _updateDisplayName: function()
868 this._displayName = this._titleText || "";
869 if (this._subtitleText)
870 this._displayName += " (" + this._subtitleText + ")";
873 _updateTitle: function()
875 this._updateDisplayName();
877 if (!this.titleElement)
880 this._titleTextNode.textContent = this._titleText || "";
883 _updateSubtitle: function()
885 this._updateDisplayName();
887 if (!this.titleElement)
890 if (this._subtitleText) {
891 if (!this._subtitleElement)
892 this._subtitleElement = this.titleElement.createChild("span", "base-storage-tree-element-subtitle");
893 this._subtitleElement.textContent = "(" + this._subtitleText + ")";
894 } else if (this._subtitleElement) {
895 this._subtitleElement.remove();
896 delete this._subtitleElement;
904 onselect: function(selectedByUser)
908 var itemURL = this.itemURL;
910 WebInspector.settings.resourcesLastSelectedItem.set(itemURL);
919 if (this.listItemElement)
920 this.listItemElement.scrollIntoViewIfNeeded(false);
925 return this._titleText;
928 set titleText(titleText)
930 this._titleText = titleText;
936 return this._subtitleText;
939 set subtitleText(subtitleText)
941 this._subtitleText = subtitleText;
942 this._updateSubtitle();
945 __proto__: TreeElement.prototype
950 * @extends {WebInspector.BaseStorageTreeElement}
951 * @param {!WebInspector.ResourcesPanel} storagePanel
952 * @param {string} categoryName
953 * @param {string} settingsKey
954 * @param {?Array.<string>=} iconClasses
955 * @param {boolean=} noIcon
957 WebInspector.StorageCategoryTreeElement = function(storagePanel, categoryName, settingsKey, iconClasses, noIcon)
959 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, categoryName, iconClasses, false, noIcon);
960 this._expandedSettingKey = "resources" + settingsKey + "Expanded";
961 WebInspector.settings[this._expandedSettingKey] = WebInspector.settings.createSetting(this._expandedSettingKey, settingsKey === "Frames");
962 this._categoryName = categoryName;
963 this._target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.mainTarget());
966 WebInspector.StorageCategoryTreeElement.prototype = {
968 * @return {!WebInspector.Target}
977 return "category://" + this._categoryName;
984 onselect: function(selectedByUser)
986 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
987 this._storagePanel.showCategoryView(this._categoryName);
996 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
997 if (WebInspector.settings[this._expandedSettingKey].get())
1004 onexpand: function()
1006 WebInspector.settings[this._expandedSettingKey].set(true);
1012 oncollapse: function()
1014 WebInspector.settings[this._expandedSettingKey].set(false);
1017 __proto__: WebInspector.BaseStorageTreeElement.prototype
1022 * @extends {WebInspector.BaseStorageTreeElement}
1024 WebInspector.FrameTreeElement = function(storagePanel, frame)
1026 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, "", ["frame-storage-tree-item"]);
1027 this._frame = frame;
1028 this.frameNavigated(frame);
1031 WebInspector.FrameTreeElement.prototype = {
1032 frameNavigated: function(frame)
1034 this.removeChildren();
1035 this._frameId = frame.id;
1037 this.titleText = frame.name;
1038 this.subtitleText = new WebInspector.ParsedURL(frame.url).displayName;
1040 this._categoryElements = {};
1041 this._treeElementForResource = {};
1043 this._storagePanel.addDocumentURL(frame.url);
1048 return "frame://" + encodeURI(this.displayName);
1055 onselect: function(selectedByUser)
1057 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1058 this._storagePanel.showCategoryView(this.displayName);
1060 this.listItemElement.classList.remove("hovered");
1061 DOMAgent.hideHighlight();
1065 set hovered(hovered)
1068 this.listItemElement.classList.add("hovered");
1069 DOMAgent.highlightFrame(this._frameId, WebInspector.Color.PageHighlight.Content.toProtocolRGBA(), WebInspector.Color.PageHighlight.ContentOutline.toProtocolRGBA());
1071 this.listItemElement.classList.remove("hovered");
1072 DOMAgent.hideHighlight();
1076 appendResource: function(resource)
1078 if (resource.isHidden())
1080 var categoryName = resource.type.name();
1081 var categoryElement = resource.type === WebInspector.resourceTypes.Document ? this : this._categoryElements[categoryName];
1082 if (!categoryElement) {
1083 categoryElement = new WebInspector.StorageCategoryTreeElement(this._storagePanel, resource.type.categoryTitle(), categoryName, null, true);
1084 this._categoryElements[resource.type.name()] = categoryElement;
1085 this._insertInPresentationOrder(this, categoryElement);
1087 var resourceTreeElement = new WebInspector.FrameResourceTreeElement(this._storagePanel, resource);
1088 this._insertInPresentationOrder(categoryElement, resourceTreeElement);
1089 this._treeElementForResource[resource.url] = resourceTreeElement;
1093 * @param {string} url
1094 * @return {?WebInspector.Resource}
1096 resourceByURL: function(url)
1098 var treeElement = this._treeElementForResource[url];
1099 return treeElement ? treeElement.representedObject : null;
1102 appendChild: function(treeElement)
1104 this._insertInPresentationOrder(this, treeElement);
1107 _insertInPresentationOrder: function(parentTreeElement, childTreeElement)
1109 // Insert in the alphabetical order, first frames, then resources. Document resource goes last.
1110 function typeWeight(treeElement)
1112 if (treeElement instanceof WebInspector.StorageCategoryTreeElement)
1114 if (treeElement instanceof WebInspector.FrameTreeElement)
1119 function compare(treeElement1, treeElement2)
1121 var typeWeight1 = typeWeight(treeElement1);
1122 var typeWeight2 = typeWeight(treeElement2);
1125 if (typeWeight1 > typeWeight2)
1127 else if (typeWeight1 < typeWeight2)
1130 var title1 = treeElement1.displayName || treeElement1.titleText;
1131 var title2 = treeElement2.displayName || treeElement2.titleText;
1132 result = title1.localeCompare(title2);
1137 var children = parentTreeElement.children;
1139 for (i = 0; i < children.length; ++i) {
1140 if (compare(childTreeElement, children[i]) < 0)
1143 parentTreeElement.insertChild(childTreeElement, i);
1146 __proto__: WebInspector.BaseStorageTreeElement.prototype
1151 * @extends {WebInspector.BaseStorageTreeElement}
1153 WebInspector.FrameResourceTreeElement = function(storagePanel, resource)
1155 WebInspector.BaseStorageTreeElement.call(this, storagePanel, resource, resource.displayName, ["resource-sidebar-tree-item", "resources-type-" + resource.type.name()]);
1156 this._resource = resource;
1157 this._resource.addEventListener(WebInspector.Resource.Events.MessageAdded, this._consoleMessageAdded, this);
1158 this._resource.addEventListener(WebInspector.Resource.Events.MessagesCleared, this._consoleMessagesCleared, this);
1159 this.tooltip = resource.url;
1162 WebInspector.FrameResourceTreeElement.prototype = {
1165 return this._resource.url;
1172 onselect: function(selectedByUser)
1174 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1175 this._storagePanel._showResourceView(this._resource);
1183 ondblclick: function(event)
1185 InspectorFrontendHost.openInNewTab(this._resource.url);
1192 onattach: function()
1194 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1196 if (this._resource.type === WebInspector.resourceTypes.Image) {
1197 var iconElement = document.createElementWithClass("div", "icon");
1198 var previewImage = iconElement.createChild("img", "image-resource-icon-preview");
1199 this._resource.populateImageSource(previewImage);
1200 this.listItemElement.replaceChild(iconElement, this.imageElement);
1203 this._statusElement = document.createElementWithClass("div", "status");
1204 this.listItemElement.insertBefore(this._statusElement, this.titleElement);
1206 this.listItemElement.draggable = true;
1207 this.listItemElement.addEventListener("dragstart", this._ondragstart.bind(this), false);
1208 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1210 this._updateErrorsAndWarningsBubbles();
1214 * @param {!MouseEvent} event
1217 _ondragstart: function(event)
1219 event.dataTransfer.setData("text/plain", this._resource.content);
1220 event.dataTransfer.effectAllowed = "copy";
1224 _handleContextMenuEvent: function(event)
1226 var contextMenu = new WebInspector.ContextMenu(event);
1227 contextMenu.appendApplicableItems(this._resource);
1234 _setBubbleText: function(x)
1236 if (!this._bubbleElement)
1237 this._bubbleElement = this._statusElement.createChild("div", "bubble-repeat-count");
1238 this._bubbleElement.textContent = x;
1241 _resetBubble: function()
1243 if (this._bubbleElement) {
1244 this._bubbleElement.textContent = "";
1245 this._bubbleElement.classList.remove("warning");
1246 this._bubbleElement.classList.remove("error");
1250 _updateErrorsAndWarningsBubbles: function()
1252 if (this._storagePanel.currentQuery)
1255 this._resetBubble();
1257 if (this._resource.warnings || this._resource.errors)
1258 this._setBubbleText(this._resource.warnings + this._resource.errors);
1260 if (this._resource.warnings)
1261 this._bubbleElement.classList.add("warning");
1263 if (this._resource.errors)
1264 this._bubbleElement.classList.add("error");
1267 _consoleMessagesCleared: function()
1269 // FIXME: move to the SourceFrame.
1270 if (this._sourceView)
1271 this._sourceView.clearMessages();
1273 this._updateErrorsAndWarningsBubbles();
1276 _consoleMessageAdded: function(event)
1278 var msg = event.data;
1279 if (this._sourceView)
1280 this._sourceView.addMessage(msg);
1281 this._updateErrorsAndWarningsBubbles();
1285 * @return {!WebInspector.ResourceSourceFrame}
1287 sourceView: function()
1289 if (!this._sourceView) {
1290 var sourceFrame = new WebInspector.ResourceSourceFrame(this._resource);
1291 sourceFrame.setHighlighterType(this._resource.canonicalMimeType());
1292 this._sourceView = sourceFrame;
1293 if (this._resource.messages) {
1294 for (var i = 0; i < this._resource.messages.length; i++)
1295 this._sourceView.addMessage(this._resource.messages[i]);
1298 return this._sourceView;
1301 __proto__: WebInspector.BaseStorageTreeElement.prototype
1306 * @extends {WebInspector.BaseStorageTreeElement}
1307 * @param {!WebInspector.ResourcesPanel} storagePanel
1308 * @param {!WebInspector.Database} database
1310 WebInspector.DatabaseTreeElement = function(storagePanel, database)
1312 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, database.name, ["database-storage-tree-item"], true);
1313 this._database = database;
1316 WebInspector.DatabaseTreeElement.prototype = {
1319 return "database://" + encodeURI(this._database.name);
1326 onselect: function(selectedByUser)
1328 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1329 this._storagePanel._showDatabase(this._database);
1336 onexpand: function()
1338 this._updateChildren();
1341 _updateChildren: function()
1343 this.removeChildren();
1346 * @param {!Array.<string>} tableNames
1347 * @this {WebInspector.DatabaseTreeElement}
1349 function tableNamesCallback(tableNames)
1351 var tableNamesLength = tableNames.length;
1352 for (var i = 0; i < tableNamesLength; ++i)
1353 this.appendChild(new WebInspector.DatabaseTableTreeElement(this._storagePanel, this._database, tableNames[i]));
1355 this._database.getTableNames(tableNamesCallback.bind(this));
1358 __proto__: WebInspector.BaseStorageTreeElement.prototype
1363 * @extends {WebInspector.BaseStorageTreeElement}
1365 WebInspector.DatabaseTableTreeElement = function(storagePanel, database, tableName)
1367 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, tableName, ["database-table-storage-tree-item"]);
1368 this._database = database;
1369 this._tableName = tableName;
1372 WebInspector.DatabaseTableTreeElement.prototype = {
1375 return "database://" + encodeURI(this._database.name) + "/" + encodeURI(this._tableName);
1382 onselect: function(selectedByUser)
1384 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1385 this._storagePanel._showDatabase(this._database, this._tableName);
1389 __proto__: WebInspector.BaseStorageTreeElement.prototype
1394 * @extends {WebInspector.StorageCategoryTreeElement}
1395 * @param {!WebInspector.ResourcesPanel} storagePanel
1397 WebInspector.IndexedDBTreeElement = function(storagePanel)
1399 WebInspector.StorageCategoryTreeElement.call(this, storagePanel, WebInspector.UIString("IndexedDB"), "IndexedDB", ["indexed-db-storage-tree-item"]);
1402 WebInspector.IndexedDBTreeElement.prototype = {
1403 _initialize: function()
1405 WebInspector.targetManager.addModelListener(WebInspector.IndexedDBModel, WebInspector.IndexedDBModel.EventTypes.DatabaseAdded, this._indexedDBAdded, this);
1406 WebInspector.targetManager.addModelListener(WebInspector.IndexedDBModel, WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved, this._indexedDBRemoved, this);
1407 WebInspector.targetManager.addModelListener(WebInspector.IndexedDBModel, WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded, this._indexedDBLoaded, this);
1408 /** @type {!Array.<!WebInspector.IDBDatabaseTreeElement>} */
1409 this._idbDatabaseTreeElements = [];
1411 var targets = WebInspector.targetManager.targets();
1412 for (var i = 0; i < targets.length; ++i) {
1413 var databases = targets[i].indexedDBModel.databases();
1414 for (var j = 0; j < databases.length; ++j)
1415 this._addIndexedDB(targets[i].indexedDBModel, databases[j]);
1419 onattach: function()
1421 WebInspector.StorageCategoryTreeElement.prototype.onattach.call(this);
1422 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1425 _handleContextMenuEvent: function(event)
1427 var contextMenu = new WebInspector.ContextMenu(event);
1428 contextMenu.appendItem(WebInspector.UIString("Refresh IndexedDB"), this.refreshIndexedDB.bind(this));
1432 refreshIndexedDB: function()
1434 var targets = WebInspector.targetManager.targets();
1435 for (var i = 0; i < targets.length; ++i)
1436 targets[i].indexedDBModel.refreshDatabaseNames();
1440 * @param {!WebInspector.Event} event
1442 _indexedDBAdded: function(event)
1444 var databaseId = /** @type {!WebInspector.IndexedDBModel.DatabaseId} */ (event.data);
1445 var model = /** @type {!WebInspector.IndexedDBModel} */ (event.target);
1446 this._addIndexedDB(model, databaseId);
1450 * @param {!WebInspector.IndexedDBModel} model
1451 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1453 _addIndexedDB: function(model, databaseId)
1455 var idbDatabaseTreeElement = new WebInspector.IDBDatabaseTreeElement(this._storagePanel, model, databaseId);
1456 this._idbDatabaseTreeElements.push(idbDatabaseTreeElement);
1457 this.appendChild(idbDatabaseTreeElement);
1458 model.refreshDatabase(databaseId);
1462 * @param {!WebInspector.Event} event
1464 _indexedDBRemoved: function(event)
1466 var databaseId = /** @type {!WebInspector.IndexedDBModel.DatabaseId} */ (event.data);
1467 var model = /** @type {!WebInspector.IndexedDBModel} */ (event.target);
1469 var idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, databaseId)
1470 if (!idbDatabaseTreeElement)
1473 idbDatabaseTreeElement.clear();
1474 this.removeChild(idbDatabaseTreeElement);
1475 this._idbDatabaseTreeElements.remove(idbDatabaseTreeElement);
1479 * @param {!WebInspector.Event} event
1481 _indexedDBLoaded: function(event)
1483 var database = /** @type {!WebInspector.IndexedDBModel.Database} */ (event.data);
1484 var model = /** @type {!WebInspector.IndexedDBModel} */ (event.target);
1486 var idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, database.databaseId)
1487 if (!idbDatabaseTreeElement)
1490 idbDatabaseTreeElement.update(database);
1494 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1495 * @param {!WebInspector.IndexedDBModel} model
1496 * @return {?WebInspector.IDBDatabaseTreeElement}
1498 _idbDatabaseTreeElement: function(model, databaseId)
1501 for (var i = 0; i < this._idbDatabaseTreeElements.length; ++i) {
1502 if (this._idbDatabaseTreeElements[i]._databaseId.equals(databaseId) && this._idbDatabaseTreeElements[i]._model === model) {
1508 return this._idbDatabaseTreeElements[i];
1512 __proto__: WebInspector.StorageCategoryTreeElement.prototype
1517 * @extends {WebInspector.StorageCategoryTreeElement}
1518 * @param {!WebInspector.ResourcesPanel} storagePanel
1520 WebInspector.FileSystemListTreeElement = function(storagePanel)
1522 WebInspector.StorageCategoryTreeElement.call(this, storagePanel, WebInspector.UIString("FileSystem"), "FileSystem", ["file-system-storage-tree-item"]);
1525 WebInspector.FileSystemListTreeElement.prototype = {
1526 _initialize: function()
1528 this._refreshFileSystem();
1531 onattach: function()
1533 WebInspector.StorageCategoryTreeElement.prototype.onattach.call(this);
1534 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1537 _handleContextMenuEvent: function(event)
1539 var contextMenu = new WebInspector.ContextMenu(event);
1540 contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Refresh FileSystem list" : "Refresh FileSystem List"), this._refreshFileSystem.bind(this));
1544 _fileSystemAdded: function(event)
1546 var fileSystem = /** @type {!WebInspector.FileSystemModel.FileSystem} */ (event.data);
1547 var fileSystemTreeElement = new WebInspector.FileSystemTreeElement(this._storagePanel, fileSystem);
1548 this.appendChild(fileSystemTreeElement);
1551 _fileSystemRemoved: function(event)
1553 var fileSystem = /** @type {!WebInspector.FileSystemModel.FileSystem} */ (event.data);
1554 var fileSystemTreeElement = this._fileSystemTreeElementByName(fileSystem.name);
1555 if (!fileSystemTreeElement)
1557 fileSystemTreeElement.clear();
1558 this.removeChild(fileSystemTreeElement);
1561 _fileSystemTreeElementByName: function(fileSystemName)
1563 for (var i = 0; i < this.children.length; ++i) {
1564 var child = /** @type {!WebInspector.FileSystemTreeElement} */ (this.children[i]);
1565 if (child.fileSystemName === fileSystemName)
1566 return this.children[i];
1571 _refreshFileSystem: function()
1573 if (!this._fileSystemModel) {
1574 this._fileSystemModel = new WebInspector.FileSystemModel(this.target());
1575 this._fileSystemModel.addEventListener(WebInspector.FileSystemModel.EventTypes.FileSystemAdded, this._fileSystemAdded, this);
1576 this._fileSystemModel.addEventListener(WebInspector.FileSystemModel.EventTypes.FileSystemRemoved, this._fileSystemRemoved, this);
1579 this._fileSystemModel.refreshFileSystemList();
1582 __proto__: WebInspector.StorageCategoryTreeElement.prototype
1587 * @extends {WebInspector.BaseStorageTreeElement}
1588 * @param {!WebInspector.ResourcesPanel} storagePanel
1589 * @param {!WebInspector.IndexedDBModel} model
1590 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1592 WebInspector.IDBDatabaseTreeElement = function(storagePanel, model, databaseId)
1594 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, databaseId.name + " - " + databaseId.securityOrigin, ["indexed-db-storage-tree-item"]);
1595 this._model = model;
1596 this._databaseId = databaseId;
1597 this._idbObjectStoreTreeElements = {};
1600 WebInspector.IDBDatabaseTreeElement.prototype = {
1603 return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name;
1606 onattach: function()
1608 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1609 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1612 _handleContextMenuEvent: function(event)
1614 var contextMenu = new WebInspector.ContextMenu(event);
1615 contextMenu.appendItem(WebInspector.UIString("Refresh IndexedDB"), this._refreshIndexedDB.bind(this));
1619 _refreshIndexedDB: function()
1621 this._model.refreshDatabaseNames();
1625 * @param {!WebInspector.IndexedDBModel.Database} database
1627 update: function(database)
1629 this._database = database;
1630 var objectStoreNames = {};
1631 for (var objectStoreName in this._database.objectStores) {
1632 var objectStore = this._database.objectStores[objectStoreName];
1633 objectStoreNames[objectStore.name] = true;
1634 if (!this._idbObjectStoreTreeElements[objectStore.name]) {
1635 var idbObjectStoreTreeElement = new WebInspector.IDBObjectStoreTreeElement(this._storagePanel, this._model, this._databaseId, objectStore);
1636 this._idbObjectStoreTreeElements[objectStore.name] = idbObjectStoreTreeElement;
1637 this.appendChild(idbObjectStoreTreeElement);
1639 this._idbObjectStoreTreeElements[objectStore.name].update(objectStore);
1641 for (var objectStoreName in this._idbObjectStoreTreeElements) {
1642 if (!objectStoreNames[objectStoreName])
1643 this._objectStoreRemoved(objectStoreName);
1646 if (this.children.length) {
1647 this.hasChildren = true;
1652 this._view.update(database);
1654 this._updateTooltip();
1657 _updateTooltip: function()
1659 this.tooltip = WebInspector.UIString("Version") + ": " + this._database.version;
1666 onselect: function(selectedByUser)
1668 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1670 this._view = new WebInspector.IDBDatabaseView(this._database);
1672 this._storagePanel.showIndexedDB(this._view);
1677 * @param {string} objectStoreName
1679 _objectStoreRemoved: function(objectStoreName)
1681 var objectStoreTreeElement = this._idbObjectStoreTreeElements[objectStoreName];
1682 objectStoreTreeElement.clear();
1683 this.removeChild(objectStoreTreeElement);
1684 delete this._idbObjectStoreTreeElements[objectStoreName];
1689 for (var objectStoreName in this._idbObjectStoreTreeElements)
1690 this._objectStoreRemoved(objectStoreName);
1693 __proto__: WebInspector.BaseStorageTreeElement.prototype
1698 * @extends {WebInspector.BaseStorageTreeElement}
1699 * @param {!WebInspector.ResourcesPanel} storagePanel
1700 * @param {!WebInspector.IndexedDBModel} model
1701 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1702 * @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
1704 WebInspector.IDBObjectStoreTreeElement = function(storagePanel, model, databaseId, objectStore)
1706 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, objectStore.name, ["indexed-db-object-store-storage-tree-item"]);
1707 this._model = model;
1708 this._databaseId = databaseId;
1709 this._idbIndexTreeElements = {};
1712 WebInspector.IDBObjectStoreTreeElement.prototype = {
1715 return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name + "/" + this._objectStore.name;
1718 onattach: function()
1720 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1721 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1724 _handleContextMenuEvent: function(event)
1726 var contextMenu = new WebInspector.ContextMenu(event);
1727 contextMenu.appendItem(WebInspector.UIString("Clear"), this._clearObjectStore.bind(this));
1731 _clearObjectStore: function()
1734 * @this {WebInspector.IDBObjectStoreTreeElement}
1736 function callback() {
1737 this.update(this._objectStore);
1739 this._model.clearObjectStore(this._databaseId, this._objectStore.name, callback.bind(this));
1743 * @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
1745 update: function(objectStore)
1747 this._objectStore = objectStore;
1749 var indexNames = {};
1750 for (var indexName in this._objectStore.indexes) {
1751 var index = this._objectStore.indexes[indexName];
1752 indexNames[index.name] = true;
1753 if (!this._idbIndexTreeElements[index.name]) {
1754 var idbIndexTreeElement = new WebInspector.IDBIndexTreeElement(this._storagePanel, this._model, this._databaseId, this._objectStore, index);
1755 this._idbIndexTreeElements[index.name] = idbIndexTreeElement;
1756 this.appendChild(idbIndexTreeElement);
1758 this._idbIndexTreeElements[index.name].update(index);
1760 for (var indexName in this._idbIndexTreeElements) {
1761 if (!indexNames[indexName])
1762 this._indexRemoved(indexName);
1764 for (var indexName in this._idbIndexTreeElements) {
1765 if (!indexNames[indexName]) {
1766 this.removeChild(this._idbIndexTreeElements[indexName]);
1767 delete this._idbIndexTreeElements[indexName];
1771 if (this.children.length) {
1772 this.hasChildren = true;
1777 this._view.update(this._objectStore);
1779 this._updateTooltip();
1782 _updateTooltip: function()
1785 var keyPathString = this._objectStore.keyPathString;
1786 var tooltipString = keyPathString !== null ? (WebInspector.UIString("Key path: ") + keyPathString) : "";
1787 if (this._objectStore.autoIncrement)
1788 tooltipString += "\n" + WebInspector.UIString("autoIncrement");
1789 this.tooltip = tooltipString
1796 onselect: function(selectedByUser)
1798 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1800 this._view = new WebInspector.IDBDataView(this._model, this._databaseId, this._objectStore, null);
1802 this._storagePanel.showIndexedDB(this._view);
1807 * @param {string} indexName
1809 _indexRemoved: function(indexName)
1811 var indexTreeElement = this._idbIndexTreeElements[indexName];
1812 indexTreeElement.clear();
1813 this.removeChild(indexTreeElement);
1814 delete this._idbIndexTreeElements[indexName];
1819 for (var indexName in this._idbIndexTreeElements)
1820 this._indexRemoved(indexName);
1825 __proto__: WebInspector.BaseStorageTreeElement.prototype
1830 * @extends {WebInspector.BaseStorageTreeElement}
1831 * @param {!WebInspector.ResourcesPanel} storagePanel
1832 * @param {!WebInspector.IndexedDBModel} model
1833 * @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
1834 * @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
1835 * @param {!WebInspector.IndexedDBModel.Index} index
1837 WebInspector.IDBIndexTreeElement = function(storagePanel, model, databaseId, objectStore, index)
1839 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, index.name, ["indexed-db-index-storage-tree-item"]);
1840 this._model = model;
1841 this._databaseId = databaseId;
1842 this._objectStore = objectStore;
1843 this._index = index;
1846 WebInspector.IDBIndexTreeElement.prototype = {
1849 return "indexedDB://" + this._databaseId.securityOrigin + "/" + this._databaseId.name + "/" + this._objectStore.name + "/" + this._index.name;
1853 * @param {!WebInspector.IndexedDBModel.Index} index
1855 update: function(index)
1857 this._index = index;
1860 this._view.update(this._index);
1862 this._updateTooltip();
1865 _updateTooltip: function()
1867 var tooltipLines = [];
1868 var keyPathString = this._index.keyPathString;
1869 tooltipLines.push(WebInspector.UIString("Key path: ") + keyPathString);
1870 if (this._index.unique)
1871 tooltipLines.push(WebInspector.UIString("unique"));
1872 if (this._index.multiEntry)
1873 tooltipLines.push(WebInspector.UIString("multiEntry"));
1874 this.tooltip = tooltipLines.join("\n");
1881 onselect: function(selectedByUser)
1883 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1885 this._view = new WebInspector.IDBDataView(this._model, this._databaseId, this._objectStore, this._index);
1887 this._storagePanel.showIndexedDB(this._view);
1897 __proto__: WebInspector.BaseStorageTreeElement.prototype
1902 * @extends {WebInspector.BaseStorageTreeElement}
1904 WebInspector.DOMStorageTreeElement = function(storagePanel, domStorage, className)
1906 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, domStorage.securityOrigin ? domStorage.securityOrigin : WebInspector.UIString("Local Files"), ["domstorage-storage-tree-item", className]);
1907 this._domStorage = domStorage;
1910 WebInspector.DOMStorageTreeElement.prototype = {
1913 return "storage://" + this._domStorage.securityOrigin + "/" + (this._domStorage.isLocalStorage ? "local" : "session");
1920 onselect: function(selectedByUser)
1922 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1923 this._storagePanel._showDOMStorage(this._domStorage);
1927 __proto__: WebInspector.BaseStorageTreeElement.prototype
1932 * @extends {WebInspector.BaseStorageTreeElement}
1934 WebInspector.CookieTreeElement = function(storagePanel, cookieDomain)
1936 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, cookieDomain ? cookieDomain : WebInspector.UIString("Local Files"), ["cookie-storage-tree-item"]);
1937 this._cookieDomain = cookieDomain;
1940 WebInspector.CookieTreeElement.prototype = {
1943 return "cookies://" + this._cookieDomain;
1946 onattach: function()
1948 WebInspector.BaseStorageTreeElement.prototype.onattach.call(this);
1949 this.listItemElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
1953 * @param {!Event} event
1955 _handleContextMenuEvent: function(event)
1957 var contextMenu = new WebInspector.ContextMenu(event);
1958 contextMenu.appendItem(WebInspector.UIString("Clear"), this._clearCookies.bind(this));
1963 * @param {string} domain
1965 _clearCookies: function(domain)
1967 this._storagePanel.clearCookies(this._cookieDomain);
1974 onselect: function(selectedByUser)
1976 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
1977 this._storagePanel.showCookies(this, this._cookieDomain);
1981 __proto__: WebInspector.BaseStorageTreeElement.prototype
1986 * @extends {WebInspector.BaseStorageTreeElement}
1988 WebInspector.ApplicationCacheManifestTreeElement = function(storagePanel, manifestURL)
1990 var title = new WebInspector.ParsedURL(manifestURL).displayName;
1991 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, title, ["application-cache-storage-tree-item"]);
1992 this.tooltip = manifestURL;
1993 this._manifestURL = manifestURL;
1996 WebInspector.ApplicationCacheManifestTreeElement.prototype = {
1999 return "appcache://" + this._manifestURL;
2004 return this._manifestURL;
2011 onselect: function(selectedByUser)
2013 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
2014 this._storagePanel.showCategoryView(this._manifestURL);
2018 __proto__: WebInspector.BaseStorageTreeElement.prototype
2023 * @extends {WebInspector.BaseStorageTreeElement}
2025 WebInspector.ApplicationCacheFrameTreeElement = function(storagePanel, frameId, manifestURL)
2027 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, "", ["frame-storage-tree-item"]);
2028 this._frameId = frameId;
2029 this._manifestURL = manifestURL;
2030 this._refreshTitles();
2033 WebInspector.ApplicationCacheFrameTreeElement.prototype = {
2036 return "appcache://" + this._manifestURL + "/" + encodeURI(this.displayName);
2041 return this._frameId;
2046 return this._manifestURL;
2049 _refreshTitles: function()
2051 var frame = WebInspector.resourceTreeModel.frameForId(this._frameId);
2053 this.subtitleText = WebInspector.UIString("new frame");
2056 this.titleText = frame.name;
2057 this.subtitleText = new WebInspector.ParsedURL(frame.url).displayName;
2060 frameNavigated: function()
2062 this._refreshTitles();
2069 onselect: function(selectedByUser)
2071 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
2072 this._storagePanel.showApplicationCache(this._frameId);
2076 __proto__: WebInspector.BaseStorageTreeElement.prototype
2081 * @extends {WebInspector.BaseStorageTreeElement}
2082 * @param {!WebInspector.ResourcesPanel} storagePanel
2083 * @param {!WebInspector.FileSystemModel.FileSystem} fileSystem
2085 WebInspector.FileSystemTreeElement = function(storagePanel, fileSystem)
2087 var displayName = fileSystem.type + " - " + fileSystem.origin;
2088 WebInspector.BaseStorageTreeElement.call(this, storagePanel, null, displayName, ["file-system-storage-tree-item"]);
2089 this._fileSystem = fileSystem;
2092 WebInspector.FileSystemTreeElement.prototype = {
2093 get fileSystemName()
2095 return this._fileSystem.name;
2100 return "filesystem://" + this._fileSystem.name;
2107 onselect: function(selectedByUser)
2109 WebInspector.BaseStorageTreeElement.prototype.onselect.call(this, selectedByUser);
2110 this._fileSystemView = new WebInspector.FileSystemView(this._fileSystem);
2111 this._storagePanel.showFileSystem(this._fileSystemView);
2117 if (this.fileSystemView && this._storagePanel.visibleView === this.fileSystemView)
2118 this._storagePanel.closeVisibleView();
2121 __proto__: WebInspector.BaseStorageTreeElement.prototype
2126 * @extends {WebInspector.VBox}
2128 WebInspector.StorageCategoryView = function()
2130 WebInspector.VBox.call(this);
2132 this.element.classList.add("storage-view");
2133 this._emptyView = new WebInspector.EmptyView("");
2134 this._emptyView.show(this.element);
2137 WebInspector.StorageCategoryView.prototype = {
2138 setText: function(text)
2140 this._emptyView.text = text;
2143 __proto__: WebInspector.VBox.prototype