/* 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"; // This is loaded into chrome windows with the subscript loader. Wrap in // a block to prevent accidentally leaking globals onto `window`. { /* globals XULFrameElement */ class MozEditor extends XULFrameElement { connectedCallback() { this._editorContentListener = { QueryInterface: ChromeUtils.generateQI([ "nsIURIContentListener", "nsISupportsWeakReference", ]), doContent() { return false; }, isPreferred() { return false; }, canHandleContent() { return false; }, loadCookie: null, parentContentListener: null, }; this._finder = null; this._fastFind = null; this._lastSearchString = null; // Make window editable immediately only // if the "editortype" attribute is supplied // This allows using same contentWindow for different editortypes, // where the type is determined during the apps's window.onload handler. if (this.editortype) { this.makeEditable(this.editortype, true); } } get finder() { if (!this._finder) { if (!this.docShell) { return null; } let { Finder } = ChromeUtils.importESModule( "resource://gre/modules/Finder.sys.mjs" ); this._finder = new Finder(this.docShell); } return this._finder; } get fastFind() { if (!this._fastFind) { if (!("@mozilla.org/typeaheadfind;1" in Cc)) { return null; } if (!this.docShell) { return null; } this._fastFind = Cc["@mozilla.org/typeaheadfind;1"].createInstance( Ci.nsITypeAheadFind ); this._fastFind.init(this.docShell); } return this._fastFind; } set editortype(val) { this.setAttribute("editortype", val); } get editortype() { return this.getAttribute("editortype"); } get currentURI() { return this.webNavigation.currentURI; } get webBrowserFind() { return this.docShell .QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebBrowserFind); } get editingSession() { return this.docShell.editingSession; } get commandManager() { return this.webNavigation .QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsICommandManager); } set fullZoom(val) { this.browsingContext.fullZoom = val; } get fullZoom() { return this.browsingContext.fullZoom; } set textZoom(val) { this.browsingContext.textZoom = val; } get textZoom() { return this.browsingContext.textZoom; } get isSyntheticDocument() { return this.contentDocument.isSyntheticDocument; } get messageManager() { if (this.frameLoader) { return this.frameLoader.messageManager; } return null; } // Copied from toolkit/content/widgets/browser-custom-element.js. // Send an asynchronous message to the remote child via an actor. // Note: use this only for messages through an actor. For old-style // messages, use the message manager. // The value of the scope argument determines which browsing contexts // are sent to: // 'all' - send to actors associated with all descendant child frames. // 'roots' - send only to actors associated with process roots. // undefined/'' - send only to the top-level actor and not any descendants. sendMessageToActor(messageName, args, actorName, scope) { if (!this.frameLoader) { return; } function sendToChildren(browsingContext, childScope) { let windowGlobal = browsingContext.currentWindowGlobal; // If 'roots' is set, only send if windowGlobal.isProcessRoot is true. if ( windowGlobal && (childScope != "roots" || windowGlobal.isProcessRoot) ) { windowGlobal.getActor(actorName).sendAsyncMessage(messageName, args); } // Iterate as long as scope in assigned. Note that we use the original // passed in scope, not childScope here. if (scope) { for (let context of browsingContext.children) { sendToChildren(context, scope); } } } // Pass no second argument to always send to the top-level browsing context. sendToChildren(this.browsingContext); } get outerWindowID() { return this.docShell.outerWindowID; } makeEditable(editortype, waitForUrlLoad) { let win = this.contentWindow; this.editingSession.makeWindowEditable( win, editortype, waitForUrlLoad, true, false ); this.setAttribute("editortype", editortype); this.docShell .QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIURIContentListener).parentContentListener = this._editorContentListener; } getEditor(containingWindow) { return this.editingSession.getEditorForWindow(containingWindow); } getHTMLEditor(containingWindow) { var editor = this.editingSession.getEditorForWindow(containingWindow); return editor.QueryInterface(Ci.nsIHTMLEditor); } } customElements.define("editor", MozEditor); }