Home | History | Annotate | Download | only in front-end
      1 /*
      2  * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
      3  * Copyright (C) 2009 Joseph Pecoraro
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * 1.  Redistributions of source code must retain the above copyright
     10  *     notice, this list of conditions and the following disclaimer.
     11  * 2.  Redistributions in binary form must reproduce the above copyright
     12  *     notice, this list of conditions and the following disclaimer in the
     13  *     documentation and/or other materials provided with the distribution.
     14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     15  *     its contributors may be used to endorse or promote products derived
     16  *     from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 WebInspector.StoragePanel = function(database)
     31 {
     32     WebInspector.Panel.call(this);
     33 
     34     this.createSidebar();
     35 
     36     this.databasesListTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("DATABASES"), {}, true);
     37     this.sidebarTree.appendChild(this.databasesListTreeElement);
     38     this.databasesListTreeElement.expand();
     39 
     40     this.localStorageListTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("LOCAL STORAGE"), {}, true);
     41     this.sidebarTree.appendChild(this.localStorageListTreeElement);
     42     this.localStorageListTreeElement.expand();
     43 
     44     this.sessionStorageListTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("SESSION STORAGE"), {}, true);
     45     this.sidebarTree.appendChild(this.sessionStorageListTreeElement);
     46     this.sessionStorageListTreeElement.expand();
     47 
     48     this.cookieListTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("COOKIES"), {}, true);
     49     this.sidebarTree.appendChild(this.cookieListTreeElement);
     50     this.cookieListTreeElement.expand();
     51 
     52     this.storageViews = document.createElement("div");
     53     this.storageViews.id = "storage-views";
     54     this.element.appendChild(this.storageViews);
     55 
     56     this.storageViewStatusBarItemsContainer = document.createElement("div");
     57     this.storageViewStatusBarItemsContainer.id = "storage-view-status-bar-items";
     58 
     59     this.reset();
     60 }
     61 
     62 WebInspector.StoragePanel.prototype = {
     63     toolbarItemClass: "storage",
     64 
     65     get toolbarItemLabel()
     66     {
     67         return WebInspector.UIString("Storage");
     68     },
     69 
     70     get statusBarItems()
     71     {
     72         return [this.storageViewStatusBarItemsContainer];
     73     },
     74 
     75     reset: function()
     76     {
     77         if (this._databases) {
     78             var databasesLength = this._databases.length;
     79             for (var i = 0; i < databasesLength; ++i) {
     80                 var database = this._databases[i];
     81 
     82                 delete database._tableViews;
     83                 delete database._queryView;
     84             }
     85         }
     86 
     87         this._databases = [];
     88 
     89         if (this._domStorage) {
     90             var domStorageLength = this._domStorage.length;
     91             for (var i = 0; i < domStorageLength; ++i) {
     92                 var domStorage = this._domStorage[i];
     93 
     94                 delete domStorage._domStorageView;
     95             }
     96         }
     97 
     98         this._domStorage = [];
     99 
    100         this._cookieViews = {};
    101 
    102         this.databasesListTreeElement.removeChildren();
    103         this.localStorageListTreeElement.removeChildren();
    104         this.sessionStorageListTreeElement.removeChildren();
    105         this.cookieListTreeElement.removeChildren();
    106 
    107         this.storageViews.removeChildren();
    108 
    109         this.storageViewStatusBarItemsContainer.removeChildren();
    110 
    111         if (this.sidebarTree.selectedTreeElement)
    112             this.sidebarTree.selectedTreeElement.deselect();
    113     },
    114 
    115     addDatabase: function(database)
    116     {
    117         this._databases.push(database);
    118 
    119         var databaseTreeElement = new WebInspector.DatabaseSidebarTreeElement(database);
    120         database._databasesTreeElement = databaseTreeElement;
    121         this.databasesListTreeElement.appendChild(databaseTreeElement);
    122     },
    123 
    124     addCookieDomain: function(domain)
    125     {
    126         var cookieDomainTreeElement = new WebInspector.CookieSidebarTreeElement(domain);
    127         this.cookieListTreeElement.appendChild(cookieDomainTreeElement);
    128     },
    129 
    130     addDOMStorage: function(domStorage)
    131     {
    132         this._domStorage.push(domStorage);
    133         var domStorageTreeElement = new WebInspector.DOMStorageSidebarTreeElement(domStorage, (domStorage.isLocalStorage ? "local-storage" : "session-storage"));
    134         domStorage._domStorageTreeElement = domStorageTreeElement;
    135         if (domStorage.isLocalStorage)
    136             this.localStorageListTreeElement.appendChild(domStorageTreeElement);
    137         else
    138             this.sessionStorageListTreeElement.appendChild(domStorageTreeElement);
    139     },
    140 
    141     selectDatabase: function(databaseId)
    142     {
    143         var database;
    144         for (var i = 0, len = this._databases.length; i < len; ++i) {
    145             database = this._databases[i];
    146             if (database.id === databaseId) {
    147                 this.showDatabase(database);
    148                 database._databasesTreeElement.select();
    149                 return;
    150             }
    151         }
    152     },
    153 
    154     selectDOMStorage: function(storageId)
    155     {
    156         var domStorage = this._domStorageForId(storageId);
    157         if (domStorage) {
    158             this.showDOMStorage(domStorage);
    159             domStorage._domStorageTreeElement.select();
    160         }
    161     },
    162 
    163     showDatabase: function(database, tableName)
    164     {
    165         if (!database)
    166             return;
    167 
    168         if (this.visibleView)
    169             this.visibleView.hide();
    170 
    171         var view;
    172         if (tableName) {
    173             if (!("_tableViews" in database))
    174                 database._tableViews = {};
    175             view = database._tableViews[tableName];
    176             if (!view) {
    177                 view = new WebInspector.DatabaseTableView(database, tableName);
    178                 database._tableViews[tableName] = view;
    179             }
    180         } else {
    181             view = database._queryView;
    182             if (!view) {
    183                 view = new WebInspector.DatabaseQueryView(database);
    184                 database._queryView = view;
    185             }
    186         }
    187 
    188         view.show(this.storageViews);
    189 
    190         this.visibleView = view;
    191 
    192         this.storageViewStatusBarItemsContainer.removeChildren();
    193         var statusBarItems = view.statusBarItems || [];
    194         for (var i = 0; i < statusBarItems.length; ++i)
    195             this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i].element);
    196     },
    197 
    198     showDOMStorage: function(domStorage)
    199     {
    200         if (!domStorage)
    201             return;
    202 
    203         if (this.visibleView)
    204             this.visibleView.hide();
    205 
    206         var view;
    207         view = domStorage._domStorageView;
    208         if (!view) {
    209             view = new WebInspector.DOMStorageItemsView(domStorage);
    210             domStorage._domStorageView = view;
    211         }
    212 
    213         view.show(this.storageViews);
    214 
    215         this.visibleView = view;
    216 
    217         this.storageViewStatusBarItemsContainer.removeChildren();
    218         var statusBarItems = view.statusBarItems;
    219         for (var i = 0; i < statusBarItems.length; ++i)
    220             this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
    221     },
    222 
    223     showCookies: function(treeElement, cookieDomain)
    224     {
    225         if (this.visibleView)
    226             this.visibleView.hide();
    227 
    228         var view = this._cookieViews[cookieDomain];
    229         if (!view) {
    230             view = new WebInspector.CookieItemsView(treeElement, cookieDomain);
    231             this._cookieViews[cookieDomain] = view;
    232         }
    233 
    234         view.show(this.storageViews);
    235 
    236         this.visibleView = view;
    237 
    238         this.storageViewStatusBarItemsContainer.removeChildren();
    239         var statusBarItems = view.statusBarItems;
    240         for (var i = 0; i < statusBarItems.length; ++i)
    241             this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
    242     },
    243 
    244     closeVisibleView: function()
    245     {
    246         if (this.visibleView)
    247             this.visibleView.hide();
    248         delete this.visibleView;
    249     },
    250 
    251     updateDatabaseTables: function(database)
    252     {
    253         if (!database || !database._databasesTreeElement)
    254             return;
    255 
    256         database._databasesTreeElement.shouldRefreshChildren = true;
    257 
    258         if (!("_tableViews" in database))
    259             return;
    260 
    261         var tableNamesHash = {};
    262         var self = this;
    263         function tableNamesCallback(tableNames)
    264         {
    265             var tableNamesLength = tableNames.length;
    266             for (var i = 0; i < tableNamesLength; ++i)
    267                 tableNamesHash[tableNames[i]] = true;
    268 
    269             for (var tableName in database._tableViews) {
    270                 if (!(tableName in tableNamesHash)) {
    271                     if (self.visibleView === database._tableViews[tableName])
    272                         self.closeVisibleView();
    273                     delete database._tableViews[tableName];
    274                 }
    275             }
    276         }
    277         database.getTableNames(tableNamesCallback);
    278     },
    279 
    280     dataGridForResult: function(rows)
    281     {
    282         if (!rows.length)
    283             return null;
    284 
    285         var columns = {};
    286         var numColumns = 0;
    287 
    288         for (var columnIdentifier in rows[0]) {
    289             var column = {};
    290             column.width = columnIdentifier.length;
    291             column.title = columnIdentifier;
    292 
    293             columns[columnIdentifier] = column;
    294             ++numColumns;
    295         }
    296 
    297         var nodes = [];
    298         var length = rows.length;
    299         for (var i = 0; i < length; ++i) {
    300             var data = {};
    301 
    302             var row = rows[i];
    303             for (var columnIdentifier in row)
    304                 data[columnIdentifier] = row[columnIdentifier];
    305 
    306             var node = new WebInspector.DataGridNode(data, false);
    307             node.selectable = false;
    308             nodes.push(node);
    309         }
    310 
    311         var dataGrid = new WebInspector.DataGrid(columns);
    312         var length = nodes.length;
    313         for (var i = 0; i < length; ++i)
    314             dataGrid.appendChild(nodes[i]);
    315 
    316         return dataGrid;
    317     },
    318 
    319     updateDOMStorage: function(storageId)
    320     {
    321         var domStorage = this._domStorageForId(storageId);
    322         if (!domStorage)
    323             return;
    324 
    325         var view = domStorage._domStorageView;
    326         if (this.visibleView && view === this.visibleView)
    327             domStorage._domStorageView.update();
    328     },
    329 
    330     _domStorageForId: function(storageId)
    331     {
    332         if (!this._domStorage)
    333             return null;
    334         var domStorageLength = this._domStorage.length;
    335         for (var i = 0; i < domStorageLength; ++i) {
    336             var domStorage = this._domStorage[i];
    337             if (domStorage.id == storageId)
    338                 return domStorage;
    339         }
    340         return null;
    341     },
    342 
    343     updateMainViewWidth: function(width)
    344     {
    345         this.storageViews.style.left = width + "px";
    346         this.storageViewStatusBarItemsContainer.style.left = width + "px";
    347         this.resize();
    348     }
    349 }
    350 
    351 WebInspector.StoragePanel.prototype.__proto__ = WebInspector.Panel.prototype;
    352 
    353 WebInspector.DatabaseSidebarTreeElement = function(database)
    354 {
    355     this.database = database;
    356 
    357     WebInspector.SidebarTreeElement.call(this, "database-sidebar-tree-item", "", "", database, true);
    358 
    359     this.refreshTitles();
    360 }
    361 
    362 WebInspector.DatabaseSidebarTreeElement.prototype = {
    363     onselect: function()
    364     {
    365         WebInspector.panels.storage.showDatabase(this.database);
    366     },
    367 
    368     oncollapse: function()
    369     {
    370         // Request a refresh after every collapse so the next
    371         // expand will have an updated table list.
    372         this.shouldRefreshChildren = true;
    373     },
    374 
    375     onpopulate: function()
    376     {
    377         this.removeChildren();
    378 
    379         var self = this;
    380         function tableNamesCallback(tableNames)
    381         {
    382             var tableNamesLength = tableNames.length;
    383             for (var i = 0; i < tableNamesLength; ++i)
    384                 self.appendChild(new WebInspector.SidebarDatabaseTableTreeElement(self.database, tableNames[i]));
    385         }
    386         this.database.getTableNames(tableNamesCallback);
    387     },
    388 
    389     get mainTitle()
    390     {
    391         return this.database.name;
    392     },
    393 
    394     set mainTitle(x)
    395     {
    396         // Do nothing.
    397     },
    398 
    399     get subtitle()
    400     {
    401         return this.database.displayDomain;
    402     },
    403 
    404     set subtitle(x)
    405     {
    406         // Do nothing.
    407     }
    408 }
    409 
    410 WebInspector.DatabaseSidebarTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype;
    411 
    412 WebInspector.SidebarDatabaseTableTreeElement = function(database, tableName)
    413 {
    414     this.database = database;
    415     this.tableName = tableName;
    416 
    417     WebInspector.SidebarTreeElement.call(this, "database-table-sidebar-tree-item small", tableName, "", null, false);
    418 }
    419 
    420 WebInspector.SidebarDatabaseTableTreeElement.prototype = {
    421     onselect: function()
    422     {
    423         WebInspector.panels.storage.showDatabase(this.database, this.tableName);
    424     }
    425 }
    426 
    427 WebInspector.SidebarDatabaseTableTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype;
    428 
    429 WebInspector.DOMStorageSidebarTreeElement = function(domStorage, className)
    430 {
    431 
    432     this.domStorage = domStorage;
    433 
    434     WebInspector.SidebarTreeElement.call(this, "domstorage-sidebar-tree-item " + className, domStorage, "", null, false);
    435 
    436     this.refreshTitles();
    437 }
    438 
    439 WebInspector.DOMStorageSidebarTreeElement.prototype = {
    440     onselect: function()
    441     {
    442         WebInspector.panels.storage.showDOMStorage(this.domStorage);
    443     },
    444 
    445     get mainTitle()
    446     {
    447         return this.domStorage.domain ? this.domStorage.domain : WebInspector.UIString("Local Files");
    448     },
    449 
    450     set mainTitle(x)
    451     {
    452         // Do nothing.
    453     },
    454 
    455     get subtitle()
    456     {
    457         return ""; //this.database.displayDomain;
    458     },
    459 
    460     set subtitle(x)
    461     {
    462         // Do nothing.
    463     }
    464 }
    465 
    466 WebInspector.DOMStorageSidebarTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype;
    467 
    468 WebInspector.CookieSidebarTreeElement = function(cookieDomain)
    469 {
    470     WebInspector.SidebarTreeElement.call(this, "cookie-sidebar-tree-item", cookieDomain, "", null, false);
    471     this._cookieDomain = cookieDomain;
    472     this._subtitle = "";
    473 
    474     this.refreshTitles();
    475 }
    476 
    477 WebInspector.CookieSidebarTreeElement.prototype = {
    478     onselect: function()
    479     {
    480         WebInspector.panels.storage.showCookies(this, this._cookieDomain);
    481     },
    482 
    483     get mainTitle()
    484     {
    485         return this._cookieDomain ? this._cookieDomain : WebInspector.UIString("Local Files");
    486     },
    487 
    488     set mainTitle(x)
    489     {
    490         // Do nothing.
    491     },
    492 
    493     get subtitle()
    494     {
    495         return this._subtitle;
    496     },
    497 
    498     set subtitle(x)
    499     {
    500         this._subtitle = x;
    501         this.refreshTitles();
    502     }
    503 }
    504 
    505 WebInspector.CookieSidebarTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype;
    506