/* -*- mode: js; indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* 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 = ["BrowserUtils"]; const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); const { XPCOMUtils } = ChromeUtils.import( "resource://gre/modules/XPCOMUtils.jsm" ); var BrowserUtils = { /** * Return or create a principal with the content of one, and the originAttributes * of an existing principal (e.g. on a docshell, where the originAttributes ought * not to change, that is, we should keep the userContextId, privateBrowsingId, * etc. the same when changing the principal). * * @param principal * The principal whose content/null/system-ness we want. * @param existingPrincipal * The principal whose originAttributes we want, usually the current * principal of a docshell. * @return an nsIPrincipal that matches the content/null/system-ness of the first * param, and the originAttributes of the second. */ principalWithMatchingOA(principal, existingPrincipal) { // Don't care about system principals: if (principal.isSystemPrincipal) { return principal; } // If the originAttributes already match, just return the principal as-is. if (existingPrincipal.originSuffix == principal.originSuffix) { return principal; } let secMan = Services.scriptSecurityManager; if (principal.isContentPrincipal) { return secMan.principalWithOA( principal, existingPrincipal.originAttributes ); } if (principal.isNullPrincipal) { return secMan.createNullPrincipal(existingPrincipal.originAttributes); } throw new Error( "Can't change the originAttributes of an expanded principal!" ); }, /** * Returns true if |mimeType| is text-based, or false otherwise. * * @param mimeType * The MIME type to check. */ mimeTypeIsTextBased(mimeType) { return ( mimeType.startsWith("text/") || mimeType.endsWith("+xml") || mimeType == "application/x-javascript" || mimeType == "application/javascript" || mimeType == "application/json" || mimeType == "application/xml" ); }, /** * Returns true if we can show a find bar, including FAYT, for the specified * document location. The location must not be in a blacklist of specific * "about:" pages for which find is disabled. * * This can be called from the parent process or from content processes. */ canFindInPage(location) { return ( !location.startsWith("about:addons") && !location.startsWith( "chrome://mozapps/content/extensions/aboutaddons.html" ) && !location.startsWith("about:preferences") ); }, isFindbarVisible(docShell) { const FINDER_JSM = "resource://gre/modules/Finder.jsm"; return ( Cu.isModuleLoaded(FINDER_JSM) && ChromeUtils.import(FINDER_JSM).Finder.isFindbarVisible(docShell) ); }, /** * Returns a Promise which resolves when the given observer topic has been * observed. * * @param {string} topic * The topic to observe. * @param {function(nsISupports, string)} [test] * An optional test function which, when called with the * observer's subject and data, should return true if this is the * expected notification, false otherwise. * @returns {Promise} */ promiseObserved(topic, test = () => true) { return new Promise(resolve => { let observer = (subject, topic, data) => { if (test(subject, data)) { Services.obs.removeObserver(observer, topic); resolve({ subject, data }); } }; Services.obs.addObserver(observer, topic); }); }, isShareableURL(url) { if (!url) { return false; } // Disallow sharing URLs with more than 65535 characters. if (url.spec.length > 65535) { return false; } let scheme = url.scheme; return !( "about" == scheme || "resource" == scheme || "chrome" == scheme || "blob" == scheme || "moz-extension" == scheme ); }, }; XPCOMUtils.defineLazyPreferenceGetter( BrowserUtils, "navigationRequireUserInteraction", "browser.navigation.requireUserInteraction", false );