/* -*- 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/. */
// Services = object with smart getters for common XPCOM services var { AppConstants } = ChromeUtils.importESModule( "resource://gre/modules/AppConstants.sys.mjs"
); var { XPCOMUtils } = ChromeUtils.importESModule( "resource://gre/modules/XPCOMUtils.sys.mjs"
);
Object.defineProperty(this, "BROWSER_NEW_TAB_URL", {
enumerable: true,
get() { if (PrivateBrowsingUtils.isWindowPrivate(window)) { if (
!PrivateBrowsingUtils.permanentPrivateBrowsing &&
!AboutNewTab.newTabURLOverridden
) { return"about:privatebrowsing";
} // If an extension controls the setting and does not have private // browsing permission, use the default setting.
let extensionControlled = Services.prefs.getBoolPref( "browser.newtab.extensionControlled", false
);
let privateAllowed = Services.prefs.getBoolPref( "browser.newtab.privateAllowed", false
); // There is a potential on upgrade that the prefs are not set yet, so we double check // for moz-extension. if (
!privateAllowed &&
(extensionControlled ||
AboutNewTab.newTabURL.startsWith("moz-extension://"))
) { return"about:privatebrowsing";
}
} return AboutNewTab.newTabURL;
},
});
var TAB_DROP_TYPE = "application/x-moz-tabbrowser-tab";
var gBidiUI = false;
/** * Determines whether the given url is considered a special URL for new tabs.
*/ function isBlankPageURL(aURL) { return (
aURL == "about:blank" ||
aURL == "about:home" ||
aURL == BROWSER_NEW_TAB_URL ||
aURL == "chrome://browser/content/blanktab.html"
);
}
function doGetProtocolFlags(aURI) { return Services.io.getDynamicProtocolFlags(aURI);
}
// Used as an onclick handler for UI elements with link-like behavior. // e.g. onclick="checkForMiddleClick(this, event);" // Not needed for menuitems because those fire command events even on middle clicks. function checkForMiddleClick(node, event) { // We should be using the disabled property here instead of the attribute, // but some elements that this function is used with don't support it (e.g. // menuitem). if (node.getAttribute("disabled") == "true") { return;
} // Do nothing
if (event.target.tagName == "menuitem") { // Menu items fire command on middle-click by themselves. return;
}
if (event.button == 1) { /* Execute the node's oncommand or command.
*/
// If the middle-click was on part of a menu, close the menu. // (Menus close automatically with left-click but not with middle-click.)
closeMenus(event.target);
}
}
// Populate a menu with user-context menu items. This method should be called // by onpopupshowing passing the event as first argument. function createUserContextMenu(
event,
{
isContextMenu = false,
excludeUserContextId = 0,
showDefaultTab = false,
useAccessKeys = true,
} = {}
) { while (event.target.hasChildNodes()) {
event.target.firstChild.remove();
}
MozXULElement.insertFTLIfNeeded("toolkit/global/contextual-identity.ftl");
let docfrag = document.createDocumentFragment();
// If we are excluding a userContextId, we want to add a 'no-container' item. if (excludeUserContextId || showDefaultTab) {
let menuitem = document.createXULElement("menuitem"); if (useAccessKeys) {
document.l10n.setAttributes(menuitem, "user-context-none");
} else { const label =
ContextualIdentityService.formatContextLabel("user-context-none");
menuitem.setAttribute("label", label);
}
menuitem.setAttribute("data-usercontextid", "0"); if (!isContextMenu) {
menuitem.setAttribute("command", "Browser:NewUserContextTab");
}
docfrag.appendChild(menuitem);
let menuseparator = document.createXULElement("menuseparator");
docfrag.appendChild(menuseparator);
}
ContextualIdentityService.getPublicIdentities().forEach(identity => { if (identity.userContextId == excludeUserContextId) { return;
}
// Closes all popups that are ancestors of the node. function closeMenus(node) { if ("tagName" in node) { if (
node.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" &&
(node.tagName == "menupopup" || node.tagName == "popup")
) {
node.hidePopup();
}
closeMenus(node.parentNode);
}
}
/** This function takes in a key element and compares it to the keys pressed during an event. * * @param aEvent * The KeyboardEvent event you want to compare against your key. * * @param aKey * The <key> element checked to see if it was called in aEvent. * For example, aKey can be a variable set to document.getElementById("key_close") * to check if the close command key was pressed in aEvent.
*/ function eventMatchesKey(aEvent, aKey) {
let keyPressed = (aKey.getAttribute("key") || "").toLowerCase();
let keyModifiers = aKey.getAttribute("modifiers");
let modifiers = ["Alt", "Control", "Meta", "Shift"];
if (aEvent.key != keyPressed) { returnfalse;
}
let eventModifiers = modifiers.filter(modifier =>
aEvent.getModifierState(modifier)
); // Check if aEvent has a modifier and aKey doesn't if (eventModifiers.length && !keyModifiers.length) { returnfalse;
} // Check whether aKey's modifiers match aEvent's modifiers if (keyModifiers) {
keyModifiers = keyModifiers.split(/[\s,]+/); // Capitalize first letter of aKey's modifers to compare to aEvent's modifier
keyModifiers.forEach(function (modifier, index) { if (modifier == "accel") {
keyModifiers[index] =
AppConstants.platform == "macosx" ? "Meta" : "Control";
} else {
keyModifiers[index] = modifier[0].toUpperCase() + modifier.slice(1);
}
}); return modifiers.every(
modifier =>
keyModifiers.includes(modifier) == aEvent.getModifierState(modifier)
);
} returntrue;
}
// Gather all descendent text under given document node. function gatherTextUnder(root) { var text = ""; var node = root.firstChild; var depth = 1; while (node && depth > 0) { // See if this node is text. if (node.nodeType == Node.TEXT_NODE) { // Add this text to our collection.
text += " " + node.data;
} elseif (HTMLImageElement.isInstance(node)) { // If it has an "alt" attribute, add that. var altText = node.getAttribute("alt"); if (altText) {
text += " " + altText;
}
} // Find next node to test. // First, see if this node has children. if (node.hasChildNodes()) { // Go to first child.
node = node.firstChild;
depth++;
} else { // No children, try next sibling (or parent next sibling). while (depth > 0 && !node.nextSibling) {
node = node.parentNode;
depth--;
} if (node.nextSibling) {
node = node.nextSibling;
}
}
} // Strip leading and tailing whitespace.
text = text.trim(); // Compress remaining whitespace.
text = text.replace(/\s+/g, " "); return text;
}
// This function exists for legacy reasons. function getShellService() { return ShellService;
}
function isBidiEnabled() { // first check the pref. if (Services.prefs.getBoolPref("bidi.browser.ui", false)) { returntrue;
}
// now see if the app locale is an RTL one. const isRTL = Services.locale.isAppLocaleRTL;
if (isRTL) {
Services.prefs.setBoolPref("bidi.browser.ui", true);
} return isRTL;
}
function openAboutDialog() { for (let win of Services.wm.getEnumerator("Browser:About")) { // Only open one about window (Bug 599573) if (win.closed) { continue;
}
win.focus(); return;
}
var features = "chrome,"; if (AppConstants.platform == "win") {
features += "centerscreen,dependent";
} elseif (AppConstants.platform == "macosx") {
features += "centerscreen,resizable=no,minimizable=no";
} else {
features += "centerscreen,dependent,dialog=no";
}
async function openPreferences(paneID, extraArgs) { // This function is duplicated from preferences.js. function internalPrefCategoryNameToFriendlyName(aName) { return (aName || "").replace(/^pane./, function (toReplace) { return toReplace[4].toLowerCase();
});
}
let win = Services.wm.getMostRecentWindow("navigator:browser");
let friendlyCategoryName = internalPrefCategoryNameToFriendlyName(paneID);
let params; if (extraArgs && extraArgs.urlParams) {
params = new URLSearchParams();
let urlParams = extraArgs.urlParams; for (let name in urlParams) { if (urlParams[name] !== undefined) {
params.set(name, urlParams[name]);
}
}
}
let preferencesURLSuffix =
(params ? "?" + params : "") +
(friendlyCategoryName ? "#" + friendlyCategoryName : "");
let newLoad = true;
let browser = null; if (!win) {
let windowArguments = Cc["@mozilla.org/array;1"].createInstance(
Ci.nsIMutableArray
);
let supportsStringPrefURL = Cc[ "@mozilla.org/supports-string;1"
].createInstance(Ci.nsISupportsString);
supportsStringPrefURL.data = "about:preferences" + preferencesURLSuffix;
windowArguments.appendElement(supportsStringPrefURL);
if (!newLoad && paneID) { if (browser.contentDocument?.readyState != "complete") {
await new Promise(resolve => {
browser.addEventListener("load", resolve, {
capture: true,
once: true,
});
});
}
browser.contentWindow.gotoPref(paneID);
}
}
/** * Opens the troubleshooting information (about:support) page for this version * of the application.
*/ function openTroubleshootingPage() {
openTrustedLinkIn("about:support", "tab");
}
/** * Opens the feedback page for this version of the application.
*/ function openFeedbackPage() { var url = Services.urlFormatter.formatURLPref("app.feedback.baseURL");
openTrustedLinkIn(url, "tab");
}
/** * Appends UTM parameters to then opens the SUMO URL for device migration.
*/ function openSwitchingDevicesPage() {
let url = getHelpLinkURL("switching-devices");
let parsedUrl = new URL(url);
parsedUrl.searchParams.set("utm_content", "switch-to-new-device");
parsedUrl.searchParams.set("utm_source", "help-menu");
parsedUrl.searchParams.set("utm_medium", "firefox-desktop");
parsedUrl.searchParams.set("utm_campaign", "migration");
openTrustedLinkIn(parsedUrl.href, "tab");
}
function buildHelpMenu() {
document.getElementById("feedbackPage").disabled =
!Services.policies.isAllowed("feedbackCommands");
let supportMenu = Services.policies.getSupportMenu(); if (supportMenu) {
let menuitem = document.getElementById("helpPolicySupport");
menuitem.hidden = false;
menuitem.setAttribute("label", supportMenu.Title); if ("AccessKey" in supportMenu) {
menuitem.setAttribute("accesskey", supportMenu.AccessKey);
}
document.getElementById("helpPolicySeparator").hidden = false;
}
// Enable/disable the "Report Web Forgery" menu item. if (typeof gSafeBrowsing != "undefined") {
gSafeBrowsing.setReportPhishingMenu();
}
}
function isElementVisible(aElement) { if (!aElement) { returnfalse;
}
// If aElement or a direct or indirect parent is hidden or collapsed, // height, width or both will be 0. var rect = aElement.getBoundingClientRect(); return rect.height > 0 && rect.width > 0;
}
function makeURLAbsolute(aBase, aUrl) { // Note: makeURI() will throw if aUri is not a valid URI return makeURI(aUrl, null, makeURI(aBase)).spec;
}
function getHelpLinkURL(aHelpTopic) { var url = Services.urlFormatter.formatURLPref("app.support.baseURL"); return url + aHelpTopic;
}
// aCalledFromModal is optional function openHelpLink(aHelpTopic, aCalledFromModal, aWhere) { var url = getHelpLinkURL(aHelpTopic); var where = aWhere; if (!aWhere) {
where = aCalledFromModal ? "window" : "tab";
}
openTrustedLinkIn(url, where);
}
function openPrefsHelp(aEvent) {
let helpTopic = aEvent.target.getAttribute("helpTopic");
openHelpLink(helpTopic);
}
¤ Dauer der Verarbeitung: 0.34 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.