dom-helpers.js (2215B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 exports.DOMHelpers = { 8 /** 9 * A simple way to be notified (once) when a window becomes 10 * interactive (DOMContentLoaded). 11 * 12 * It is based on the chromeEventHandler. This is useful when 13 * chrome iframes are loaded in content docshells (in Firefox 14 * tabs for example). 15 * 16 * @param nsIDOMWindow win 17 * The content window, owning the document to traverse. 18 * @param Function callback 19 * The method to call when the frame is loaded. 20 * @param String targetURL 21 * (optional) Check that the frame URL corresponds to the provided URL 22 * before calling the callback. 23 */ 24 onceDOMReady(win, callback, targetURL) { 25 if (!win) { 26 throw new Error("window can't be null or undefined"); 27 } 28 const docShell = win.docShell; 29 const onReady = function (event) { 30 if (event.target == win.document) { 31 docShell.chromeEventHandler.removeEventListener( 32 "DOMContentLoaded", 33 onReady 34 ); 35 // If in `callback` the URL of the window is changed and a listener to DOMContentLoaded 36 // is attached, the event we just received will be also be caught by the new listener. 37 // We want to avoid that so we execute the callback in the next queue. 38 Services.tm.dispatchToMainThread(callback); 39 } 40 }; 41 // The initial document is special in that, while uncommitted, its readyState 42 // will already be "complete" even though the document is still loading. 43 // It is either transient and will be replaced by a different document, 44 // or it will be committed to and a load event will be fired for it. 45 if ( 46 (win.document.readyState == "complete" || 47 win.document.readyState == "interactive") && 48 win.location.href == targetURL && 49 !win.document.isUncommittedInitialDocument 50 ) { 51 Services.tm.dispatchToMainThread(callback); 52 } else { 53 docShell.chromeEventHandler.addEventListener("DOMContentLoaded", onReady); 54 } 55 }, 56 };