зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1685801: Part 6 - Move some front-end code from BrowserUtils to a separate module. r=mccr8
Differential Revision: https://phabricator.services.mozilla.com/D101486
This commit is contained in:
Родитель
16d8777f81
Коммит
69c936d646
|
@ -14,8 +14,8 @@ const { XPCOMUtils } = ChromeUtils.import(
|
|||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm"
|
||||
"BrowserUIUtils",
|
||||
"resource:///modules/BrowserUIUtils.jsm"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function() {
|
||||
|
@ -73,7 +73,7 @@ class EncryptedMediaParent extends JSWindowActorParent {
|
|||
let link = document.createXULElement("label", { is: "text-link" });
|
||||
link.setAttribute("href", baseURL + "drm-content");
|
||||
link.textContent = text;
|
||||
return BrowserUtils.getLocalizedFragment(document, mainMessage, link);
|
||||
return BrowserUIUtils.getLocalizedFragment(document, mainMessage, link);
|
||||
}
|
||||
|
||||
getMessageWithBrandName(aNotificationId) {
|
||||
|
|
|
@ -631,7 +631,7 @@ var gXPInstallObserver = {
|
|||
);
|
||||
let b = doc.createElementNS("http://www.w3.org/1999/xhtml", "b");
|
||||
b.textContent = options.name;
|
||||
let fragment = BrowserUtils.getLocalizedFragment(doc, text, b);
|
||||
let fragment = BrowserUIUtils.getLocalizedFragment(doc, text, b);
|
||||
message.appendChild(fragment);
|
||||
} else {
|
||||
message.textContent = gNavigatorBundle.getString(
|
||||
|
|
|
@ -2188,7 +2188,7 @@ var BookmarkingUI = {
|
|||
) {
|
||||
let isBookmarked = this._itemGuids.size > 0;
|
||||
if (!isBookmarked) {
|
||||
BrowserUtils.setToolbarButtonHeightProperty(this.star);
|
||||
BrowserUIUtils.setToolbarButtonHeightProperty(this.star);
|
||||
// there are no other animations on this element, so we can simply
|
||||
// listen for animationend with the "once" option to clean up
|
||||
let animatableBox = document.getElementById(
|
||||
|
|
|
@ -23,6 +23,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
BrowserSearchTelemetry: "resource:///modules/BrowserSearchTelemetry.jsm",
|
||||
BrowserUsageTelemetry: "resource:///modules/BrowserUsageTelemetry.jsm",
|
||||
BrowserTelemetryUtils: "resource://gre/modules/BrowserTelemetryUtils.jsm",
|
||||
BrowserUIUtils: "resource:///modules/BrowserUIUtils.jsm",
|
||||
BrowserUtils: "resource://gre/modules/BrowserUtils.jsm",
|
||||
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
|
||||
CFRPageActions: "resource://activity-stream/lib/CFRPageActions.jsm",
|
||||
|
@ -4938,7 +4939,7 @@ var XULBrowserWindow = {
|
|||
);
|
||||
|
||||
if (UrlbarPrefs.get("trimURLs")) {
|
||||
url = BrowserUtils.trimURL(url);
|
||||
url = BrowserUIUtils.trimURL(url);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5127,7 +5128,7 @@ var XULBrowserWindow = {
|
|||
aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT;
|
||||
if (
|
||||
(location == "about:blank" &&
|
||||
BrowserUtils.checkEmptyPageOrigin(gBrowser.selectedBrowser)) ||
|
||||
BrowserUIUtils.checkEmptyPageOrigin(gBrowser.selectedBrowser)) ||
|
||||
location == ""
|
||||
) {
|
||||
// Second condition is for new tabs, otherwise
|
||||
|
@ -5590,7 +5591,7 @@ var CombinedStopReload = {
|
|||
|
||||
this._cancelTransition();
|
||||
if (shouldAnimate) {
|
||||
BrowserUtils.setToolbarButtonHeightProperty(this.stopReloadContainer);
|
||||
BrowserUIUtils.setToolbarButtonHeightProperty(this.stopReloadContainer);
|
||||
this.stopReloadContainer.setAttribute("animate", "true");
|
||||
} else {
|
||||
this.stopReloadContainer.removeAttribute("animate");
|
||||
|
@ -5613,7 +5614,7 @@ var CombinedStopReload = {
|
|||
this.stopReloadContainer.closest("#nav-bar-customization-target");
|
||||
|
||||
if (shouldAnimate) {
|
||||
BrowserUtils.setToolbarButtonHeightProperty(this.stopReloadContainer);
|
||||
BrowserUIUtils.setToolbarButtonHeightProperty(this.stopReloadContainer);
|
||||
this.stopReloadContainer.setAttribute("animate", "true");
|
||||
} else {
|
||||
this.stopReloadContainer.removeAttribute("animate");
|
||||
|
|
|
@ -228,7 +228,7 @@
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!BrowserUtils.checkEmptyPageOrigin(browser)) {
|
||||
if (!BrowserUIUtils.checkEmptyPageOrigin(browser)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
BookmarkJSONUtils: "resource://gre/modules/BookmarkJSONUtils.jsm",
|
||||
BrowserSearchTelemetry: "resource:///modules/BrowserSearchTelemetry.jsm",
|
||||
BrowserUsageTelemetry: "resource:///modules/BrowserUsageTelemetry.jsm",
|
||||
BrowserUtils: "resource://gre/modules/BrowserUtils.jsm",
|
||||
BrowserUIUtils: "resource:///modules/BrowserUIUtils.jsm",
|
||||
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
|
||||
ContextualIdentityService:
|
||||
"resource://gre/modules/ContextualIdentityService.jsm",
|
||||
|
@ -3950,7 +3950,7 @@ BrowserGlue.prototype = {
|
|||
// same way that the url bar would.
|
||||
body = URIs[0].uri.replace(/([?#]).*$/, "$1");
|
||||
let wasTruncated = body.length < URIs[0].uri.length;
|
||||
body = BrowserUtils.trimURL(body);
|
||||
body = BrowserUIUtils.trimURL(body);
|
||||
if (wasTruncated) {
|
||||
body = bundle.formatStringFromName(
|
||||
"singleTabArrivingWithTruncatedURL.body",
|
||||
|
|
|
@ -52,8 +52,8 @@ ChromeUtils.defineModuleGetter(
|
|||
);
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm"
|
||||
"BrowserUIUtils",
|
||||
"resource:///modules/BrowserUIUtils.jsm"
|
||||
);
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
|
@ -791,7 +791,7 @@ CustomizeMode.prototype = {
|
|||
}
|
||||
if (!this.window.gReduceMotion) {
|
||||
let overflowButton = this.$("nav-bar-overflow-button");
|
||||
BrowserUtils.setToolbarButtonHeightProperty(overflowButton).then(() => {
|
||||
BrowserUIUtils.setToolbarButtonHeightProperty(overflowButton).then(() => {
|
||||
overflowButton.setAttribute("animate", "true");
|
||||
overflowButton.addEventListener("animationend", function onAnimationEnd(
|
||||
event
|
||||
|
|
|
@ -34,8 +34,8 @@ ChromeUtils.defineModuleGetter(
|
|||
);
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm"
|
||||
"BrowserUIUtils",
|
||||
"resource:///modules/BrowserUIUtils.jsm"
|
||||
);
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
|
@ -367,7 +367,7 @@ class ExtensionControlledPopup {
|
|||
);
|
||||
} else {
|
||||
description.appendChild(
|
||||
BrowserUtils.getLocalizedFragment(doc, message, addonDetails)
|
||||
BrowserUIUtils.getLocalizedFragment(doc, message, addonDetails)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm"
|
||||
"BrowserUIUtils",
|
||||
"resource:///modules/BrowserUIUtils.jsm"
|
||||
);
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
|
@ -64,7 +64,7 @@ XPCOMUtils.defineLazyGetter(this, "tabHidePopup", () => {
|
|||
getLocalizedDescription: (doc, message, addonDetails) => {
|
||||
let image = doc.createXULElement("image");
|
||||
image.setAttribute("class", "extension-controlled-icon alltabs-icon");
|
||||
return BrowserUtils.getLocalizedFragment(
|
||||
return BrowserUIUtils.getLocalizedFragment(
|
||||
doc,
|
||||
message,
|
||||
addonDetails,
|
||||
|
|
|
@ -10,8 +10,8 @@ const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm"
|
||||
"BrowserUIUtils",
|
||||
"resource:///modules/BrowserUIUtils.jsm"
|
||||
);
|
||||
|
||||
var Pocket = {
|
||||
|
@ -46,7 +46,7 @@ var Pocket = {
|
|||
|
||||
let libraryButton = document.getElementById("library-button");
|
||||
if (libraryButton) {
|
||||
BrowserUtils.setToolbarButtonHeightProperty(libraryButton);
|
||||
BrowserUIUtils.setToolbarButtonHeightProperty(libraryButton);
|
||||
}
|
||||
|
||||
let urlToSave = Pocket._urlToSave;
|
||||
|
|
|
@ -11,8 +11,8 @@ const { XPCOMUtils } = ChromeUtils.import(
|
|||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm"
|
||||
"BrowserUIUtils",
|
||||
"resource:///modules/BrowserUIUtils.jsm"
|
||||
);
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
|
@ -76,7 +76,7 @@ var PocketPageAction = {
|
|||
return;
|
||||
}
|
||||
|
||||
BrowserUtils.setToolbarButtonHeightProperty(urlbarNode);
|
||||
BrowserUIUtils.setToolbarButtonHeightProperty(urlbarNode);
|
||||
|
||||
PocketPageAction.urlbarNode = urlbarNode;
|
||||
PocketPageAction.urlbarNode.setAttribute("open", "true");
|
||||
|
|
|
@ -396,7 +396,7 @@ function test() {
|
|||
);
|
||||
is(
|
||||
gURLBar.value,
|
||||
BrowserUtils.trimURL("http://example.com/"),
|
||||
BrowserUIUtils.trimURL("http://example.com/"),
|
||||
"Address bar's value set after loading URI"
|
||||
);
|
||||
runNextTest();
|
||||
|
|
|
@ -13,6 +13,7 @@ const { XPCOMUtils } = ChromeUtils.import(
|
|||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
AppConstants: "resource://gre/modules/AppConstants.jsm",
|
||||
BrowserSearchTelemetry: "resource:///modules/BrowserSearchTelemetry.jsm",
|
||||
BrowserUIUtils: "resource:///modules/BrowserUIUtils.jsm",
|
||||
BrowserUtils: "resource://gre/modules/BrowserUtils.jsm",
|
||||
ExtensionSearchHandler: "resource://gre/modules/ExtensionSearchHandler.jsm",
|
||||
ObjectUtils: "resource://gre/modules/ObjectUtils.jsm",
|
||||
|
@ -330,7 +331,7 @@ class UrlbarInput {
|
|||
// only if there's no opener (bug 370555).
|
||||
if (
|
||||
this.window.isInitialPage(uri) &&
|
||||
BrowserUtils.checkEmptyPageOrigin(
|
||||
BrowserUIUtils.checkEmptyPageOrigin(
|
||||
this.window.gBrowser.selectedBrowser,
|
||||
uri
|
||||
)
|
||||
|
@ -349,7 +350,7 @@ class UrlbarInput {
|
|||
!this.window.isBlankPageURL(uri.spec) || uri.schemeIs("moz-extension");
|
||||
} else if (
|
||||
this.window.isInitialPage(value) &&
|
||||
BrowserUtils.checkEmptyPageOrigin(this.window.gBrowser.selectedBrowser)
|
||||
BrowserUIUtils.checkEmptyPageOrigin(this.window.gBrowser.selectedBrowser)
|
||||
) {
|
||||
value = "";
|
||||
valid = true;
|
||||
|
@ -1076,10 +1077,10 @@ class UrlbarInput {
|
|||
if (
|
||||
result.type == UrlbarUtils.RESULT_TYPE.URL &&
|
||||
UrlbarPrefs.get("trimURLs") &&
|
||||
result.payload.url.startsWith(BrowserUtils.trimURLProtocol)
|
||||
result.payload.url.startsWith(BrowserUIUtils.trimURLProtocol)
|
||||
) {
|
||||
let fixupInfo = this._getURIFixupInfo(
|
||||
BrowserUtils.trimURL(result.payload.url)
|
||||
BrowserUIUtils.trimURL(result.payload.url)
|
||||
);
|
||||
if (fixupInfo?.keywordAsSent) {
|
||||
allowTrim = false;
|
||||
|
@ -2089,12 +2090,12 @@ class UrlbarInput {
|
|||
// url. First check for a trimmed value.
|
||||
|
||||
if (
|
||||
!selectedVal.startsWith(BrowserUtils.trimURLProtocol) &&
|
||||
!selectedVal.startsWith(BrowserUIUtils.trimURLProtocol) &&
|
||||
// Note _trimValue may also trim a trailing slash, thus we can't just do
|
||||
// a straight string compare to tell if the protocol was trimmed.
|
||||
!displaySpec.startsWith(this._trimValue(displaySpec))
|
||||
) {
|
||||
selectedVal = BrowserUtils.trimURLProtocol + selectedVal;
|
||||
selectedVal = BrowserUIUtils.trimURLProtocol + selectedVal;
|
||||
}
|
||||
|
||||
return selectedVal;
|
||||
|
@ -2176,7 +2177,7 @@ class UrlbarInput {
|
|||
* The trimmed string
|
||||
*/
|
||||
_trimValue(val) {
|
||||
return UrlbarPrefs.get("trimURLs") ? BrowserUtils.trimURL(val) : val;
|
||||
return UrlbarPrefs.get("trimURLs") ? BrowserUIUtils.trimURL(val) : val;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,7 +18,7 @@ const { XPCOMUtils } = ChromeUtils.import(
|
|||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
BrowserUtils: "resource://gre/modules/BrowserUtils.jsm",
|
||||
BrowserUIUtils: "resource:///modules/BrowserUIUtils.jsm",
|
||||
JsonSchemaValidator:
|
||||
"resource://gre/modules/components-utils/JsonSchemaValidator.jsm",
|
||||
Services: "resource://gre/modules/Services.jsm",
|
||||
|
@ -226,7 +226,7 @@ class UrlbarResult {
|
|||
payloadInfo.displayUrl = [...payloadInfo.url];
|
||||
let url = payloadInfo.displayUrl[0];
|
||||
if (url && UrlbarPrefs.get("trimURLs")) {
|
||||
url = BrowserUtils.removeSingleTrailingSlashFromURL(url);
|
||||
url = BrowserUIUtils.removeSingleTrailingSlashFromURL(url);
|
||||
if (url.startsWith("https://")) {
|
||||
url = url.substring(8);
|
||||
if (url.startsWith("www.")) {
|
||||
|
|
|
@ -13,7 +13,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
AddonTestUtils: "resource://testing-common/AddonTestUtils.jsm",
|
||||
AppConstants: "resource://gre/modules/AppConstants.jsm",
|
||||
BrowserTestUtils: "resource://testing-common/BrowserTestUtils.jsm",
|
||||
BrowserUtils: "resource://gre/modules/BrowserUtils.jsm",
|
||||
BrowserUIUtils: "resource:///modules/BrowserUIUtils.jsm",
|
||||
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
|
||||
FormHistoryTestUtils: "resource://testing-common/FormHistoryTestUtils.jsm",
|
||||
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
|
||||
|
@ -113,7 +113,7 @@ var UrlbarTestUtils = {
|
|||
window.gURLBar.inputField.focus();
|
||||
// Using the value setter in some cases may trim and fetch unexpected
|
||||
// results, then pick an alternate path.
|
||||
if (UrlbarPrefs.get("trimURLs") && value != BrowserUtils.trimURL(value)) {
|
||||
if (UrlbarPrefs.get("trimURLs") && value != BrowserUIUtils.trimURL(value)) {
|
||||
window.gURLBar.inputField.value = value;
|
||||
fireInputEvent = true;
|
||||
} else {
|
||||
|
|
|
@ -102,7 +102,7 @@ function testVal(originalValue, targetValue) {
|
|||
gURLBar.value = originalValue;
|
||||
gURLBar.valueIsTyped = false;
|
||||
let trimmedValue = UrlbarPrefs.get("trimURLs")
|
||||
? BrowserUtils.trimURL(originalValue)
|
||||
? BrowserUIUtils.trimURL(originalValue)
|
||||
: originalValue;
|
||||
Assert.equal(gURLBar.value, trimmedValue, "url bar value set");
|
||||
// Now focus the urlbar and check the inputField value is properly set.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
// modifies the selected url, or just closes the results pane, we do a visit
|
||||
// rather than searching for the trimmed string.
|
||||
|
||||
const url = BrowserUtils.trimURLProtocol + "invalid.somehost/mytest";
|
||||
const url = BrowserUIUtils.trimURLProtocol + "invalid.somehost/mytest";
|
||||
|
||||
add_task(async function setup() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
|
|
|
@ -16,14 +16,14 @@ add_task(async function() {
|
|||
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
|
||||
is(
|
||||
gURLBar.value,
|
||||
BrowserUtils.trimURL(goodURL),
|
||||
BrowserUIUtils.trimURL(goodURL),
|
||||
"location bar reflects loaded page"
|
||||
);
|
||||
|
||||
await typeAndSubmitAndStop(badURL);
|
||||
is(
|
||||
gURLBar.value,
|
||||
BrowserUtils.trimURL(goodURL),
|
||||
BrowserUIUtils.trimURL(goodURL),
|
||||
"location bar reflects loaded page after stop()"
|
||||
);
|
||||
gBrowser.removeCurrentTab();
|
||||
|
@ -34,7 +34,7 @@ add_task(async function() {
|
|||
await typeAndSubmitAndStop(badURL);
|
||||
is(
|
||||
gURLBar.value,
|
||||
BrowserUtils.trimURL(badURL),
|
||||
BrowserUIUtils.trimURL(badURL),
|
||||
"location bar reflects stopped page in an empty tab"
|
||||
);
|
||||
gBrowser.removeCurrentTab();
|
||||
|
|
|
@ -51,7 +51,7 @@ add_task(async function() {
|
|||
BrowserTestUtils.loadURI(partialURLTab.linkedBrowser, testURL);
|
||||
await Promise.all([loaded1, loaded2, loaded3]);
|
||||
|
||||
testURL = BrowserUtils.trimURL(testURL);
|
||||
testURL = BrowserUIUtils.trimURL(testURL);
|
||||
testPartialURL = testURL.substr(0, testURL.length - charsToDelete);
|
||||
|
||||
function cleanUp() {
|
||||
|
|
|
@ -0,0 +1,204 @@
|
|||
/* -*- 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 = ["BrowserUIUtils"];
|
||||
|
||||
var BrowserUIUtils = {
|
||||
/**
|
||||
* Check whether a page can be considered as 'empty', that its URI
|
||||
* reflects its origin, and that if it's loaded in a tab, that tab
|
||||
* could be considered 'empty' (e.g. like the result of opening
|
||||
* a 'blank' new tab).
|
||||
*
|
||||
* We have to do more than just check the URI, because especially
|
||||
* for things like about:blank, it is possible that the opener or
|
||||
* some other page has control over the contents of the page.
|
||||
*
|
||||
* @param {Browser} browser
|
||||
* The browser whose page we're checking.
|
||||
* @param {nsIURI} [uri]
|
||||
* The URI against which we're checking (the browser's currentURI
|
||||
* if omitted).
|
||||
*
|
||||
* @return {boolean} false if the page was opened by or is controlled by
|
||||
* arbitrary web content, unless that content corresponds with the URI.
|
||||
* true if the page is blank and controlled by a principal matching
|
||||
* that URI (or the system principal if the principal has no URI)
|
||||
*/
|
||||
checkEmptyPageOrigin(browser, uri = browser.currentURI) {
|
||||
// If another page opened this page with e.g. window.open, this page might
|
||||
// be controlled by its opener.
|
||||
if (browser.hasContentOpener) {
|
||||
return false;
|
||||
}
|
||||
let contentPrincipal = browser.contentPrincipal;
|
||||
// Not all principals have URIs...
|
||||
// There are two special-cases involving about:blank. One is where
|
||||
// the user has manually loaded it and it got created with a null
|
||||
// principal. The other involves the case where we load
|
||||
// some other empty page in a browser and the current page is the
|
||||
// initial about:blank page (which has that as its principal, not
|
||||
// just URI in which case it could be web-based). Especially in
|
||||
// e10s, we need to tackle that case specifically to avoid race
|
||||
// conditions when updating the URL bar.
|
||||
//
|
||||
// Note that we check the documentURI here, since the currentURI on
|
||||
// the browser might have been set by SessionStore in order to
|
||||
// support switch-to-tab without having actually loaded the content
|
||||
// yet.
|
||||
let uriToCheck = browser.documentURI || uri;
|
||||
if (
|
||||
(uriToCheck.spec == "about:blank" && contentPrincipal.isNullPrincipal) ||
|
||||
contentPrincipal.spec == "about:blank"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (contentPrincipal.isContentPrincipal) {
|
||||
return contentPrincipal.equalsURI(uri);
|
||||
}
|
||||
// ... so for those that don't have them, enforce that the page has the
|
||||
// system principal (this matches e.g. on about:newtab).
|
||||
return contentPrincipal.isSystemPrincipal;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the --toolbarbutton-button-height CSS property on the closest
|
||||
* toolbar to the provided element. Useful if you need to vertically
|
||||
* center a position:absolute element within a toolbar that uses
|
||||
* -moz-pack-align:stretch, and thus a height which is dependant on
|
||||
* the font-size.
|
||||
*
|
||||
* @param element An element within the toolbar whose height is desired.
|
||||
*/
|
||||
async setToolbarButtonHeightProperty(element) {
|
||||
let window = element.ownerGlobal;
|
||||
let dwu = window.windowUtils;
|
||||
let toolbarItem = element;
|
||||
let urlBarContainer = element.closest("#urlbar-container");
|
||||
if (urlBarContainer) {
|
||||
// The stop-reload-button, which is contained in #urlbar-container,
|
||||
// needs to use #urlbar-container to calculate the bounds.
|
||||
toolbarItem = urlBarContainer;
|
||||
}
|
||||
if (!toolbarItem) {
|
||||
return;
|
||||
}
|
||||
let bounds = dwu.getBoundsWithoutFlushing(toolbarItem);
|
||||
if (!bounds.height) {
|
||||
await window.promiseDocumentFlushed(() => {
|
||||
bounds = dwu.getBoundsWithoutFlushing(toolbarItem);
|
||||
});
|
||||
}
|
||||
if (bounds.height) {
|
||||
toolbarItem.style.setProperty(
|
||||
"--toolbarbutton-height",
|
||||
bounds.height + "px"
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate a document fragment for a localized string that has DOM
|
||||
* node replacements. This avoids using getFormattedString followed
|
||||
* by assigning to innerHTML. Fluent can probably replace this when
|
||||
* it is in use everywhere.
|
||||
*
|
||||
* @param {Document} doc
|
||||
* @param {String} msg
|
||||
* The string to put replacements in. Fetch from
|
||||
* a stringbundle using getString or GetStringFromName,
|
||||
* or even an inserted dtd string.
|
||||
* @param {Node|String} nodesOrStrings
|
||||
* The replacement items. Can be a mix of Nodes
|
||||
* and Strings. However, for correct behaviour, the
|
||||
* number of items provided needs to exactly match
|
||||
* the number of replacement strings in the l10n string.
|
||||
* @returns {DocumentFragment}
|
||||
* A document fragment. In the trivial case (no
|
||||
* replacements), this will simply be a fragment with 1
|
||||
* child, a text node containing the localized string.
|
||||
*/
|
||||
getLocalizedFragment(doc, msg, ...nodesOrStrings) {
|
||||
// Ensure replacement points are indexed:
|
||||
for (let i = 1; i <= nodesOrStrings.length; i++) {
|
||||
if (!msg.includes("%" + i + "$S")) {
|
||||
msg = msg.replace(/%S/, "%" + i + "$S");
|
||||
}
|
||||
}
|
||||
let numberOfInsertionPoints = msg.match(/%\d+\$S/g).length;
|
||||
if (numberOfInsertionPoints != nodesOrStrings.length) {
|
||||
Cu.reportError(
|
||||
`Message has ${numberOfInsertionPoints} insertion points, ` +
|
||||
`but got ${nodesOrStrings.length} replacement parameters!`
|
||||
);
|
||||
}
|
||||
|
||||
let fragment = doc.createDocumentFragment();
|
||||
let parts = [msg];
|
||||
let insertionPoint = 1;
|
||||
for (let replacement of nodesOrStrings) {
|
||||
let insertionString = "%" + insertionPoint++ + "$S";
|
||||
let partIndex = parts.findIndex(
|
||||
part => typeof part == "string" && part.includes(insertionString)
|
||||
);
|
||||
if (partIndex == -1) {
|
||||
fragment.appendChild(doc.createTextNode(msg));
|
||||
return fragment;
|
||||
}
|
||||
|
||||
if (typeof replacement == "string") {
|
||||
parts[partIndex] = parts[partIndex].replace(
|
||||
insertionString,
|
||||
replacement
|
||||
);
|
||||
} else {
|
||||
let [firstBit, lastBit] = parts[partIndex].split(insertionString);
|
||||
parts.splice(partIndex, 1, firstBit, replacement, lastBit);
|
||||
}
|
||||
}
|
||||
|
||||
// Put everything in a document fragment:
|
||||
for (let part of parts) {
|
||||
if (typeof part == "string") {
|
||||
if (part) {
|
||||
fragment.appendChild(doc.createTextNode(part));
|
||||
}
|
||||
} else {
|
||||
fragment.appendChild(part);
|
||||
}
|
||||
}
|
||||
return fragment;
|
||||
},
|
||||
|
||||
removeSingleTrailingSlashFromURL(aURL) {
|
||||
// remove single trailing slash for http/https/ftp URLs
|
||||
return aURL.replace(/^((?:http|https|ftp):\/\/[^/]+)\/$/, "$1");
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a URL which has been trimmed by removing 'http://' and any
|
||||
* trailing slash (in http/https/ftp urls).
|
||||
* Note that a trimmed url may not load the same page as the original url, so
|
||||
* before loading it, it must be passed through URIFixup, to check trimming
|
||||
* doesn't change its destination. We don't run the URIFixup check here,
|
||||
* because trimURL is in the page load path (see onLocationChange), so it
|
||||
* must be fast and simple.
|
||||
*
|
||||
* @param {string} aURL The URL to trim.
|
||||
* @returns {string} The trimmed string.
|
||||
*/
|
||||
get trimURLProtocol() {
|
||||
return "http://";
|
||||
},
|
||||
trimURL(aURL) {
|
||||
let url = this.removeSingleTrailingSlashFromURL(aURL);
|
||||
// Remove "http://" prefix.
|
||||
return url.startsWith(this.trimURLProtocol)
|
||||
? url.substring(this.trimURLProtocol.length)
|
||||
: url;
|
||||
},
|
||||
};
|
|
@ -128,6 +128,7 @@ EXTRA_JS_MODULES += [
|
|||
"AboutNewTab.jsm",
|
||||
"AppUpdater.jsm",
|
||||
"AsyncTabSwitcher.jsm",
|
||||
"BrowserUIUtils.jsm",
|
||||
"BrowserUsageTelemetry.jsm",
|
||||
"BrowserWindowTracker.jsm",
|
||||
"ContentCrashHandlers.jsm",
|
||||
|
|
|
@ -36,7 +36,7 @@ toolbar[brighttext] {
|
|||
animation-iteration-count: 1;
|
||||
list-style-image: none;
|
||||
/* Height must be equal to height of toolbarbutton padding-box. --toolbarbutton-height
|
||||
is calculated and set during runtime by BrowserUtils.setToolbarButtonHeightProperty()
|
||||
is calculated and set during runtime by BrowserUIUtils.setToolbarButtonHeightProperty()
|
||||
before the animation begins. */
|
||||
height: var(--toolbarbutton-height);
|
||||
}
|
||||
|
|
|
@ -18,63 +18,6 @@ ChromeUtils.defineModuleGetter(
|
|||
);
|
||||
|
||||
var BrowserUtils = {
|
||||
/**
|
||||
* Check whether a page can be considered as 'empty', that its URI
|
||||
* reflects its origin, and that if it's loaded in a tab, that tab
|
||||
* could be considered 'empty' (e.g. like the result of opening
|
||||
* a 'blank' new tab).
|
||||
*
|
||||
* We have to do more than just check the URI, because especially
|
||||
* for things like about:blank, it is possible that the opener or
|
||||
* some other page has control over the contents of the page.
|
||||
*
|
||||
* @param {Browser} browser
|
||||
* The browser whose page we're checking.
|
||||
* @param {nsIURI} [uri]
|
||||
* The URI against which we're checking (the browser's currentURI
|
||||
* if omitted).
|
||||
*
|
||||
* @return {boolean} false if the page was opened by or is controlled by
|
||||
* arbitrary web content, unless that content corresponds with the URI.
|
||||
* true if the page is blank and controlled by a principal matching
|
||||
* that URI (or the system principal if the principal has no URI)
|
||||
*/
|
||||
checkEmptyPageOrigin(browser, uri = browser.currentURI) {
|
||||
// If another page opened this page with e.g. window.open, this page might
|
||||
// be controlled by its opener.
|
||||
if (browser.hasContentOpener) {
|
||||
return false;
|
||||
}
|
||||
let contentPrincipal = browser.contentPrincipal;
|
||||
// Not all principals have URIs...
|
||||
// There are two special-cases involving about:blank. One is where
|
||||
// the user has manually loaded it and it got created with a null
|
||||
// principal. The other involves the case where we load
|
||||
// some other empty page in a browser and the current page is the
|
||||
// initial about:blank page (which has that as its principal, not
|
||||
// just URI in which case it could be web-based). Especially in
|
||||
// e10s, we need to tackle that case specifically to avoid race
|
||||
// conditions when updating the URL bar.
|
||||
//
|
||||
// Note that we check the documentURI here, since the currentURI on
|
||||
// the browser might have been set by SessionStore in order to
|
||||
// support switch-to-tab without having actually loaded the content
|
||||
// yet.
|
||||
let uriToCheck = browser.documentURI || uri;
|
||||
if (
|
||||
(uriToCheck.spec == "about:blank" && contentPrincipal.isNullPrincipal) ||
|
||||
contentPrincipal.spec == "about:blank"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (contentPrincipal.isContentPrincipal) {
|
||||
return contentPrincipal.equalsURI(uri);
|
||||
}
|
||||
// ... so for those that don't have them, enforce that the page has the
|
||||
// system principal (this matches e.g. on about:newtab).
|
||||
return contentPrincipal.isSystemPrincipal;
|
||||
},
|
||||
|
||||
/**
|
||||
* urlSecurityCheck: JavaScript wrapper for checkLoadURIWithPrincipal
|
||||
* and checkLoadURIStrWithPrincipal.
|
||||
|
@ -348,42 +291,6 @@ var BrowserUtils = {
|
|||
return !!toolbars && toolbars.has(which);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the --toolbarbutton-button-height CSS property on the closest
|
||||
* toolbar to the provided element. Useful if you need to vertically
|
||||
* center a position:absolute element within a toolbar that uses
|
||||
* -moz-pack-align:stretch, and thus a height which is dependant on
|
||||
* the font-size.
|
||||
*
|
||||
* @param element An element within the toolbar whose height is desired.
|
||||
*/
|
||||
async setToolbarButtonHeightProperty(element) {
|
||||
let window = element.ownerGlobal;
|
||||
let dwu = window.windowUtils;
|
||||
let toolbarItem = element;
|
||||
let urlBarContainer = element.closest("#urlbar-container");
|
||||
if (urlBarContainer) {
|
||||
// The stop-reload-button, which is contained in #urlbar-container,
|
||||
// needs to use #urlbar-container to calculate the bounds.
|
||||
toolbarItem = urlBarContainer;
|
||||
}
|
||||
if (!toolbarItem) {
|
||||
return;
|
||||
}
|
||||
let bounds = dwu.getBoundsWithoutFlushing(toolbarItem);
|
||||
if (!bounds.height) {
|
||||
await window.promiseDocumentFlushed(() => {
|
||||
bounds = dwu.getBoundsWithoutFlushing(toolbarItem);
|
||||
});
|
||||
}
|
||||
if (bounds.height) {
|
||||
toolbarItem.style.setProperty(
|
||||
"--toolbarbutton-height",
|
||||
bounds.height + "px"
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Track whether a toolbar is visible for a given a docShell.
|
||||
*
|
||||
|
@ -646,79 +553,6 @@ var BrowserUtils = {
|
|||
return [url, postData];
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate a document fragment for a localized string that has DOM
|
||||
* node replacements. This avoids using getFormattedString followed
|
||||
* by assigning to innerHTML. Fluent can probably replace this when
|
||||
* it is in use everywhere.
|
||||
*
|
||||
* @param {Document} doc
|
||||
* @param {String} msg
|
||||
* The string to put replacements in. Fetch from
|
||||
* a stringbundle using getString or GetStringFromName,
|
||||
* or even an inserted dtd string.
|
||||
* @param {Node|String} nodesOrStrings
|
||||
* The replacement items. Can be a mix of Nodes
|
||||
* and Strings. However, for correct behaviour, the
|
||||
* number of items provided needs to exactly match
|
||||
* the number of replacement strings in the l10n string.
|
||||
* @returns {DocumentFragment}
|
||||
* A document fragment. In the trivial case (no
|
||||
* replacements), this will simply be a fragment with 1
|
||||
* child, a text node containing the localized string.
|
||||
*/
|
||||
getLocalizedFragment(doc, msg, ...nodesOrStrings) {
|
||||
// Ensure replacement points are indexed:
|
||||
for (let i = 1; i <= nodesOrStrings.length; i++) {
|
||||
if (!msg.includes("%" + i + "$S")) {
|
||||
msg = msg.replace(/%S/, "%" + i + "$S");
|
||||
}
|
||||
}
|
||||
let numberOfInsertionPoints = msg.match(/%\d+\$S/g).length;
|
||||
if (numberOfInsertionPoints != nodesOrStrings.length) {
|
||||
Cu.reportError(
|
||||
`Message has ${numberOfInsertionPoints} insertion points, ` +
|
||||
`but got ${nodesOrStrings.length} replacement parameters!`
|
||||
);
|
||||
}
|
||||
|
||||
let fragment = doc.createDocumentFragment();
|
||||
let parts = [msg];
|
||||
let insertionPoint = 1;
|
||||
for (let replacement of nodesOrStrings) {
|
||||
let insertionString = "%" + insertionPoint++ + "$S";
|
||||
let partIndex = parts.findIndex(
|
||||
part => typeof part == "string" && part.includes(insertionString)
|
||||
);
|
||||
if (partIndex == -1) {
|
||||
fragment.appendChild(doc.createTextNode(msg));
|
||||
return fragment;
|
||||
}
|
||||
|
||||
if (typeof replacement == "string") {
|
||||
parts[partIndex] = parts[partIndex].replace(
|
||||
insertionString,
|
||||
replacement
|
||||
);
|
||||
} else {
|
||||
let [firstBit, lastBit] = parts[partIndex].split(insertionString);
|
||||
parts.splice(partIndex, 1, firstBit, replacement, lastBit);
|
||||
}
|
||||
}
|
||||
|
||||
// Put everything in a document fragment:
|
||||
for (let part of parts) {
|
||||
if (typeof part == "string") {
|
||||
if (part) {
|
||||
fragment.appendChild(doc.createTextNode(part));
|
||||
}
|
||||
} else {
|
||||
fragment.appendChild(part);
|
||||
}
|
||||
}
|
||||
return fragment;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a Promise which resolves when the given observer topic has been
|
||||
* observed.
|
||||
|
@ -742,34 +576,6 @@ var BrowserUtils = {
|
|||
Services.obs.addObserver(observer, topic);
|
||||
});
|
||||
},
|
||||
|
||||
removeSingleTrailingSlashFromURL(aURL) {
|
||||
// remove single trailing slash for http/https/ftp URLs
|
||||
return aURL.replace(/^((?:http|https|ftp):\/\/[^/]+)\/$/, "$1");
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a URL which has been trimmed by removing 'http://' and any
|
||||
* trailing slash (in http/https/ftp urls).
|
||||
* Note that a trimmed url may not load the same page as the original url, so
|
||||
* before loading it, it must be passed through URIFixup, to check trimming
|
||||
* doesn't change its destination. We don't run the URIFixup check here,
|
||||
* because trimURL is in the page load path (see onLocationChange), so it
|
||||
* must be fast and simple.
|
||||
*
|
||||
* @param {string} aURL The URL to trim.
|
||||
* @returns {string} The trimmed string.
|
||||
*/
|
||||
get trimURLProtocol() {
|
||||
return "http://";
|
||||
},
|
||||
trimURL(aURL) {
|
||||
let url = this.removeSingleTrailingSlashFromURL(aURL);
|
||||
// Remove "http://" prefix.
|
||||
return url.startsWith(this.trimURLProtocol)
|
||||
? url.substring(this.trimURLProtocol.length)
|
||||
: url;
|
||||
},
|
||||
};
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
|
|
Загрузка…
Ссылка в новой задаче