OLD | NEW |
| (Empty) |
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, true); | |
33 | |
34 this.databasesListTreeElement = new WebInspector.SidebarSectionTreeElement(W
ebInspector.UIString("DATABASES"), {}, true); | |
35 this.sidebarTree.appendChild(this.databasesListTreeElement); | |
36 this.databasesListTreeElement.expand(); | |
37 | |
38 this.localStorageListTreeElement = new WebInspector.SidebarSectionTreeElemen
t(WebInspector.UIString("LOCAL STORAGE"), {}, true); | |
39 this.sidebarTree.appendChild(this.localStorageListTreeElement); | |
40 this.localStorageListTreeElement.expand(); | |
41 | |
42 this.sessionStorageListTreeElement = new WebInspector.SidebarSectionTreeElem
ent(WebInspector.UIString("SESSION STORAGE"), {}, true); | |
43 this.sidebarTree.appendChild(this.sessionStorageListTreeElement); | |
44 this.sessionStorageListTreeElement.expand(); | |
45 | |
46 this.cookieListTreeElement = new WebInspector.SidebarSectionTreeElement(WebI
nspector.UIString("COOKIES"), {}, true); | |
47 this.sidebarTree.appendChild(this.cookieListTreeElement); | |
48 this.cookieListTreeElement.expand(); | |
49 | |
50 this.storageViews = document.createElement("div"); | |
51 this.storageViews.id = "storage-views"; | |
52 this.element.appendChild(this.storageViews); | |
53 | |
54 this.storageViewStatusBarItemsContainer = document.createElement("div"); | |
55 this.storageViewStatusBarItemsContainer.id = "storage-view-status-bar-items"
; | |
56 | |
57 this.reset(); | |
58 } | |
59 | |
60 WebInspector.StoragePanel.prototype = { | |
61 toolbarItemClass: "storage", | |
62 | |
63 get toolbarItemLabel() | |
64 { | |
65 return WebInspector.UIString("Storage"); | |
66 }, | |
67 | |
68 get statusBarItems() | |
69 { | |
70 return [this.storageViewStatusBarItemsContainer]; | |
71 }, | |
72 | |
73 reset: function() | |
74 { | |
75 if (this._databases) { | |
76 var databasesLength = this._databases.length; | |
77 for (var i = 0; i < databasesLength; ++i) { | |
78 var database = this._databases[i]; | |
79 | |
80 delete database._tableViews; | |
81 delete database._queryView; | |
82 } | |
83 } | |
84 | |
85 this._databases = []; | |
86 | |
87 if (this._domStorage) { | |
88 var domStorageLength = this._domStorage.length; | |
89 for (var i = 0; i < domStorageLength; ++i) { | |
90 var domStorage = this._domStorage[i]; | |
91 | |
92 delete domStorage._domStorageView; | |
93 } | |
94 } | |
95 | |
96 this._domStorage = []; | |
97 | |
98 this._cookieDomains = {}; | |
99 this._cookieViews = {}; | |
100 | |
101 this.databasesListTreeElement.removeChildren(); | |
102 this.localStorageListTreeElement.removeChildren(); | |
103 this.sessionStorageListTreeElement.removeChildren(); | |
104 this.cookieListTreeElement.removeChildren(); | |
105 | |
106 this.storageViews.removeChildren(); | |
107 | |
108 this.storageViewStatusBarItemsContainer.removeChildren(); | |
109 | |
110 if (this.sidebarTree.selectedTreeElement) | |
111 this.sidebarTree.selectedTreeElement.deselect(); | |
112 }, | |
113 | |
114 handleKeyEvent: function(event) | |
115 { | |
116 this.sidebarTree.handleKeyEvent(event); | |
117 }, | |
118 | |
119 addDatabase: function(database) | |
120 { | |
121 this._databases.push(database); | |
122 | |
123 var databaseTreeElement = new WebInspector.DatabaseSidebarTreeElement(da
tabase); | |
124 database._databasesTreeElement = databaseTreeElement; | |
125 this.databasesListTreeElement.appendChild(databaseTreeElement); | |
126 }, | |
127 | |
128 addCookieDomain: function(domain) | |
129 { | |
130 // Eliminate duplicate domains from the list. | |
131 if (typeof this._cookieDomains[domain] !== "undefined") | |
132 return; | |
133 | |
134 var cookieDomainTreeElement = new WebInspector.CookieSidebarTreeElement(
domain); | |
135 this.cookieListTreeElement.appendChild(cookieDomainTreeElement); | |
136 this._cookieDomains[domain] = true; | |
137 }, | |
138 | |
139 addDOMStorage: function(domStorage) | |
140 { | |
141 this._domStorage.push(domStorage); | |
142 var domStorageTreeElement = new WebInspector.DOMStorageSidebarTreeElemen
t(domStorage, (domStorage.isLocalStorage ? "local-storage" : "session-storage"))
; | |
143 domStorage._domStorageTreeElement = domStorageTreeElement; | |
144 if (domStorage.isLocalStorage) | |
145 this.localStorageListTreeElement.appendChild(domStorageTreeElement); | |
146 else | |
147 this.sessionStorageListTreeElement.appendChild(domStorageTreeElement
); | |
148 }, | |
149 | |
150 selectDatabase: function(databaseId) | |
151 { | |
152 var database; | |
153 for (var i = 0, len = this._databases.length; i < len; ++i) { | |
154 database = this._databases[i]; | |
155 if (database.id === databaseId) { | |
156 this.showDatabase(database); | |
157 database._databasesTreeElement.select(); | |
158 return; | |
159 } | |
160 } | |
161 }, | |
162 | |
163 selectDOMStorage: function(storageId) | |
164 { | |
165 var domStorage = this._domStorageForId(storageId); | |
166 if (domStorage) { | |
167 this.showDOMStorage(domStorage); | |
168 domStorage._domStorageTreeElement.select(); | |
169 } | |
170 }, | |
171 | |
172 showDatabase: function(database, tableName) | |
173 { | |
174 if (!database) | |
175 return; | |
176 | |
177 if (this.visibleView) | |
178 this.visibleView.hide(); | |
179 | |
180 var view; | |
181 if (tableName) { | |
182 if (!("_tableViews" in database)) | |
183 database._tableViews = {}; | |
184 view = database._tableViews[tableName]; | |
185 if (!view) { | |
186 view = new WebInspector.DatabaseTableView(database, tableName); | |
187 database._tableViews[tableName] = view; | |
188 } | |
189 } else { | |
190 view = database._queryView; | |
191 if (!view) { | |
192 view = new WebInspector.DatabaseQueryView(database); | |
193 database._queryView = view; | |
194 } | |
195 } | |
196 | |
197 view.show(this.storageViews); | |
198 | |
199 this.visibleView = view; | |
200 | |
201 this.storageViewStatusBarItemsContainer.removeChildren(); | |
202 var statusBarItems = view.statusBarItems || []; | |
203 for (var i = 0; i < statusBarItems.length; ++i) | |
204 this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i
].element); | |
205 }, | |
206 | |
207 showDOMStorage: function(domStorage) | |
208 { | |
209 if (!domStorage) | |
210 return; | |
211 | |
212 if (this.visibleView) | |
213 this.visibleView.hide(); | |
214 | |
215 var view; | |
216 view = domStorage._domStorageView; | |
217 if (!view) { | |
218 view = new WebInspector.DOMStorageItemsView(domStorage); | |
219 domStorage._domStorageView = view; | |
220 } | |
221 | |
222 view.show(this.storageViews); | |
223 | |
224 this.visibleView = view; | |
225 | |
226 this.storageViewStatusBarItemsContainer.removeChildren(); | |
227 var statusBarItems = view.statusBarItems; | |
228 for (var i = 0; i < statusBarItems.length; ++i) | |
229 this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i
]); | |
230 }, | |
231 | |
232 showCookies: function(cookieDomain) | |
233 { | |
234 if (this.visibleView) | |
235 this.visibleView.hide(); | |
236 | |
237 var view = this._cookieViews[cookieDomain]; | |
238 if (!view) { | |
239 view = new WebInspector.CookieItemsView(cookieDomain); | |
240 this._cookieViews[cookieDomain] = view; | |
241 } | |
242 | |
243 view.show(this.storageViews); | |
244 | |
245 this.visibleView = view; | |
246 | |
247 this.storageViewStatusBarItemsContainer.removeChildren(); | |
248 var statusBarItems = view.statusBarItems; | |
249 for (var i = 0; i < statusBarItems.length; ++i) | |
250 this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i
]); | |
251 }, | |
252 | |
253 closeVisibleView: function() | |
254 { | |
255 if (this.visibleView) | |
256 this.visibleView.hide(); | |
257 delete this.visibleView; | |
258 }, | |
259 | |
260 updateDatabaseTables: function(database) | |
261 { | |
262 if (!database || !database._databasesTreeElement) | |
263 return; | |
264 | |
265 database._databasesTreeElement.shouldRefreshChildren = true; | |
266 | |
267 if (!("_tableViews" in database)) | |
268 return; | |
269 | |
270 var tableNamesHash = {}; | |
271 var self = this; | |
272 function tableNamesCallback(tableNames) | |
273 { | |
274 var tableNamesLength = tableNames.length; | |
275 for (var i = 0; i < tableNamesLength; ++i) | |
276 tableNamesHash[tableNames[i]] = true; | |
277 | |
278 for (var tableName in database._tableViews) { | |
279 if (!(tableName in tableNamesHash)) { | |
280 if (self.visibleView === database._tableViews[tableName]) | |
281 self.closeVisibleView(); | |
282 delete database._tableViews[tableName]; | |
283 } | |
284 } | |
285 } | |
286 database.getTableNames(tableNamesCallback); | |
287 }, | |
288 | |
289 dataGridForResult: function(rows) | |
290 { | |
291 if (!rows.length) | |
292 return null; | |
293 | |
294 var columns = {}; | |
295 var numColumns = 0; | |
296 | |
297 for (var columnIdentifier in rows[0]) { | |
298 var column = {}; | |
299 column.width = columnIdentifier.length; | |
300 column.title = columnIdentifier; | |
301 | |
302 columns[columnIdentifier] = column; | |
303 ++numColumns; | |
304 } | |
305 | |
306 var nodes = []; | |
307 var length = rows.length; | |
308 for (var i = 0; i < length; ++i) { | |
309 var data = {}; | |
310 | |
311 var row = rows[i]; | |
312 for (var columnIdentifier in row) { | |
313 var text = row[columnIdentifier]; | |
314 data[columnIdentifier] = text; | |
315 if (text.length > columns[columnIdentifier].width) | |
316 columns[columnIdentifier].width = text.length; | |
317 } | |
318 | |
319 var node = new WebInspector.DataGridNode(data, false); | |
320 node.selectable = false; | |
321 nodes.push(node); | |
322 } | |
323 | |
324 var totalColumnWidths = 0; | |
325 for (var columnIdentifier in columns) | |
326 totalColumnWidths += columns[columnIdentifier].width; | |
327 | |
328 // Calculate the percentage width for the columns. | |
329 const minimumPrecent = Math.min(5, Math.floor(100/numColumns)); | |
330 var recoupPercent = 0; | |
331 for (var columnIdentifier in columns) { | |
332 var width = columns[columnIdentifier].width; | |
333 width = Math.round((width / totalColumnWidths) * 100); | |
334 if (width < minimumPrecent) { | |
335 recoupPercent += (minimumPrecent - width); | |
336 width = minimumPrecent; | |
337 } | |
338 | |
339 columns[columnIdentifier].width = width; | |
340 } | |
341 | |
342 // Enforce the minimum percentage width. | |
343 while (recoupPercent > 0) { | |
344 for (var columnIdentifier in columns) { | |
345 if (columns[columnIdentifier].width > minimumPrecent) { | |
346 --columns[columnIdentifier].width; | |
347 --recoupPercent; | |
348 if (!recoupPercent) | |
349 break; | |
350 } | |
351 } | |
352 } | |
353 | |
354 // Change the width property to a string suitable for a style width. | |
355 for (var columnIdentifier in columns) | |
356 columns[columnIdentifier].width += "%"; | |
357 | |
358 var dataGrid = new WebInspector.DataGrid(columns); | |
359 var length = nodes.length; | |
360 for (var i = 0; i < length; ++i) | |
361 dataGrid.appendChild(nodes[i]); | |
362 | |
363 return dataGrid; | |
364 }, | |
365 | |
366 resize: function() | |
367 { | |
368 var visibleView = this.visibleView; | |
369 if (visibleView && "resize" in visibleView) | |
370 visibleView.resize(); | |
371 }, | |
372 | |
373 updateDOMStorage: function(storageId) | |
374 { | |
375 var domStorage = this._domStorageForId(storageId); | |
376 if (!domStorage) | |
377 return; | |
378 | |
379 var view = domStorage._domStorageView; | |
380 if (this.visibleView && view === this.visibleView) | |
381 domStorage._domStorageView.update(); | |
382 }, | |
383 | |
384 _domStorageForId: function(storageId) | |
385 { | |
386 if (!this._domStorage) | |
387 return null; | |
388 var domStorageLength = this._domStorage.length; | |
389 for (var i = 0; i < domStorageLength; ++i) { | |
390 var domStorage = this._domStorage[i]; | |
391 if (domStorage.id == storageId) | |
392 return domStorage; | |
393 } | |
394 return null; | |
395 }, | |
396 | |
397 setMainViewWidth: function(width) | |
398 { | |
399 this.storageViews.style.left = width + "px"; | |
400 this.storageViewStatusBarItemsContainer.style.left = width + "px"; | |
401 } | |
402 } | |
403 | |
404 WebInspector.StoragePanel.prototype.__proto__ = WebInspector.Panel.prototype; | |
405 | |
406 WebInspector.DatabaseSidebarTreeElement = function(database) | |
407 { | |
408 this.database = database; | |
409 | |
410 WebInspector.SidebarTreeElement.call(this, "database-sidebar-tree-item", "",
"", database, true); | |
411 | |
412 this.refreshTitles(); | |
413 } | |
414 | |
415 WebInspector.DatabaseSidebarTreeElement.prototype = { | |
416 onselect: function() | |
417 { | |
418 WebInspector.panels.storage.showDatabase(this.database); | |
419 }, | |
420 | |
421 oncollapse: function() | |
422 { | |
423 // Request a refresh after every collapse so the next | |
424 // expand will have an updated table list. | |
425 this.shouldRefreshChildren = true; | |
426 }, | |
427 | |
428 onpopulate: function() | |
429 { | |
430 this.removeChildren(); | |
431 | |
432 var self = this; | |
433 function tableNamesCallback(tableNames) | |
434 { | |
435 var tableNamesLength = tableNames.length; | |
436 for (var i = 0; i < tableNamesLength; ++i) | |
437 self.appendChild(new WebInspector.SidebarDatabaseTableTreeElemen
t(self.database, tableNames[i])); | |
438 } | |
439 this.database.getTableNames(tableNamesCallback); | |
440 }, | |
441 | |
442 get mainTitle() | |
443 { | |
444 return this.database.name; | |
445 }, | |
446 | |
447 set mainTitle(x) | |
448 { | |
449 // Do nothing. | |
450 }, | |
451 | |
452 get subtitle() | |
453 { | |
454 return this.database.displayDomain; | |
455 }, | |
456 | |
457 set subtitle(x) | |
458 { | |
459 // Do nothing. | |
460 } | |
461 } | |
462 | |
463 WebInspector.DatabaseSidebarTreeElement.prototype.__proto__ = WebInspector.Sideb
arTreeElement.prototype; | |
464 | |
465 WebInspector.SidebarDatabaseTableTreeElement = function(database, tableName) | |
466 { | |
467 this.database = database; | |
468 this.tableName = tableName; | |
469 | |
470 WebInspector.SidebarTreeElement.call(this, "database-table-sidebar-tree-item
small", tableName, "", null, false); | |
471 } | |
472 | |
473 WebInspector.SidebarDatabaseTableTreeElement.prototype = { | |
474 onselect: function() | |
475 { | |
476 WebInspector.panels.storage.showDatabase(this.database, this.tableName); | |
477 } | |
478 } | |
479 | |
480 WebInspector.SidebarDatabaseTableTreeElement.prototype.__proto__ = WebInspector.
SidebarTreeElement.prototype; | |
481 | |
482 WebInspector.DOMStorageSidebarTreeElement = function(domStorage, className) | |
483 { | |
484 | |
485 this.domStorage = domStorage; | |
486 | |
487 WebInspector.SidebarTreeElement.call(this, "domstorage-sidebar-tree-item " +
className, domStorage, "", null, false); | |
488 | |
489 this.refreshTitles(); | |
490 } | |
491 | |
492 WebInspector.DOMStorageSidebarTreeElement.prototype = { | |
493 onselect: function() | |
494 { | |
495 WebInspector.panels.storage.showDOMStorage(this.domStorage); | |
496 }, | |
497 | |
498 get mainTitle() | |
499 { | |
500 return this.domStorage.domain ? this.domStorage.domain : WebInspector.UI
String("Local Files"); | |
501 }, | |
502 | |
503 set mainTitle(x) | |
504 { | |
505 // Do nothing. | |
506 }, | |
507 | |
508 get subtitle() | |
509 { | |
510 return ""; //this.database.displayDomain; | |
511 }, | |
512 | |
513 set subtitle(x) | |
514 { | |
515 // Do nothing. | |
516 } | |
517 } | |
518 | |
519 WebInspector.DOMStorageSidebarTreeElement.prototype.__proto__ = WebInspector.Sid
ebarTreeElement.prototype; | |
520 | |
521 WebInspector.CookieSidebarTreeElement = function(cookieDomain) | |
522 { | |
523 WebInspector.SidebarTreeElement.call(this, "cookie-sidebar-tree-item", cooki
eDomain, "", null, false); | |
524 this._cookieDomain = cookieDomain; | |
525 | |
526 this.refreshTitles(); | |
527 } | |
528 | |
529 WebInspector.CookieSidebarTreeElement.prototype = { | |
530 onselect: function() | |
531 { | |
532 WebInspector.panels.storage.showCookies(this._cookieDomain); | |
533 }, | |
534 | |
535 get mainTitle() | |
536 { | |
537 return this._cookieDomain ? this._cookieDomain : WebInspector.UIString("
Local Files"); | |
538 }, | |
539 | |
540 set mainTitle(x) | |
541 { | |
542 // Do nothing. | |
543 }, | |
544 | |
545 get subtitle() | |
546 { | |
547 return ""; | |
548 }, | |
549 | |
550 set subtitle(x) | |
551 { | |
552 // Do nothing. | |
553 } | |
554 } | |
555 | |
556 WebInspector.CookieSidebarTreeElement.prototype.__proto__ = WebInspector.Sidebar
TreeElement.prototype; | |
OLD | NEW |