/* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Netscape Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 2001 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Joe Hewitt (original author) * * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the NPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /*************************************************************** * InspectorApp ------------------------------------------------- * The primary object that controls the Inspector application. ****************************************************************/ //////////// global variables ///////////////////// var inspector; //////////// global constants //////////////////// const kSearchRegURL = "resource:///res/inspector/search-registry.rdf"; const kWindowMediatorCID = "@mozilla.org/rdf/datasource;1?name=window-mediator"; const kClipboardHelperCID = "@mozilla.org/widget/clipboardhelper;1"; const nsIWebNavigation = Components.interfaces.nsIWebNavigation; ////////////////////////////////////////////////// window.addEventListener("load", InspectorApp_initialize, false); window.addEventListener("unload", InspectorApp_destroy, false); function InspectorApp_initialize() { inspector = new InspectorApp(); inspector.initialize(window.arguments && window.arguments.length > 0 ? window.arguments[0] : null); } function InspectorApp_destroy() { inspector.destroy(); } //////////////////////////////////////////////////////////////////////////// //// class InspectorApp function InspectorApp() { } InspectorApp.prototype = { //////////////////////////////////////////////////////////////////////////// //// Initialization mSearchService: null, mShowBrowser: false, mClipboardHelper: null, get document() { return this.mDocPanel.viewer.subject }, get searchRegistry() { return this.mSearchService }, get panelset() { return this.mPanelSet; }, initialize: function(aTarget) { this.mInitTarget = aTarget; //this.initSearch(); var el = document.getElementById("bxBrowser"); el.addEventListener("load", BrowserLoadListener, true); this.toggleBrowser(true, false); //this.toggleSearch(true, false); this.mClipboardHelper = XPCU.getService(kClipboardHelperCID, "nsIClipboardHelper"); this.mPanelSet = document.getElementById("bxPanelSet"); this.mPanelSet.addObserver("panelsetready", this, false); this.mPanelSet.initialize(); }, destroy: function() { InsUtil.persistAll("bxDocPanel"); InsUtil.persistAll("bxObjectPanel"); }, //////////////////////////////////////////////////////////////////////////// //// Viewer Panels initViewerPanels: function() { this.mDocPanel = this.mPanelSet.getPanel(0); this.mDocPanel.addObserver("subjectChange", this, false); this.mObjectPanel = this.mPanelSet.getPanel(1); if (this.mInitTarget) { if (this.mInitTarget.nodeType == 9) this.setTargetDocument(this.mInitTarget); else if (this.mInitTarget.nodeType == 1) { this.setTargetDocument(this.mInitTarget.ownerDocument); this.mDocPanel.params = this.mInitTarget; } this.mInitTarget = null; } }, onEvent: function(aEvent) { switch (aEvent.type) { case "panelsetready": this.initViewerPanels(); break; case "subjectChange": if (aEvent.target == this.mDocPanel.viewer && aEvent.subject && "location" in aEvent.subject) { this.locationText = aEvent.subject.location; // display document url } } }, //////////////////////////////////////////////////////////////////////////// //// UI Commands doViewerCommand: function(aCommand) { this.mPanelSet.execCommand(aCommand); }, showOpenURLDialog: function() { var url = prompt("Enter a URL:", ""); if (url) { this.gotoURL(url); } }, showPrefsDialog: function() { goPreferences("advancedItem", "chrome://inspector/content/prefs/pref-inspector.xul", "inspector"); }, runSearch: function() { var path = null; // TODO: should persist last path chosen in a pref var file = FilePickerUtils.pickFile("Find Search File", path, ["filterXML"], "Open"); if (file) { var ioService = XPCU.getService("@mozilla.org/network/io-service;1","nsIIOService"); var url = ioService.getURLSpecFromFile(file); // XX temporary until 56354 is fixed url = url.replace("file://", "file:///"); this.startSearchModule(url); } }, toggleBrowser: function(aExplicit, aValue, aSetOnly) { var val = aExplicit ? aValue : !this.mShowBrowser; this.mShowBrowser = val; if (!aSetOnly) this.openSplitter("Browser", val); var cmd = document.getElementById("cmdToggleBrowser"); cmd.setAttribute("checked", val); }, toggleSearch: function(aExplicit, aValue, aSetOnly) { var val = aExplicit ? aValue : !this.mShowSearch; this.mShowSearch = val; if (!aSetOnly) this.openSplitter("Search", val); var cmd = document.getElementById("cmdToggleSearch"); cmd.setAttribute("checked", val); }, openSplitter: function(aName, aTruth) { var splitter = document.getElementById("spl" + aName); if (aTruth) splitter.open(); else splitter.close(); }, /* viewSearchItem: function() { if (this.mCurrentSearch.canViewItems) window.openDialog("chrome://inspector/content/utilWindow.xul", "viewItem", "chrome,resizable"); }, doViewSearchItem: function(aWindow) { var idx = this.getSelectedSearchIndex(); var el = this.mCurrentSearch.viewItemAt(idx); aWindow.title = this.mCurrentSearch.getItemDescription(idx); aWindow.document.getElementById("bxCenter").appendChild(el); }, editSearchItem: function() { }, onSearchTreeClick: function(aEvent) { if (aEvent.detail == 2) { // double click this.viewSearchItem(); } }, */ copySearchItemLine: function() { var mod = this.mSearchService.currentModule; var idx = this.mSearchService.getSelectedIndex(0); var text = mod.getItemText(idx); this.mClipboardHelper.copyString(text); }, copySearchItemAll: function() { var text = this.getAllSearchItemText(); this.mClipboardHelper.writeStringToClipboard(text, kGlobalClipboard); }, saveSearchItemText: function() { var target = FilePickerUtils.pickFile("Save Results As", null, ["filterAll", "filterText"], "Save"); var text = this.getAllSearchItemText(); var file = new File(target.path); file.open('w'); file.write(text); file.close(); }, getAllSearchItemText: function() { var mod = this.mSearchService.currentModule; var len = mod.resultCount; var text = ""; for (var i = 0; i < len; i++) { text += mod.getItemText(i) + "\r"; } return text; }, exit: function() { window.close(); // Todo: remove observer service here }, //////////////////////////////////////////////////////////////////////////// //// Navigation gotoTypedURL: function() { var url = document.getElementById("tfURLBar").value; this.gotoURL(url); }, gotoURL: function(aURL, aNoSaveHistory) { this.mPendingURL = aURL; this.mPendingNoSave = aNoSaveHistory; this.browseToURL(aURL); this.toggleBrowser(true, true); }, browseToURL: function(aURL) { this.webNavigation.loadURI(aURL, nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null); }, goToWindow: function(aMenuitem) { this.setTargetWindowById(aMenuitem.id); }, setTargetWindowById: function(aResId) { var windowManager = XPCU.getService(kWindowMediatorCID, "nsIWindowMediator"); var win = windowManager.getWindowForResource(aResId); if (win) { this.setTargetWindow(win); this.toggleBrowser(true, false); } else alert("Unable to switch to window."); }, setTargetWindow: function(aWindow) { this.setTargetDocument(aWindow.document); }, setTargetDocument: function(aDoc) { this.mDocPanel.subject = aDoc; }, get webNavigation() { var browser = document.getElementById("ifBrowser"); return browser.webNavigation; }, //////////////////////////////////////////////////////////////////////////// //// UI Labels getters and setters get locationText() { return document.getElementById("tfURLBar").value; }, set locationText(aText) { document.getElementById("tfURLBar").value = aText; }, get statusText() { return document.getElementById("txStatus").value; }, set statusText(aText) { document.getElementById("txStatus").value = aText; }, get progress() { return document.getElementById("pmStatus").value; }, set progress(aPct) { document.getElementById("pmStatus").value = aPct; }, get searchTitle(aTitle) { return document.getElementById("splSearch").label; }, set searchTitle(aTitle) { var splitter = document.getElementById("splSearch"); splitter.setAttribute("label", "Search" + (aTitle ? " - " + aTitle : "")); }, //////////////////////////////////////////////////////////////////////////// //// Document Loading documentLoaded: function() { this.setTargetWindow(_content); var url = this.webNavigation.currentURI.spec; // put the url into the urlbar this.locationText = url; // add url to the history, unless explicity told not to if (!this.mPendingNoSave) this.addToHistory(url); this.mPendingURL = null; this.mPendingNoSave = null; }, //////////////////////////////////////////////////////////////////////////// //// Search initSearch: function() { var ss = new inSearchService(); this.mSearchService = ss; ss.addSearchObserver(this); ss.resultsTree = document.getElementById("trSearch"); ss.contextMenu = document.getElementById("ppSearchResults"); ss.contextMenuInsertPt = document.getElementById("ppSearchResults-insertion"); ss.contextMenuInsert = inSearchService.INSERT_BEFORE; }, startSearchModule: function(aModuleURL) { this.mSearchService.startModule(aModuleURL); }, clearSearchResults: function() { this.searchTitle = null; this.statusText = ""; this.progress = 0; this.mSearchService.clearSearch(); }, //////////////////////////////////////////////////////////////////////////// //// interface inISearchObserver onSearchStart: function(aModule) { this.searchTitle = aModule.title; this.toggleSearch(true, true); }, onSearchResult: function(aModule) { if (aModule.isPastMilestone) { this.statusText = "Searching - " + aModule.resultCount + " results found."; // XXX localize this.progress = aModule.progressPercent; } }, onSearchEnd: function(aModule, aResult) { var diff = Math.round(aModule.elapsed / 100) / 10; this.progress = 100; this.statusText = "Search complete - " + aModule.resultCount + " results found ("+diff+"s)"; // XXX localize }, onSearchError: function(aModule, aMessage) { alert("Unable to complete this search due to the following error:\n" + aMessage); }, //////////////////////////////////////////////////////////////////////////// //// History addToHistory: function(aURL) { }, //////////////////////////////////////////////////////////////////////////// //// Uncategorized get isViewingContent() { return this.mPanelSet.getPanel(0).subject != null; }, fillInTooltip: function(tipElement) { var retVal = false; var textNode = document.getElementById("txTooltip"); if (textNode) { try { var tipText = tipElement.getAttribute("tooltiptext"); if (tipText != "") { textNode.setAttribute("value", tipText); retVal = true; } } catch (e) { } } return retVal; }, initPopup: function(aPopup) { var items = aPopup.getElementsByTagName("menuitem"); var js, fn, item; for (var i = 0; i < items.length; i++) { item = items[i]; fn = "isDisabled" in item ? item.isDisabled : null; if (!fn) { js = item.getAttribute("isDisabled"); if (js) { fn = new Function(js); item.isDisabled = fn; } else { item.isDisabled = null; // to prevent annoying "strict" warning messages } } if (fn) { if (item.isDisabled()) item.setAttribute("disabled", "true"); else item.removeAttribute("disabled"); } fn = null; } }, emptyChildren: function(aNode) { while (aNode.childNodes.length > 0) { aNode.removeChild(aNode.lastChild); } }, onSplitterOpen: function(aSplitter) { if (aSplitter.id == "splBrowser") { this.toggleBrowser(true, aSplitter.isOpened, true); } else if (aSplitter.id == "splSearch") { this.toggleSearch(true, aSplitter.isOpened, true); } }, // needed by overlayed commands from viewer to get references to a specific // viewer object by name getViewer: function(aUID) { return this.mPanelSet.registry.getViewerByUID(aUID); } }; //////////////////////////////////////////////////////////////////////////// //// event listeners function BrowserLoadListener(aEvent) { // since we will also get load events for frame documents, // make sure we respond to the top-level document load if (aEvent.target.defaultView == _content) inspector.documentLoaded(); } function UtilWindowOpenListener(aWindow) { inspector.doViewSearchItem(aWindow); }