diff options
Diffstat (limited to 'remote/targets/TabTarget.jsm')
-rw-r--r-- | remote/targets/TabTarget.jsm | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/remote/targets/TabTarget.jsm b/remote/targets/TabTarget.jsm new file mode 100644 index 0000000000..fd672677aa --- /dev/null +++ b/remote/targets/TabTarget.jsm @@ -0,0 +1,164 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +var EXPORTED_SYMBOLS = ["TabTarget"]; + +const { Target } = ChromeUtils.import( + "chrome://remote/content/targets/Target.jsm" +); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); +const { TabSession } = ChromeUtils.import( + "chrome://remote/content/sessions/TabSession.jsm" +); +const { XPCOMUtils } = ChromeUtils.import( + "resource://gre/modules/XPCOMUtils.jsm" +); +const { RemoteAgent } = ChromeUtils.import( + "chrome://remote/content/RemoteAgent.jsm" +); + +XPCOMUtils.defineLazyServiceGetter( + this, + "Favicons", + "@mozilla.org/browser/favicon-service;1", + "nsIFaviconService" +); + +/** + * Target for a local tab or a remoted frame. + */ +class TabTarget extends Target { + /** + * @param Targets targets + * @param BrowserElement browser + */ + constructor(targets, browser) { + super(targets, TabSession); + + this.browser = browser; + + // Define the HTTP path to query this target + this.path = `/devtools/page/${this.id}`; + + Services.obs.addObserver(this, "message-manager-disconnect"); + } + + destructor() { + Services.obs.removeObserver(this, "message-manager-disconnect"); + super.destructor(); + } + + get browserContextId() { + return parseInt(this.browser.getAttribute("usercontextid")); + } + + get browsingContext() { + return this.browser.browsingContext; + } + + get mm() { + return this.browser.messageManager; + } + + get window() { + return this.browser.ownerGlobal; + } + + get tab() { + return this.window.gBrowser.getTabForBrowser(this.browser); + } + + /** + * Determines if the content browser remains attached + * to its parent chrome window. + * + * We determine this by checking if the <browser> element + * is still attached to the DOM. + * + * @return {boolean} + * True if target's browser is still attached, + * false if it has been disconnected. + */ + get closed() { + return !this.browser || !this.browser.isConnected; + } + + get description() { + return ""; + } + + get frontendURL() { + return null; + } + + /** @return {Promise.<String=>} */ + get faviconUrl() { + return new Promise((resolve, reject) => { + Favicons.getFaviconURLForPage(this.browser.currentURI, url => { + if (url) { + resolve(url.spec); + } else { + resolve(null); + } + }); + }); + } + + get title() { + return this.browsingContext.currentWindowGlobal.documentTitle; + } + + get type() { + return "page"; + } + + get url() { + return this.browser.currentURI.spec; + } + + get wsDebuggerURL() { + const { host, port } = RemoteAgent; + return `ws://${host}:${port}${this.path}`; + } + + toString() { + return `[object Target ${this.id}]`; + } + + toJSON() { + return { + description: this.description, + devtoolsFrontendUrl: this.frontendURL, + // TODO(ato): toJSON cannot be marked async )-: + faviconUrl: "", + id: this.id, + // Bug 1680817: Fails to encode some UTF-8 characters + // title: this.title, + type: this.type, + url: this.url, + browsingContextId: this.browsingContext.id, + webSocketDebuggerUrl: this.wsDebuggerURL, + }; + } + + // nsIObserver + + observe(subject, topic, data) { + if (subject === this.mm && subject == "message-manager-disconnect") { + // disconnect debugging target if <browser> is disconnected, + // otherwise this is just a host process change + if (this.closed) { + this.disconnect(); + } + } + } + + // XPCOM + + get QueryInterface() { + return ChromeUtils.generateQI(["nsIHttpRequestHandler", "nsIObserver"]); + } +} |