1
/* ***** BEGIN LICENSE BLOCK *****
2
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
4
* The contents of this file are subject to the Netscape Public License
5
* Version 1.1 (the "License"); you may not use this file except in
6
* compliance with the License. You may obtain a copy of the License at
7
* http://www.mozilla.org/NPL/
9
* Software distributed under the License is distributed on an "AS IS" basis,
10
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
* for the specific language governing rights and limitations under the
14
* The Original Code is mozilla.org code.
16
* The Initial Developer of the Original Code is
17
* Netscape Communications Corporation.
18
* Portions created by the Initial Developer are Copyright (C) 2001
19
* the Initial Developer. All Rights Reserved.
22
* Joe Hewitt <hewitt@netscape.com> (original author)
25
* Alternatively, the contents of this file may be used under the terms of
26
* either the GNU General Public License Version 2 or later (the "GPL"), or
27
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28
* in which case the provisions of the GPL or the LGPL are applicable instead
29
* of those above. If you wish to allow use of your version of this file only
30
* under the terms of either the GPL or the LGPL, and not to allow others to
31
* use your version of this file under the terms of the NPL, indicate your
32
* decision by deleting the provisions above and replace them with the notice
33
* and other provisions required by the GPL or the LGPL. If you do not delete
34
* the provisions above, a recipient may use your version of this file under
35
* the terms of any one of the NPL, the GPL or the LGPL.
37
* ***** END LICENSE BLOCK ***** */
39
/***************************************************************
40
* InspectorApp -------------------------------------------------
41
* The primary object that controls the Inspector application.
42
****************************************************************/
44
//////////// global variables /////////////////////
48
//////////// global constants ////////////////////
50
const kSearchRegURL = "resource:///res/inspector/search-registry.rdf";
52
const kWindowDataSourceCID = "@mozilla.org/rdf/datasource;1?name=window-mediator";
53
const kClipboardHelperCID = "@mozilla.org/widget/clipboardhelper;1";
54
const kPromptServiceCID = "@mozilla.org/embedcomp/prompt-service;1";
55
const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
57
//////////////////////////////////////////////////
59
window.addEventListener("load", InspectorApp_initialize, false);
60
window.addEventListener("unload", InspectorApp_destroy, false);
62
function InspectorApp_initialize()
64
inspector = new InspectorApp();
66
// window.arguments may be either a string or a node.
67
// If passed via a command line handler, it will be a uri string.
68
// If passed via navigator hooks, it will be a dom node to inspect.
69
var initNode, initURI;
70
if (window.arguments.length) {
71
if (typeof window.arguments[0] == "string") {
72
initURI = window.arguments[0];
74
else if (window.arguments[0] instanceof Components.interfaces.nsIDOMNode) {
75
initNode = window.arguments[0];
78
inspector.initialize(initNode, initURI);
81
function InspectorApp_destroy()
86
////////////////////////////////////////////////////////////////////////////
87
//// class InspectorApp
89
function InspectorApp()
93
InspectorApp.prototype =
95
////////////////////////////////////////////////////////////////////////////
100
mClipboardHelper: null,
101
mPromptService: null,
103
get document() { return this.mDocPanel.viewer.subject },
104
get searchRegistry() { return this.mSearchService },
105
get panelset() { return this.mPanelSet; },
107
initialize: function(aTarget, aURI)
109
this.mInitTarget = aTarget;
113
var el = document.getElementById("bxBrowser");
114
el.addEventListener("load", BrowserLoadListener, true);
116
this.setBrowser(false, true);
117
//this.setSearch(false, true);
119
this.mClipboardHelper = XPCU.getService(kClipboardHelperCID, "nsIClipboardHelper");
120
this.mPromptService = XPCU.getService(kPromptServiceCID, "nsIPromptService");
122
this.mPanelSet = document.getElementById("bxPanelSet");
123
this.mPanelSet.addObserver("panelsetready", this, false);
124
this.mPanelSet.initialize();
133
InsUtil.persistAll("bxDocPanel");
134
InsUtil.persistAll("bxObjectPanel");
137
////////////////////////////////////////////////////////////////////////////
140
initViewerPanels: function()
142
this.mDocPanel = this.mPanelSet.getPanel(0);
143
this.mDocPanel.addObserver("subjectChange", this, false);
144
this.mObjectPanel = this.mPanelSet.getPanel(1);
146
if (this.mInitTarget) {
147
if (this.mInitTarget.nodeType == Node.DOCUMENT_NODE)
148
this.setTargetDocument(this.mInitTarget);
149
else if (this.mInitTarget.nodeType == Node.ELEMENT_NODE) {
150
this.setTargetDocument(this.mInitTarget.ownerDocument);
151
this.mDocPanel.params = this.mInitTarget;
153
this.mInitTarget = null;
157
onEvent: function(aEvent)
159
switch (aEvent.type) {
160
case "panelsetready":
161
this.initViewerPanels();
163
case "subjectChange":
164
if (aEvent.target == this.mDocPanel.viewer &&
165
aEvent.subject && "location" in aEvent.subject) {
166
this.locationText = aEvent.subject.location; // display document url
171
////////////////////////////////////////////////////////////////////////////
174
doViewerCommand: function(aCommand)
176
this.mPanelSet.execCommand(aCommand);
179
showOpenURLDialog: function()
181
var bundle = this.mPanelSet.stringBundle;
182
var msg = bundle.getString("inspectURL.message");
183
var title = bundle.getString("inspectURL.title");
184
var url = { value: "http://" };
185
var dummy = { value: false };
186
var go = this.mPromptService.prompt(window, title, msg, url, null, dummy);
188
this.gotoURL(url.value);
192
showPrefsDialog: function()
194
goPreferences("advancedItem", "chrome://inspector/content/prefs/pref-inspector.xul", "inspector");
197
toggleBrowser: function(aToggleSplitter)
199
this.setBrowser(!this.mShowBrowser, aToggleSplitter)
202
setBrowser: function(aValue, aToggleSplitter)
204
this.mShowBrowser = aValue;
206
this.openSplitter("Browser", aValue);
207
var cmd = document.getElementById("cmdToggleBrowser");
208
cmd.setAttribute("checked", aValue);
211
toggleSearch: function(aToggleSplitter)
213
this.setSearch(!this.mShowSearch, aToggleSplitter);
216
setSearch: function(aValue, aToggleSplitter)
218
this.mShowSearch = aValue;
220
this.openSplitter("Search", aValue);
221
var cmd = document.getElementById("cmdToggleSearch");
222
cmd.setAttribute("checked", aValue);
225
openSplitter: function(aName, aTruth)
227
var splitter = document.getElementById("spl" + aName);
236
The following code needs to evaluated. What does it do? Why does nobody
237
call it? If deemed necessary, turn it back on with the right callers,
241
runSearch: function()
243
var path = null; // TODO: should persist last path chosen in a pref
244
var file = FilePickerUtils.pickFile("Find Search File", path, ["filterXML"], "Open");
246
var ioService = XPCU.getService("@mozilla.org/network/io-service;1","nsIIOService");
247
var fileHandler = XPCU.QI(ioService.getProtocolHandler("file"), "nsIFileProtocolHandler");
249
var url = fileHandler.getURLSpecFromFile(file);
251
this.startSearchModule(url);
255
viewSearchItem: function()
257
if (this.mCurrentSearch.canViewItems)
258
window.openDialog("chrome://inspector/content/utilWindow.xul", "viewItem", "chrome,resizable");
261
doViewSearchItem: function(aWindow)
263
var idx = this.getSelectedSearchIndex();
264
var el = this.mCurrentSearch.viewItemAt(idx);
266
aWindow.title = this.mCurrentSearch.getItemDescription(idx);
267
aWindow.document.getElementById("bxCenter").appendChild(el);
270
editSearchItem: function()
274
onSearchTreeClick: function(aEvent)
276
if (aEvent.detail == 2) { // double click
277
this.viewSearchItem();
281
copySearchItemLine: function()
283
var mod = this.mSearchService.currentModule;
284
var idx = this.mSearchService.getSelectedIndex(0);
285
var text = mod.getItemText(idx);
286
this.mClipboardHelper.copyString(text);
289
// XXX what is this? It doesn't seem to get called from anywhere?
290
copySearchItemAll: function()
292
var text = this.getAllSearchItemText();
293
this.mClipboardHelper.copyString(text);
296
saveSearchItemText: function()
298
var target = FilePickerUtils.pickFile("Save Results As", null, ["filterAll", "filterText"], "Save");
300
var text = this.getAllSearchItemText();
302
var file = new File(target.path);
308
getAllSearchItemText: function()
310
var mod = this.mSearchService.currentModule;
311
var len = mod.resultCount;
313
for (var i = 0; i < len; i++) {
314
text += mod.getItemText(i) + "\r";
324
// Todo: remove observer service here
327
////////////////////////////////////////////////////////////////////////////
330
gotoTypedURL: function()
332
var url = document.getElementById("tfURLBar").value;
336
gotoURL: function(aURL, aNoSaveHistory)
338
this.mPendingURL = aURL;
339
this.mPendingNoSave = aNoSaveHistory;
340
this.browseToURL(aURL);
341
this.setBrowser(true, true);
344
browseToURL: function(aURL)
347
this.webNavigation.loadURI(aURL, nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
350
// nsIWebNavigation.loadURI will spit out an appropriate user prompt, so
351
// we don't need to do anything here. See nsDocShell::DisplayLoadError()
355
goToWindow: function(aMenuitem)
357
this.setTargetWindowById(aMenuitem.id);
360
setTargetWindowById: function(aResId)
362
var windowManager = XPCU.getService(kWindowDataSourceCID, "nsIWindowDataSource");
363
var win = windowManager.getWindowForResource(aResId);
366
this.setTargetWindow(win);
367
this.setBrowser(false, true);
369
var bundle = this.mPanelSet.stringBundle;
370
var msg = bundle.getString("inspectWindow.error.message");
371
var title = bundle.getString("inspectWindow.error.title");
372
this.mPromptService.alert(window, title, msg);
376
setTargetWindow: function(aWindow)
378
this.setTargetDocument(aWindow.document);
381
setTargetDocument: function(aDoc)
383
this.mDocPanel.subject = aDoc;
388
var browser = document.getElementById("ifBrowser");
389
return browser.webNavigation;
392
////////////////////////////////////////////////////////////////////////////
393
//// UI Labels getters and setters
395
get locationText() { return document.getElementById("tfURLBar").value; },
396
set locationText(aText) { document.getElementById("tfURLBar").value = aText; },
398
get statusText() { return document.getElementById("txStatus").value; },
399
set statusText(aText) { document.getElementById("txStatus").value = aText; },
401
get progress() { return document.getElementById("pmStatus").value; },
402
set progress(aPct) { document.getElementById("pmStatus").value = aPct; },
405
XXXcaa -- What is this?
408
get searchTitle(aTitle) { return document.getElementById("splSearch").label; },
409
set searchTitle(aTitle)
411
var splitter = document.getElementById("splSearch");
412
splitter.setAttribute("label", "Search" + (aTitle ? " - " + aTitle : ""));
415
////////////////////////////////////////////////////////////////////////////
416
//// Document Loading
418
documentLoaded: function()
420
this.setTargetWindow(_content);
422
var url = this.webNavigation.currentURI.spec;
424
// put the url into the urlbar
425
this.locationText = url;
427
// add url to the history, unless explicity told not to
428
if (!this.mPendingNoSave)
429
this.addToHistory(url);
431
this.mPendingURL = null;
432
this.mPendingNoSave = null;
435
////////////////////////////////////////////////////////////////////////////
438
initSearch: function()
440
var ss = new inSearchService();
441
this.mSearchService = ss;
443
ss.addSearchObserver(this);
444
ss.resultsTree = document.getElementById("trSearch");
445
ss.contextMenu = document.getElementById("ppSearchResults");
446
ss.contextMenuInsertPt = document.getElementById("ppSearchResults-insertion");
447
ss.contextMenuInsert = inSearchService.INSERT_BEFORE;
450
startSearchModule: function(aModuleURL)
452
this.mSearchService.startModule(aModuleURL);
455
clearSearchResults: function()
457
this.searchTitle = null;
458
this.statusText = "";
461
this.mSearchService.clearSearch();
464
////////////////////////////////////////////////////////////////////////////
465
//// interface inISearchObserver
467
onSearchStart: function(aModule)
469
this.searchTitle = aModule.title;
470
this.toggleSearch(true, true);
473
onSearchResult: function(aModule)
475
if (aModule.isPastMilestone) {
476
this.statusText = "Searching - " + aModule.resultCount + " results found."; // XXX localize
477
this.progress = aModule.progressPercent;
481
onSearchEnd: function(aModule, aResult)
483
var diff = Math.round(aModule.elapsed / 100) / 10;
485
this.statusText = "Search complete - " + aModule.resultCount + " results found ("+diff+"s)"; // XXX localize
488
onSearchError: function(aModule, aMessage)
490
alert("Unable to complete this search due to the following error:\n" + aMessage);
495
////////////////////////////////////////////////////////////////////////////
498
addToHistory: function(aURL)
502
////////////////////////////////////////////////////////////////////////////
505
get isViewingContent() { return this.mPanelSet.getPanel(0).subject != null; },
507
fillInTooltip: function(tipElement)
510
var textNode = document.getElementById("txTooltip");
513
var tipText = tipElement.getAttribute("tooltiptext");
515
textNode.setAttribute("value", tipText);
525
initPopup: function(aPopup)
527
var items = aPopup.getElementsByTagName("menuitem");
529
for (var i = 0; i < items.length; i++) {
531
fn = "isDisabled" in item ? item.isDisabled : null;
533
js = item.getAttribute("isDisabled");
535
fn = new Function(js);
536
item.isDisabled = fn;
538
item.isDisabled = null; // to prevent annoying "strict" warning messages
542
if (item.isDisabled())
543
item.setAttribute("disabled", "true");
545
item.removeAttribute("disabled");
552
emptyChildren: function(aNode)
554
while (aNode.childNodes.length > 0) {
555
aNode.removeChild(aNode.lastChild);
559
onSplitterOpen: function(aSplitter)
561
if (aSplitter.id == "splBrowser") {
562
this.setBrowser(aSplitter.isOpened, false);
563
} else if (aSplitter.id == "splSearch") {
564
this.setSearch(aSplitter.isOpened, false);
568
// needed by overlayed commands from viewer to get references to a specific
569
// viewer object by name
570
getViewer: function(aUID)
572
return this.mPanelSet.registry.getViewerByUID(aUID);
577
////////////////////////////////////////////////////////////////////////////
580
function BrowserLoadListener(aEvent)
582
// since we will also get load events for frame documents,
583
// make sure we respond to the top-level document load
584
if (aEvent.target.defaultView == _content)
585
inspector.documentLoaded();
588
function UtilWindowOpenListener(aWindow)
590
inspector.doViewSearchItem(aWindow);