Merge autoland to m-c, a=merge

MozReview-Commit-ID: Gr2qiJufRRz
This commit is contained in:
Phil Ringnalda 2017-07-01 17:34:20 -07:00
Родитель a1aa8b434a 5e0291886b
Коммит 68f5ce100a
227 изменённых файлов: 5136 добавлений и 1696 удалений

Просмотреть файл

@ -299,6 +299,7 @@ pref("browser.urlbar.doubleClickSelectsAll", false);
// Control autoFill behavior
pref("browser.urlbar.autoFill", true);
pref("browser.urlbar.autoFill.typed", true);
pref("browser.urlbar.speculativeConnect.enabled", true);
// 0: Match anywhere (e.g., middle of words)
// 1: Match on word boundaries and then try matching anywhere
@ -1141,8 +1142,6 @@ pref("browser.taskbar.lists.tasks.enabled", true);
pref("browser.taskbar.lists.refreshInSeconds", 120);
#endif
// The sync engines to use.
pref("services.sync.registerEngines", "Bookmarks,Form,History,Password,Prefs,Tab,Addons,ExtensionStorage");
// Preferences to be synced by default
pref("services.sync.prefs.sync.accessibility.blockautorefresh", true);
pref("services.sync.prefs.sync.accessibility.browsewithcaret", true);

Просмотреть файл

@ -1312,8 +1312,7 @@ var gBrowserInit = {
// have been initialized.
Services.obs.notifyObservers(window, "browser-window-before-show");
gUIDensity.update();
gPrefService.addObserver(gUIDensity.prefDomain, gUIDensity);
gUIDensity.init();
let isResistFingerprintingEnabled = gPrefService.getBoolPref("privacy.resistFingerprinting");
@ -1775,7 +1774,7 @@ var gBrowserInit = {
Services.obs.removeObserver(gPluginHandler.NPAPIPluginCrashed, "plugin-crashed");
gPrefService.removeObserver(gUIDensity.prefDomain, gUIDensity);
gUIDensity.uninit();
try {
gBrowser.removeProgressListener(window.XULBrowserWindow);
@ -5456,26 +5455,50 @@ function displaySecurityInfo() {
// Updates the UI density (for touch and compact mode) based on the uidensity pref.
var gUIDensity = {
MODE_NORMAL: 0,
MODE_COMPACT: 1,
MODE_TOUCH: 2,
prefDomain: "browser.uidensity",
uiDensityPref: "browser.uidensity",
autoTouchModePref: "browser.touchmode.auto",
init() {
this.update();
gPrefService.addObserver(this.uiDensityPref, this);
gPrefService.addObserver(this.autoTouchModePref, this);
},
uninit() {
gPrefService.removeObserver(this.uiDensityPref, this);
gPrefService.removeObserver(this.autoTouchModePref, this);
},
observe(aSubject, aTopic, aPrefName) {
if (aTopic != "nsPref:changed" || aPrefName != this.prefDomain)
if (aTopic != "nsPref:changed" ||
(aPrefName != this.uiDensityPref &&
aPrefName != this.autoTouchModePref)) {
return;
}
this.update();
},
update() {
let mode;
getCurrentDensity() {
// Automatically override the uidensity to touch in Windows tablet mode.
if (AppConstants.isPlatformAndVersionAtLeast("win", "10") &&
WindowsUIUtils.inTabletMode &&
gPrefService.getBoolPref("browser.touchmode.auto")) {
mode = this.MODE_TOUCH;
} else {
mode = gPrefService.getIntPref(this.prefDomain);
gPrefService.getBoolPref(this.autoTouchModePref)) {
return { mode: this.MODE_TOUCH, overridden: true };
}
return { mode: gPrefService.getIntPref(this.uiDensityPref), overridden: false };
},
setCurrentMode(mode) {
gPrefService.setIntPref(this.uiDensityPref, mode);
},
update(mode) {
if (mode == null) {
mode = this.getCurrentDensity().mode;
}
let doc = document.documentElement;
@ -8176,10 +8199,11 @@ var RestoreLastSessionObserver = {
if (SessionStore.canRestoreLastSession &&
!PrivateBrowsingUtils.isWindowPrivate(window)) {
if (Services.prefs.getBoolPref("browser.tabs.restorebutton")) {
let {restoreTabsButton} = gBrowser.tabContainer;
let {restoreTabsButton, restoreTabsButtonWrapperWidth} = gBrowser.tabContainer;
let restoreTabsButtonWrapper = restoreTabsButton.parentNode;
restoreTabsButtonWrapper.setAttribute("session-exists", "true");
gBrowser.tabContainer.updateSessionRestoreVisibility();
restoreTabsButton.style.maxWidth = `${restoreTabsButtonWrapperWidth}px`;
gBrowser.tabContainer.addEventListener("TabOpen", this);
}
Services.obs.addObserver(this, "sessionstore-last-session-cleared", true);
@ -8196,17 +8220,16 @@ var RestoreLastSessionObserver = {
},
removeRestoreButton() {
let {restoreTabsButton, restoreTabsButtonWrapperWidth} = gBrowser.tabContainer;
let {restoreTabsButton} = gBrowser.tabContainer;
let restoreTabsButtonWrapper = restoreTabsButton.parentNode;
restoreTabsButtonWrapper.removeAttribute("session-exists");
gBrowser.tabContainer.addEventListener("transitionend", function maxWidthTransitionHandler(e) {
if (e.propertyName == "max-width") {
if (e.target == gBrowser.tabContainer && e.propertyName == "max-width") {
gBrowser.tabContainer.updateSessionRestoreVisibility();
gBrowser.tabContainer.removeEventListener("transitionend", maxWidthTransitionHandler);
}
});
restoreTabsButton.style.maxWidth = `${restoreTabsButtonWrapperWidth}px`;
requestAnimationFrame(() => restoreTabsButton.style.maxWidth = 0);
restoreTabsButtonWrapper.removeAttribute("session-exists");
restoreTabsButton.style.maxWidth = 0;
gBrowser.tabContainer.removeEventListener("TabOpen", this);
},

Просмотреть файл

@ -116,7 +116,7 @@ nsContextMenu.prototype = {
pageUrl: this.browser ? this.browser.currentURI.spec : undefined,
linkText: this.linkTextStr,
linkUrl: this.linkURL,
selectionText: this.isTextSelected ? this.selectionInfo.text : undefined,
selectionText: this.isTextSelected ? this.selectionInfo.fullText : undefined,
frameId: this.frameOuterWindowID,
};
subject.wrappedJSObject = subject;

Просмотреть файл

@ -2160,7 +2160,7 @@
"characterSet", "fullZoom", "textZoom", "webProgress",
"addProgressListener", "removeProgressListener", "audioPlaybackStarted",
"audioPlaybackStopped", "pauseMedia", "stopMedia",
"blockMedia", "resumeMedia", "mute", "unmute", "blockedPopups", "lastURI",
"resumeMedia", "mute", "unmute", "blockedPopups", "lastURI",
"purgeSessionHistory", "stopScroll", "startScroll",
"userTypedValue", "userTypedClear", "mediaBlocked"
]</field>
@ -2226,7 +2226,6 @@
};
};
break;
case "blockMedia":
case "resumeMedia":
getter = () => {
return () => {

Просмотреть файл

@ -110,6 +110,7 @@ support-files =
support-files =
file_urlbar_edit_dos.html
[browser_urlbar_searchsettings.js]
[browser_urlbar_search_speculative_connect.js]
[browser_urlbar_stop_pending.js]
support-files =
slow-page.sjs

Просмотреть файл

@ -0,0 +1,82 @@
"use strict";
// This test ensures that we setup a speculative network
// connection for autoFilled values.
let {HttpServer} = Cu.import("resource://testing-common/httpd.js", {});
let gHttpServer = null;
let gScheme = "http";
let gHost = "localhost"; // 'localhost' by default.
let gPort = -1;
add_task(async function setup() {
if (!gHttpServer) {
gHttpServer = new HttpServer();
try {
gHttpServer.start(gPort);
gPort = gHttpServer.identity.primaryPort;
gHttpServer.identity.setPrimary(gScheme, gHost, gPort);
} catch (ex) {
info("We can't launch our http server successfully.")
}
}
is(gHttpServer.identity.has(gScheme, gHost, gPort), true, "make sure we have this domain listed");
await SpecialPowers.pushPrefEnv({
set: [["browser.urlbar.autoFill", true],
["browser.urlbar.speculativeConnection.enabled", true],
// In mochitest this number is 0 by default but we have to turn it on.
["network.http.speculative-parallel-limit", 6],
// The http server is using IPv4, so it's better to disable IPv6 to avoid weird
// networking problem.
["network.dns.disableIPv6", true]],
});
await PlacesTestUtils.addVisits([{
uri: `${gScheme}://${gHost}:${gPort}`,
title: "test visit for speculative connection",
transition: Ci.nsINavHistoryService.TRANSITION_TYPED,
}]);
// Bug 764062 - we can't get port number from autocomplete result, so we have to mock
// this function to add it manually.
let oldSpeculativeConnect = gURLBar.popup.maybeSetupSpeculativeConnect.bind(gURLBar.popup);
gURLBar.popup.maybeSetupSpeculativeConnect = (uriString) => {
info(`Original uri is ${uriString}`);
let newUriString = uriString.substr(0, uriString.length - 1) +
":" + gPort + "/";
info(`New uri is ${newUriString}`);
oldSpeculativeConnect(newUriString);
};
registerCleanupFunction(async function() {
await PlacesTestUtils.clearHistory();
gURLBar.popup.maybeSetupSpeculativeConnect = oldSpeculativeConnect;
gHttpServer.identity.remove(gScheme, gHost, gPort);
gHttpServer.stop(() => {
gHttpServer = null;
});
});
});
add_task(async function autofill_tests() {
const test = {
search: gHost.substr(0, 2),
autofilledValue: `${gHost}/`
};
info(`Searching for '${test.search}'`);
await promiseAutocompleteResultPopup(test.search, window, true);
is(gURLBar.inputField.value, test.autofilledValue,
`Autofilled value is as expected for search '${test.search}'`);
await BrowserTestUtils.waitForCondition(() => {
if (gHttpServer) {
is(gHttpServer.connectionNumber, 1,
`${gHttpServer.connectionNumber} speculative connection has been setup.`)
return gHttpServer.connectionNumber == 1;
}
return false;
}, "Waiting for connection setup");
});

Просмотреть файл

@ -2114,6 +2114,24 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
</body>
</method>
<method name="maybeSetupSpeculativeConnect">
<parameter name="aUriString"/>
<body><![CDATA[
// We shouldn't leak autocomplete result in the private context.
if (!Services.prefs.getBoolPref("browser.urlbar.speculativeConnect.enabled") ||
this.input.inPrivateContext) {
return;
}
try {
let uri = makeURI(aUriString);
Services.io.speculativeConnect2(uri, gBrowser.contentPrincipal, null);
} catch (ex) {
// Can't setup speculative connection for this uri string for some
// reason, just ignore it.
}
]]></body>
</method>
<method name="onResultsAdded">
<body>
<![CDATA[
@ -2126,6 +2144,20 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
this.input.controller.setInitiallySelectedIndex(0);
this.richlistbox.suppressMenuItemEvent = false;
}
// If this is the first time we get the result from the current
// search, and the result is an "autofill" result, that means it's
// the site that user frequently visits. Then we could speculatively
// connect to this site as a performance optimization.
if (!this.input.gotResultForCurrentQuery &&
this.input.mController.matchCount > 0 &&
this.input.mController.getStyleAt(0).includes("autofill")) {
let uri = this.input.mController.getFinalCompleteValueAt(0);
// "http" will be stripped out, but other scheme won't.
if (!uri.includes("://")) {
uri = "http://" + uri;
}
this.maybeSetupSpeculativeConnect(uri);
}
// When a result is present the footer should always be visible.
this.footer.collapsed = false;

Просмотреть файл

@ -45,6 +45,8 @@ const kPrefCustomizationState = "browser.uiCustomization.state";
const kPrefCustomizationAutoAdd = "browser.uiCustomization.autoAdd";
const kPrefCustomizationDebug = "browser.uiCustomization.debug";
const kPrefDrawInTitlebar = "browser.tabs.drawInTitlebar";
const kPrefUIDensity = "browser.uidensity";
const kPrefAutoTouchMode = "browser.touchmode.auto";
const kExpectedWindowURL = "chrome://browser/content/browser.xul";
@ -159,6 +161,8 @@ var gUIStateBeforeReset = {
uiCustomizationState: null,
drawInTitlebar: null,
currentTheme: null,
uiDensity: null,
autoTouchMode: null,
};
var gDefaultPanelPlacements = null;
@ -2551,6 +2555,8 @@ var CustomizableUIInternal = {
try {
gUIStateBeforeReset.drawInTitlebar = Services.prefs.getBoolPref(kPrefDrawInTitlebar);
gUIStateBeforeReset.uiCustomizationState = Services.prefs.getCharPref(kPrefCustomizationState);
gUIStateBeforeReset.uiDensity = Services.prefs.getIntPref(kPrefUIDensity);
gUIStateBeforeReset.autoTouchMode = Services.prefs.getBoolPref(kPrefAutoTouchMode);
gUIStateBeforeReset.currentTheme = LightweightThemeManager.currentTheme;
} catch (e) { }
@ -2558,6 +2564,8 @@ var CustomizableUIInternal = {
Services.prefs.clearUserPref(kPrefCustomizationState);
Services.prefs.clearUserPref(kPrefDrawInTitlebar);
Services.prefs.clearUserPref(kPrefUIDensity);
Services.prefs.clearUserPref(kPrefAutoTouchMode);
LightweightThemeManager.currentTheme = null;
log.debug("State reset");
@ -2628,6 +2636,8 @@ var CustomizableUIInternal = {
let uiCustomizationState = gUIStateBeforeReset.uiCustomizationState;
let drawInTitlebar = gUIStateBeforeReset.drawInTitlebar;
let currentTheme = gUIStateBeforeReset.currentTheme;
let uiDensity = gUIStateBeforeReset.uiDensity;
let autoTouchMode = gUIStateBeforeReset.autoTouchMode;
// Need to clear the previous state before setting the prefs
// because pref observers may check if there is a previous UI state.
@ -2635,6 +2645,8 @@ var CustomizableUIInternal = {
Services.prefs.setCharPref(kPrefCustomizationState, uiCustomizationState);
Services.prefs.setBoolPref(kPrefDrawInTitlebar, drawInTitlebar);
Services.prefs.setIntPref(kPrefUIDensity, uiDensity);
Services.prefs.setBoolPref(kPrefAutoTouchMode, autoTouchMode);
LightweightThemeManager.currentTheme = currentTheme;
this.loadSavedState();
// If the user just customizes toolbar/titlebar visibility, gSavedState will be null
@ -2809,6 +2821,16 @@ var CustomizableUIInternal = {
}
}
if (Services.prefs.prefHasUserValue(kPrefUIDensity)) {
log.debug(kPrefUIDensity + " pref is non-default");
return false;
}
if (Services.prefs.prefHasUserValue(kPrefAutoTouchMode)) {
log.debug(kPrefAutoTouchMode + " pref is non-default");
return false;
}
if (Services.prefs.prefHasUserValue(kPrefDrawInTitlebar)) {
log.debug(kPrefDrawInTitlebar + " pref is non-default");
return false;
@ -3540,7 +3562,9 @@ this.CustomizableUI = {
get canUndoReset() {
return gUIStateBeforeReset.uiCustomizationState != null ||
gUIStateBeforeReset.drawInTitlebar != null ||
gUIStateBeforeReset.currentTheme != null;
gUIStateBeforeReset.currentTheme != null ||
gUIStateBeforeReset.autoTouchMode != null ||
gUIStateBeforeReset.uiDensity != null;
},
/**

Просмотреть файл

@ -1385,6 +1385,98 @@ CustomizeMode.prototype = {
this.window.openUILinkIn(getMoreURL, "tab");
},
updateUIDensity(mode) {
this.window.gUIDensity.update(mode);
},
setUIDensity(mode) {
let win = this.window;
let gUIDensity = win.gUIDensity;
let currentDensity = gUIDensity.getCurrentDensity();
let panel = win.document.getElementById("customization-uidensity-menu");
Services.prefs.setIntPref(gUIDensity.uiDensityPref, mode);
// If the user is choosing a different UI density mode while
// the mode is overriden to Touch, remove the override.
if (currentDensity.overridden) {
Services.prefs.setBoolPref(gUIDensity.autoTouchModePref, false);
}
this._onUIChange();
panel.hidePopup();
},
resetUIDensity() {
this.window.gUIDensity.update();
},
onUIDensityMenuShowing() {
let win = this.window;
let doc = win.document;
let gUIDensity = win.gUIDensity;
let currentDensity = gUIDensity.getCurrentDensity();
let normalButton = doc.getElementById("customization-uidensity-menu-button-normal");
normalButton.mode = gUIDensity.MODE_NORMAL;
let compactButton = doc.getElementById("customization-uidensity-menu-button-compact");
compactButton.mode = gUIDensity.MODE_COMPACT;
let buttons = [normalButton, compactButton];
let touchButton = doc.getElementById("customization-uidensity-menu-button-touch");
// Touch mode can not be enabled in OSX right now.
if (touchButton) {
touchButton.mode = gUIDensity.MODE_TOUCH;
buttons.push(touchButton);
}
// Mark the active mode button.
for (let button of buttons) {
if (button.mode == currentDensity.mode) {
button.setAttribute("aria-checked", "true");
button.setAttribute("active", "true");
} else {
button.removeAttribute("aria-checked");
button.removeAttribute("active");
}
}
// Add menu items for automatically switching to Touch mode in Windows Tablet Mode,
// which is only available in Windows 10.
if (AppConstants.isPlatformAndVersionAtLeast("win", "10")) {
let spacer = doc.getElementById("customization-uidensity-touch-spacer");
let checkbox = doc.getElementById("customization-uidensity-autotouchmode-checkbox");
spacer.removeAttribute("hidden");
checkbox.removeAttribute("hidden");
// Show a hint that the UI density was overridden automatically.
if (currentDensity.overridden) {
let sb = Services.strings.createBundle("chrome://browser/locale/uiDensity.properties");
touchButton.setAttribute("acceltext",
sb.GetStringFromName("uiDensity.menu-button-touch.acceltext"));
} else {
touchButton.removeAttribute("acceltext");
}
let autoTouchMode = Services.prefs.getBoolPref(win.gUIDensity.autoTouchModePref);
if (autoTouchMode) {
checkbox.setAttribute("checked", "true");
} else {
checkbox.removeAttribute("checked");
}
}
},
updateAutoTouchMode(checked) {
Services.prefs.setBoolPref("browser.touchmode.auto", checked);
// Re-render the menu items since the active mode might have
// change because of this.
this.onUIDensityMenuShowing();
this._onUIChange();
},
onLWThemesMenuShowing(aEvent) {
const DEFAULT_THEME_ID = "{972ce4c6-7e08-4474-a285-3208198ce6fd}";
const RECENT_LWT_COUNT = 5;

Просмотреть файл

@ -51,6 +51,63 @@
</hbox>
</panel>
</button>
#ifdef MOZ_PHOTON_THEME
<button id="customization-uidensity-button"
label="&customizeMode.uidensity;"
class="customizationmode-button"
type="menu">
<panel type="arrow" id="customization-uidensity-menu"
onpopupshowing="gCustomizeMode.onUIDensityMenuShowing();"
position="topcenter bottomleft"
flip="none"
role="menu">
<menuitem id="customization-uidensity-menu-button-normal"
class="menuitem-iconic customization-uidensity-menu-button"
role="menuitemradio"
label="&customizeMode.uidensity.menuNormal.label;"
accesskey="&customizeMode.uidensity.menuNormal.accessKey;"
tooltiptext="&customizeMode.uidensity.menuNormal.tooltip;"
tabindex="0"
onfocus="gCustomizeMode.updateUIDensity(this.mode);"
onmouseover="gCustomizeMode.updateUIDensity(this.mode);"
onblur="gCustomizeMode.resetUIDensity();"
onmouseout="gCustomizeMode.resetUIDensity();"
oncommand="gCustomizeMode.setUIDensity(this.mode);" />
<menuitem id="customization-uidensity-menu-button-compact"
class="menuitem-iconic customization-uidensity-menu-button"
role="menuitemradio"
label="&customizeMode.uidensity.menuCompact.label;"
accesskey="&customizeMode.uidensity.menuCompact.accessKey;"
tooltiptext="&customizeMode.uidensity.menuCompact.tooltip;"
tabindex="0"
onfocus="gCustomizeMode.updateUIDensity(this.mode);"
onmouseover="gCustomizeMode.updateUIDensity(this.mode);"
onblur="gCustomizeMode.resetUIDensity();"
onmouseout="gCustomizeMode.resetUIDensity();"
oncommand="gCustomizeMode.setUIDensity(this.mode);" />
#ifndef XP_MACOSX
<menuitem id="customization-uidensity-menu-button-touch"
class="menuitem-iconic customization-uidensity-menu-button"
role="menuitemradio"
label="&customizeMode.uidensity.menuTouch.label;"
accesskey="&customizeMode.uidensity.menuTouch.accessKey;"
tooltiptext="&customizeMode.uidensity.menuTouch.tooltip;"
tabindex="0"
onfocus="gCustomizeMode.updateUIDensity(this.mode);"
onmouseover="gCustomizeMode.updateUIDensity(this.mode);"
onblur="gCustomizeMode.resetUIDensity();"
onmouseout="gCustomizeMode.resetUIDensity();"
oncommand="gCustomizeMode.setUIDensity(this.mode);">
</menuitem>
<spacer hidden="true" id="customization-uidensity-touch-spacer"/>
<checkbox id="customization-uidensity-autotouchmode-checkbox"
hidden="true"
label="&customizeMode.uidensity.autoTouchMode.checkbox.label;"
oncommand="gCustomizeMode.updateAutoTouchMode(this.checked)"/>
#endif
</panel>
</button>
#endif
<spacer id="customization-footer-spacer"/>
<button id="customization-undo-reset-button"

Просмотреть файл

@ -666,11 +666,6 @@
key="key_savePage"
command="Browser:SavePage"
/>
<toolbarbutton id="appMenu-page-setup-button"
class="subviewbutton"
label="&printSetupCmd.label;"
command="cmd_pageSetup"
/>
<toolbarbutton id="appMenu-print-button"
class="subviewbutton subviewbutton-iconic"
label="&printButton.label;"

Просмотреть файл

@ -147,6 +147,7 @@ skip-if = os == "mac"
[browser_1161838_inserted_new_default_buttons.js]
[browser_bootstrapped_custom_toolbar.js]
[browser_customizemode_contextmenu_menubuttonstate.js]
[browser_customizemode_uidensity.js]
[browser_exit_background_customize_mode.js]
[browser_overflow_use_subviews.js]
[browser_panel_keyboard_navigation.js]

Просмотреть файл

@ -0,0 +1,181 @@
/* 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";
const PREF_UI_DENSITY = "browser.uidensity";
const PREF_AUTO_TOUCH_MODE = "browser.touchmode.auto";
async function testModeButton(mode, modePref) {
await startCustomizing();
let win = document.getElementById("main-window");
let popupButton = document.getElementById("customization-uidensity-button");
let popup = document.getElementById("customization-uidensity-menu");
// Show the popup.
let popupShownPromise = popupShown(popup);
EventUtils.synthesizeMouseAtCenter(popupButton, {});
await popupShownPromise;
let button = document.getElementById("customization-uidensity-menu-button-" + mode);
let normalButton = document.getElementById("customization-uidensity-menu-button-normal");
is(normalButton.getAttribute("active"), "true",
"Normal mode button should be active by default.");
// Hover over the mode button and wait until the UI density is updated.
EventUtils.synthesizeMouseAtCenter(button, { type: "mouseover" });
await BrowserTestUtils.waitForAttribute("uidensity", win, mode);
is(win.getAttribute("uidensity"), mode,
`UI Density should be set to ${mode} on ${mode} button hover.`);
is(Services.prefs.getIntPref(PREF_UI_DENSITY), window.gUIDensity.MODE_NORMAL,
`UI Density pref should still be set to normal on ${mode} button hover.`);
// Hover the normal button again and check that the UI density reset to normal.
EventUtils.synthesizeMouseAtCenter(normalButton, { type: "mouseover" });
await BrowserTestUtils.waitForCondition(() => !win.hasAttribute("uidensity"));
ok(!win.hasAttribute("uidensity"),
`UI Density should be reset when no longer hovering the ${mode} button.`);
// Select the custom UI density and wait for the popup to be hidden.
let popupHiddenPromise = popupHidden(popup);
EventUtils.synthesizeMouseAtCenter(button, {});
await popupHiddenPromise;
// Check that the click permanently changed the UI density.
is(win.getAttribute("uidensity"), mode,
`UI Density should be set to ${mode} on ${mode} button click.`);
is(Services.prefs.getIntPref(PREF_UI_DENSITY), modePref,
`UI Density pref should be set to ${mode} when clicking the ${mode} button.`);
// Open the popup again.
popupShownPromise = popupShown(popup);
EventUtils.synthesizeMouseAtCenter(popupButton, {});
await popupShownPromise;
// Check that the button is still active after opening and closing the popup.
is(button.getAttribute("active"), "true", `${mode} mode button should be active.`);
// Hide the popup again.
popupHiddenPromise = popupHidden(popup);
EventUtils.synthesizeMouseAtCenter(popupButton, {});
await popupHiddenPromise;
// Check that the button is still active after re-opening customize mode.
await endCustomizing();
await startCustomizing();
popupShownPromise = popupShown(popup);
EventUtils.synthesizeMouseAtCenter(popupButton, {});
await popupShownPromise;
is(button.getAttribute("active"), "true",
`${mode} mode button should be active after entering and exiting customize mode.`);
// Click the normal button and check that the density is reset.
popupHiddenPromise = popupHidden(popup);
EventUtils.synthesizeMouseAtCenter(normalButton, {});
await popupHiddenPromise;
ok(!win.hasAttribute("uidensity"),
"UI Density should be reset when clicking the normal button.");
is(Services.prefs.getIntPref(PREF_UI_DENSITY), window.gUIDensity.MODE_NORMAL,
"UI Density pref should be set to normal.");
// Show the popup and click on the mode button again to test the
// reset default feature.
popupShownPromise = popupShown(popup);
EventUtils.synthesizeMouseAtCenter(popupButton, {});
await popupShownPromise;
popupHiddenPromise = popupHidden(popup);
EventUtils.synthesizeMouseAtCenter(button, {});
await popupHiddenPromise;
is(win.getAttribute("uidensity"), mode,
`UI Density should be set to ${mode} on ${mode} button click.`);
is(Services.prefs.getIntPref(PREF_UI_DENSITY), modePref,
`UI Density pref should be set to ${mode} when clicking the ${mode} button.`);
await gCustomizeMode.reset();
ok(!win.hasAttribute("uidensity"),
"UI Density should be reset when clicking the normal button.");
is(Services.prefs.getIntPref(PREF_UI_DENSITY), window.gUIDensity.MODE_NORMAL,
"UI Density pref should be set to normal.");
await endCustomizing();
}
add_task(async function test_compact_mode_button() {
if (!AppConstants.MOZ_PHOTON_THEME) {
ok(true, "Skipping test because Photon is not enabled.");
return;
}
await testModeButton("compact", window.gUIDensity.MODE_COMPACT);
});
add_task(async function test_touch_mode_button() {
if (!AppConstants.MOZ_PHOTON_THEME) {
ok(true, "Skipping test because Photon is not enabled.");
return;
}
// OSX doesn't get touch mode for now.
if (AppConstants.platform == "macosx") {
is(document.getElementById("customization-uidensity-menu-button-touch"), null,
"There's no touch option on Mac OSX");
return;
}
await testModeButton("touch", window.gUIDensity.MODE_TOUCH);
// Test the checkbox for automatic Touch Mode transition
// in Windows 10 Tablet Mode.
if (AppConstants.isPlatformAndVersionAtLeast("win", "10")) {
await startCustomizing();
let popupButton = document.getElementById("customization-uidensity-button");
let popup = document.getElementById("customization-uidensity-menu");
let popupShownPromise = popupShown(popup);
EventUtils.synthesizeMouseAtCenter(popupButton, {});
await popupShownPromise;
let checkbox = document.getElementById("customization-uidensity-autotouchmode-checkbox");
ok(checkbox.checked, "Checkbox should be checked by default");
// Test toggling the checkbox.
EventUtils.synthesizeMouseAtCenter(checkbox, {});
is(Services.prefs.getBoolPref(PREF_AUTO_TOUCH_MODE), false,
"Automatic Touch Mode is off when the checkbox is unchecked.");
EventUtils.synthesizeMouseAtCenter(checkbox, {});
is(Services.prefs.getBoolPref(PREF_AUTO_TOUCH_MODE), true,
"Automatic Touch Mode is on when the checkbox is checked.");
// Test reset to defaults.
EventUtils.synthesizeMouseAtCenter(checkbox, {});
is(Services.prefs.getBoolPref(PREF_AUTO_TOUCH_MODE), false,
"Automatic Touch Mode is off when the checkbox is unchecked.");
await gCustomizeMode.reset();
is(Services.prefs.getBoolPref(PREF_AUTO_TOUCH_MODE), true,
"Automatic Touch Mode is on when the checkbox is checked.");
}
});
add_task(async function cleanup() {
await endCustomizing();
Services.prefs.clearUserPref(PREF_UI_DENSITY);
Services.prefs.clearUserPref(PREF_AUTO_TOUCH_MODE);
});

Просмотреть файл

@ -193,7 +193,7 @@ var gMenuBuilder = {
let label = item.title;
if (label) {
if (contextData.isTextSelected && label.indexOf("%s") > -1) {
let selection = contextData.selectionText;
let selection = contextData.selectionText.trim();
// The rendering engine will truncate the title if it's longer than 64 characters.
// But if it makes sense let's try truncate selection text only, to handle cases like
// 'look up "%s" in MyDictionary' more elegantly.

Просмотреть файл

@ -59,6 +59,13 @@ add_task(async function() {
},
background: async function() {
browser.test.onMessage.addListener(msg => {
if (msg == "removeall") {
browser.contextMenus.removeAll();
browser.test.sendMessage("removed");
}
});
// A generic onclick callback function.
function genericOnClick(info, tab) {
browser.test.sendMessage("onclick", {info, tab});
@ -86,10 +93,7 @@ add_task(async function() {
if (context == "selection") {
browser.contextMenus.update("ext-selection", {
title: "selection is: '%s'",
onclick: (info, tab) => {
browser.contextMenus.removeAll();
genericOnClick(info, tab);
},
onclick: genericOnClick,
});
}
}
@ -290,7 +294,7 @@ add_task(async function() {
expectedClickInfo = {
menuItemId: "ext-selection",
pageUrl: PAGE,
selectionText: "just some text 1234567890123456789012345678901234567890123456789012345678901234567890123456789012",
selectionText: " just some text 1234567890123456789012345678901234567890123456789012345678901234567890123456789012",
};
result = await extension.awaitMessage("onclick");
@ -298,6 +302,72 @@ add_task(async function() {
result = await extension.awaitMessage("browser.contextMenus.onClicked");
checkClickInfo(result);
// Select a lot of text
await ContentTask.spawn(gBrowser.selectedBrowser, { }, function* (arg) {
let doc = content.document;
let range = doc.createRange();
let selection = content.getSelection();
selection.removeAllRanges();
let textNode = doc.getElementById("longtext").firstChild;
range.setStart(textNode, 0);
range.setEnd(textNode, textNode.length);
selection.addRange(range);
});
// Bring up context menu again
extensionMenuRoot = await openExtensionContextMenu("#longtext");
// Check some menu items
items = extensionMenuRoot.getElementsByAttribute("label", "selection is: 'Sed ut perspiciatis unde omnis iste natus err...'");
is(items.length, 1, `contextMenu item for longtext selection was found (context=selection)`);
await closeExtensionContextMenu(items[0]);
expectedClickInfo = {
menuItemId: "ext-selection",
pageUrl: PAGE,
};
result = await extension.awaitMessage("onclick");
checkClickInfo(result);
result = await extension.awaitMessage("browser.contextMenus.onClicked");
checkClickInfo(result);
ok(result.info.selectionText.endsWith("quo voluptas nulla pariatur?"), "long text selection worked");
// Select a lot of text, excercise the nsIDOMNSEditableElement code path in
// the Browser:GetSelection handler.
await ContentTask.spawn(gBrowser.selectedBrowser, { }, function(arg) {
let doc = content.document;
let node = doc.getElementById("editabletext");
// content.js handleContentContextMenu fails intermittently without focus.
node.focus();
node.selectionStart = 0;
node.selectionEnd = 844;
});
// Bring up context menu again
extensionMenuRoot = await openExtensionContextMenu("#editabletext");
// Check some menu items
items = extensionMenuRoot.getElementsByAttribute("label", "editable");
is(items.length, 1, "contextMenu item for text input element was found (context=editable)");
await closeExtensionContextMenu(items[0]);
expectedClickInfo = {
menuItemId: "ext-editable",
editable: true,
pageUrl: PAGE,
};
result = await extension.awaitMessage("onclick");
checkClickInfo(result);
result = await extension.awaitMessage("browser.contextMenus.onClicked");
checkClickInfo(result);
ok(result.info.selectionText.endsWith("perferendis doloribus asperiores repellat."), "long text selection worked");
extension.sendMessage("removeall");
await extension.awaitMessage("removed");
let contentAreaContextMenu = await openContextMenu("#img1");
items = contentAreaContextMenu.getElementsByAttribute("ext-type", "top-level-menu");
is(items.length, 0, "top level item was not found (after removeAll()");

Просмотреть файл

@ -155,10 +155,13 @@ add_task(async function test_url() {
// Create a new tab for testing update.
browser.tabs.create({}, function(tab) {
browser.tabs.onUpdated.addListener(function onUpdated(tabId, changeInfo) {
// Check callback
browser.test.assertEq(tabId, tab.id, "Check tab id");
browser.test.log("onUpdate: " + JSON.stringify(changeInfo));
if ("url" in changeInfo) {
// When activity stream is enabled, about:newtab runs in the content process
// which causes some timing issues for onUpdated. So if we encounter
// about:newtab, return early and continue waiting for about:blank.
if (changeInfo.url === "about:newtab") {
return;
}
browser.test.assertEq("about:blank", changeInfo.url,
"Check changeInfo.url");
browser.tabs.onUpdated.removeListener(onUpdated);
@ -166,6 +169,9 @@ add_task(async function test_url() {
browser.tabs.remove(tabId);
browser.test.notifyPass("finish");
}
// Check callback
browser.test.assertEq(tabId, tab.id, "Check tab id");
browser.test.log("onUpdate: " + JSON.stringify(changeInfo));
});
browser.tabs.update(tab.id, {url: "about:blank"});
});

Просмотреть файл

@ -1,3 +1,4 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
@ -20,6 +21,20 @@
<input type="text" id="edit-me"><br>
<input type="password" id="password">
</p>
<iframe id="frame" src="context_frame.html"/>
<iframe id="frame" src="context_frame.html"></iframe>
<p id="longtext">Sed ut perspiciatis unde omnis iste natus error sit
voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque
ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta
sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut
odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem
sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit
amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora
incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad
minima veniam, quis nostrum exercitationem ullam corporis suscipit
laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum
iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae
consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</p>
<input id="editabletext" type="text" value="At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat." />
</body>
</html>

Просмотреть файл

@ -666,7 +666,10 @@ add_task(async function checkUndoVisitsState() {
add_task(async function checkHistoryRemovalCompletion() {
AutoMigrate._errorMap = {bookmarks: 0, visits: 0, logins: 0};
await AutoMigrate._removeSomeVisits([{url: "http://www.example.com/", limit: -1}]);
await AutoMigrate._removeSomeVisits([{url: "http://www.example.com/",
first: 0,
last: PlacesUtils.toPRTime(new Date()),
limit: -1}]);
ok(true, "Removing visits should complete even if removing some visits failed.");
Assert.equal(AutoMigrate._errorMap.visits, 1, "Should have logged the error for visits.");

Просмотреть файл

@ -3598,9 +3598,7 @@ var SessionStoreInternal = {
tab.toggleMuteAudio(tabData.muteReason);
}
if (tabData.mediaBlocked) {
browser.blockMedia();
} else {
if (!tabData.mediaBlocked) {
browser.resumeMedia();
}

Просмотреть файл

@ -481,6 +481,13 @@ if (typeof Mozilla == "undefined") {
* @property {String} distribution - Contains the distributionId property. This value will be
* "default" in most cases but can differ for repack or
* funnelcake builds. Since Fx48
* @property {Number} profileCreatedWeeksAgo - The number of weeks since the profile was created,
* starting from 0 for profiles dating less than
* seven days old. Since Fx56.
* @property {Number} profileResetWeeksAgo - The number of weeks since the profile was last reset,
* starting from 0 for profiles reset less than seven
* days ago. If the profile has never been reset it
* returns null. Since Fx56.
* @property {String} version - Version string e.g. "48.0a2"
* @since 35
*/

Просмотреть файл

@ -29,6 +29,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "BrowserUITelemetry",
"resource:///modules/BrowserUITelemetry.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ProfileAge",
"resource://gre/modules/ProfileAge.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ReaderParent",
"resource:///modules/ReaderParent.jsm");
@ -1483,43 +1485,7 @@ this.UITour = {
getConfiguration(aMessageManager, aWindow, aConfiguration, aCallbackID) {
switch (aConfiguration) {
case "appinfo":
let props = ["defaultUpdateChannel", "version"];
let appinfo = {};
props.forEach(property => appinfo[property] = Services.appinfo[property]);
// Identifier of the partner repack, as stored in preference "distribution.id"
// and included in Firefox and other update pings. Note this is not the same as
// Services.appinfo.distributionID (value of MOZ_DISTRIBUTION_ID is set at build time).
let distribution =
Services.prefs.getDefaultBranch("distribution.").getCharPref("id", "default");
appinfo["distribution"] = distribution;
let isDefaultBrowser = null;
try {
let shell = aWindow.getShellService();
if (shell) {
isDefaultBrowser = shell.isDefaultBrowser(false);
}
} catch (e) {}
appinfo["defaultBrowser"] = isDefaultBrowser;
let canSetDefaultBrowserInBackground = true;
if (AppConstants.isPlatformAndVersionAtLeast("win", "6.2") ||
AppConstants.isPlatformAndVersionAtLeast("macosx", "10.10")) {
canSetDefaultBrowserInBackground = false;
} else if (AppConstants.platform == "linux") {
// The ShellService may not exist on some versions of Linux.
try {
aWindow.getShellService();
} catch (e) {
canSetDefaultBrowserInBackground = null;
}
}
appinfo["canSetDefaultBrowserInBackground"] =
canSetDefaultBrowserInBackground;
this.sendPageCallback(aMessageManager, aCallbackID, appinfo);
this.getAppInfo(aMessageManager, aWindow, aCallbackID);
break;
case "availableTargets":
this.getAvailableTargets(aMessageManager, aWindow, aCallbackID);
@ -1576,6 +1542,64 @@ this.UITour = {
}
},
getAppInfo(aMessageManager, aWindow, aCallbackID) {
(async() => {
let props = ["defaultUpdateChannel", "version"];
let appinfo = {};
props.forEach(property => appinfo[property] = Services.appinfo[property]);
// Identifier of the partner repack, as stored in preference "distribution.id"
// and included in Firefox and other update pings. Note this is not the same as
// Services.appinfo.distributionID (value of MOZ_DISTRIBUTION_ID is set at build time).
let distribution =
Services.prefs.getDefaultBranch("distribution.").getCharPref("id", "default");
appinfo["distribution"] = distribution;
let isDefaultBrowser = null;
try {
let shell = aWindow.getShellService();
if (shell) {
isDefaultBrowser = shell.isDefaultBrowser(false);
}
} catch (e) {}
appinfo["defaultBrowser"] = isDefaultBrowser;
let canSetDefaultBrowserInBackground = true;
if (AppConstants.isPlatformAndVersionAtLeast("win", "6.2") ||
AppConstants.isPlatformAndVersionAtLeast("macosx", "10.10")) {
canSetDefaultBrowserInBackground = false;
} else if (AppConstants.platform == "linux") {
// The ShellService may not exist on some versions of Linux.
try {
aWindow.getShellService();
} catch (e) {
canSetDefaultBrowserInBackground = null;
}
}
appinfo["canSetDefaultBrowserInBackground"] =
canSetDefaultBrowserInBackground;
// Expose Profile creation and last reset dates in weeks.
const ONE_WEEK = 7 * 24 * 60 * 60 * 1000;
let profileAge = new ProfileAge(null, null);
let createdDate = await profileAge.created;
let resetDate = await profileAge.reset;
let createdWeeksAgo = Math.floor((Date.now() - createdDate) / ONE_WEEK);
let resetWeeksAgo = null;
if (resetDate) {
resetWeeksAgo = Math.floor((Date.now() - resetDate) / ONE_WEEK);
}
appinfo["profileCreatedWeeksAgo"] = createdWeeksAgo;
appinfo["profileResetWeeksAgo"] = resetWeeksAgo;
this.sendPageCallback(aMessageManager, aCallbackID, appinfo);
})().catch(err => {
log.error(err);
this.sendPageCallback(aMessageManager, aCallbackID, {});
})
},
getAvailableTargets(aMessageManager, aChromeWindow, aCallbackID) {
(async () => {
let window = aChromeWindow;

Просмотреть файл

@ -8,6 +8,8 @@ var gContentAPI;
var gContentWindow;
Components.utils.import("resource://testing-common/TelemetryArchiveTesting.jsm", this);
Components.utils.import("resource://gre/modules/ProfileAge.jsm", this);
function test() {
UITourTest();
@ -303,6 +305,21 @@ var tests = [
});
});
},
function test_getConfigurationProfileAge(done) {
gContentAPI.getConfiguration("appinfo", (result) => {
ok(typeof(result.profileCreatedWeeksAgo) === "number", "profileCreatedWeeksAgo should be number.");
ok(result.profileResetWeeksAgo === null, "profileResetWeeksAgo should be null.");
// Set profile reset date to 15 days ago.
let profileAccessor = new ProfileAge();
profileAccessor.recordProfileReset(Date.now() - (15 * 24 * 60 * 60 * 1000));
gContentAPI.getConfiguration("appinfo", (result2) => {
ok(typeof(result2.profileResetWeeksAgo) === "number", "profileResetWeeksAgo should be number.");
is(result2.profileResetWeeksAgo, 2, "profileResetWeeksAgo should be 2.");
done();
});
});
},
function test_addToolbarButton(done) {
let placement = CustomizableUI.getPlacementOfWidget("panic-button");
is(placement, null, "default UI has panic button in the palette");

Просмотреть файл

@ -0,0 +1,35 @@
[
{
"version": "gcc 4.9.4 + PR64905",
"size": 101297752,
"digest": "42aa2e3fdd232b5e390472a788e7f7db71a1fee4221e260b6cb58c9a1d73e6cdd10afcbac137f7844290169cd6b561b424ecc92b159e9726b0ad5de3f478a8be",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": true
},
{
"version": "clang 4.0.1 gecko build for linux",
"size": 215309284,
"visibility": "public",
"digest": "8f6d386ca1d4606526dd24f366b1dbc1914c6c6d7f54c69c2a2ca0e7cfabe641c1168952d606295feffa9f38ad687084de5efb1e80be3ed2f431ac91de80039b",
"algorithm": "sha512",
"filename": "clang.tar.xz",
"unpack": true
},
{
"version": "rustc 1.18.0 (03fc9d622 2017-06-06) repack",
"size": 146886764,
"digest": "e03eeebd4acc593369d5635a059f55a6beed2d2fb839a8c196ccc735a246620d3285a15c17ab34fa8bcf9dd57dd25f735d4ef3eb2fc3be672bbde62342823f1e",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true
},
{
"size": 12072532,
"digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"setup": "setup.sh",
"unpack": true
}
]

Просмотреть файл

@ -51,6 +51,29 @@ const CONTENT = {
popupIconURL: "chrome://formautofill/content/icon-address-save.svg",
},
},
update: {
notificationId: "autofill-address",
message: GetStringFromName("updateAddressMessage"),
anchor: {
id: "autofill-address-notification-icon",
URL: "chrome://formautofill/content/formfill-anchor.svg",
tooltiptext: GetStringFromName("openAutofillMessagePanel"),
},
mainAction: {
label: GetStringFromName("updateAddressLabel"),
accessKey: "U",
callbackState: "update",
},
secondaryActions: [{
label: GetStringFromName("createAddressLabel"),
accessKey: "C",
callbackState: "create",
}],
options: {
persistWhileVisible: true,
popupIconURL: "chrome://formautofill/content/icon-address-update.svg",
},
},
};
let FormAutofillDoorhanger = {

Просмотреть файл

@ -280,7 +280,25 @@ FormAutofillParent.prototype = {
if (address.guid) {
if (!this.profileStorage.addresses.mergeIfPossible(address.guid, address.record)) {
// TODO: Show update doorhanger(bug 1303513) and set probe(bug 990200)
FormAutofillDoorhanger.show(target, "update").then((state) => {
let changedGUIDs = this.profileStorage.addresses.mergeToStorage(address.record);
switch (state) {
case "create":
if (!changedGUIDs.length) {
changedGUIDs.push(this.profileStorage.addresses.add(address.record));
}
break;
case "update":
if (!changedGUIDs.length) {
this.profileStorage.addresses.update(address.guid, address.record);
changedGUIDs.push(address.guid);
} else {
this.profileStorage.addresses.remove(address.guid);
}
break;
}
changedGUIDs.forEach(guid => this.profileStorage.addresses.notifyUsed(guid));
});
return;
}
this.profileStorage.addresses.notifyUsed(address.guid);

Просмотреть файл

@ -0,0 +1,6 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<path fill="#999899" d="M22 13.7H9.4c-.6 0-1.2.5-1.2 1.2 0 .6.5 1.2 1.2 1.2H22c.6 0 1.2-.5 1.2-1.2s-.6-1.2-1.2-1.2zM6.1 26.6V5.5c0-.8.7-1.5 1.5-1.5h16c.9 0 1.5.6 1.5 1.5V16h2V3.8c0-1-.7-1.8-1.8-1.8H5.9c-1 0-1.8.8-1.8 1.8v24.5c0 1 .8 1.7 1.8 1.7h9.3v-2H7.6c-.8 0-1.5-.6-1.5-1.4zm9.8-7.5H9.4c-.6 0-1.2.5-1.2 1.2s.5 1.2 1.2 1.2h6.5c.6 0 1.2-.5 1.2-1.2s-.6-1.2-1.2-1.2zM22 7.8H9.4c-.6 0-1.2.5-1.2 1.2s.5 1.2 1.2 1.2H22c.6 0 1.2-.5 1.2-1.2s-.6-1.2-1.2-1.2zm-5.7 16l4.4-4.3c.2-.2.5-.3.8-.3s.6.1.8.3l4.4 4.3c.5.5.3.8-.3.8h-2.6v4.7c0 .4-.4.8-.8.8h-3c-.4 0-.8-.4-.8-.8v-4.7h-2.5c-.7 0-.8-.4-.4-.8z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 874 B

Просмотреть файл

@ -10,6 +10,9 @@ viewAutofillOptionsLink = View Form Autofill Options
changeAutofillOptions = Change Form Autofill Options
viewAutofillOptionsLinkOSX = View Form Autofill Preferences
changeAutofillOptionsOSX = Change Form Autofill Preferences
updateAddressMessage = Would you like to update your address with this new information?
createAddressLabel = Create New Address
updateAddressLabel = Update Address
openAutofillMessagePanel = Open Form Autofill message panel
autocompleteFooterOption = Form Autofill Options
autocompleteFooterOptionShort = Options

Просмотреть файл

@ -11,3 +11,4 @@ support-files =
[browser_privacyPreferences.js]
[browser_manageProfilesDialog.js]
[browser_submission_in_private_mode.js]
[browser_update_doorhanger.js]

Просмотреть файл

@ -0,0 +1,120 @@
"use strict";
const FORM_URL = "http://mochi.test:8888/browser/browser/extensions/formautofill/test/browser/autocomplete_basic.html";
add_task(async function test_update_address() {
await saveAddress(TEST_ADDRESS_1);
let addresses = await getAddresses();
is(addresses.length, 1, "1 address in storage");
await BrowserTestUtils.withNewTab({gBrowser, url: FORM_URL},
async function(browser) {
let promiseShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
"popupshown");
await ContentTask.spawn(browser, null, async function() {
content.document.querySelector("form #organization").focus();
});
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser);
await expectPopupOpen(browser);
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser);
await BrowserTestUtils.synthesizeKey("VK_RETURN", {}, browser);
await ContentTask.spawn(browser, null, async function() {
let form = content.document.getElementById("form");
let org = form.querySelector("#organization");
await new Promise(resolve => setTimeout(resolve, 1000));
org.value = "Mozilla";
// Wait 1000ms before submission to make sure the input value applied
await new Promise(resolve => setTimeout(resolve, 1000));
form.querySelector("input[type=submit]").click();
});
await promiseShown;
let notificationElement = PopupNotifications.panel.firstChild;
notificationElement.button.click();
}
);
addresses = await getAddresses();
is(addresses.length, 1, "Still 1 address in storage");
is(addresses[0].organization, "Mozilla", "Verify the organization field");
});
add_task(async function test_create_new_address() {
let addresses = await getAddresses();
is(addresses.length, 1, "1 address in storage");
await BrowserTestUtils.withNewTab({gBrowser, url: FORM_URL},
async function(browser) {
let promiseShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
"popupshown");
await ContentTask.spawn(browser, null, async function() {
content.document.querySelector("form #tel").focus();
});
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser);
await expectPopupOpen(browser);
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser);
await BrowserTestUtils.synthesizeKey("VK_RETURN", {}, browser);
await ContentTask.spawn(browser, null, async function() {
let form = content.document.getElementById("form");
let tel = form.querySelector("#tel");
await new Promise(resolve => setTimeout(resolve, 1000));
tel.value = "+1-234-567-890";
// Wait 1000ms before submission to make sure the input value applied
await new Promise(resolve => setTimeout(resolve, 1000));
form.querySelector("input[type=submit]").click();
});
await promiseShown;
let notificationElement = PopupNotifications.panel.firstChild;
notificationElement.secondaryButton.click();
}
);
addresses = await getAddresses();
is(addresses.length, 2, "2 addresses in storage");
is(addresses[1].tel, "+1-234-567-890", "Verify the tel field");
});
add_task(async function test_create_new_address_merge() {
let addresses = await getAddresses();
is(addresses.length, 2, "2 address in storage");
await BrowserTestUtils.withNewTab({gBrowser, url: FORM_URL},
async function(browser) {
let promiseShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
"popupshown");
await ContentTask.spawn(browser, null, async function() {
content.document.querySelector("form #tel").focus();
});
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser);
await expectPopupOpen(browser);
await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser);
await BrowserTestUtils.synthesizeKey("VK_RETURN", {}, browser);
// Choose the latest address and revert to the original phone number
await ContentTask.spawn(browser, null, async function() {
let form = content.document.getElementById("form");
let tel = form.querySelector("#tel");
tel.value = "+1 617 253 5702";
// Wait 1000ms before submission to make sure the input value applied
await new Promise(resolve => setTimeout(resolve, 1000));
form.querySelector("input[type=submit]").click();
});
await promiseShown;
let notificationElement = PopupNotifications.panel.firstChild;
notificationElement.secondaryButton.click();
}
);
addresses = await getAddresses();
is(addresses.length, 2, "Still 2 addresses in storage");
});

Просмотреть файл

@ -99,6 +99,26 @@ add_task(async function new_address_submitted_and_merged() {
delete expectedAddresses[0].timesUsed;
});
// Submit an updated autofill address and merge.
add_task(async function check_storage_after_form_submitted() {
document.querySelector("form").reset();
// Add country to second address in storage
await setInput("#country", "US");
TEST_ADDRESSES[1].country = "US";
await setInput("#organization", "Moz");
doKey("down");
await expectPopup();
doKey("down");
doKey("return");
clickOnElement("input[type=submit]");
let expectedAddresses = TEST_ADDRESSES.slice(0);
await onAddressChanged("merge");
let matching = await checkAddresses(expectedAddresses);
ok(matching, "Updated address merged as expected");
});
</script>
<div>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

До

Ширина:  |  Высота:  |  Размер: 65 KiB

После

Ширина:  |  Высота:  |  Размер: 66 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

До

Ширина:  |  Высота:  |  Размер: 71 KiB

После

Ширина:  |  Высота:  |  Размер: 91 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

До

Ширина:  |  Высота:  |  Размер: 10 KiB

После

Ширина:  |  Высота:  |  Размер: 16 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

До

Ширина:  |  Высота:  |  Размер: 52 KiB

После

Ширина:  |  Высота:  |  Размер: 51 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

До

Ширина:  |  Высота:  |  Размер: 20 KiB

После

Ширина:  |  Высота:  |  Размер: 13 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

До

Ширина:  |  Высота:  |  Размер: 8.1 KiB

После

Ширина:  |  Высота:  |  Размер: 645 B

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

До

Ширина:  |  Высота:  |  Размер: 7.5 KiB

После

Ширина:  |  Высота:  |  Размер: 645 B

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

До

Ширина:  |  Высота:  |  Размер: 5.6 KiB

После

Ширина:  |  Высота:  |  Размер: 729 B

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

До

Ширина:  |  Высота:  |  Размер: 6.6 KiB

После

Ширина:  |  Высота:  |  Размер: 729 B

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

До

Ширина:  |  Высота:  |  Размер: 5.8 KiB

После

Ширина:  |  Высота:  |  Размер: 978 B

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

До

Ширина:  |  Высота:  |  Размер: 5.8 KiB

После

Ширина:  |  Высота:  |  Размер: 978 B

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

До

Ширина:  |  Высота:  |  Размер: 5.8 KiB

После

Ширина:  |  Высота:  |  Размер: 528 B

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

До

Ширина:  |  Высота:  |  Размер: 6.8 KiB

После

Ширина:  |  Высота:  |  Размер: 528 B

Просмотреть файл

@ -1 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><defs><style>.cls-1{fill:none;}.cls-2{fill:#fff;}.cls-3{fill:#e1e1e5;}.cls-4{fill:#767aa8;}.cls-5{fill:#f9f9fa;}.cls-6{fill:#cd6f14;}</style></defs><title>icons</title><path class="cls-1" d="M5.36,20.85H19.86l5.33,5.81a.63.63,0,0,0,.46.17,2.31,2.31,0,0,0,1.47-.76,2.17,2.17,0,0,0,.75-1.57A2.22,2.22,0,0,1,27.12,26c-.69.69-1.56,1-1.93.59L19.86,20.8H5.36A1.32,1.32,0,0,1,4,19.48V14.35H4v5.17A1.32,1.32,0,0,0,5.36,20.85Z"/><path class="cls-1" d="M24.12,20.8l0,0a1.32,1.32,0,0,0,1.27-1.31v0A1.32,1.32,0,0,1,24.12,20.8Z"/><path class="cls-2" d="M23.6,20.32h.51a.84.84,0,0,0,.84-.84V14.31a.84.84,0,0,0-.84-.84H21.33a7.34,7.34,0,0,1-1.45,3.86l.63.63a.82.82,0,0,1,.77.22Z"/><path class="cls-2" d="M19.06,19.41l-.63-.63a7.39,7.39,0,0,1-11.82-5.3H5.36a.84.84,0,0,0-.84.84v5.17a.84.84,0,0,0,.84.84h14l-.13-.14A.82.82,0,0,1,19.06,19.41Z"/><path class="cls-3" d="M5.36,20.8H19.86l-.44-.48h-14a.84.84,0,0,1-.84-.84V14.31a.84.84,0,0,1,.84-.84H6.61c0-.16,0-.31,0-.47,0,0,0,0,0,0H5.36A1.32,1.32,0,0,0,4,14.35v5.13A1.32,1.32,0,0,0,5.36,20.8Z"/><path class="cls-3" d="M24.1,13.48a.84.84,0,0,1,.84.84v5.17a.84.84,0,0,1-.84.84H23.6l.26.24.26.24a1.32,1.32,0,0,0,1.3-1.32V14.36A1.32,1.32,0,0,0,24.1,13H21.34v0c0,.15,0,.31,0,.46Z"/><path class="cls-4" d="M8.75,18.11a7.4,7.4,0,0,0,9.68.67l.63.63A2.22,2.22,0,0,1,20.51,18l-.63-.63a7.34,7.34,0,0,0,1.45-3.86c0-.15,0-.31,0-.46a7.37,7.37,0,0,0-1.59-4.71l-.1-.12c-.14-.17-.29-.34-.45-.5A7.39,7.39,0,0,0,6.59,13c0,.16,0,.31,0,.47A7.36,7.36,0,0,0,8.75,18.11ZM8.28,10.9a6,6,0,0,1,.43-1h0a6,6,0,0,1,10.46,0h0c0,.07.06.15.1.22s.08.13.11.2l-.06-.08a6.15,6.15,0,0,1,.28.63A6,6,0,0,1,8.87,16.08l0,.08c-.06-.09-.1-.19-.15-.28l-.14-.26c-.05-.11-.11-.21-.15-.32a6,6,0,0,1-.25-.66v0A6,6,0,0,1,8,13.83v-.05a5.79,5.79,0,0,1,.27-2.87Z"/><path class="cls-5" d="M14.36,7.56A6,6,0,0,0,9.58,9.93h9.56A6,6,0,0,0,14.36,7.56Z"/><path class="cls-2" d="M8,12.92a6,6,0,0,1,.35-2h0A5.79,5.79,0,0,0,8,13.77,6.05,6.05,0,0,1,8,12.92Z"/><path class="cls-2" d="M8.33,13.59a6,6,0,0,0,.54,2.49A6,6,0,0,0,19.66,10.9H9A6,6,0,0,0,8.33,13.59Z"/><path class="cls-3" d="M8,12.92a6.05,6.05,0,0,0,.06.86v.05a6,6,0,0,0,.17.78v0a6,6,0,0,0,.25.66c0,.11.1.21.15.32l.14.26c.05.09.1.19.15.28l0-.08A6,6,0,0,1,9,10.9H19.66a6.15,6.15,0,0,0-.28-.63l.06.08c0-.07-.07-.13-.11-.2s-.06-.15-.1-.22h0a6,6,0,0,0-10.46,0h0a6,6,0,0,0-.43,1h0A6,6,0,0,0,8,12.92Zm6.41-5.35a6,6,0,0,1,4.78,2.37H9.58A6,6,0,0,1,14.36,7.56Z"/><path class="cls-6" d="M21.1,22.15,23.25,20l.61.56-.26-.24-2.32-2.13a.82.82,0,0,0-.77-.22,2.22,2.22,0,0,0-1.44,1.44.82.82,0,0,0,.22.77l.13.14.44.48,5.33,5.81c.37.37,1.24.1,1.93-.59a2.22,2.22,0,0,0,.75-1.53.59.59,0,0,0-.16-.36L26.4,22.93,24,25.32Z"/><path class="cls-4" d="M23.86,20.56,23.25,20,21.1,22.15,24,25.32l2.39-2.39-2.28-2.09h0l0,0Z"/><path class="cls-2" d="M5.36,21.85H19.42l5,5.49a1.65,1.65,0,0,0,1.2.49,3.27,3.27,0,0,0,2.18-1c1.12-1.12,1.37-2.56.59-3.34l-2.58-2.37a2.31,2.31,0,0,0,.59-1.54V14.36A2.32,2.32,0,0,0,24.1,12H22.3A8.37,8.37,0,0,0,8,7,8.31,8.31,0,0,0,5.63,12H5.36A2.32,2.32,0,0,0,3,14.36v5.17A2.32,2.32,0,0,0,5.36,21.85ZM4,14.36H4A1.32,1.32,0,0,1,5.36,13H6.59s0,0,0,0A7.39,7.39,0,0,1,19.2,7.69c.16.16.31.33.45.5l.1.12A7.37,7.37,0,0,1,21.34,13v0H24.1a1.32,1.32,0,0,1,1.32,1.32v5.17a1.32,1.32,0,0,1-1.27,1.31h0l2.28,2.09,1.31,1.21a.59.59,0,0,1,.16.36,2.17,2.17,0,0,1-.75,1.57,2.31,2.31,0,0,1-1.47.76.63.63,0,0,1-.46-.17l-5.33-5.81H5.36A1.32,1.32,0,0,1,4,19.52Z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="8 8 16 16 "><title>Icons / Search</title><g fill="none"><path d="M0 0h32v32H0z"/><path d="M23.7 22.3l-4.8-4.8c1.8-2.5 1.4-6.1-1-8.1s-5.9-1.9-8.1.4c-2.3 2.2-2.4 5.7-.4 8.1 2 2.4 5.6 2.8 8.1 1l4.8 4.8c.4.4 1 .4 1.4 0 .4-.4.4-1 0-1.4zM14 18c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4c0 1.1-.4 2.1-1.1 2.9-.8.7-1.8 1.1-2.9 1.1z" fill="#0A84FF"/></g></svg>

До

Ширина:  |  Высота:  |  Размер: 3.4 KiB

После

Ширина:  |  Высота:  |  Размер: 417 B

Просмотреть файл

@ -1 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><defs><style>.cls-1{fill:none;}.cls-2{fill:#fff;}.cls-3{fill:#d9ebff;}.cls-4{fill:#f9f9fa;}.cls-5{fill:#e1e1e6;}.cls-6{fill:#59acff;}</style></defs><title>icons</title><path class="cls-1" d="M5.36,20.8A1.32,1.32,0,0,1,4,19.48v0a1.32,1.32,0,0,0,1.32,1.32H19.86l1.2,1.31,0,0L19.86,20.8Z"/><path class="cls-1" d="M24.35,20.75l0,0a1.3,1.3,0,0,0,1-1.26v0A1.3,1.3,0,0,1,24.35,20.75Z"/><path class="cls-1" d="M25.19,26.61,24,25.32l0,0,1.2,1.31a.63.63,0,0,0,.46.17,2.31,2.31,0,0,0,1.47-.76,2.17,2.17,0,0,0,.75-1.57A2.22,2.22,0,0,1,27.12,26C26.43,26.72,25.56,27,25.19,26.61Z"/><path class="cls-2" d="M4.53,14.31v5.17a.84.84,0,0,0,.84.84h14l-.13-.14a.82.82,0,0,1-.22-.77l-.63-.63a7.38,7.38,0,0,1-8.11.49.24.24,0,0,1,0,.15.25.25,0,0,1-.22.13.26.26,0,0,1-.12,0,7.75,7.75,0,0,1-3.78-6H5.36A.84.84,0,0,0,4.53,14.31Z"/><path class="cls-2" d="M20.34,17.8l0,0c.05,0,.53-.37,1.33.48.29.31,1.24,1.19,2.2,2.07h.23a.84.84,0,0,0,.84-.84V14.31a.84.84,0,0,0-.84-.84H21.8A6.19,6.19,0,0,1,21,16.2l0,.07a.24.24,0,0,1-.23.16h-.08a.23.23,0,0,1-.11-.1,7.32,7.32,0,0,1-.64,1Z"/><path class="cls-3" d="M19.87,17.33a7.32,7.32,0,0,0,.64-1,.25.25,0,0,1,0-.22.88.88,0,0,1,.08-.15,5.77,5.77,0,0,0,.78-3.17,7.35,7.35,0,0,0-1.58-4.45l-.1-.12c-.14-.17-.29-.34-.45-.5a7.39,7.39,0,0,0-12.59,4.6,7.58,7.58,0,0,0,3.6,6.78.24.24,0,0,1,.11.2,7.38,7.38,0,0,0,8.11-.49l.63.63a.82.82,0,0,0,.22.77l.13.14h-14a.84.84,0,0,1-.84-.84V14.31a.84.84,0,0,1,.84-.84h.81c0-.16,0-.3,0-.44H5.36A1.32,1.32,0,0,0,4,14.36v5.13A1.32,1.32,0,0,0,5.36,20.8H19.86l1.22,1.33,2-1.92c-.77-.72-1.46-1.36-1.71-1.63s-.62-.44-.68-.41a.24.24,0,0,1-.34,0s0-.06,0-.09a.25.25,0,0,1,.06-.24ZM14,18.91a6,6,0,0,1-5.1-2.82l0,.08c-.06-.09-.1-.19-.15-.28l-.14-.26c-.05-.11-.11-.21-.15-.32a6,6,0,0,1-.25-.66v0A6,6,0,0,1,8,13.83v-.05a6.06,6.06,0,0,1,.7-3.84h0a6,6,0,0,1,10.46,0l.12.22c0,.06.08.13.11.2l-.06-.08-.24-.33H9.58a6,6,0,0,0-.61,1H19.66a6,6,0,0,1-5.69,8Z"/><path class="cls-3" d="M24.94,14.31v5.17a.84.84,0,0,1-.84.84h-.23l.47.43a1.3,1.3,0,0,0,1.07-1.27V14.36A1.32,1.32,0,0,0,24.1,13H21.82c0,.15,0,.3,0,.44H24.1A.84.84,0,0,1,24.94,14.31Z"/><path class="cls-4" d="M14.36,7.56A6,6,0,0,0,9.58,9.93h9.56A6,6,0,0,0,14.36,7.56Z"/><path class="cls-2" d="M19.66,10.9H9a6,6,0,0,0-.1,5.18A6,6,0,0,0,19.66,10.9Z"/><path class="cls-2" d="M8.31,10.9h0A5.79,5.79,0,0,0,8,13.77a5.93,5.93,0,0,1,.29-2.87Z"/><path class="cls-5" d="M8.75,9.93h0a6,6,0,0,0-.43,1h0A6,6,0,0,1,8.75,9.93Z"/><path class="cls-6" d="M9,10.9a6,6,0,0,1,10.17-1l.24.33.06.08c0-.07-.07-.13-.11-.2l-.12-.22A6,6,0,0,0,8,13.77v.05a6,6,0,0,0,.17.78v0a6,6,0,0,0,.25.66c0,.11.1.21.15.32l.14.26c.05.09.1.19.15.28l0-.08A6,6,0,0,1,9,10.9Z"/><path class="cls-3" d="M26.4,22.93,24,25.32l1.18,1.29c.37.37,1.24.1,1.93-.59a2.22,2.22,0,0,0,.75-1.53.59.59,0,0,0-.16-.36Z"/><path class="cls-6" d="M28.42,23.43l-2.58-2.37a2.31,2.31,0,0,0,.59-1.54V14.36A2.32,2.32,0,0,0,24.1,12H22.3A8.37,8.37,0,0,0,8,7,8.31,8.31,0,0,0,5.63,12H5.36A2.32,2.32,0,0,0,3,14.36v5.17a2.32,2.32,0,0,0,2.32,2.32H19.42l5,5.49a1.65,1.65,0,0,0,1.2.49,3.27,3.27,0,0,0,2.18-1C29,25.65,29.2,24.22,28.42,23.43ZM20.28,18s0,.06,0,.09a.24.24,0,0,0,.34,0c.06,0,.29,0,.68.41s.94.91,1.71,1.63l-2,1.92,0,0-1.2-1.31H5.36A1.32,1.32,0,0,1,4,19.52V14.36A1.32,1.32,0,0,1,5.36,13h.77c0,.14,0,.28,0,.44a7.75,7.75,0,0,0,3.78,6,.26.26,0,0,0,.12,0,.25.25,0,0,0,.22-.12.24.24,0,0,0,0-.15.24.24,0,0,0-.11-.2,7.58,7.58,0,0,1-3.6-6.78A7.39,7.39,0,0,1,19.2,7.69c.16.16.31.33.45.5l.1.12a7.35,7.35,0,0,1,1.58,4.45,5.77,5.77,0,0,1-.78,3.17.88.88,0,0,0-.08.15.25.25,0,0,0,0,.22.23.23,0,0,0,.11.1h.08a.24.24,0,0,0,.23-.16l0-.07a6.19,6.19,0,0,0,.82-2.72c0-.14,0-.29,0-.44H24.1a1.32,1.32,0,0,1,1.32,1.32v5.17a1.3,1.3,0,0,1-1,1.26l0,0-.47-.43c-1-.88-1.9-1.76-2.2-2.07-.8-.85-1.28-.52-1.33-.48l0,0A.25.25,0,0,0,20.28,18Zm6.84,8a2.31,2.31,0,0,1-1.47.76.63.63,0,0,1-.46-.17L24,25.34l0,0,2.39-2.39,1.31,1.21a.59.59,0,0,1,.16.36A2.17,2.17,0,0,1,27.12,26.07Z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="8 8 16 16 "><title>Icons / Search</title><g fill="none"><path d="M0 0h32v32H0z"/><path d="M23.7 22.3l-4.8-4.8c1.8-2.5 1.4-6.1-1-8.1s-5.9-1.9-8.1.4c-2.3 2.2-2.4 5.7-.4 8.1 2 2.4 5.6 2.8 8.1 1l4.8 4.8c.4.4 1 .4 1.4 0 .4-.4.4-1 0-1.4zM14 18c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4c0 1.1-.4 2.1-1.1 2.9-.8.7-1.8 1.1-2.9 1.1z" fill="#3E3D40"/></g></svg>

До

Ширина:  |  Высота:  |  Размер: 3.9 KiB

После

Ширина:  |  Высота:  |  Размер: 417 B

Просмотреть файл

@ -116,22 +116,20 @@
#onboarding-tour-list > li {
list-style: none;
border-inline-start: 6px solid transparent;
border-radius: 2px;
padding-inline-start: 49px;
padding-top: 14px;
padding-bottom: 14px;
margin-inline-start: 10px;
margin-inline-start: 16px;
margin-bottom: 9px;
background-repeat: no-repeat;
background-position: left 10px top 7px;
background-size: 34px;
background-position: left 17px top 14px;
background-size: 20px;
font-size: 16px;
cursor: pointer;
}
#onboarding-tour-list > li:dir(rtl) {
background-position-x: right 10px;
background-position-x: right 17px;
}
#onboarding-tour-list > li.onboarding-complete::before {
@ -147,8 +145,7 @@
#onboarding-tour-list > li.onboarding-active,
#onboarding-tour-list > li:hover {
border-inline-start-color: #5ce6e6;
background-color: #fff;
color: #0A84FF;
}
/* Sync tour */
@ -221,15 +218,19 @@
.onboarding-tour-content {
grid-row: tour-page-start / tour-button-start;
grid-column: tour-content-start / tour-page-end;
padding-top: 0;
padding-bottom: 0;
padding-inline-start: 0;
padding-inline-end: 27px;
padding: 0;
text-align: end;
}
.onboarding-tour-content > img {
width: 352px;
margin: 0 calc(50% - 176px);
margin: 0;
}
/* These illustrations need to be stuck on the right side to the border. Thus we
need to flip them horizontally on RTL . */
.onboarding-tour-content > img:dir(rtl) {
transform: scaleX(-1);
}
.onboarding-tour-content > iframe {
@ -365,6 +366,10 @@
transform: translateY(-50%);
}
#onboarding-notification-icon:dir(rtl) {
background-position: right 34px center;
}
#onboarding-notification-icon::after {
--height: 22px;
content: attr(data-tooltip);
@ -396,8 +401,8 @@
display: flex;
align-items: center;
position: absolute;
offset-block-start: 50%;
offset-inline-start: 50%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

Просмотреть файл

@ -55,8 +55,8 @@ var onboardingTours = [
let div = win.document.createElement("div");
div.innerHTML = `
<section class="onboarding-tour-description">
<h1 data-l10n-id="onboarding.tour-private-browsing.title"></h1>
<p data-l10n-id="onboarding.tour-private-browsing.description"></p>
<h1 data-l10n-id="onboarding.tour-private-browsing.title2"></h1>
<p data-l10n-id="onboarding.tour-private-browsing.description2"></p>
</section>
<section class="onboarding-tour-content">
<img src="resource://onboarding/img/figure_private.svg" />
@ -82,8 +82,8 @@ var onboardingTours = [
let div = win.document.createElement("div");
div.innerHTML = `
<section class="onboarding-tour-description">
<h1 data-l10n-id="onboarding.tour-addons.title"></h1>
<p data-l10n-id="onboarding.tour-addons.description"></p>
<h1 data-l10n-id="onboarding.tour-addons.title2"></h1>
<p data-l10n-id="onboarding.tour-addons.description2"></p>
</section>
<section class="onboarding-tour-content">
<img src="resource://onboarding/img/figure_addons.svg" />
@ -109,8 +109,8 @@ var onboardingTours = [
let div = win.document.createElement("div");
div.innerHTML = `
<section class="onboarding-tour-description">
<h1 data-l10n-id="onboarding.tour-customize.title"></h1>
<p data-l10n-id="onboarding.tour-customize.description"></p>
<h1 data-l10n-id="onboarding.tour-customize.title2"></h1>
<p data-l10n-id="onboarding.tour-customize.description2"></p>
</section>
<section class="onboarding-tour-content">
<img src="resource://onboarding/img/figure_customize.svg" />
@ -124,7 +124,7 @@ var onboardingTours = [
},
{
id: "onboarding-tour-search",
tourNameId: "onboarding.tour-search",
tourNameId: "onboarding.tour-search2",
getNotificationStrings(bundle) {
return {
title: bundle.GetStringFromName("onboarding.notification.onboarding-tour-search.title"),
@ -136,8 +136,8 @@ var onboardingTours = [
let div = win.document.createElement("div");
div.innerHTML = `
<section class="onboarding-tour-description">
<h1 data-l10n-id="onboarding.tour-search.title"></h1>
<p data-l10n-id="onboarding.tour-search.description"></p>
<h1 data-l10n-id="onboarding.tour-search.title2"></h1>
<p data-l10n-id="onboarding.tour-search.description2"></p>
</section>
<section class="onboarding-tour-content">
<img src="resource://onboarding/img/figure_search.svg" />
@ -165,8 +165,8 @@ var onboardingTours = [
"onboarding.tour-default-browser.win7.button" : "onboarding.tour-default-browser.button";
div.innerHTML = `
<section class="onboarding-tour-description">
<h1 data-l10n-id="onboarding.tour-default-browser.title"></h1>
<p data-l10n-id="onboarding.tour-default-browser.description"></p>
<h1 data-l10n-id="onboarding.tour-default-browser.title2"></h1>
<p data-l10n-id="onboarding.tour-default-browser.description2"></p>
</section>
<section class="onboarding-tour-content">
<img src="resource://onboarding/img/figure_default.svg" />
@ -180,7 +180,7 @@ var onboardingTours = [
},
{
id: "onboarding-tour-sync",
tourNameId: "onboarding.tour-sync",
tourNameId: "onboarding.tour-sync2",
getNotificationStrings(bundle) {
return {
title: bundle.GetStringFromName("onboarding.notification.onboarding-tour-sync.title"),
@ -193,8 +193,8 @@ var onboardingTours = [
div.classList.add("onboarding-no-button");
div.innerHTML = `
<section class="onboarding-tour-description">
<h1 data-l10n-id="onboarding.tour-sync.title"></h1>
<p data-l10n-id="onboarding.tour-sync.description"></p>
<h1 data-l10n-id="onboarding.tour-sync.title2"></h1>
<p data-l10n-id="onboarding.tour-sync.description2"></p>
</section>
<section class="onboarding-tour-content">
<form>
@ -260,7 +260,7 @@ class Onboarding {
if (doc.hidden) {
// When the preloaded-browser feature is on,
// it would preload an hidden about:newtab in the background.
// We don't wnat to show notification in that hidden state.
// We don't want to show notification in that hidden state.
let onVisible = () => {
if (!doc.hidden) {
doc.removeEventListener("visibilitychange", onVisible);
@ -324,11 +324,9 @@ class Onboarding {
case "onboarding-overlay":
this.toggleOverlay();
break;
case "onboarding-notification-close-btn":
this.hideNotification();
break;
case "onboarding-notification-action-btn":
let tourId = this._notificationBar.dataset.targetTourId;
this.toggleOverlay();
@ -488,7 +486,7 @@ class Onboarding {
_renderNotificationBar() {
let div = this._window.document.createElement("div");
div.id = "onboarding-notification-bar";
// Here we use `innerHTML` is for more friendly reading.
// We use `innerHTML` for more friendly reading.
// The security should be fine because this is not from an external input.
div.innerHTML = `
<div id="onboarding-notification-icon"></div>
@ -524,7 +522,7 @@ class Onboarding {
_renderOverlay() {
let div = this._window.document.createElement("div");
div.id = "onboarding-overlay";
// Here we use `innerHTML` is for more friendly reading.
// We use `innerHTML` for more friendly reading.
// The security should be fine because this is not from an external input.
div.innerHTML = `
<div id="onboarding-overlay-dialog">

Просмотреть файл

@ -6,70 +6,69 @@ onboarding.overlay-title=Getting started with %S
onboarding.hidden-checkbox-label-text=Mark all as complete, and hide the tour
#LOCALIZATION NOTE(onboarding.button.learnMore): this string is used as a button label, displayed near the message, and shared across all the onboarding notifications.
onboarding.button.learnMore=Learn More
# LOCALIZATION NOTE(onboarding.notification-icon-tool-tip): %S is brandShortName.
# LOCALIZATION NOTE(onboarding.notification-icon-tool-tip): This string will be used to show the tooltip alongside the notification icon. %S is brandShortName.
onboarding.notification-icon-tool-tip=New to %S?
onboarding.tour-search=One-Click Search
onboarding.tour-search.title=Find the needle or the haystack.
# LOCALIZATION NOTE (onboarding.tour-search.description): If Amazon is not part
onboarding.tour-search2=Search
onboarding.tour-search.title2=Find it faster.
# LOCALIZATION NOTE (onboarding.tour-search.description2): If Amazon is not part
# of the default searchplugins for your locale, you can replace it with another
# ecommerce website (if you're shipping one), but not with a general purpose
# search engine (Google, Bing, Yandex, etc.). Alternatively, only reference
# Wikipedia and drop Amazon from the text.
onboarding.tour-search.description=Having a default search engine doesnt mean its the only one you use. Pick a search engine or a site, like Amazon or Wikipedia, to search on the fly.
onboarding.tour-search.description2=Having a default search engine doesnt mean its the only one you can use. Choose a search engine or a site, like Amazon or Wikipedia, right from the search box.
onboarding.tour-search.button=Open One-Click Search
onboarding.notification.onboarding-tour-search.title=Find it faster.
onboarding.notification.onboarding-tour-search.message=Access all of your favorite search engines with a click. Search the whole Web or just one website right from the search box.
onboarding.tour-private-browsing=Private Browsing
onboarding.tour-private-browsing.title=A little privacy goes a long way.
# LOCALIZATION NOTE(onboarding.tour-private-browsing.description): %S is brandShortName.
onboarding.tour-private-browsing.description=Browse the internet without saving your searches or the sites you visited. When your session ends, the cookies disappear from %S like they were never there.
onboarding.tour-private-browsing.title2=Browse by yourself.
# LOCALIZATION NOTE(onboarding.tour-private-browsing.description2): %S is brandShortName.
onboarding.tour-private-browsing.description2=Want to keep something to yourself? Use Private Browsing with Tracking Protection. When you close your session, %S clears search and browsing history.
onboarding.tour-private-browsing.button=Show Private Browsing in Menu
onboarding.notification.onboarding-tour-private-browsing.title=Browse by yourself.
onboarding.notification.onboarding-tour-private-browsing.message=Theres no reason to share your online life with trackers every time you browse. Want to keep something to yourself? Use Private Browsing with Tracking Protection.
onboarding.tour-addons=Add-ons
onboarding.tour-addons.title=Add more functionality.
# LOCALIZATION NOTE(onboarding.tour-addons.description): This string will be used in the add-on tour description. %1$S is brandShortName
onboarding.tour-addons.description=Add-ons expand %1$Ss built-in features, so %1$S works the way you do. Compare prices, check the weather or express your personality with a custom theme.
onboarding.tour-addons.title2=Get more done.
# LOCALIZATION NOTE(onboarding.tour-addons.description2): This string will be used in the add-on tour description. %S is brandShortName
onboarding.tour-addons.description2=Add-ons let you add features to %S, so your browser works harder for you. Compare prices, check the weather or express your personality with a custom theme.
onboarding.tour-addons.button=Show Add-ons in Menu
onboarding.notification.onboarding-tour-addons.title=Get more done.
# LOCALIZATION NOTE(onboarding.notification.onboarding-tour-addons.message): %S is brandShortName.
# LOCALIZATION NOTE(onboarding.notification.onboarding-tour-addons.message): This string will be used in the notification message for the add-ons tour. %S is brandShortName.
onboarding.notification.onboarding-tour-addons.message=Add-ons are small apps you can add to %S that do lots of things — from managing to-do lists, to downloading videos, to changing the look of your browser.
onboarding.tour-customize=Customize
onboarding.tour-customize.title=Do things your way.
# LOCALIZATION NOTE(onboarding.tour-customize.description): This string will be used in the customize tour description. %S is brandShortName
onboarding.tour-customize.description=Drag, drop, and reorder %Ss toolbar and menu to fit your needs. You can even select a compact theme to give websites more room.
onboarding.tour-customize.title2=Rearrange your toolbar.
# LOCALIZATION NOTE(onboarding.tour-customize.description2): This string will be used in the customize tour description. %S is brandShortName
onboarding.tour-customize.description2=Put the tools you use most right at your fingertips. Drag, drop, and reorder %Ss toolbar and menu to fit your needs. Or choose a compact theme to make more room for tabbed browsing.
onboarding.tour-customize.button=Show Customize in Menu
onboarding.notification.onboarding-tour-customize.title=Rearrange your toolbar.
# LOCALIZATION NOTE(onboarding.notification.onboarding-tour-customize.message): %S is brandShortName.
# LOCALIZATION NOTE(onboarding.notification.onboarding-tour-customize.message): This string will be used in the notification message for Customize tour. %S is brandShortName.
onboarding.notification.onboarding-tour-customize.message=Put the tools you use most right at your fingertips. Add more options to your toolbar. Or select a theme to make %S reflect your personality.
onboarding.tour-default-browser=Default Browser
onboarding.tour-default-browser.title=Were there for you.
# LOCALIZATION NOTE(onboarding.tour-default-browser.description): This string will be used in the default browser tour description. %1$S is brandShortName
onboarding.tour-default-browser.description=Love %1$S? Set it as your default browser. Then when you open a link from another application, %1$S has you covered.
# LOCALIZATION NOTE(onboarding.tour-default-browser.title2): This string will be used in the default browser tour title. %S is brandShortName
onboarding.tour-default-browser.title2=Make %S your go-to browser.
# LOCALIZATION NOTE(onboarding.tour-default-browser.description2): This string will be used in the default browser tour description. %1$S is brandShortName
onboarding.tour-default-browser.description2=Love %1$S? Set it as your default browser. Open a link from another application, and %1$S will be there for you.
# LOCALIZATION NOTE(onboarding.tour-default-browser.button): Label for a button to open the OS default browser settings where it's not possible to set the default browser directly. (OSX, Linux, Windows 8 and higher)
onboarding.tour-default-browser.button=Open Default Browser Settings
# LOCALIZATION NOTE(onboarding.tour-default-browser.win7.button): Label for a button to directly set the default browser (Windows 7). %S is brandShortName
onboarding.tour-default-browser.win7.button=Make %S Your Default Browser
# LOCALIZATION NOTE(onboarding.notification.onboarding-tour-default-browser.title): %S is brandShortName.
# LOCALIZATION NOTE(onboarding.notification.onboarding-tour-default-browser.title): This string will be used in the notification message for the default browser tour. %S is brandShortName.
onboarding.notification.onboarding-tour-default-browser.title=Make %S your go-to browser.
# LOCALIZATION NOTE(onboarding.notification.onboarding-tour-default-browser.message): %1$S is brandShortName
onboarding.notification.onboarding-tour-default-browser.message=It doesnt take much to get the most from %1$S. Just set %1$S as your default browser and put control, customization, and protection on autopilot.
onboarding.tour-sync=Firefox Sync
onboarding.tour-sync.title=Sync brings it all together.
onboarding.tour-sync.description=Access your bookmarks and passwords on any device. You can even send a tab from your laptop to your phone! Better yet, you can choose what you sync and what you dont.
onboarding.tour-sync2=Sync
onboarding.tour-sync.title2=Pick up where you left off.
onboarding.tour-sync.description2=Sync makes it easy to access bookmarks, passwords, and even open tabs on all your devices. Sync also gives you control of the types of information you want, and dont want, to share.
# LOCALIZATION NOTE(onboarding.tour-sync.form.title): This string is displayed
# as a title and followed by onboarding.tour-sync.form.description.
# Your translation should be consistent with the form displayed in
# about:accounts when signing up to Firefox Account.
onboarding.tour-sync.form.title=Create a Firefox Account
# LOCALIZATION NOTE(onboarding.tour-sync.form.description): The description
# continues after onboarding.tour-sync.form.title to create a complete sentence.
# If it's not possible for your locale, you can translate this string as

4
browser/extensions/screenshots/bootstrap.js поставляемый
Просмотреть файл

@ -81,9 +81,7 @@ function shutdown(data, reason) { // eslint-disable-line no-unused-vars
id: ADDON_ID,
resourceURI: addonResourceURI
});
if (webExtension.started) {
stop(webExtension, reason);
}
stop(webExtension, reason);
}
function install(data, reason) {} // eslint-disable-line no-unused-vars

Просмотреть файл

@ -107,11 +107,6 @@
; Register AccessibleHandler.dll with COM (this writes to HKLM)
${RegisterAccessibleHandler}
!ifndef HAVE_64BIT_BUILD
; Clean up any IAccessible registry corruption
${FixCorruptOleAccRegistration}
!endif
!ifdef MOZ_MAINTENANCE_SERVICE
Call IsUserAdmin
Pop $R0
@ -927,49 +922,6 @@
!macroend
!define RegisterAccessibleHandler "!insertmacro RegisterAccessibleHandler"
!ifndef HAVE_64BIT_BUILD
!define IID_IAccessible "{618736E0-3C3D-11CF-810C-00AA00389B71}"
!define CLSID_UniversalMarshaler "{00020404-0000-0000-C000-000000000046}"
!define OleAccTypeLib "{1EA4DBF0-3C3B-11CF-810C-00AA00389B71}"
!define OleAccTypeLibVersion "1.1"
Function FixCorruptOleAccRegistration
Push $0
; Read IAccessible's ProxyStubClsid32. If it is not CLSID_UniversalMarshaler
; then we must be running Windows 10 Creators Update which does not use a
; type library.
ReadRegStr $0 HKCR "Interface\${IID_IAccessible}\ProxyStubClsid32" ""
${Unless} "$0" == "${CLSID_UniversalMarshaler}"
Pop $0
Return
${EndIf}
Push $1
; IAccessible is using the universal marshler, therefore we expect a valid
; TypeLib key to exist
ClearErrors
ReadRegStr $0 HKCR "Interface\${IID_IAccessible}\TypeLib" ""
ReadRegStr $1 HKCR "Interface\${IID_IAccessible}\TypeLib" "Version"
ReadRegStr $0 HKCR "TypeLib\$0\$1\0\win32" ""
Pop $1
${IfNot} ${Errors}
${AndIf} ${FileExists} "$0"
Pop $0
Return
${EndIf}
Pop $0
; Some third-party code has previously overridden system typelibs
; with their own but did not clean itself up during uninstall.
; Revert to the system typelib.
WriteRegStr HKCR "Interface\${IID_IAccessible}\TypeLib" "" "${OleAccTypeLib}"
WriteRegStr HKCR "Interface\${IID_IAccessible}\TypeLib" "Version" "${OleAccTypeLibVersion}"
FunctionEnd
!define FixCorruptOleAccRegistration "Call FixCorruptOleAccRegistration"
!endif
; Removes various registry entries for reasons noted below (does not use SHCTX).
!macro RemoveDeprecatedKeys
StrCpy $0 "SOFTWARE\Classes"

Просмотреть файл

@ -856,6 +856,17 @@ you can use these alternative items. Otherwise, their values should be empty. -
<!ENTITY customizeMode.lwthemes.menuGetMore "Get More Themes">
<!ENTITY customizeMode.lwthemes.menuGetMore.accessKey "G">
<!ENTITY customizeMode.emptyOverflowList.description "Drag and drop items here to keep them within reach but out of your toolbar…">
<!ENTITY customizeMode.uidensity "Density">
<!ENTITY customizeMode.uidensity.menuNormal.label "Normal">
<!ENTITY customizeMode.uidensity.menuNormal.tooltip "Normal">
<!ENTITY customizeMode.uidensity.menuNormal.accessKey "N">
<!ENTITY customizeMode.uidensity.menuCompact.label "Compact">
<!ENTITY customizeMode.uidensity.menuCompact.tooltip "Compact">
<!ENTITY customizeMode.uidensity.menuCompact.accessKey "C">
<!ENTITY customizeMode.uidensity.menuTouch.label "Touch">
<!ENTITY customizeMode.uidensity.menuTouch.tooltip "Touch">
<!ENTITY customizeMode.uidensity.menuTouch.accessKey "T">
<!ENTITY customizeMode.uidensity.autoTouchMode.checkbox.label "Use Touch for Tablet Mode">
<!ENTITY getUserMedia.selectCamera.label "Camera to share:">
<!ENTITY getUserMedia.selectCamera.accesskey "C">

Просмотреть файл

@ -0,0 +1,5 @@
# 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/.
uiDensity.menu-button-touch.acceltext=Tablet Mode Enabled

Просмотреть файл

@ -25,6 +25,9 @@
locale/browser/browser.properties (%chrome/browser/browser.properties)
locale/browser/customizableui/customizableWidgets.properties (%chrome/browser/customizableui/customizableWidgets.properties)
locale/browser/lightweightThemes.properties (%chrome/browser/lightweightThemes.properties)
#ifdef XP_WIN
locale/browser/uiDensity.properties (%chrome/browser/uiDensity.properties)
#endif
locale/browser/newTab.dtd (%chrome/browser/newTab.dtd)
locale/browser/newTab.properties (%chrome/browser/newTab.properties)
locale/browser/pageInfo.dtd (%chrome/browser/pageInfo.dtd)

Просмотреть файл

@ -35,6 +35,7 @@
}
%endif
%endif
%endif
/* Go button */

Просмотреть файл

@ -245,19 +245,28 @@
height: 16px;
}
#customization-uidensity-button > .box-inherit > .box-inherit > .button-text,
#customization-lwtheme-button > .box-inherit > .box-inherit > .button-text {
/* Sadly, button.css thinks its margins are perfect for everyone. */
margin-inline-start: 6px !important;
}
#customization-uidensity-button > .box-inherit > .box-inherit > .button-icon,
#customization-lwtheme-button > .box-inherit > .box-inherit > .button-icon {
width: 16px;
height: 16px;
border-radius: 2px;
background-image: url("chrome://browser/content/default-theme-icon.svg");
background-size: contain;
}
#customization-lwtheme-button > .box-inherit > .box-inherit > .button-icon {
background-image: url("chrome://browser/content/default-theme-icon.svg");
}
#customization-uidensity-button > .box-inherit > .box-inherit > .button-icon {
background-image: url("chrome://browser/skin/customizableui/density-normal.svg");
}
%ifndef MOZ_PHOTON_THEME
#main-window[customize-entered] #customization-panel-container {
background-image: url("chrome://browser/skin/customizableui/customizeMode-separatorHorizontal.png"),
@ -407,18 +416,38 @@ toolbarpaletteitem[place="toolbar"]:not([mousedown="true"]):-moz-focusring {
margin-right: 0;
}
#customization-uidensity-touch-spacer {
border-top: 1px solid ThreeDLightShadow;
margin: 0 -10px 10px;
}
#customization-uidensity-autotouchmode-checkbox {
margin-bottom: 10px;
}
#customization-uidensity-menu > .panel-arrowcontainer > .panel-arrowcontent,
#customization-lwtheme-menu > .panel-arrowcontainer > .panel-arrowcontent {
-moz-box-orient: vertical;
}
#customization-lwtheme-menu > .panel-arrowcontainer > .panel-arrowcontent {
/* Make the panel padding uniform across all platforms due to the
styling of the section headers and footer. */
padding: 10px;
}
#customization-uidensity-menu > .panel-arrowcontainer > .panel-arrowcontent {
padding: 5px 10px;
}
.customization-uidensity-menu-button > .menu-iconic-left > .menu-iconic-icon,
.customization-lwtheme-menu-theme > .toolbarbutton-icon {
width: 32px;
height: 32px;
margin: 5px;
}
.customization-uidensity-menu-button,
.customization-lwtheme-menu-theme {
-moz-appearance: none;
border: 1px solid transparent;
@ -433,21 +462,34 @@ toolbarpaletteitem[place="toolbar"]:not([mousedown="true"]):-moz-focusring {
list-style-image: url(chrome://browser/content/default-theme-icon.svg);
}
#customization-uidensity-menu-button-normal {
list-style-image: url("chrome://browser/skin/customizableui/density-normal.svg");
}
#customization-uidensity-menu-button-compact {
list-style-image: url("chrome://browser/skin/customizableui/density-compact.svg");
}
#customization-uidensity-menu-button-touch {
list-style-image: url("chrome://browser/skin/customizableui/density-touch.svg");
}
.customization-uidensity-menu-button[active="true"],
.customization-uidensity-menu-button:hover,
.customization-lwtheme-menu-theme[active="true"],
.customization-lwtheme-menu-theme:hover {
background-color: var(--arrowpanel-dimmed);
border-color: var(--panel-separator-color);
}
.customization-uidensity-menu-button[active="true"],
.customization-uidensity-menu-button:hover:active,
.customization-lwtheme-menu-theme[active="true"],
.customization-lwtheme-menu-theme:hover:active {
background-color: var(--arrowpanel-dimmed-further);
}
.customization-lwtheme-menu-theme > .toolbarbutton-icon {
margin: 5px;
}
.customization-uidensity-menu-button > .menu-iconic-text,
.customization-lwtheme-menu-theme > .toolbarbutton-text {
text-align: start;
}

Просмотреть файл

@ -0,0 +1,21 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<rect x="1" y="1" width="30" height="30" rx="2" ry="2" fill="#fff"/>
<path d="M3 1h26c1.1 0 2 .479 2 1.071V14H1V2.071C1 1.479 1.9 1 3 1z" fill="#f9f9fa"/>
<path d="M1 13.5h30" fill="none" stroke="#adadb3"/>
<rect x="1" y="1" width="30" height="30" rx="2" ry="2" fill="none" stroke="#adadb3" stroke-width="2"/>
<g opacity=".8" fill="none" stroke="#0c0c0d" stroke-linecap="round">
<path d="M3.5 7.5h6"/>
<path stroke-linejoin="round" d="M6.5 4.5l-3 3 3 3"/>
</g>
<g opacity=".8" fill="none" stroke="#0c0c0d" stroke-linecap="round">
<path d="M18.5 7.5h-6"/>
<path stroke-linejoin="round" d="M15.5 4.5l3 3-3 3"/>
</g>
<g opacity=".8" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round">
<path d="M28.5 4.5v2h-2"/>
<path d="M27.623 9.614a3.03 3.03 0 1 1 .636-3.324"/>
</g>
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Просмотреть файл

@ -0,0 +1,18 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<rect x="1" y="1" width="30" height="30" rx="2" ry="2" fill="#fff"/>
<path d="M3 1h26c1.1 0 2 .627 2 1.4V18H1V2.4C1 1.627 1.9 1 3 1z" fill="#f9f9fa"/>
<g opacity=".8" fill="none" stroke="#0c0c0d" stroke-linecap="round">
<path d="M25.5 9.5h-6"/>
<path stroke-linejoin="round" d="M22.5 6.5l3 3-3 3"/>
</g>
<path d="M2 17.5h29" fill="none" stroke="#adadb3"/>
<rect x="1" y="1" width="30" height="30" rx="2" ry="2" fill="none" stroke="#adadb3" stroke-width="2"/>
<circle cx="9.5" cy="9.5" r="6" fill="#fff" stroke="#adadb3"/>
<g opacity=".8" fill="none" stroke="#0c0c0d" stroke-linecap="round">
<path d="M6.5 9.5h6"/>
<path stroke-linejoin="round" d="M9.5 6.5l-3 3 3 3"/>
</g>
</svg>

После

Ширина:  |  Высота:  |  Размер: 1010 B

Просмотреть файл

@ -0,0 +1,14 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<rect x="1" y="1" width="30" height="30" rx="2" ry="2" fill="#fff"/>
<path d="M2.942 1.073l26-.145a1.88 1.88 0 0 1 2.01 1.718l.108 19.27-30 .168L.951 2.813a1.88 1.88 0 0 1 1.991-1.74z" fill="#f9f9fa"/>
<path d="M1 21.5h30" fill="none" stroke="#adadb3"/>
<rect x="1" y="1" width="30" height="30" rx="2" ry="2" fill="none" stroke="#adadb3" stroke-width="2"/>
<circle cx="15.5" cy="11.5" r="8" fill="#fff" stroke="#adadb3"/>
<g opacity=".8" fill="none" stroke="#0c0c0d" stroke-linecap="round">
<path d="M12.5 11.5h6"/>
<path stroke-linejoin="round" d="M15.5 8.5l-3 3 3 3"/>
</g>
</svg>

После

Ширина:  |  Высота:  |  Размер: 901 B

Просмотреть файл

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="context-fill" d="M14.5,15h-13C0.7,15,0,14.3,0,13.5v-11C0,1.7,0.7,1,1.5,1h13C15.3,1,16,1.7,16,2.5v11C16,14.3,15.3,15,14.5,15z M2,6v6
c0,0.5,0.4,1,0.9,1c0,0,0.1,0,0.1,0h7V5H3C2.5,5,2,5.4,2,5.9C2,5.9,2,6,2,6z M8.5,2C8.2,2,8,2.2,8,2.4c0,0,0,0,0,0.1
C8,2.8,8.2,3,8.5,3S9,2.8,9,2.5C9,2.2,8.8,2,8.5,2C8.5,2,8.5,2,8.5,2z M10.4,2c-0.3,0-0.5,0.2-0.5,0.4c0,0,0,0,0,0.1
c0,0.3,0.2,0.5,0.5,0.5c0.3,0,0.5-0.2,0.5-0.4c0,0,0,0,0-0.1C10.9,2.2,10.7,2,10.4,2C10.4,2,10.4,2,10.4,2z M13.5,2h-1
C12.2,2,12,2.2,12,2.4c0,0,0,0,0,0.1C12,2.8,12.2,3,12.4,3c0,0,0,0,0.1,0h1C13.8,3,14,2.8,14,2.6c0,0,0,0,0-0.1
C14,2.2,13.8,2,13.5,2C13.5,2,13.5,2,13.5,2z M14,6c0-0.5-0.4-1-0.9-1c0,0-0.1,0-0.1,0h-1v8h1c0.5,0,1-0.4,1-0.9c0,0,0-0.1,0-0.1V6z
"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.0 KiB

Просмотреть файл

@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="context-fill" d="M14.5 15h-13A1.538 1.538 0 0 1 0 13.5v-11A1.538 1.538 0 0 1 1.5 1h13A1.538 1.538 0 0 1 16 2.5v11a1.538 1.538 0 0 1-1.5 1.5zM2 6v6a.945.945 0 0 0 1 1h7V5H3a.945.945 0 0 0-1 1zm6.5-4a.472.472 0 0 0-.5.5.5.5 0 0 0 1 0 .472.472 0 0 0-.5-.5zm1.9 0a.472.472 0 0 0-.5.5.536.536 0 0 0 .5.5.472.472 0 0 0 .5-.5.472.472 0 0 0-.5-.5zm3.1 0h-1a.472.472 0 0 0-.5.5.472.472 0 0 0 .5.5h1a.472.472 0 0 0 .5-.5.472.472 0 0 0-.5-.5zm.5 4a.945.945 0 0 0-1-1h-1v8h1a.945.945 0 0 0 1-1z"/>
<path fill="context-fill" d="M14.5,15h-13C0.7,15,0,14.3,0,13.5v-11C0,1.7,0.7,1,1.5,1h13C15.3,1,16,1.7,16,2.5v11C16,14.3,15.3,15,14.5,15z M2,6v6
c0,0.5,0.4,1,0.9,1c0,0,0.1,0,0.1,0h1V5H3C2.5,5,2,5.4,2,5.9C2,5.9,2,6,2,6z M8.5,2C8.2,2,8,2.2,8,2.4c0,0,0,0,0,0.1
C8,2.8,8.2,3,8.5,3S9,2.8,9,2.5C9,2.2,8.8,2,8.5,2C8.5,2,8.5,2,8.5,2z M10.4,2c-0.3,0-0.5,0.2-0.5,0.4c0,0,0,0,0,0.1
c0,0.3,0.2,0.5,0.5,0.5c0.3,0,0.5-0.2,0.5-0.4c0,0,0,0,0-0.1C10.9,2.2,10.7,2,10.4,2C10.4,2,10.4,2,10.4,2z M13.5,2h-1
C12.2,2,12,2.2,12,2.4c0,0,0,0,0,0.1C12,2.8,12.2,3,12.4,3c0,0,0,0,0.1,0h1C13.8,3,14,2.8,14,2.6c0,0,0,0,0-0.1
C14,2.2,13.8,2,13.5,2C13.5,2,13.5,2,13.5,2z M14,6c0-0.5-0.4-1-0.9-1c0,0-0.1,0-0.1,0H6v8h7c0.5,0,1-0.4,1-0.9c0,0,0-0.1,0-0.1V6z"
/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 803 B

После

Ширина:  |  Высота:  |  Размер: 1.0 KiB

Просмотреть файл

@ -657,14 +657,15 @@ groupbox {
menulist[indicator=true] > menupopup menuitem:not([image]) > .menu-iconic-left {
display: -moz-box;
width: 10px;
width: 8px;
min-width: auto; /* Override the min-width defined in menu.css */
height: 10px;
margin-inline-end: 6px;
}
menulist[indicator=true] > menupopup menuitem[indicator=true]:not([image]) > .menu-iconic-left {
background-image: url(chrome://global/skin/icons/search-arrow-indicator.svg);
background-repeat: no-repeat;
background-size: 12px 10px;
menulist[indicator=true] > menupopup menuitem[indicator=true]:not([image]) > .menu-iconic-left > .menu-iconic-icon {
list-style-image: url(chrome://global/skin/icons/search-arrow-indicator.svg);
width: 8px;
height: 10px;
margin: 0;
}

Просмотреть файл

@ -39,6 +39,9 @@
#ifdef MOZ_PHOTON_THEME
skin/classic/browser/customizableui/empty-overflow-panel.png (../shared/customizableui/empty-overflow-panel.png)
skin/classic/browser/customizableui/empty-overflow-panel@2x.png (../shared/customizableui/empty-overflow-panel@2x.png)
skin/classic/browser/customizableui/density-compact.svg (../shared/customizableui/density-compact.svg)
skin/classic/browser/customizableui/density-normal.svg (../shared/customizableui/density-normal.svg)
skin/classic/browser/customizableui/density-touch.svg (../shared/customizableui/density-touch.svg)
#else
skin/classic/browser/customizableui/customize-illustration.png (../shared/customizableui/customize-illustration.png)
skin/classic/browser/customizableui/customize-illustration@2x.png (../shared/customizableui/customize-illustration@2x.png)
@ -163,6 +166,7 @@
skin/classic/browser/settings.svg (../shared/icons/settings.svg)
skin/classic/browser/share.svg (../shared/icons/share.svg)
skin/classic/browser/sidebars.svg (../shared/icons/sidebars.svg)
skin/classic/browser/sidebars-right.svg (../shared/icons/sidebars-right.svg)
skin/classic/browser/stop.svg (../shared/icons/stop.svg)
skin/classic/browser/sync.svg (../shared/icons/sync.svg)
skin/classic/browser/synced-tabs.svg (../shared/icons/synced-tabs.svg)

Просмотреть файл

@ -628,7 +628,8 @@
border-radius: 3px;
margin: 3px;
margin-inline-start: 9px;
transition: max-width 300ms;
transition: max-width 100ms;
padding: 0 5px;
}
.restore-tabs-button:hover {
@ -660,5 +661,4 @@
.restore-tabs-button > .toolbarbutton-text {
display: -moz-box;
padding: 0 5px;
}

Просмотреть файл

@ -194,12 +194,12 @@ toolbar:not([brighttext]) #bookmarks-menu-button[cui-areatype="toolbar"][starred
}
#sidebar-button[cui-areatype="toolbar"] {
list-style-image: url("chrome://browser/skin/sidebars.svg");
list-style-image: url("chrome://browser/skin/sidebars-right.svg");
}
#sidebar-button[cui-areatype="toolbar"]:-moz-locale-dir(ltr):not([positionend]),
#sidebar-button[cui-areatype="toolbar"]:-moz-locale-dir(rtl)[positionend] {
transform: scaleX(-1);
list-style-image: url("chrome://browser/skin/sidebars.svg");
}
#panic-button[cui-areatype="toolbar"] {

Просмотреть файл

@ -121,6 +121,11 @@
to { filter: blur(5px) sepia(60%) saturate(30%); }
}
@keyframes anim-filter-drop-shadow {
from { filter: drop-shadow(10px 10px 10px rgb(0, 255, 0)); }
to { filter: drop-shadow(50px 30px 10px rgb(255, 0, 0)); }
}
@keyframes anim-text-shadow {
to { text-shadow: none; }
}
@ -563,15 +568,32 @@ test(function(t) {
}, 'KeyframeEffectReadOnly.getKeyframes() returns expected values for ' +
'animations with filter properties and missing keyframes');
test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-filter-drop-shadow 100s';
var frames = getKeyframes(div);
assert_equals(frames.length, 2, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "ease",
filter: "drop-shadow(10px 10px 10px rgb(0, 255, 0))" },
{ offset: 1, computedOffset: 1, easing: "ease",
filter: "drop-shadow(50px 30px 10px rgb(255, 0, 0))" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getKeyframes() returns expected values for ' +
'animation with drop-shadow of filter property');
// Gecko-specific test case: We are specifically concerned here that the
// computed value for text-shadow and a "none" specified on a keyframe
// are correctly represented.
test(function(t) {
if (!isServoEnabled()) {
// FIXME : Bug 1374564 : the serialization of text-shadow is wrong on gecko
return;
}
var div = addDiv(t);
div.style.textShadow = '1px 1px 2px rgb(0, 0, 0), ' +

Просмотреть файл

@ -340,14 +340,3 @@ function addSVGElement(target, tag, attrs) {
target.appendChild(element);
return element;
}
/*
* Return true if servo is enabled.
*/
function isServoEnabled() {
try {
return SpecialPowers.getBoolPref('layout.css.servo.enabled');
} catch(e) {
return false;
}
}

Просмотреть файл

@ -453,6 +453,9 @@ class CGDOMJSClass(CGThing):
traceHook = 'nullptr'
reservedSlots = slotCount
if self.descriptor.interface.hasProbablyShortLivingWrapper():
if not self.descriptor.wrapperCache:
raise TypeError("Need a wrapper cache to support nursery "
"allocation of DOM objects")
classFlags += " | JSCLASS_SKIP_NURSERY_FINALIZE"
if self.descriptor.interface.getExtendedAttribute("NeedResolve"):
@ -12452,6 +12455,22 @@ class CGDOMJSProxyHandler_isCallable(ClassMethod):
""")
class CGDOMJSProxyHandler_canNurseryAllocate(ClassMethod):
"""
Override the default canNurseryAllocate in BaseProxyHandler, for cases when
we should be nursery-allocated.
"""
def __init__(self):
ClassMethod.__init__(self, "canNurseryAllocate", "bool",
[],
virtual=True, override=True, const=True)
def getBody(self):
return dedent("""
return true;
""")
class CGDOMJSProxyHandler(CGClass):
def __init__(self, descriptor):
assert (descriptor.supportsIndexedProperties() or
@ -12488,6 +12507,11 @@ class CGDOMJSProxyHandler(CGClass):
if descriptor.operations['LegacyCaller']:
methods.append(CGDOMJSProxyHandler_call())
methods.append(CGDOMJSProxyHandler_isCallable())
if descriptor.interface.hasProbablyShortLivingWrapper():
if not descriptor.wrapperCache:
raise TypeError("Need a wrapper cache to support nursery "
"allocation of DOM objects")
methods.append(CGDOMJSProxyHandler_canNurseryAllocate())
if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
parentClass = 'ShadowingDOMProxyHandler'

Просмотреть файл

@ -2,7 +2,7 @@ default-preferences pref(dom.forms.number,true) pref(dom.forms.datetime,true)
fuzzy-if(skiaContent,1,3) needs-focus == input-load.html input-ref.html
fuzzy-if(skiaContent,1,3) needs-focus == input-create.html input-ref.html
fuzzy-if(skiaContent,1,3) needs-focus skip-if(styloVsGecko) == input-number.html input-number-ref.html
fuzzy-if(skiaContent,1,3) needs-focus fails-if(styloVsGecko) == input-time.html input-time-ref.html
fuzzy-if(skiaContent,1,3) needs-focus == input-time.html input-time-ref.html
fuzzy-if(skiaContent,1,3) needs-focus == button-load.html button-ref.html
fuzzy-if(skiaContent,1,3) needs-focus == button-create.html button-ref.html
fuzzy-if(skiaContent,1,3) needs-focus == textarea-load.html textarea-ref.html

Просмотреть файл

@ -1520,13 +1520,26 @@ StartMacOSContentSandbox()
PR_GetEnv("MOZ_SANDBOX_LOGGING");
info.appPath.assign(appPath.get());
info.appBinaryPath.assign(appBinaryPath.get());
if (developer_repo_dir != nullptr) {
info.appDir.assign(developer_repo_dir);
} else {
info.appDir.assign(appDir.get());
}
info.appDir.assign(appDir.get());
info.appTempDir.assign(tempDirPath.get());
// These paths are used to whitelist certain directories used by the testing
// system. They should not be considered a public API, and are only intended
// for use in automation.
nsAdoptingCString testingReadPath1 =
Preferences::GetCString("security.sandbox.content.mac.testing_read_path1");
if (!testingReadPath1.IsEmpty()) {
info.testingReadPath1.assign(testingReadPath1.get());
}
nsAdoptingCString testingReadPath2 =
Preferences::GetCString("security.sandbox.content.mac.testing_read_path2");
if (!testingReadPath2.IsEmpty()) {
info.testingReadPath2.assign(testingReadPath2.get());
}
if (developer_repo_dir) {
info.testingReadPath3.assign(developer_repo_dir);
}
if (profileDir) {
info.hasSandboxedProfile = true;
info.profileDir.assign(profileDirPath.get());

Просмотреть файл

@ -784,7 +784,6 @@ skip-if = toolkit == 'android' # android(bug 1232305)
[test_loop.html]
skip-if = toolkit == 'android' # bug 1242112, android(bug 1232305)
[test_media_selection.html]
skip-if = toolkit == 'android' # bug 1372457
[test_media_sniffer.html]
skip-if = android_version == '15' || android_version == '17' # android(bug 1232305)
[test_mediarecorder_avoid_recursion.html]

Просмотреть файл

@ -376,6 +376,7 @@ var pedanticChecks = report => {
+ stat.framesEncoded);
}
} else if (stat.type == "candidate-pair") {
info("candidate-pair is: " + JSON.stringify(stat));
//
// Required fields
//
@ -411,7 +412,10 @@ var pedanticChecks = report => {
+ stat.writable);
// state
if (stat.state == "succeeded") {
if (stat.state == "succeeded" &&
stat.selected !== undefined &&
stat.selected) {
info("candidate-pair state is succeeded and selected is true");
// nominated
ok(stat.nominated,
stat.type + ".nominated is true. value="
@ -438,10 +442,23 @@ var pedanticChecks = report => {
+ stat.lastPacketReceivedTimestamp);
} else {
info("candidate-pair is _not_ both state == succeeded and selected");
// nominated
ok(!stat.nominated,
stat.type + ".nominated is false. value="
ok(stat.nominated !== undefined,
stat.type + ".nominated exists. value="
+ stat.nominated);
ok(stat.bytesSent !== undefined,
stat.type + ".bytesSent exists. value="
+ stat.bytesSent);
ok(stat.bytesReceived !== undefined,
stat.type + ".bytesReceived exists. value="
+ stat.bytesReceived);
ok(stat.lastPacketSentTimestamp !== undefined,
stat.type + ".lastPacketSentTimestamp exists. value="
+ stat.lastPacketSentTimestamp);
ok(stat.lastPacketReceivedTimestamp !== undefined,
stat.type + ".lastPacketReceivedTimestamp exists. value="
+ stat.lastPacketReceivedTimestamp);
}
@ -450,9 +467,10 @@ var pedanticChecks = report => {
//
// selected
ok(stat.selected === undefined ||
((stat.state == "succeeded" && stat.selected == true) ||
(stat.selected == false)),
stat.type + ".selected is undefined or true. value="
((stat.state == "succeeded" && stat.selected) ||
!stat.selected),
stat.type + ".selected is undefined, true when state is succeeded, "
+ "or false. value="
+ stat.selected);
}

Просмотреть файл

@ -10,6 +10,7 @@
* liability, trademark and document use rules apply.
*/
[ProbablyShortLivingWrapper]
interface NodeList {
getter Node? item(unsigned long index);
readonly attribute unsigned long length;

Просмотреть файл

@ -168,7 +168,7 @@ void
nsXBLPrototypeResources::ComputeServoStyleSet(nsPresContext* aPresContext)
{
mServoStyleSet.reset(new ServoStyleSet());
mServoStyleSet->Init(aPresContext);
mServoStyleSet->Init(aPresContext, nullptr);
for (StyleSheet* sheet : mStyleSheetList) {
MOZ_ASSERT(sheet->IsServo(),
"This should only be called with Servo-flavored style backend!");

Просмотреть файл

@ -5,16 +5,23 @@
#include "TexturePoolOGL.h"
#include <stdlib.h> // for malloc
#include "GLContext.h" // for GLContext
#include "mozilla/Logging.h"
#include "mozilla/Monitor.h" // for Monitor, MonitorAutoLock
#include "mozilla/mozalloc.h" // for operator delete, etc
#include "mozilla/layers/CompositorThread.h"
#include "nsDebug.h" // for NS_ASSERTION, NS_ERROR, etc
#include "nsDeque.h" // for nsDeque
#include "nsThreadUtils.h"
#ifdef MOZ_WIDGET_ANDROID
#include "GeneratedJNINatives.h"
#endif
#define TEXTURE_POOL_SIZE 10
static const unsigned int TEXTURE_POOL_SIZE = 10;
static const unsigned int TEXTURE_REFILL_THRESHOLD = TEXTURE_POOL_SIZE / 2;
static mozilla::LazyLogModule gTexturePoolLog("TexturePoolOGL");
#define LOG(arg, ...) MOZ_LOG(gTexturePoolLog, mozilla::LogLevel::Debug, ("TexturePoolOGL::%s: " arg, __func__, ##__VA_ARGS__))
namespace mozilla {
namespace gl {
@ -24,6 +31,15 @@ static GLContext* sActiveContext = nullptr;
static Monitor* sMonitor = nullptr;
static nsDeque* sTextures = nullptr;
enum class PoolState : uint8_t {
NOT_INITIALIZE,
INITIALIZED,
SHUTDOWN
};
static PoolState sPoolState = PoolState::NOT_INITIALIZE;
static bool sHasPendingFillTask = false;
#ifdef MOZ_WIDGET_ANDROID
class GeckoSurfaceTextureSupport final
@ -37,9 +53,27 @@ public:
#endif // MOZ_WIDGET_ANDROID
void TexturePoolOGL::MaybeFillTextures()
{
if (sTextures->GetSize() < TEXTURE_REFILL_THRESHOLD &&
!sHasPendingFillTask) {
LOG("need to refill the texture pool.");
sHasPendingFillTask = true;
MessageLoop* loop = mozilla::layers::CompositorThreadHolder::Loop();
MOZ_ASSERT(loop);
loop->PostTask(
NS_NewRunnableFunction(
"TexturePoolOGL::MaybeFillTextures",
[] () {
TexturePoolOGL::Fill(sActiveContext);
}));
}
}
GLuint TexturePoolOGL::AcquireTexture()
{
NS_ASSERTION(sMonitor, "not initialized");
MOZ_ASSERT(sPoolState != PoolState::NOT_INITIALIZE, "not initialized");
MOZ_ASSERT(sPoolState != PoolState::SHUTDOWN, "should not be called after shutdown");
MonitorAutoLock lock(*sMonitor);
@ -72,6 +106,9 @@ GLuint TexturePoolOGL::AcquireTexture()
delete popped;
NS_ASSERTION(texture, "Failed to retrieve texture from pool");
MaybeFillTextures();
LOG("remaining textures num = %zu", sTextures->GetSize());
}
return texture;
@ -93,10 +130,12 @@ static void Clear()
void TexturePoolOGL::Fill(GLContext* aContext)
{
NS_ASSERTION(aContext, "NULL GLContext");
NS_ASSERTION(sMonitor, "not initialized");
MOZ_ASSERT(aContext, "NULL GLContext");
MOZ_ASSERT(sPoolState != PoolState::NOT_INITIALIZE, "not initialized");
MOZ_ASSERT(sPoolState != PoolState::SHUTDOWN, "should not be called after shutdown");
MonitorAutoLock lock(*sMonitor);
sHasPendingFillTask = false;
if (sActiveContext != aContext) {
Clear();
@ -116,6 +155,7 @@ void TexturePoolOGL::Fill(GLContext* aContext)
sTextures->Push((void*) texture);
}
LOG("fill texture pool to %d", TEXTURE_POOL_SIZE);
sMonitor->NotifyAll();
}
@ -126,6 +166,7 @@ GLContext* TexturePoolOGL::GetGLContext()
void TexturePoolOGL::Init()
{
MOZ_ASSERT(sPoolState != PoolState::INITIALIZED);
sMonitor = new Monitor("TexturePoolOGL.sMonitor");
sTextures = new nsDeque();
@ -134,10 +175,13 @@ void TexturePoolOGL::Init()
GeckoSurfaceTextureSupport::Init();
}
#endif
sPoolState = PoolState::INITIALIZED;
}
void TexturePoolOGL::Shutdown()
{
MOZ_ASSERT(sPoolState == PoolState::INITIALIZED);
sPoolState = PoolState::SHUTDOWN;
delete sMonitor;
delete sTextures;
}

Просмотреть файл

@ -32,6 +32,9 @@ public:
// Clears all internal data structures in preparation for shutdown
static void Shutdown();
private:
// These methods are used to refill textures to avoid pool becomes dry
static void MaybeFillTextures();
};
} // namespace gl

Просмотреть файл

@ -713,6 +713,13 @@ CheckProxyFlags()
((Flags >> JSCLASS_RESERVED_SLOTS_SHIFT) & JSCLASS_RESERVED_SLOTS_MASK)
<= shadow::Object::MAX_FIXED_SLOTS,
"ProxyValueArray size must not exceed max JSObject size");
// Proxies must not have the JSCLASS_SKIP_NURSERY_FINALIZE flag set: they
// always have finalizers, and whether they can be nursery allocated is
// controlled by the canNurseryAllocate() method on the proxy handler.
static_assert(!(Flags & JSCLASS_SKIP_NURSERY_FINALIZE),
"Proxies must not use JSCLASS_SKIP_NURSERY_FINALIZE; use "
"the canNurseryAllocate() proxy handler method instead.");
return Flags;
}

Просмотреть файл

@ -221,6 +221,9 @@ function treatAsSafeArgument(entry, varName, csuName)
["Gecko_nsStyleSVG_CopyContextProperties", "aDst", null],
["Gecko_nsStyleFont_PrefillDefaultForGeneric", "aFont", null],
["Gecko_nsStyleSVG_SetContextPropertiesLength", "aSvg", null],
["Gecko_ClearAlternateValues", "aFont", null],
["Gecko_AppendAlternateValues", "aFont", null],
["Gecko_CopyAlternateValuesFrom", "aDest", null],
];
for (var [entryMatch, varMatch, csuMatch] of whitelist) {
assert(entryMatch || varMatch || csuMatch);

Просмотреть файл

@ -0,0 +1,64 @@
var g_foo = "foo";
var g_bar = "bar";
// Define base class with a read-only and a writable data property
class Base
{
}
Object.defineProperty(Base.prototype, "foo", { value: "Base", writable: true });
Object.defineProperty(Base.prototype, "bar", { value: "Base", writable: false });
// Test various cases that should throw during SETPROP_SUPER
class Derived extends Base
{
// ECMA-2018 9.1.9.1, step 4.a
testReadonly() {
super.bar = "Derived";
}
testReadonlyElem() {
super[g_bar] = "Derived";
}
// ECMA-2018 9.1.9.1, step 4.b
testPrimitiveReceiver() {
super.foo = "Derived";
}
testPrimitiveReceiverElem() {
super[g_foo] = "Derived";
}
// ECMA-2018 9.1.9.1, step 4.d.i
testAccessorShadow() {
Object.defineProperty(this, "foo", { get: function() { } });
super.foo = "Derived";
}
testAccessorShadowElem() {
Object.defineProperty(this, "foo", { get: function() { } });
super[g_foo] = "Derived";
}
// ECMA-2018 9.1.9.1, step 4.d.ii
testReadonlyShadow() {
Object.defineProperty(this, "foo", { writable: false });
super.foo = "Derived";
}
testReadonlyShadowElem() {
Object.defineProperty(this, "foo", { writable: false });
super[g_foo] = "Derived";
}
}
for (let i = 0; i < 10; ++i) {
var cnt = 0;
try { new Derived().testReadonly(); } catch(e) { cnt++; }
try { new Derived().testReadonlyElem(); } catch(e) { cnt++; }
try { Derived.prototype.testPrimitiveReceiver.call(null); } catch(e) { cnt++; }
try { Derived.prototype.testPrimitiveReceiverElem.call(null); } catch(e) { cnt++; }
try { new Derived().testAccessorShadow(); } catch(e) { cnt++; }
try { new Derived().testAccessorShadowElem(); } catch(e) { cnt++; }
try { new Derived().testReadonlyShadow(); } catch(e) { cnt++; }
try { new Derived().testReadonlyShadowElem(); } catch(e) { cnt++; }
assertEq(cnt, 8);
}

Просмотреть файл

@ -0,0 +1,67 @@
class Base
{
set setter(val) {
this.set_val = val;
this.set_this = this;
}
}
Base.prototype.prop = "Base";
class Derived extends Base
{
set setter(val) { super.setter = val; }
setelem(pname, val) { super[pname] = val; }
}
// Test SETPROP_SUPER invoke setters correctly
function testSetterChain() {
let d = new Derived();
for (let i = 0; i < 10; ++i)
{
d.setter = i;
assertEq(d.set_val, i);
assertEq(d.set_this, d);
}
}
function testSetterChainElem() {
let d = new Derived();
for (let i = 0; i < 10; ++i)
{
d.setelem("setter", i);
assertEq(d.set_val, i);
assertEq(d.set_this, d);
}
}
// Test that SETPROP_SUPER modifies |this| and not home object
function testSuperSetProp() {
let d = new Derived();
for (let i = 0; i < 10; ++i)
{
d.prop = i;
assertEq(d.prop, i);
assertEq(d.hasOwnProperty("prop"), true);
assertEq(Derived.prototype.prop, "Base");
}
}
function testSuperSetPropElem() {
let d = new Derived();
for (let i = 0; i < 10; ++i)
{
d.setelem("prop", i);
assertEq(d.prop, i);
assertEq(d.hasOwnProperty("prop"), true);
assertEq(Derived.prototype.prop, "Base");
}
}
testSetterChain();
testSetterChainElem();
testSuperSetProp();
testSuperSetPropElem();

Просмотреть файл

@ -2348,6 +2348,47 @@ BaselineCompiler::emit_JSOP_STRICTSETELEM()
return emit_JSOP_SETELEM();
}
typedef bool (*SetObjectElementFn)(JSContext*, HandleObject, HandleValue,
HandleValue, HandleValue, bool);
static const VMFunction SetObjectElementInfo =
FunctionInfo<SetObjectElementFn>(js::SetObjectElement, "SetObjectElement");
bool
BaselineCompiler::emit_JSOP_SETELEM_SUPER()
{
bool strict = IsCheckStrictOp(JSOp(*pc));
// Incoming stack is |propval, receiver, obj, rval|. We need to shuffle
// stack to leave rval when operation is complete.
// Pop rval into R0, then load propval into R1 and replace with rval.
frame.popRegsAndSync(1);
masm.loadValue(frame.addressOfStackValue(frame.peek(-3)), R1);
masm.storeValue(R0, frame.addressOfStackValue(frame.peek(-3)));
prepareVMCall();
pushArg(Imm32(strict));
masm.loadValue(frame.addressOfStackValue(frame.peek(-2)), R2);
pushArg(R2); // receiver
pushArg(R0); // rval
pushArg(R1); // propval
masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg());
pushArg(R0.scratchReg()); // obj
if (!callVM(SetObjectElementInfo))
return false;
frame.popn(2);
return true;
}
bool
BaselineCompiler::emit_JSOP_STRICTSETELEM_SUPER()
{
return emit_JSOP_SETELEM_SUPER();
}
typedef bool (*DeleteElementFn)(JSContext*, HandleValue, HandleValue, bool*);
static const VMFunction DeleteElementStrictInfo
= FunctionInfo<DeleteElementFn>(DeleteElementJit<true>, "DeleteElementStrict");
@ -2546,6 +2587,46 @@ BaselineCompiler::emit_JSOP_STRICTSETGNAME()
return emit_JSOP_SETPROP();
}
typedef bool (*SetPropertySuperFn)(JSContext*, HandleObject, HandleValue,
HandlePropertyName, HandleValue, bool);
static const VMFunction SetPropertySuperInfo =
FunctionInfo<SetPropertySuperFn>(js::SetPropertySuper, "SetPropertySuper");
bool
BaselineCompiler::emit_JSOP_SETPROP_SUPER()
{
bool strict = IsCheckStrictOp(JSOp(*pc));
// Incoming stack is |receiver, obj, rval|. We need to shuffle stack to
// leave rval when operation is complete.
// Pop rval into R0, then load receiver into R1 and replace with rval.
frame.popRegsAndSync(1);
masm.loadValue(frame.addressOfStackValue(frame.peek(-2)), R1);
masm.storeValue(R0, frame.addressOfStackValue(frame.peek(-2)));
prepareVMCall();
pushArg(Imm32(strict));
pushArg(R0); // rval
pushArg(ImmGCPtr(script->getName(pc)));
pushArg(R1); // receiver
masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg());
pushArg(R0.scratchReg()); // obj
if (!callVM(SetPropertySuperInfo))
return false;
frame.pop();
return true;
}
bool
BaselineCompiler::emit_JSOP_STRICTSETPROP_SUPER()
{
return emit_JSOP_SETPROP_SUPER();
}
bool
BaselineCompiler::emit_JSOP_GETPROP()
{

Просмотреть файл

@ -123,6 +123,8 @@ namespace jit {
_(JSOP_DELELEM) \
_(JSOP_STRICTDELELEM) \
_(JSOP_GETELEM_SUPER) \
_(JSOP_SETELEM_SUPER) \
_(JSOP_STRICTSETELEM_SUPER) \
_(JSOP_IN) \
_(JSOP_HASOWN) \
_(JSOP_GETGNAME) \
@ -138,6 +140,8 @@ namespace jit {
_(JSOP_DELPROP) \
_(JSOP_STRICTDELPROP) \
_(JSOP_GETPROP_SUPER) \
_(JSOP_SETPROP_SUPER) \
_(JSOP_STRICTSETPROP_SUPER) \
_(JSOP_LENGTH) \
_(JSOP_GETBOUNDNAME) \
_(JSOP_GETALIASEDVAR) \

Просмотреть файл

@ -2868,18 +2868,14 @@ CASE(JSOP_STRICTSETPROP_SUPER)
static_assert(JSOP_SETPROP_SUPER_LENGTH == JSOP_STRICTSETPROP_SUPER_LENGTH,
"setprop-super and strictsetprop-super must be the same size");
ReservedRooted<Value> receiver(&rootValue0, REGS.sp[-3]);
ReservedRooted<JSObject*> obj(&rootObject0, &REGS.sp[-2].toObject());
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
ReservedRooted<jsid> id(&rootId0, NameToId(script->getName(REGS.pc)));
ObjectOpResult result;
if (!SetProperty(cx, obj, id, rval, receiver, result))
goto error;
ReservedRooted<PropertyName*> name(&rootName0, script->getName(REGS.pc));
bool strict = JSOp(*REGS.pc) == JSOP_STRICTSETPROP_SUPER;
if (!result.checkStrictErrorOrWarning(cx, obj, id, strict))
if (!SetPropertySuper(cx, obj, receiver, name, rval, strict))
goto error;
REGS.sp[-3] = REGS.sp[-1];
@ -2953,14 +2949,13 @@ CASE(JSOP_STRICTSETELEM_SUPER)
static_assert(JSOP_SETELEM_SUPER_LENGTH == JSOP_STRICTSETELEM_SUPER_LENGTH,
"setelem-super and strictsetelem-super must be the same size");
ReservedRooted<jsid> id(&rootId0);
FETCH_ELEMENT_ID(-4, id);
ReservedRooted<Value> index(&rootValue1, REGS.sp[-4]);
ReservedRooted<Value> receiver(&rootValue0, REGS.sp[-3]);
ReservedRooted<JSObject*> obj(&rootObject1, &REGS.sp[-2].toObject());
HandleValue value = REGS.stackHandleAt(-1);
bool strict = JSOp(*REGS.pc) == JSOP_STRICTSETELEM_SUPER;
if (!SetObjectElementOperation(cx, obj, id, value, receiver, strict))
if (!SetObjectElement(cx, obj, index, value, receiver, strict))
goto error;
REGS.sp[-4] = value;
REGS.sp -= 3;
@ -4623,6 +4618,16 @@ js::SetObjectElement(JSContext* cx, HandleObject obj, HandleValue index, HandleV
return SetObjectElementOperation(cx, obj, id, value, receiver, strict, script, pc);
}
bool
js::SetObjectElement(JSContext* cx, HandleObject obj, HandleValue index, HandleValue value,
HandleValue receiver, bool strict)
{
RootedId id(cx);
if (!ToPropertyKey(cx, index, &id))
return false;
return SetObjectElementOperation(cx, obj, id, value, receiver, strict);
}
bool
js::SetObjectElement(JSContext* cx, HandleObject obj, HandleValue index, HandleValue value,
HandleValue receiver, bool strict, HandleScript script, jsbytecode* pc)
@ -5257,3 +5262,15 @@ js::ThrowInitializedThis(JSContext* cx, AbstractFramePtr frame)
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_REINIT_THIS);
return false;
}
bool
js::SetPropertySuper(JSContext* cx, HandleObject obj, HandleValue receiver,
HandlePropertyName name, HandleValue rval, bool strict)
{
RootedId id(cx, NameToId(name));
ObjectOpResult result;
if (!SetProperty(cx, obj, id, rval, receiver, result))
return false;
return result.checkStrictErrorOrWarning(cx, obj, id, strict);
}

Просмотреть файл

@ -438,6 +438,9 @@ SetObjectElement(JSContext* cx, HandleObject obj, HandleValue index, HandleValue
bool strict, HandleScript script, jsbytecode* pc);
bool
SetObjectElement(JSContext* cx, HandleObject obj, HandleValue index, HandleValue value,
HandleValue receiver, bool strict);
bool
SetObjectElement(JSContext* cx, HandleObject obj, HandleValue index, HandleValue value,
HandleValue receiver, bool strict, HandleScript script, jsbytecode* pc);
@ -598,6 +601,10 @@ HomeObjectSuperBase(JSContext* cx, HandleObject homeObj);
JSObject*
SuperFunOperation(JSContext* cx, HandleObject callee);
bool
SetPropertySuper(JSContext* cx, HandleObject obj, HandleValue receiver,
HandlePropertyName id, HandleValue rval, bool strict);
} /* namespace js */
#endif /* vm_Interpreter_h */

Просмотреть файл

@ -971,14 +971,7 @@ PresShell::Init(nsIDocument* aDocument,
// calling Init, since various subroutines need to find the style set off
// the PresContext during initialization.
mStyleSet = aStyleSet;
mStyleSet->Init(aPresContext);
// Set up our style rule observer. We don't need to inform a ServoStyleSet
// of the binding manager because it gets XBL style sheets from bindings
// in a different way.
if (mStyleSet->IsGecko()) {
mStyleSet->AsGecko()->SetBindingManager(mDocument->BindingManager());
}
mStyleSet->Init(aPresContext, mDocument->BindingManager());
// Notify our prescontext that it now has a compatibility mode. Note that
// this MUST happen after we set up our style set but before we create any

Просмотреть файл

@ -97,20 +97,17 @@ inDOMUtils::GetAllStyleSheets(nsIDOMDocument *aDocument, uint32_t *aLength,
for (int32_t i = 0; i < styleSet->SheetCount(sheetType); i++) {
sheets.AppendElement(styleSet->StyleSheetAt(sheetType, i));
}
if (styleSet->IsGecko()) {
AutoTArray<CSSStyleSheet*, 32> xblSheetArray;
styleSet->AsGecko()->AppendAllXBLStyleSheets(xblSheetArray);
// The XBL stylesheet array will quite often be full of duplicates. Cope:
nsTHashtable<nsPtrHashKey<CSSStyleSheet>> sheetSet;
for (CSSStyleSheet* sheet : xblSheetArray) {
if (!sheetSet.Contains(sheet)) {
sheetSet.PutEntry(sheet);
sheets.AppendElement(sheet);
}
AutoTArray<StyleSheet*, 32> xblSheetArray;
styleSet->AsGecko()->AppendAllXBLStyleSheets(xblSheetArray);
// The XBL stylesheet array will quite often be full of duplicates. Cope:
nsTHashtable<nsPtrHashKey<StyleSheet>> sheetSet;
for (StyleSheet* sheet : xblSheetArray) {
if (!sheetSet.Contains(sheet)) {
sheetSet.PutEntry(sheet);
sheets.AppendElement(sheet);
}
} else {
NS_WARNING("stylo: XBL style sheets not supported yet");
}
}

Просмотреть файл

@ -83,11 +83,11 @@ fuzzy-if(gtkWidget,6,26200) == 28811-2b.html 28811-2-ref.html # Bug 1128229
== 76331-1.html 76331-1-ref.html
== 81947-1.html 81947-ref.html
== 82711-1.html 82711-1-ref.html
fails-if(styloVsGecko) == 82711-2.html 82711-2-ref.html
== 82711-2.html 82711-2-ref.html
== 82711-3.html 82711-3-ref.html
!= 82711-1-ref.html 82711-2-ref.html
!= 82711-1-ref.html 82711-3-ref.html
fails-if(styloVsGecko) != 82711-2-ref.html 82711-3-ref.html
!= 82711-2-ref.html 82711-3-ref.html
fuzzy-if(Android,4,1) == 84400-1.html 84400-1-ref.html
fuzzy-if(skiaContent,2,13) == 84400-2.html 84400-2-ref.html
== 97777-1.html 97777-1-ref.html
@ -661,7 +661,7 @@ fails-if(Android) fuzzy-if(skiaContent&&!Android,2,40) == 373381-2.html 373381-2
fails-if(Android) random-if(d2d) == 373381-3.html 373381-3-ref.html
fails-if(Android) == 373381-4.html 373381-4-ref.html
== 373383-1.html 373383-1-ref.html
fails-if(styloVsGecko) == 373433-1.html 373433-1-ref.html
== 373433-1.html 373433-1-ref.html
== 373533-1.xhtml about:blank
== 373533-2.xhtml about:blank
== 373533-3.xhtml about:blank
@ -1811,7 +1811,7 @@ fuzzy-if(skiaContent,1,5) == 956513-1.svg 956513-1-ref.svg
fuzzy-if(skiaContent,1,80) == 961887-1.html 961887-1-ref.html
== 961887-2.html 961887-2-ref.html
== 961887-3.html 961887-3-ref.html
pref(layout.css.overflow-clip-box.enabled,true) fuzzy(50,145) fuzzy-if(asyncPan&&!layersGPUAccelerated,102,3712) fails-if(styloVsGecko||stylo) == 966992-1.html 966992-1-ref.html
pref(layout.css.overflow-clip-box.enabled,true) fuzzy(50,145) fuzzy-if(asyncPan&&!layersGPUAccelerated,102,3712) == 966992-1.html 966992-1-ref.html
skip-if(Android) == 966510-1.html 966510-1-ref.html # scrollable elements other than the root probably won't work well on android until bug 776030 is fixed
skip-if(Android) == 966510-2.html 966510-2-ref.html # same as above
fuzzy-if(skiaContent,1,123) == 978911-1.svg 978911-1-ref.svg
@ -1952,7 +1952,7 @@ fuzzy-if(skiaContent,1,1) == 1202512-2.html 1202512-2-ref.html
== 1209994-3.html 1209994-3-ref.html
== 1209994-4.html 1209994-4-ref.html
== 1222226-1.html 1222226-1-ref.html
pref(layout.css.overflow-clip-box.enabled,true) fails-if(styloVsGecko||stylo) == 1226278.html 1226278-ref.html
pref(layout.css.overflow-clip-box.enabled,true) == 1226278.html 1226278-ref.html
== 1230466.html about:blank
random-if(gtkWidget) != 1238243-1.html 1238243-1-notref.html # may fail on Linux, depending on Korean fonts available
== 1238243-2.html 1238243-2-ref.html

Просмотреть файл

@ -0,0 +1,7 @@
<!DOCTYPE html>
<style>
a:visited { color: green }
input { color: inherit }
input::placeholder { color: green }
</style>
<a href="visited-page.html"><input placeholder="This should be green"></a>

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE html>
<style>
a:visited { color: green }
input { color: inherit }
</style>
<a href="visited-page.html"><input placeholder="This should be green"></a>

Просмотреть файл

@ -13,7 +13,7 @@
include pagination/reftest.list
# Tests for cross-axis alignment (align-self / align-items properties)
fails fails-if(styloVsGecko) == flexbox-align-self-baseline-horiz-2.xhtml flexbox-align-self-baseline-horiz-2-ref.xhtml # bug 793456, and possibly others
fails-if(!styloVsGecko) == flexbox-align-self-baseline-horiz-2.xhtml flexbox-align-self-baseline-horiz-2-ref.xhtml # bug 793456, and possibly others
# This one fails on windows R (but not Ru, strangely) and GTK.
# On Windows R and GTK, the single-line <label> flex item has a different
# background size in test vs. ref

Просмотреть файл

@ -88,9 +88,9 @@ fuzzy-if(gtkWidget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(f
fuzzy-if(gtkWidget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-textarea-contents-at-1.html threshold-textarea-contents-at-1-ref.html
fuzzy-if(gtkWidget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-textarea-contents-at-2.html threshold-textarea-contents-at-2-ref.html
fuzzy-if(gtkWidget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-input-text-contents-under-1.html threshold-input-text-contents-under-1.html
fuzzy-if(gtkWidget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) fails-if(styloVsGecko) == threshold-input-text-contents-under-2.html threshold-input-text-contents-under-2.html
fuzzy-if(gtkWidget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-input-text-contents-under-2.html threshold-input-text-contents-under-2.html
fuzzy-if(gtkWidget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-input-text-contents-at-1.html threshold-input-text-contents-at-1-ref.html
fuzzy-if(gtkWidget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) fails-if(styloVsGecko) == threshold-input-text-contents-at-2.html threshold-input-text-contents-at-2-ref.html
fuzzy-if(gtkWidget,1,10) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-input-text-contents-at-2.html threshold-input-text-contents-at-2-ref.html
test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-listbox-contents-under-1.html threshold-select-listbox-contents-under-1.html
test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-listbox-contents-under-2.html threshold-select-listbox-contents-under-2.html
test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,100) == threshold-select-listbox-contents-at-1.html threshold-select-listbox-contents-at-1-ref.html

Просмотреть файл

@ -1,10 +1,10 @@
== bounds-1.html bounds-1-ref.html
fuzzy-if(asyncPan&&!layersGPUAccelerated,140,111) == size-1.html size-1-ref.html
== size-2.html size-2-ref.html
fails-if(styloVsGecko) HTTP(..) == baseline-1.html baseline-1-ref.html
HTTP(..) == baseline-1.html baseline-1-ref.html
HTTP(..) == centering-1.xul centering-1-ref.xul
== dynamic-height-1.xul dynamic-height-1-ref.xul
fuzzy-if(skiaContent,1,500) needs-focus == select.html select-ref.html
== intrinsic-size.html intrinsic-size-ref.html
fails-if(styloVsGecko) == line-height-0.5.html line-height-1.0.html
== line-height-0.5.html line-height-1.0.html
!= line-height-1.5.html line-height-1.0.html

Просмотреть файл

@ -16,7 +16,7 @@
== placeholder-3.html placeholder-overridden-ref.html
== placeholder-4.html placeholder-overridden-ref.html
== placeholder-5.html placeholder-visible-ref.html
fuzzy-if(winWidget,160,10) fuzzy-if(Android,1,1) fuzzy-if(asyncPan&&!layersGPUAccelerated,146,317) fuzzy-if(OSX==1010&&browserIsRemote,1,8) fails-if(styloVsGecko) == placeholder-6.html placeholder-overflow-ref.html
fuzzy-if(winWidget,160,10) fuzzy-if(Android,1,1) fuzzy-if(asyncPan&&!layersGPUAccelerated,146,317) fuzzy-if(OSX==1010&&browserIsRemote,1,8) == placeholder-6.html placeholder-overflow-ref.html
skip-if(Android&&asyncPan) == placeholder-6-textarea.html placeholder-overflow-textarea-ref.html
# needs-focus == placeholder-7.html placeholder-focus-ref.html
# needs-focus == placeholder-8.html placeholder-focus-ref.html

Просмотреть файл

@ -10,5 +10,5 @@ fuzzy-if(skiaContent,1,1) == rtl.html rtl-dynamic-attr.html
fuzzy-if(skiaContent,1,1) == rtl.html rtl-dynamic-style.html
== rtl.html in-dynamic-rtl-doc.html
fuzzy-if(skiaContent,1,3) == setvalue-framereconstruction-1.html setvalue-framereconstruction-ref.html
fuzzy-if(asyncPan&&!layersGPUAccelerated,102,4168) fails-if(styloVsGecko||stylo) == padding-scrollbar-placement.html padding-scrollbar-placement-ref.html
fuzzy-if(asyncPan&&!layersGPUAccelerated,102,4168) == padding-scrollbar-placement.html padding-scrollbar-placement-ref.html
== various-cols.html various-cols-ref.html

Просмотреть файл

@ -151,7 +151,7 @@ HTTP(..) == zwnj-02.xhtml zwnj-02-ref.xhtml # HTTP(..) for ../filters.svg
== initial-zwj-1.html initial-zwj-1-ref.html
== cgj-01.html cgj-01-ref.html
== 444656.html 444656-ref.html
fails-if(styloVsGecko) == 449555-1.html 449555-1-ref.html
== 449555-1.html 449555-1-ref.html
== 467722.html 467722-ref.html
fuzzy-if(skiaContent,1,600) HTTP(..) == 475092-sub.html 475092-ref.html
fails-if(Android) fuzzy-if(skiaContent&&!Android,90,3100) HTTP(..) == 475092-pos.html 475092-sub.html # bug 482596

Просмотреть файл

@ -247,6 +247,12 @@ Gecko_ElementState(RawGeckoElementBorrowed aElement)
return aElement->StyleState().ServoValue();
}
EventStates::ServoType
Gecko_DocumentState(const nsIDocument* aDocument)
{
return aDocument->ThreadSafeGetDocumentState().ServoValue();
}
bool
Gecko_IsTextNode(RawGeckoNodeBorrowed aNode)
{
@ -819,7 +825,7 @@ Gecko_GetXMLLangValue(RawGeckoElementBorrowed aElement)
}
nsIDocument::DocumentTheme
Gecko_GetDocumentLWTheme(const nsIDocument *aDocument)
Gecko_GetDocumentLWTheme(const nsIDocument* aDocument)
{
return aDocument->ThreadSafeGetDocumentLWTheme();
}
@ -1238,6 +1244,29 @@ Gecko_nsFont_Destroy(nsFont* aDest)
}
void
Gecko_ClearAlternateValues(nsFont* aFont, size_t aLength)
{
aFont->alternateValues.Clear();
aFont->alternateValues.SetCapacity(aLength);
}
void
Gecko_AppendAlternateValues(nsFont* aFont, uint32_t aAlternateName, nsIAtom* aAtom)
{
aFont->alternateValues.AppendElement(gfxAlternateValue {
aAlternateName,
nsDependentAtomString(aAtom)
});
}
void
Gecko_CopyAlternateValuesFrom(nsFont* aDest, const nsFont* aSrc)
{
aDest->alternateValues.Clear();
aDest->alternateValues.AppendElements(aSrc->alternateValues);
}
void
Gecko_SetImageOrientation(nsStyleVisibility* aVisibility,
double aRadians, bool aFlip)
@ -1435,6 +1464,7 @@ Gecko_CreateGradient(uint8_t aShape,
uint8_t aSize,
bool aRepeating,
bool aLegacySyntax,
bool aMozLegacySyntax,
uint32_t aStopCount)
{
nsStyleGradient* result = new nsStyleGradient();
@ -1443,6 +1473,7 @@ Gecko_CreateGradient(uint8_t aShape,
result->mSize = aSize;
result->mRepeating = aRepeating;
result->mLegacySyntax = aLegacySyntax;
result->mMozLegacySyntax = aMozLegacySyntax;
result->mAngle.SetNoneValue();
result->mBgPosX.SetNoneValue();

Просмотреть файл

@ -154,6 +154,7 @@ void Gecko_LoadStyleSheet(mozilla::css::Loader* loader,
// Selector Matching.
uint64_t Gecko_ElementState(RawGeckoElementBorrowed element);
uint64_t Gecko_DocumentState(const nsIDocument* aDocument);
bool Gecko_IsTextNode(RawGeckoNodeBorrowed node);
bool Gecko_IsRootElement(RawGeckoElementBorrowed element);
bool Gecko_MatchesElement(mozilla::CSSPseudoClassType type, RawGeckoElementBorrowed element);
@ -164,7 +165,7 @@ bool Gecko_MatchLang(RawGeckoElementBorrowed element,
nsIAtom* override_lang, bool has_override_lang,
const char16_t* value);
nsIAtom* Gecko_GetXMLLangValue(RawGeckoElementBorrowed element);
nsIDocument::DocumentTheme Gecko_GetDocumentLWTheme(const nsIDocument *aDocument);
nsIDocument::DocumentTheme Gecko_GetDocumentLWTheme(const nsIDocument* aDocument);
// Attributes.
#define SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(prefix_, implementor_) \
@ -275,6 +276,11 @@ void Gecko_nsFont_InitSystem(nsFont* dst, int32_t font_id,
const nsStyleFont* font, RawGeckoPresContextBorrowed pres_context);
void Gecko_nsFont_Destroy(nsFont* dst);
// Font variant alternates
void Gecko_ClearAlternateValues(nsFont* font, size_t length);
void Gecko_AppendAlternateValues(nsFont* font, uint32_t alternate_name, nsIAtom* atom);
void Gecko_CopyAlternateValuesFrom(nsFont* dest, const nsFont* src);
// Visibility style
void Gecko_SetImageOrientation(nsStyleVisibility* aVisibility,
double aRadians,
@ -312,6 +318,7 @@ nsStyleGradient* Gecko_CreateGradient(uint8_t shape,
uint8_t size,
bool repeating,
bool legacy_syntax,
bool moz_legacy_syntax,
uint32_t stops);
// list-style-image style.

Просмотреть файл

@ -63,10 +63,11 @@ ServoStyleSet::~ServoStyleSet()
}
void
ServoStyleSet::Init(nsPresContext* aPresContext)
ServoStyleSet::Init(nsPresContext* aPresContext, nsBindingManager* aBindingManager)
{
mPresContext = aPresContext;
mRawSet.reset(Servo_StyleSet_Init(aPresContext));
mBindingManager = aBindingManager;
mPresContext->DeviceContext()->InitFontCache();
@ -862,6 +863,14 @@ ServoStyleSet::StyleSheetAt(SheetType aType,
return mSheets[aType][aIndex];
}
void
ServoStyleSet::AppendAllXBLStyleSheets(nsTArray<StyleSheet*>& aArray) const
{
if (mBindingManager) {
mBindingManager->AppendAllSheets(aArray);
}
}
nsresult
ServoStyleSet::RemoveDocStyleSheet(ServoStyleSheet* aSheet)
{

Просмотреть файл

@ -122,7 +122,7 @@ public:
ServoStyleSet();
~ServoStyleSet();
void Init(nsPresContext* aPresContext);
void Init(nsPresContext* aPresContext, nsBindingManager* aBindingManager);
void BeginShutdown();
void Shutdown();
@ -255,6 +255,8 @@ public:
int32_t SheetCount(SheetType aType) const;
ServoStyleSheet* StyleSheetAt(SheetType aType, int32_t aIndex) const;
void AppendAllXBLStyleSheets(nsTArray<StyleSheet*>& aArray) const;
template<typename Func>
void EnumerateStyleSheetArrays(Func aCallback) const {
for (const auto& sheetArray : mSheets) {
@ -624,6 +626,9 @@ private:
// Constructed lazily when requested by devtools.
RefPtr<ServoStyleRuleMap> mStyleRuleMap;
// This can be null if we are used to hold XBL style sheets.
RefPtr<nsBindingManager> mBindingManager;
static ServoStyleSet* sInServoTraversal;
};

Просмотреть файл

@ -326,7 +326,8 @@ ToPrimitive(nsCSSValue::Array* aArray)
static void
AppendCSSShadowValue(const nsCSSShadowItem *aShadow,
nsCSSValueList **&aResultTail)
nsCSSValueList **&aResultTail,
nsCSSPropertyID aProperty)
{
MOZ_ASSERT(aShadow, "shadow expected");
@ -335,9 +336,9 @@ AppendCSSShadowValue(const nsCSSShadowItem *aShadow,
arr->Item(0).SetIntegerCoordValue(aShadow->mXOffset);
arr->Item(1).SetIntegerCoordValue(aShadow->mYOffset);
arr->Item(2).SetIntegerCoordValue(aShadow->mRadius);
// NOTE: This code sometimes stores mSpread: 0 even when
// the parser would be required to leave it null.
arr->Item(3).SetIntegerCoordValue(aShadow->mSpread);
if (aProperty == eCSSProperty_box_shadow) {
arr->Item(3).SetIntegerCoordValue(aShadow->mSpread);
}
if (aShadow->mHasColor) {
arr->Item(4).SetColorValue(aShadow->mColor);
}
@ -886,7 +887,8 @@ GetNumberOrPercent(const nsCSSValue &aValue);
static bool
ComputeSingleShadowSquareDistance(const nsCSSValueList* aShadow1,
const nsCSSValueList* aShadow2,
double& aSquareDistance)
double& aSquareDistance,
nsCSSPropertyID aProperty)
{
MOZ_ASSERT(aShadow1->mValue.GetUnit() == eCSSUnit_Array, "wrong unit");
MOZ_ASSERT(aShadow2->mValue.GetUnit() == eCSSUnit_Array, "wrong unit");
@ -896,6 +898,11 @@ ComputeSingleShadowSquareDistance(const nsCSSValueList* aShadow1,
double squareDistance = 0.0;
// X, Y, Radius, Spread
for (size_t i = 0; i < 4; ++i) {
// Spread value is not necessary on text-shadow,
// so we skip the computing distance.
if (i == 3 && (aProperty != eCSSProperty_box_shadow)) {
continue;
}
MOZ_ASSERT(array1->Item(i).GetUnit() == eCSSUnit_Pixel,
"unexpected unit");
MOZ_ASSERT(array2->Item(i).GetUnit() == eCSSUnit_Pixel,
@ -1002,7 +1009,8 @@ ComputeFilterSquareDistance(const nsCSSValueList* aList1,
"drop-shadow filter func doesn't support lists");
if (!ComputeSingleShadowSquareDistance(func1.GetListValue(),
func2.GetListValue(),
aSquareDistance)) {
aSquareDistance,
eCSSProperty_filter)) {
return false;
}
break;
@ -1793,7 +1801,8 @@ StyleAnimationValue::ComputeDistance(nsCSSPropertyID aProperty,
while (shadow1) {
double squareDistance = 0.0;
if (!ComputeSingleShadowSquareDistance(shadow1, shadow2,
squareDistance)) {
squareDistance,
aProperty)) {
NS_ERROR("Unexpected ComputeSingleShadowSquareDistance failure; "
"why didn't we fail earlier, in AddWeighted calls above?");
}
@ -2036,7 +2045,8 @@ AppendToCSSValuePairList(UniquePtr<nsCSSValuePairList>& aHead,
static UniquePtr<nsCSSValueList>
AddWeightedShadowItems(double aCoeff1, const nsCSSValue &aValue1,
double aCoeff2, const nsCSSValue &aValue2,
ColorAdditionType aColorAdditionType)
ColorAdditionType aColorAdditionType,
nsCSSPropertyID aProperty)
{
// X, Y, Radius, Spread, Color, Inset
MOZ_ASSERT(aValue1.GetUnit() == eCSSUnit_Array,
@ -2048,6 +2058,9 @@ AddWeightedShadowItems(double aCoeff1, const nsCSSValue &aValue1,
RefPtr<nsCSSValue::Array> resultArray = nsCSSValue::Array::Create(6);
for (size_t i = 0; i < 4; ++i) {
// The text-shadow is not need to spread radius,
// So we skip this interpolation.
if (i == 3 && (aProperty != eCSSProperty_box_shadow)) continue;
AddCSSValuePixel(aCoeff1, array1->Item(i), aCoeff2, array2->Item(i),
resultArray->Item(i),
// blur radius must be nonnegative
@ -2231,7 +2244,8 @@ AddWeightedFilterFunctionImpl(double aCoeff1, const nsCSSValueList* aList1,
funcArg1.GetListValue()->mValue,
aCoeff2,
funcArg2.GetListValue()->mValue,
aColorAdditionType);
aColorAdditionType,
eCSSProperty_filter);
if (!shadowValue) {
return nullptr;
}
@ -2771,7 +2785,8 @@ AddWeightedShadowList(double aCoeff1,
const nsCSSValueList* aShadow1,
double aCoeff2,
const nsCSSValueList* aShadow2,
ColorAdditionType aColorAdditionType)
ColorAdditionType aColorAdditionType,
nsCSSPropertyID aProperty)
{
// This is implemented according to:
// http://dev.w3.org/csswg/css3-transitions/#animation-of-property-types-
@ -2783,7 +2798,8 @@ AddWeightedShadowList(double aCoeff1,
UniquePtr<nsCSSValueList> shadowValue =
AddWeightedShadowItems(aCoeff1, aShadow1->mValue,
aCoeff2, aShadow2->mValue,
aColorAdditionType);
aColorAdditionType,
aProperty);
if (!shadowValue) {
return nullptr;
}
@ -2809,7 +2825,7 @@ AddWeightedShadowList(double aCoeff1,
UniquePtr<nsCSSValueList> shadowValue =
AddWeightedShadowItems(longCoeff, longShadow->mValue,
0.0, longShadow->mValue,
aColorAdditionType);
aColorAdditionType, aProperty);
if (!shadowValue) {
return nullptr;
}
@ -3179,7 +3195,8 @@ StyleAnimationValue::AddWeighted(nsCSSPropertyID aProperty,
aValue1.GetCSSValueListValue(),
aCoeff2,
aValue2.GetCSSValueListValue(),
ColorAdditionType::Clamped);
ColorAdditionType::Clamped,
aProperty);
if (!result) {
return false;
}
@ -3332,7 +3349,8 @@ StyleAnimationValue::Accumulate(nsCSSPropertyID aProperty,
UniquePtr<nsCSSValueList> resultList =
AddWeightedShadowList(1.0, result.GetCSSValueListValue(),
aCount, aA.GetCSSValueListValue(),
ColorAdditionType::Unclamped);
ColorAdditionType::Unclamped,
aProperty);
if (resultList) {
result.SetAndAdoptCSSValueListValue(resultList.release(), eUnit_Shadow);
}
@ -4568,7 +4586,8 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty,
nsCSSShadowArray* shadowArray = filter.GetDropShadow();
MOZ_ASSERT(shadowArray->Length() == 1,
"expected exactly one shadow");
AppendCSSShadowValue(shadowArray->ShadowAt(0), tmpShadowResultTail);
AppendCSSShadowValue(shadowArray->ShadowAt(0),
tmpShadowResultTail, aProperty);
*shadowResult = *tmpShadowValue;
} else {
// We checked all possible nsStyleFilter types but
@ -4816,7 +4835,7 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty,
nsAutoPtr<nsCSSValueList> result;
nsCSSValueList **resultTail = getter_Transfers(result);
for (uint32_t i = 0, i_end = shadowArray->Length(); i < i_end; ++i) {
AppendCSSShadowValue(shadowArray->ShadowAt(i), resultTail);
AppendCSSShadowValue(shadowArray->ShadowAt(i), resultTail, aProperty);
}
aComputedValue.SetAndAdoptCSSValueListValue(result.forget(),
eUnit_Shadow);

Просмотреть файл

@ -25,6 +25,7 @@ class Element;
class ShadowRoot;
} // namespace dom
} // namespace mozilla
class nsBindingManager;
class nsCSSCounterStyleRule;
struct nsFontFaceRuleContainer;
class nsIAtom;
@ -109,7 +110,7 @@ public:
// nsStyleSet or ServoStyleSet. See corresponding comments in
// nsStyleSet.h for descriptions of these methods.
inline void Init(nsPresContext* aPresContext);
inline void Init(nsPresContext* aPresContext, nsBindingManager* aBindingManager);
inline void BeginShutdown();
inline void Shutdown();
inline bool GetAuthorStyleDisabled() const;
@ -152,6 +153,7 @@ public:
StyleSheet* aReferenceSheet);
inline int32_t SheetCount(SheetType aType) const;
inline StyleSheet* StyleSheetAt(SheetType aType, int32_t aIndex) const;
inline void AppendAllXBLStyleSheets(nsTArray<StyleSheet*>& aArray) const;
inline nsresult RemoveDocStyleSheet(StyleSheet* aSheet);
inline nsresult AddDocStyleSheet(StyleSheet* aSheet, nsIDocument* aDocument);
inline void RecordStyleSheetChange(StyleSheet* aSheet, StyleSheet::ChangeType);

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше