Merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Razvan Maries 2019-04-26 12:46:15 +03:00
Родитель 32567fa488 b8db7d0c1f
Коммит 444ee13e14
49 изменённых файлов: 1313 добавлений и 258 удалений

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

@ -175,8 +175,7 @@ CustomizeMode.prototype = {
async _updateThemeButtonIcon() {
let lwthemeButton = this.$("customization-lwtheme-button");
let lwthemeIcon = this.document.getAnonymousElementByAttribute(lwthemeButton,
"class", "button-icon");
let lwthemeIcon = lwthemeButton.icon;
let theme = (await AddonManager.getAddonsByTypes(["theme"])).find(addon => addon.isActive);
lwthemeIcon.style.backgroundImage = theme ? "url(" + theme.iconURL + ")" : "";
},

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

@ -15,8 +15,7 @@ add_task(async function() {
"Reset button should start out disabled");
let themesButton = document.getElementById("customization-lwtheme-button");
let themesButtonIcon = document.getAnonymousElementByAttribute(themesButton,
"class", "button-icon");
let themesButtonIcon = themesButton.icon;
let iconURL = themesButtonIcon.style.backgroundImage;
// If we've run other tests before, we might have set the image to the
// default theme's icon explicitly, otherwise it might be empty, in which

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

@ -27,7 +27,10 @@
</vbox>
<vbox>
<hbox flex="1">
<button id="containersAdd" oncommand="gContainersPane.onAddButtonCommand();" data-l10n-id="containers-add-button"/>
<button id="containersAdd"
is="highlightable-button"
oncommand="gContainersPane.onAddButtonCommand();"
data-l10n-id="containers-add-button"/>
</hbox>
</vbox>
</groupbox>

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

@ -5,6 +5,20 @@
/* import-globals-from extensionControlled.js */
/* import-globals-from preferences.js */
// A tweak to the standard <button> CE to use textContent on the <label>
// inside the button, which allows the text to be highlighted when the user
// is searching.
const MozButton = customElements.get("button");
class HighlightableButton extends MozButton {
static get inheritedAttributes() {
return Object.assign({}, super.inheritedAttributes, {
".button-text": "text=label,accesskey,crop",
});
}
}
customElements.define("highlightable-button", HighlightableButton, {extends: "button"});
var gSearchResultsPane = {
listSearchTooltips: new Set(),
listSearchMenuitemIndicators: new Set(),
@ -332,6 +346,7 @@ var gSearchResultsPane = {
async searchWithinNode(nodeObject, searchPhrase) {
let matchesFound = false;
if (nodeObject.childElementCount == 0 ||
nodeObject.tagName == "button" ||
nodeObject.tagName == "label" ||
nodeObject.tagName == "description" ||
nodeObject.tagName == "menulist") {
@ -404,8 +419,7 @@ var gSearchResultsPane = {
this.listSearchMenuitemIndicators.add(menulist);
}
if ((nodeObject.tagName == "button" ||
nodeObject.tagName == "menulist" ||
if ((nodeObject.tagName == "menulist" ||
nodeObject.tagName == "menuitem") &&
(labelResult || valueResult || keywordsResult)) {
nodeObject.setAttribute("highlightable", "true");

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

@ -12,6 +12,7 @@
data-category="paneHome">
<html:h1 style="-moz-box-flex: 1;" data-l10n-id="pane-home-title"/>
<button id="restoreDefaultHomePageBtn"
is="highlightable-button"
class="homepage-button check-home-page-controlled"
data-preference-related="browser.startup.homepage"
data-l10n-id="home-restore-defaults"
@ -51,6 +52,7 @@
autocompletesearch="unifiedcomplete" />
<hbox class="homepage-buttons">
<button id="useCurrentBtn"
is="highlightable-button"
flex="1"
class="homepage-button check-home-page-controlled"
data-l10n-id="use-current-pages"
@ -58,6 +60,7 @@
disabled="true"
preference="pref.browser.homepage.disable_button.current_page"/>
<button id="useBookmarkBtn"
is="highlightable-button"
flex="1"
class="homepage-button check-home-page-controlled"
data-l10n-id="choose-bookmark"
@ -86,6 +89,7 @@
align="center" hidden="true" class="extension-controlled">
<description control="disableHomePageExtension" flex="1" />
<button id="disableHomePageExtension"
is="highlightable-button"
class="extension-controlled-button accessory-button"
data-l10n-id="disable-extension" />
</hbox>
@ -93,6 +97,7 @@
align="center" hidden="true" class="extension-controlled">
<description control="disableNewTabExtension" flex="1" />
<button id="disableNewTabExtension"
is="highlightable-button"
class="extension-controlled-button accessory-button"
data-l10n-id="disable-extension" />
</hbox>

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

@ -48,6 +48,7 @@
<image class="face-sad"/>
<label id="isNotDefaultLabel" flex="1" data-l10n-id="is-not-default"/>
<button id="setDefaultButton"
is="highlightable-button"
class="accessory-button"
data-l10n-id="set-as-my-default-browser"
preference="pref.general.disable_button.default_browser"/>
@ -95,6 +96,7 @@
align="center" class="extension-controlled">
<description control="disableContainersExtension" flex="1" />
<button id="disableContainersExtension"
is="highlightable-button"
class="extension-controlled-button accessory-button"
data-l10n-id="disable-extension" />
</hbox>
@ -109,6 +111,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="browserContainersSettings"
is="highlightable-button"
class="accessory-button"
data-l10n-id="browser-containers-settings"
search-l10n-ids="containers-add-button.label,
@ -176,6 +179,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="advancedFonts"
is="highlightable-button"
class="accessory-button"
icon="select-font"
data-l10n-id="advanced-fonts"
@ -248,6 +252,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="colors"
is="highlightable-button"
class="accessory-button"
icon="select-color"
data-l10n-id="colors-settings"
@ -280,6 +285,7 @@
<menupopup/>
</menulist>
<button id="manageBrowserLanguagesButton"
is="highlightable-button"
class="accessory-button"
data-l10n-id="manage-browser-languages-button"
oncommand="gMainPane.showBrowserLanguages({search: false})"/>
@ -295,6 +301,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="chooseLanguage"
is="highlightable-button"
class="accessory-button"
data-l10n-id="choose-button"
search-l10n-ids="
@ -324,6 +331,7 @@
</hbox>
</hbox>
<button id="translateButton"
is="highlightable-button"
class="accessory-button"
data-l10n-id="translate-exceptions"/>
</hbox>
@ -357,6 +365,7 @@
readonly="true"
aria-labelledby="saveTo"/>
<button id="chooseFolder"
is="highlightable-button"
class="accessory-button"
data-l10n-id="download-choose-folder"/>
</hbox>
@ -431,6 +440,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<vbox>
<button id="showUpdateHistory"
is="highlightable-button"
class="accessory-button"
data-l10n-id="update-history"
preference="app.update.disable_button.showUpdateHistory"
@ -447,18 +457,21 @@
<hbox id="checkForUpdates" align="start">
<spacer flex="1"/>
<button id="checkForUpdatesButton"
is="highlightable-button"
data-l10n-id="update-checkForUpdatesButton"
oncommand="gAppUpdater.checkForUpdates();"/>
</hbox>
<hbox id="downloadAndInstall" align="start">
<spacer flex="1"/>
<button id="downloadAndInstallButton"
is="highlightable-button"
oncommand="gAppUpdater.startDownload();"/>
<!-- label and accesskey will be filled by JS -->
</hbox>
<hbox id="apply" align="start">
<spacer flex="1"/>
<button id="updateButton"
is="highlightable-button"
data-l10n-id="update-updateButton"
oncommand="gAppUpdater.buttonRestartAfterDownload();"/>
</hbox>
@ -467,6 +480,7 @@
<label data-l10n-id="update-checkingForUpdates"></label>
<spacer flex="1"/>
<button data-l10n-id="update-checkForUpdatesButton"
is="highlightable-button"
disabled="true"/>
</hbox>
<hbox id="downloading" align="start" data-l10n-id="update-downloading">
@ -483,12 +497,14 @@
</label>
<spacer flex="1"/>
<button data-l10n-id="update-checkForUpdatesButton"
is="highlightable-button"
oncommand="gAppUpdater.checkForUpdates();"/>
</hbox>
<hbox id="policyDisabled" align="start">
<label data-l10n-id="update-adminDisabled"></label>
<spacer flex="1"/>
<button data-l10n-id="update-checkForUpdatesButton"
is="highlightable-button"
disabled="true"/>
</hbox>
<hbox id="noUpdatesFound" align="start">
@ -496,12 +512,14 @@
<label data-l10n-id="update-noUpdatesFound"></label>
<spacer flex="1"/>
<button data-l10n-id="update-checkForUpdatesButton"
is="highlightable-button"
oncommand="gAppUpdater.checkForUpdates();"/>
</hbox>
<hbox id="otherInstanceHandlingUpdates" align="start">
<label data-l10n-id="update-otherInstanceHandlingUpdates"></label>
<spacer flex="1"/>
<button data-l10n-id="update-checkForUpdatesButton"
is="highlightable-button"
disabled="true"/>
</hbox>
<hbox id="manualUpdate" align="start">
@ -511,6 +529,7 @@
</description>
<spacer flex="1"/>
<button data-l10n-id="update-checkForUpdatesButton"
is="highlightable-button"
disabled="true"/>
</hbox>
<hbox id="unsupportedSystem" align="start">
@ -519,12 +538,14 @@
</description>
<spacer flex="1"/>
<button data-l10n-id="update-checkForUpdatesButton"
is="highlightable-button"
disabled="true"/>
</hbox>
<hbox id="restarting" align="start">
<image class="update-throbber"/><label data-l10n-id="update-restarting"></label>
<spacer flex="1"/>
<button data-l10n-id="update-updateButton"
is="highlightable-button"
disabled="true"/>
</hbox>
</deck>
@ -673,6 +694,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="connectionSettings"
is="highlightable-button"
class="accessory-button"
icon="network"
data-l10n-id="network-proxy-connection-settings"

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

@ -31,6 +31,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="trackingProtectionExceptions"
is="highlightable-button"
class="accessory-button"
flex="1"
data-l10n-id="tracking-manage-exceptions"
@ -57,6 +58,7 @@
data-l10n-id="content-blocking-setting-standard"
flex="1"/>
<button id="standardArrow"
is="highlightable-button"
class="arrowhead default-content-blocking-ui"
data-l10n-id="content-blocking-expand-section"
aria-expanded="false"/>
@ -116,6 +118,7 @@
<vbox>
<spacer flex="1"/>
<button class="accessory-button reload-tabs-button"
is="highlightable-button"
data-l10n-id="content-blocking-reload-tabs-button"/>
<spacer flex="1"/>
</vbox>
@ -131,6 +134,7 @@
data-l10n-id="content-blocking-setting-strict"
flex="1"/>
<button id="strictArrow"
is="highlightable-button"
class="arrowhead"
data-l10n-id="content-blocking-expand-section"
aria-expanded="false"/>
@ -190,6 +194,7 @@
<vbox>
<spacer flex="1"/>
<button class="accessory-button reload-tabs-button"
is="highlightable-button"
data-l10n-id="content-blocking-reload-tabs-button"/>
<spacer flex="1"/>
</vbox>
@ -217,6 +222,7 @@
data-l10n-id="content-blocking-setting-custom"
flex="1"/>
<button id="customArrow"
is="highlightable-button"
class="arrowhead"
data-l10n-id="content-blocking-expand-section"
aria-expanded="false"/>
@ -228,6 +234,7 @@
align="center" hidden="true" class="extension-controlled">
<description control="contentBlockingDisableTrackingProtectionExtension" flex="1"/>
<button id="contentBlockingDisableTrackingProtectionExtension"
is="highlightable-button"
class="extension-controlled-button accessory-button"
data-l10n-id="disable-extension" hidden="true"/>
</hbox>
@ -306,6 +313,7 @@
<vbox>
<spacer flex="1"/>
<button class="accessory-button reload-tabs-button"
is="highlightable-button"
data-l10n-id="content-blocking-reload-tabs-button"/>
<spacer flex="1"/>
</vbox>
@ -368,6 +376,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="clearSiteDataButton"
is="highlightable-button"
class="accessory-button"
icon="clear"
search-l10n-ids="clear-site-data-cookies-empty.label, clear-site-data-cache-empty.label"
@ -375,6 +384,7 @@
</hbox>
<hbox>
<button id="siteDataSettings"
is="highlightable-button"
class="accessory-button"
data-l10n-id="sitedata-settings"
search-l10n-ids="
@ -388,6 +398,7 @@
</hbox>
<hbox>
<button id="cookieExceptions"
is="highlightable-button"
class="accessory-button"
data-l10n-id="sitedata-cookies-permissions"
preference="pref.privacy.disable_button.cookie_exceptions"
@ -420,6 +431,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="passwordExceptions"
is="highlightable-button"
class="accessory-button"
data-l10n-id="forms-exceptions"
preference="pref.privacy.disable_button.view_passwords_exceptions"
@ -434,6 +446,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="showPasswords"
is="highlightable-button"
class="accessory-button"
data-l10n-id="forms-saved-logins"
search-l10n-ids="forms-saved-logins.label"
@ -448,6 +461,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="changeMasterPassword"
is="highlightable-button"
class="accessory-button"
data-l10n-id="forms-master-pw-change"/>
</hbox>
@ -537,12 +551,14 @@
</deck>
<vbox id="historyButtons" align="end">
<button id="clearHistoryButton"
is="highlightable-button"
class="accessory-button"
icon="clear"
data-l10n-id="history-clear-button"/>
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="clearDataSettings"
is="highlightable-button"
class="accessory-button"
data-l10n-id="history-clear-on-close-settings"
search-l10n-ids="
@ -599,6 +615,7 @@
</description>
<hbox pack="end">
<button id="locationSettingsButton"
is="highlightable-button"
class="accessory-button"
data-l10n-id="permissions-location-settings"
search-l10n-ids="
@ -622,6 +639,7 @@
</description>
<hbox pack="end">
<button id="cameraSettingsButton"
is="highlightable-button"
class="accessory-button"
data-l10n-id="permissions-camera-settings"
search-l10n-ids="
@ -645,6 +663,7 @@
</description>
<hbox pack="end">
<button id="microphoneSettingsButton"
is="highlightable-button"
class="accessory-button"
data-l10n-id="permissions-microphone-settings"
search-l10n-ids="
@ -674,6 +693,7 @@
</description>
<hbox pack="end">
<button id="notificationSettingsButton"
is="highlightable-button"
class="accessory-button"
data-l10n-id="permissions-notification-settings"
search-l10n-ids="
@ -703,6 +723,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="autoplayMediaPolicyButton"
is="highlightable-button"
class="accessory-button"
data-l10n-id="permissions-block-autoplay-media-exceptions"
search-l10n-ids="permissions-address,
@ -723,6 +744,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="popupPolicyButton"
is="highlightable-button"
class="accessory-button"
data-l10n-id="permissions-block-popups-exceptions"
search-l10n-ids="
@ -744,6 +766,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox>
<button id="addonExceptions"
is="highlightable-button"
class="accessory-button"
data-l10n-id="permissions-addon-exceptions"
search-l10n-ids="
@ -895,6 +918,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox pack="end">
<button id="viewCertificatesButton"
is="highlightable-button"
class="accessory-button"
data-l10n-id="certs-view"
preference="security.disable_button.openCertManager"
@ -917,6 +941,7 @@
<!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
<hbox pack="end">
<button id="viewSecurityDevicesButton"
is="highlightable-button"
class="accessory-button"
data-l10n-id="certs-devices"
preference="security.disable_button.openDeviceManager"

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

@ -67,10 +67,12 @@
<hbox>
<button id="restoreDefaultSearchEngines"
is="highlightable-button"
data-l10n-id="search-restore-default"
/>
<spacer flex="1"/>
<button id="removeEngineButton"
is="highlightable-button"
class="searchEngineAction"
data-l10n-id="search-remove-engine"
disabled="true"

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

@ -35,6 +35,7 @@
<label id="signedOutAccountBoxTitle"><html:h2 data-l10n-id="sync-signedout-account-title"/></label>
</hbox>
<button id="noFxaSignIn"
is="highlightable-button"
class="accessory-button"
data-l10n-id="sync-signedout-account-signin"/>
</hbox>
@ -87,6 +88,7 @@
</label>
<label id="fxaEmailAddress" flex="1" crop="end"/>
<button id="fxaUnlinkButton"
is="highlightable-button"
class="accessory-button"
data-l10n-id="sync-disconnect"/>
</hbox>
@ -112,8 +114,12 @@
data-l10n-args='{"email": ""}'/>
</hbox>
<hbox class="fxaAccountBoxButtons">
<button id="verifyFxaAccount" data-l10n-id="sync-resend-verification"/>
<button id="unverifiedUnlinkFxaAccount" data-l10n-id="sync-remove-account"/>
<button id="verifyFxaAccount"
is="highlightable-button"
data-l10n-id="sync-resend-verification"/>
<button id="unverifiedUnlinkFxaAccount"
is="highlightable-button"
data-l10n-id="sync-remove-account"/>
</hbox>
</vbox>
</hbox>
@ -132,8 +138,12 @@
data-l10n-args='{"email": ""}'/>
</hbox>
<hbox class="fxaAccountBoxButtons">
<button id="rejectReSignIn" data-l10n-id="sync-sign-in"/>
<button id="rejectUnlinkFxaAccount" data-l10n-id="sync-remove-account"/>
<button id="rejectReSignIn"
is="highlightable-button"
data-l10n-id="sync-sign-in"/>
<button id="rejectUnlinkFxaAccount"
is="highlightable-button"
data-l10n-id="sync-remove-account"/>
</hbox>
</vbox>
</hbox>
@ -174,11 +184,14 @@
<hbox id="fxaDeviceName">
<textbox id="fxaSyncComputerName" flex="1" disabled="true"/>
<button id="fxaChangeDeviceName"
is="highlightable-button"
data-l10n-id="sync-device-name-change"/>
<button id="fxaCancelChangeDeviceName"
is="highlightable-button"
data-l10n-id="sync-device-name-cancel"
hidden="true"/>
<button id="fxaSaveChangeDeviceName"
is="highlightable-button"
data-l10n-id="sync-device-name-save"
hidden="true"/>
</hbox>

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

@ -49,10 +49,12 @@
<spacer flex="1"/>
<hbox class="actionButtons" align="right" flex="1">
<button id="butCancel"
is="highlightable-button"
oncommand="close(event);"
class="syncDisconnectButton"
data-l10n-id="sync-disconnect-cancel"/>
<button id="butDisconnect"
is="highlightable-button"
oncommand="gSyncDisconnectDialog.accept(event);"
class="syncDisconnectButton"
data-l10n-id="sync-disconnect-confirm-disconnect"/>

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

@ -79,7 +79,7 @@ FormAutofillPreferences.prototype = {
let addressAutofillCheckboxGroup = document.createXULElement("hbox");
let addressAutofillCheckbox = document.createXULElement("checkbox");
let addressAutofillLearnMore = document.createXULElement("label", {is: "text-link"});
let savedAddressesBtn = document.createXULElement("button");
let savedAddressesBtn = document.createXULElement("button", {is: "highlightable-button"});
// Wrappers are used to properly compute the search tooltip positions
let savedAddressesBtnWrapper = document.createXULElement("hbox");
let savedCreditCardsBtnWrapper = document.createXULElement("hbox");
@ -138,7 +138,7 @@ FormAutofillPreferences.prototype = {
let creditCardAutofillCheckboxGroup = document.createXULElement("hbox");
let creditCardAutofillCheckbox = document.createXULElement("checkbox");
let creditCardAutofillLearnMore = document.createXULElement("label", {is: "text-link"});
let savedCreditCardsBtn = document.createXULElement("button");
let savedCreditCardsBtn = document.createXULElement("button", {is: "highlightable-button"});
savedCreditCardsBtn.className = "accessory-button";
creditCardAutofillCheckbox.className = "tail-with-learn-more";
creditCardAutofillLearnMore.className = "learnMore";

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

@ -7,7 +7,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=683852
<window title="Mozilla Bug 683852"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<button value="testbutton" id="testbutton"/>
<xbl:bindings xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gaktekeeper/there.is.only.xul">
<xbl:binding id="test">
<xbl:content><xul:box anonid="xbl-anon">Anonymous</xul:box></xbl:content>
</xbl:binding>
</xbl:bindings>
<box id="xbl-host" style="-moz-binding: url(#test)"/>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=683852"
@ -25,14 +32,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=683852
function startTest() {
is(document.contains(document), true, "Document should contain itself!");
var tb = document.getElementById("testbutton");
is(document.contains(tb), true, "Document should contain element in it!");
is(tb.contains(tb), true, "Element should contain itself.")
var anon = document.getAnonymousElementByAttribute(tb, "anonid", "button-box");
let box = document.getElementById("xbl-host");
is(document.contains(box), true, "Document should contain element in it!");
is(box.contains(box), true, "Element should contain itself.")
let anon = document.getAnonymousElementByAttribute(box, "anonid", "xbl-anon");
is(document.contains(anon), false, "Document should not contain anonymous element in it!");
is(tb.contains(anon), false, "Element should not contain anonymous element in it!");
is(box.contains(anon), false, "Element should not contain anonymous element in it!");
is(anon.contains(anon), true, "Anonymous element should contain itself.")
is(document.documentElement.contains(tb), true, "Element should contain element in it!");
is(document.documentElement.contains(box), true, "Element should contain element in it!");
is(document.contains(document.createElement("foo")), false, "Document shouldn't contain element which is't in the document");
is(document.contains(document.createTextNode("foo")), false, "Document shouldn't contain text node which is't in the document");

Двоичный файл не отображается.

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

@ -223,6 +223,8 @@ enum AppId {
#define LS_ARCHIVE_FILE_NAME "ls-archive.sqlite"
#define LS_ARCHIVE_TMP_FILE_NAME "ls-archive-tmp.sqlite"
const uint32_t kLocalStorageArchiveVersion = 1;
const char kProfileDoChangeTopic[] = "profile-do-change";
/******************************************************************************
@ -325,6 +327,158 @@ nsresult CreateWebAppsStoreConnection(nsIFile* aWebAppsStoreFile,
return NS_OK;
}
nsresult GetLocalStorageArchiveFile(const nsAString& aDirectoryPath,
nsIFile** aLsArchiveFile) {
AssertIsOnIOThread();
MOZ_ASSERT(!aDirectoryPath.IsEmpty());
MOZ_ASSERT(aLsArchiveFile);
nsCOMPtr<nsIFile> lsArchiveFile;
nsresult rv =
NS_NewLocalFile(aDirectoryPath, false, getter_AddRefs(lsArchiveFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = lsArchiveFile->Append(NS_LITERAL_STRING(LS_ARCHIVE_FILE_NAME));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
lsArchiveFile.forget(aLsArchiveFile);
return NS_OK;
}
nsresult GetLocalStorageArchiveTmpFile(const nsAString& aDirectoryPath,
nsIFile** aLsArchiveTmpFile) {
AssertIsOnIOThread();
MOZ_ASSERT(!aDirectoryPath.IsEmpty());
MOZ_ASSERT(aLsArchiveTmpFile);
nsCOMPtr<nsIFile> lsArchiveTmpFile;
nsresult rv =
NS_NewLocalFile(aDirectoryPath, false, getter_AddRefs(lsArchiveTmpFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = lsArchiveTmpFile->Append(NS_LITERAL_STRING(LS_ARCHIVE_TMP_FILE_NAME));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
lsArchiveTmpFile.forget(aLsArchiveTmpFile);
return NS_OK;
}
nsresult InitializeLocalStorageArchive(mozIStorageConnection* aConnection,
uint32_t aVersion) {
AssertIsOnIOThread();
MOZ_ASSERT(aConnection);
nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TABLE database(version INTEGER NOT NULL DEFAULT 0);"));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<mozIStorageStatement> stmt;
rv = aConnection->CreateStatement(
NS_LITERAL_CSTRING("INSERT INTO database (version) VALUES (:version)"),
getter_AddRefs(stmt));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("version"), aVersion);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = stmt->Execute();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult IsLocalStorageArchiveInitialized(mozIStorageConnection* aConnection,
bool& aInitialized) {
AssertIsOnIOThread();
MOZ_ASSERT(aConnection);
bool exists;
nsresult rv =
aConnection->TableExists(NS_LITERAL_CSTRING("database"), &exists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
aInitialized = exists;
return NS_OK;
}
nsresult LoadLocalStorageArchiveVersion(mozIStorageConnection* aConnection,
uint32_t& aVersion) {
AssertIsOnIOThread();
MOZ_ASSERT(aConnection);
nsCOMPtr<mozIStorageStatement> stmt;
nsresult rv = aConnection->CreateStatement(
NS_LITERAL_CSTRING("SELECT version FROM database"), getter_AddRefs(stmt));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool hasResult;
rv = stmt->ExecuteStep(&hasResult);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (NS_WARN_IF(!hasResult)) {
return NS_ERROR_FILE_CORRUPTED;
}
int32_t version;
rv = stmt->GetInt32(0, &version);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
aVersion = version;
return NS_OK;
}
/*
nsresult SaveLocalStorageArchiveVersion(mozIStorageConnection* aConnection,
uint32_t aVersion) {
AssertIsOnIOThread();
MOZ_ASSERT(aConnection);
nsCOMPtr<mozIStorageStatement> stmt;
nsresult rv = aConnection->CreateStatement(
NS_LITERAL_CSTRING("UPDATE database SET version = :version;"),
getter_AddRefs(stmt));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("version"), aVersion);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = stmt->Execute();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
*/
/******************************************************************************
* Quota manager class declarations
******************************************************************************/
@ -4553,13 +4707,8 @@ nsresult QuotaManager::MaybeRemoveLocalStorageData() {
// Cleanup the tmp file first, if there's any.
nsCOMPtr<nsIFile> lsArchiveTmpFile;
nsresult rv =
NS_NewLocalFile(mStoragePath, false, getter_AddRefs(lsArchiveTmpFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = lsArchiveTmpFile->Append(NS_LITERAL_STRING(LS_ARCHIVE_TMP_FILE_NAME));
nsresult rv = GetLocalStorageArchiveTmpFile(mStoragePath,
getter_AddRefs(lsArchiveTmpFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -4579,12 +4728,7 @@ nsresult QuotaManager::MaybeRemoveLocalStorageData() {
// Now check the real archive file.
nsCOMPtr<nsIFile> lsArchiveFile;
rv = NS_NewLocalFile(mStoragePath, false, getter_AddRefs(lsArchiveFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = lsArchiveFile->Append(NS_LITERAL_STRING(LS_ARCHIVE_FILE_NAME));
rv = GetLocalStorageArchiveFile(mStoragePath, getter_AddRefs(lsArchiveFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -4740,33 +4884,27 @@ nsresult QuotaManager::MaybeRemoveLocalStorageDirectories() {
return NS_OK;
}
nsresult QuotaManager::MaybeCreateLocalStorageArchive() {
nsresult QuotaManager::CreateLocalStorageArchiveConnectionFromWebAppsStore(
mozIStorageConnection** aConnection) {
AssertIsOnIOThread();
MOZ_ASSERT(CachedNextGenLocalStorageEnabled());
MOZ_ASSERT(aConnection);
// Check if the archive was already successfully created.
nsCOMPtr<nsIFile> lsArchiveFile;
nsresult rv =
NS_NewLocalFile(mStoragePath, false, getter_AddRefs(lsArchiveFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = lsArchiveFile->Append(NS_LITERAL_STRING(LS_ARCHIVE_FILE_NAME));
GetLocalStorageArchiveFile(mStoragePath, getter_AddRefs(lsArchiveFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
#ifdef DEBUG
bool exists;
rv = lsArchiveFile->Exists(&exists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (exists) {
// ls-archive.sqlite already exists, nothing to create.
return NS_OK;
}
MOZ_ASSERT(!exists);
#endif
// Get the storage service first, we will need it at multiple places.
nsCOMPtr<mozIStorageService> ss =
@ -4856,12 +4994,8 @@ nsresult QuotaManager::MaybeCreateLocalStorageArchive() {
}
nsCOMPtr<nsIFile> lsArchiveTmpFile;
rv = NS_NewLocalFile(mStoragePath, false, getter_AddRefs(lsArchiveTmpFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = lsArchiveTmpFile->Append(NS_LITERAL_STRING(LS_ARCHIVE_TMP_FILE_NAME));
rv = GetLocalStorageArchiveTmpFile(mStoragePath,
getter_AddRefs(lsArchiveTmpFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -4895,6 +5029,15 @@ nsresult QuotaManager::MaybeCreateLocalStorageArchive() {
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<mozIStorageConnection> lsArchiveConnection;
rv = ss->OpenUnsharedDatabase(lsArchiveFile,
getter_AddRefs(lsArchiveConnection));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
lsArchiveConnection.forget(aConnection);
} else {
// If webappsstore database is not useable, just create an empty archive.
@ -4923,11 +5066,227 @@ nsresult QuotaManager::MaybeCreateLocalStorageArchive() {
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
lsArchiveConnection.forget(aConnection);
}
return NS_OK;
}
nsresult QuotaManager::CreateLocalStorageArchiveConnection(
mozIStorageConnection** aConnection, bool& aNewlyCreated) {
AssertIsOnIOThread();
MOZ_ASSERT(CachedNextGenLocalStorageEnabled());
MOZ_ASSERT(aConnection);
nsCOMPtr<nsIFile> lsArchiveTmpFile;
nsresult rv = GetLocalStorageArchiveTmpFile(mStoragePath,
getter_AddRefs(lsArchiveTmpFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool exists;
rv = lsArchiveTmpFile->Exists(&exists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (exists) {
rv = lsArchiveTmpFile->Remove(false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
// Check if the archive was already successfully created.
nsCOMPtr<nsIFile> lsArchiveFile;
rv = GetLocalStorageArchiveFile(mStoragePath, getter_AddRefs(lsArchiveFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = lsArchiveFile->Exists(&exists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (exists) {
bool removed = false;
bool isDirectory;
rv = lsArchiveFile->IsDirectory(&isDirectory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (isDirectory) {
rv = lsArchiveFile->Remove(true);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
removed = true;
}
nsCOMPtr<mozIStorageService> ss =
do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<mozIStorageConnection> connection;
rv = ss->OpenUnsharedDatabase(lsArchiveFile, getter_AddRefs(connection));
if (!removed && rv == NS_ERROR_FILE_CORRUPTED) {
rv = lsArchiveFile->Remove(false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
removed = true;
rv = ss->OpenUnsharedDatabase(lsArchiveFile, getter_AddRefs(connection));
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = StorageDBUpdater::Update(connection);
if (!removed && NS_FAILED(rv)) {
rv = connection->Close();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = lsArchiveFile->Remove(false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
removed = true;
rv = ss->OpenUnsharedDatabase(lsArchiveFile, getter_AddRefs(connection));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = StorageDBUpdater::Update(connection);
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
connection.forget(aConnection);
aNewlyCreated = removed;
return NS_OK;
}
nsCOMPtr<mozIStorageConnection> connection;
rv = CreateLocalStorageArchiveConnectionFromWebAppsStore(
getter_AddRefs(connection));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
connection.forget(aConnection);
aNewlyCreated = true;
return NS_OK;
}
nsresult QuotaManager::RecreateLocalStorageArchive(
nsCOMPtr<mozIStorageConnection>& aConnection) {
AssertIsOnIOThread();
MOZ_ASSERT(CachedNextGenLocalStorageEnabled());
// Close local storage archive connection. We are going to remove underlying
// file.
nsresult rv = aConnection->Close();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = MaybeRemoveLocalStorageDirectories();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsIFile> lsArchiveFile;
rv = GetLocalStorageArchiveFile(mStoragePath, getter_AddRefs(lsArchiveFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
#ifdef DEBUG
bool exists;
rv = lsArchiveFile->Exists(&exists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(exists);
#endif
rv = lsArchiveFile->Remove(false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = CreateLocalStorageArchiveConnectionFromWebAppsStore(
getter_AddRefs(aConnection));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult QuotaManager::DowngradeLocalStorageArchive(
nsCOMPtr<mozIStorageConnection>& aConnection) {
AssertIsOnIOThread();
MOZ_ASSERT(CachedNextGenLocalStorageEnabled());
nsresult rv = RecreateLocalStorageArchive(aConnection);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = InitializeLocalStorageArchive(aConnection, kLocalStorageArchiveVersion);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult QuotaManager::UpgradeLocalStorageArchiveFrom0To1(
nsCOMPtr<mozIStorageConnection>& aConnection) {
AssertIsOnIOThread();
MOZ_ASSERT(CachedNextGenLocalStorageEnabled());
nsresult rv = RecreateLocalStorageArchive(aConnection);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = InitializeLocalStorageArchive(aConnection, 1);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
/*
nsresult QuotaManager::UpgradeLocalStorageArchiveFrom1To2(
nsCOMPtr<mozIStorageConnection>& aConnection) {
nsresult rv = SaveLocalStorageArchiveVersion(aConnection, 2);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
*/
#ifdef DEBUG
void QuotaManager::AssertStorageIsInitialized() const {
@ -5103,12 +5462,87 @@ nsresult QuotaManager::EnsureStorageIsInitialized() {
}
if (CachedNextGenLocalStorageEnabled()) {
rv = MaybeCreateLocalStorageArchive();
nsCOMPtr<mozIStorageConnection> connection;
bool newlyCreated;
rv = CreateLocalStorageArchiveConnection(getter_AddRefs(connection),
newlyCreated);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
uint32_t version = 0;
if (!newlyCreated) {
bool initialized;
rv = IsLocalStorageArchiveInitialized(connection, initialized);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (initialized) {
rv = LoadLocalStorageArchiveVersion(connection, version);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
}
if (version > kLocalStorageArchiveVersion) {
rv = DowngradeLocalStorageArchive(connection);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = LoadLocalStorageArchiveVersion(connection, version);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(version == kLocalStorageArchiveVersion);
} else if (version != kLocalStorageArchiveVersion) {
if (newlyCreated) {
MOZ_ASSERT(version == 0);
rv = InitializeLocalStorageArchive(connection,
kLocalStorageArchiveVersion);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
static_assert(kLocalStorageArchiveVersion == 1,
"Upgrade function needed due to LocalStorage archive "
"version increase.");
while (version != kLocalStorageArchiveVersion) {
if (version == 0) {
rv = UpgradeLocalStorageArchiveFrom0To1(connection);
} /* else if (version == 1) {
rv = UpgradeLocalStorageArchiveFrom1To2(connection);
} */ else {
QM_WARNING(
"Unable to initialize LocalStorage archive, no upgrade path is "
"available!");
return NS_ERROR_FAILURE;
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = LoadLocalStorageArchiveVersion(connection, version);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
MOZ_ASSERT(version == kLocalStorageArchiveVersion);
}
}
} else {
rv = MaybeRemoveLocalStorageData();
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
mStorageInitialized = true;

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

@ -425,7 +425,25 @@ class QuotaManager final : public BackgroundThreadObject {
nsresult MaybeRemoveLocalStorageDirectories();
nsresult MaybeCreateLocalStorageArchive();
nsresult CreateLocalStorageArchiveConnectionFromWebAppsStore(
mozIStorageConnection** aConnection);
nsresult CreateLocalStorageArchiveConnection(
mozIStorageConnection** aConnection, bool& aNewlyCreated);
nsresult RecreateLocalStorageArchive(
nsCOMPtr<mozIStorageConnection>& aConnection);
nsresult DowngradeLocalStorageArchive(
nsCOMPtr<mozIStorageConnection>& aConnection);
nsresult UpgradeLocalStorageArchiveFrom0To1(
nsCOMPtr<mozIStorageConnection>& aConnection);
/*
nsresult UpgradeLocalStorageArchiveFrom1To2(
nsCOMPtr<mozIStorageConnection>& aConnection);
*/
nsresult InitializeRepository(PersistenceType aPersistenceType);

Двоичные данные
dom/quota/test/unit/localStorageArchive1upgrade_profile.zip Normal file

Двоичный файл не отображается.

Двоичные данные
dom/quota/test/unit/localStorageArchiveDowngrade_profile.zip Normal file

Двоичный файл не отображается.

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

@ -0,0 +1,65 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* This test is mainly to verify that local storage directories are removed
* during local storage archive upgrade from version 0 to version 1.
* See bug 1546305.
*/
async function testSteps() {
const lsDirs = [
"storage/default/http+++example.com/ls",
"storage/default/http+++localhost/ls",
"storage/default/http+++www.mozilla.org/ls",
];
info("Clearing");
let request = clear();
await requestFinished(request);
info("Installing package");
// The profile contains three initialized origin directories with local
// storage data, local storage archive, a script for origin initialization,
// the storage database and the web apps store database:
// - storage/default/https+++example.com
// - storage/default/https+++localhost
// - storage/default/https+++www.mozilla.org
// - storage/ls-archive.sqlite
// - create_db.js
// - storage.sqlite
// - webappsstore.sqlite
// The file create_db.js in the package was run locally (with a build that
// doesn't support local storage archive upgrades), specifically it was
// temporarily added to xpcshell.ini and then executed:
// mach xpcshell-test --interactive dom/localstorage/test/unit/create_db.js
// Note: to make it become the profile in the test, additional manual steps
// are needed.
// 1. Remove the folder "storage/temporary".
installPackage("localStorageArchive1upgrade_profile");
info("Checking ls dirs");
for (let lsDir of lsDirs) {
let dir = getRelativeFile(lsDir);
exists = dir.exists();
ok(exists, "ls directory does exist");
}
request = init();
request = await requestFinished(request);
info("Checking ls dirs");
for (let lsDir of lsDirs) {
let dir = getRelativeFile(lsDir);
exists = dir.exists();
ok(!exists, "ls directory doesn't exist");
}
}

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

@ -0,0 +1,66 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* This test is mainly to verify that local storage directories are removed
* during local storage archive downgrade from any future version to current
* version. See bug 1546305.
*/
async function testSteps() {
const lsDirs = [
"storage/default/http+++example.com/ls",
"storage/default/http+++localhost/ls",
"storage/default/http+++www.mozilla.org/ls",
];
info("Clearing");
let request = clear();
await requestFinished(request);
info("Installing package");
// The profile contains three initialized origin directories with local
// storage data, local storage archive, a script for origin initialization,
// the storage database and the web apps store database:
// - storage/default/https+++example.com
// - storage/default/https+++localhost
// - storage/default/https+++www.mozilla.org
// - storage/ls-archive.sqlite
// - create_db.js
// - storage.sqlite
// - webappsstore.sqlite
// The file create_db.js in the package was run locally (with a build that
// supports local storage archive upgrades and local storage archive version
// set to max integer), specifically it was temporarily added to xpcshell.ini
// and then executed:
// mach xpcshell-test --interactive dom/localstorage/test/unit/create_db.js
// Note: to make it become the profile in the test, additional manual steps
// are needed.
// 1. Remove the folder "storage/temporary".
installPackage("localStorageArchiveDowngrade_profile");
info("Checking ls dirs");
for (let lsDir of lsDirs) {
let dir = getRelativeFile(lsDir);
exists = dir.exists();
ok(exists, "ls directory does exist");
}
request = init();
request = await requestFinished(request);
info("Checking ls dirs");
for (let lsDir of lsDirs) {
let dir = getRelativeFile(lsDir);
exists = dir.exists();
ok(!exists, "ls directory doesn't exist");
}
}

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

@ -13,6 +13,8 @@ support-files =
groupMismatch_profile.zip
idbSubdirUpgrade1_profile.zip
idbSubdirUpgrade2_profile.zip
localStorageArchive1upgrade_profile.zip
localStorageArchiveDowngrade_profile.zip
morgueCleanup_profile.zip
obsoleteOriginAttributes_profile.zip
originAttributesUpgrade_profile.zip
@ -34,6 +36,8 @@ support-files =
[test_idbSubdirUpgrade.js]
[test_initTemporaryStorage.js]
[test_listInitializedOrigins.js]
[test_localStorageArchive1upgrade.js]
[test_localStorageArchiveDowngrade.js]
[test_morgueCleanup.js]
[test_obsoleteOriginAttributesUpgrade.js]
[test_obsoleteOrigins.js]

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

@ -586,7 +586,7 @@ double SVGContentUtils::ComputeNormalizedHypotenuse(double aWidth,
}
float SVGContentUtils::AngleBisect(float a1, float a2) {
float delta = fmod(a2 - a1, static_cast<float>(2 * M_PI));
float delta = std::fmod(a2 - a1, static_cast<float>(2 * M_PI));
if (delta < 0) {
delta += static_cast<float>(2 * M_PI);
}

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

@ -104,7 +104,7 @@ void SVGLineElement::GetMarkPoints(nsTArray<SVGMark>* aMarks) {
GetAnimatedLengthValues(&x1, &y1, &x2, &y2, nullptr);
float angle = atan2(y2 - y1, x2 - x1);
float angle = std::atan2(y2 - y1, x2 - x1);
aMarks->AppendElement(SVGMark(x1, y1, angle, SVGMark::eStart));
aMarks->AppendElement(SVGMark(x2, y2, angle, SVGMark::eEnd));

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

@ -329,7 +329,7 @@ nsresult SVGMotionSMILType::ComputeDistance(const SMILValue& aFrom,
const PathPointParams& toParams = to.mU.mPathPointParams;
MOZ_ASSERT(fromParams.mPath == toParams.mPath,
"Interpolation endpoints should be from same path");
aDistance = fabs(toParams.mDistToPoint - fromParams.mDistToPoint);
aDistance = std::fabs(toParams.mDistToPoint - fromParams.mDistToPoint);
} else {
const TranslationParams& fromParams = from.mU.mTranslationParams;
const TranslationParams& toParams = to.mU.mTranslationParams;

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

@ -195,7 +195,7 @@ static void TraverseLinetoHorizontalAbs(const float* aArgs,
SVGPathTraversalState& aState) {
Point to(aArgs[0], aState.pos.y);
if (aState.ShouldUpdateLengthAndControlPoints()) {
aState.length += fabs(to.x - aState.pos.x);
aState.length += std::fabs(to.x - aState.pos.x);
aState.cp1 = aState.cp2 = to;
}
aState.pos = to;
@ -205,7 +205,7 @@ static void TraverseLinetoHorizontalRel(const float* aArgs,
SVGPathTraversalState& aState) {
aState.pos.x += aArgs[0];
if (aState.ShouldUpdateLengthAndControlPoints()) {
aState.length += fabs(aArgs[0]);
aState.length += std::fabs(aArgs[0]);
aState.cp1 = aState.cp2 = aState.pos;
}
}
@ -214,7 +214,7 @@ static void TraverseLinetoVerticalAbs(const float* aArgs,
SVGPathTraversalState& aState) {
Point to(aState.pos.x, aArgs[0]);
if (aState.ShouldUpdateLengthAndControlPoints()) {
aState.length += fabs(to.y - aState.pos.y);
aState.length += std::fabs(to.y - aState.pos.y);
aState.cp1 = aState.cp2 = to;
}
aState.pos = to;
@ -224,7 +224,7 @@ static void TraverseLinetoVerticalRel(const float* aArgs,
SVGPathTraversalState& aState) {
aState.pos.y += aArgs[0];
if (aState.ShouldUpdateLengthAndControlPoints()) {
aState.length += fabs(aArgs[0]);
aState.length += std::fabs(aArgs[0]);
aState.cp1 = aState.cp2 = aState.pos;
}
}

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

@ -73,7 +73,7 @@ void SVGPolyElement::GetMarkPoints(nsTArray<SVGMark>* aMarks) {
for (uint32_t i = 1; i < points.Length(); ++i) {
float x = points[i].mX;
float y = points[i].mY;
float angle = atan2(y - py, x - px);
float angle = std::atan2(y - py, x - px);
// Vertex marker.
if (i == 1) {

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

@ -46,7 +46,8 @@ void SVGPolygonElement::GetMarkPoints(nsTArray<SVGMark> *aMarks) {
SVGMark *endMark = &aMarks->LastElement();
SVGMark *startMark = &aMarks->ElementAt(0);
float angle = atan2(startMark->y - endMark->y, startMark->x - endMark->x);
float angle =
std::atan2(startMark->y - endMark->y, startMark->x - endMark->x);
endMark->type = SVGMark::eMid;
endMark->angle = SVGContentUtils::AngleBisect(angle, endMark->angle);

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

@ -207,7 +207,7 @@ nsresult SVGTransformListSMILType::ComputeDistance(const SMILValue& aFrom,
case SVG_TRANSFORM_SKEWY: {
const float& a = fromTransform.mParams[0];
const float& b = toTransform.mParams[0];
aDistance = fabs(a - b);
aDistance = std::fabs(a - b);
} break;
default:

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

@ -87,8 +87,8 @@ nsresult SVGViewBoxSMILType::ComputeDistance(const SMILValue& aFrom,
float dRight = (to->x + to->width) - (from->x + from->width);
float dBottom = (to->y + to->height) - (from->y + from->height);
aDistance =
sqrt(dLeft * dLeft + dTop * dTop + dRight * dRight + dBottom * dBottom);
aDistance = std::sqrt(dLeft * dLeft + dTop * dTop + dRight * dRight +
dBottom * dBottom);
return NS_OK;
}

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

@ -13,6 +13,13 @@ function testElements(baseid, callback)
continue;
}
// Ignore content inside a <button> This can be removed if/when
// button switches to use shadow DOM.
let buttonParent = element.closest("button");
if (buttonParent && buttonParent !== element) {
continue;
}
testElement(element);
}

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

@ -100,7 +100,9 @@ class MOZ_STACK_CLASS BytecodeCompiler {
// This function lives here, not in SourceAwareCompiler, because it mostly
// uses fields in *this* class.
template <typename Unit>
MOZ_MUST_USE bool assignSource(JS::SourceText<Unit>& sourceBuffer);
MOZ_MUST_USE bool assignSource(JS::SourceText<Unit>& sourceBuffer) {
return scriptSource->assignSource(cx, options, sourceBuffer);
}
bool canLazilyParse() const;

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

@ -400,19 +400,6 @@ bool BytecodeCompiler::createScriptSource(
return true;
}
template <typename Unit>
bool BytecodeCompiler::assignSource(SourceText<Unit>& sourceBuffer) {
if (!cx->realm()->behaviors().discardSource()) {
if (options.sourceIsLazy) {
scriptSource->setSourceRetrievable();
} else if (!scriptSource->setSourceCopy(cx, sourceBuffer)) {
return false;
}
}
return true;
}
bool BytecodeCompiler::canLazilyParse() const {
return options.canLazilyParse &&
!cx->realm()->behaviors().disableLazyParsing() &&

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

@ -34,6 +34,7 @@
#include <string.h>
#include "jit/ExecutableAllocator.h"
#include "jit/Ion.h"
#include "jit/JitSpewer.h"
// Spew formatting helpers.
@ -193,6 +194,12 @@ class AssemblerBuffer {
void oomDetected() {
m_oom = true;
m_buffer.clear();
#ifdef DEBUG
JitContext* context = MaybeGetJitContext();
if (context) {
context->setOOM();
}
#endif
}
mozilla::Vector<unsigned char, 256, AssemblerBufferAllocPolicy> m_buffer;

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

@ -3659,9 +3659,8 @@ JS_PUBLIC_API JSString* JS_DecompileScript(JSContext* cx, HandleScript script) {
if (fun) {
return JS_DecompileFunction(cx, fun);
}
bool haveSource = script->scriptSource()->hasSourceText();
if (!haveSource &&
!JSScript::loadSource(cx, script->scriptSource(), &haveSource)) {
bool haveSource;
if (!ScriptSource::loadSource(cx, script->scriptSource(), &haveSource)) {
return nullptr;
}
return haveSource ? JSScript::sourceData(cx, script)

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

@ -8411,9 +8411,8 @@ class DebuggerSourceGetTextMatcher {
ReturnType match(HandleScriptSourceObject sourceObject) {
ScriptSource* ss = sourceObject->source();
bool hasSourceText = ss->hasSourceText();
if (!ss->hasSourceText() &&
!JSScript::loadSource(cx_, ss, &hasSourceText)) {
bool hasSourceText;
if (!ScriptSource::loadSource(cx_, ss, &hasSourceText)) {
return nullptr;
}
if (!hasSourceText) {

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

@ -869,9 +869,10 @@ JSString* js::FunctionToString(JSContext* cx, HandleFunction fun,
bool addParentheses =
haveSource && isToSource && (fun->isLambda() && !fun->isArrow());
if (haveSource && !script->scriptSource()->hasSourceText() &&
!JSScript::loadSource(cx, script->scriptSource(), &haveSource)) {
return nullptr;
if (haveSource) {
if (!ScriptSource::loadSource(cx, script->scriptSource(), &haveSource)) {
return nullptr;
}
}
// Fast path for the common case, to avoid StringBuffer overhead.

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

@ -1652,30 +1652,67 @@ void ScriptSourceObject::setPrivate(JSRuntime* rt, const Value& value) {
rt->addRefScriptPrivate(value);
}
class ScriptSource::LoadSourceMatcher {
JSContext* const cx_;
ScriptSource* const ss_;
bool* const loaded_;
public:
explicit LoadSourceMatcher(JSContext* cx, ScriptSource* ss, bool* loaded)
: cx_(cx), ss_(ss), loaded_(loaded) {}
template <typename Unit>
bool operator()(const Compressed<Unit>&) const {
return sourceAlreadyLoaded();
}
template <typename Unit>
bool operator()(const Uncompressed<Unit>&) const {
return sourceAlreadyLoaded();
}
bool operator()(const Missing&) const { return tryLoadingSource(); }
bool operator()(const BinAST&) const { return tryLoadingSource(); }
private:
bool sourceAlreadyLoaded() const {
*loaded_ = true;
return true;
}
bool tryLoadingSource() const {
// Establish the default outcome first.
*loaded_ = false;
if (!cx_->runtime()->sourceHook.ref() || !ss_->sourceRetrievable()) {
return true;
}
char16_t* src = nullptr;
size_t length;
if (!cx_->runtime()->sourceHook->load(cx_, ss_->filename(), &src,
&length)) {
return false;
}
if (!src) {
return true;
}
// XXX On-demand source is currently only UTF-16. Perhaps it should be
// changed to UTF-8, or UTF-8 be allowed in addition to UTF-16?
if (!ss_->setRetrievedSource(cx_, EntryUnits<char16_t>(src), length)) {
return false;
}
*loaded_ = true;
return true;
}
};
/* static */
bool JSScript::loadSource(JSContext* cx, ScriptSource* ss, bool* worked) {
MOZ_ASSERT(!ss->hasSourceText());
*worked = false;
if (!cx->runtime()->sourceHook.ref() || !ss->sourceRetrievable()) {
return true;
}
char16_t* src = nullptr;
size_t length;
if (!cx->runtime()->sourceHook->load(cx, ss->filename(), &src, &length)) {
return false;
}
if (!src) {
return true;
}
// XXX On-demand source is currently only UTF-16. Perhaps it should be
// changed to UTF-8, or UTF-8 be allowed in addition to UTF-16?
if (!ss->setSource(cx, EntryUnits<char16_t>(src), length)) {
return false;
}
*worked = true;
return true;
bool ScriptSource::loadSource(JSContext* cx, ScriptSource* ss, bool* loaded) {
return ss->data.match(LoadSourceMatcher(cx, ss, loaded));
}
/* static */
@ -2056,16 +2093,10 @@ JSFlatString* ScriptSource::functionBodyString(JSContext* cx) {
}
template <typename Unit>
void ScriptSource::setSource(
typename SourceTypeTraits<Unit>::SharedImmutableString uncompressed) {
MOZ_MUST_USE bool ScriptSource::setUncompressedSourceHelper(
JSContext* cx, EntryUnits<Unit>&& source, size_t length) {
MOZ_ASSERT(data.is<Missing>());
data = SourceType(Uncompressed<Unit>(std::move(uncompressed)));
}
template <typename Unit>
MOZ_MUST_USE bool ScriptSource::setSource(JSContext* cx,
EntryUnits<Unit>&& source,
size_t length) {
auto& cache = cx->zone()->runtimeFromAnyThread()->sharedImmutableStrings();
auto uniqueChars = SourceTypeTraits<Unit>::toCacheable(std::move(source));
@ -2075,10 +2106,20 @@ MOZ_MUST_USE bool ScriptSource::setSource(JSContext* cx,
return false;
}
setSource<Unit>(std::move(*deduped));
data = SourceType(Uncompressed<Unit>(std::move(*deduped)));
return true;
}
template <typename Unit>
MOZ_MUST_USE bool ScriptSource::setRetrievedSource(JSContext* cx,
EntryUnits<Unit>&& source,
size_t length) {
MOZ_ASSERT(sourceRetrievable_);
MOZ_ASSERT(data.is<Missing>(),
"retrievable source must be indicated as missing");
return setUncompressedSourceHelper(cx, std::move(source), length);
}
#if defined(JS_BUILD_BINAST)
MOZ_MUST_USE bool ScriptSource::setBinASTSourceCopy(JSContext* cx,
@ -2161,26 +2202,29 @@ bool ScriptSource::tryCompressOffThread(JSContext* cx) {
}
template <typename Unit>
void ScriptSource::setCompressedSource(SharedImmutableString raw,
size_t uncompressedLength) {
MOZ_ASSERT(data.is<Missing>() || hasUncompressedSource());
MOZ_ASSERT_IF(hasUncompressedSource(), length() == uncompressedLength);
void ScriptSource::convertToCompressedSource(SharedImmutableString compressed,
size_t uncompressedLength) {
MOZ_ASSERT(data.is<Uncompressed<Unit>>(),
"should only be converting uncompressed source to compressed "
"source identically encoded");
MOZ_ASSERT(length() == uncompressedLength);
if (pinnedUnitsStack_) {
MOZ_ASSERT(pendingCompressed_.empty());
pendingCompressed_.construct<Compressed<Unit>>(std::move(raw),
pendingCompressed_.construct<Compressed<Unit>>(std::move(compressed),
uncompressedLength);
} else {
data = SourceType(Compressed<Unit>(std::move(raw), uncompressedLength));
data =
SourceType(Compressed<Unit>(std::move(compressed), uncompressedLength));
}
}
template <typename Unit>
MOZ_MUST_USE bool ScriptSource::setCompressedSource(JSContext* cx,
UniqueChars&& compressed,
size_t rawLength,
size_t sourceLength) {
MOZ_ASSERT(compressed);
MOZ_MUST_USE bool ScriptSource::initializeWithCompressedSource(
JSContext* cx, UniqueChars&& compressed, size_t rawLength,
size_t sourceLength) {
MOZ_ASSERT(data.is<Missing>(), "shouldn't be double-initializing");
MOZ_ASSERT(compressed != nullptr);
auto& cache = cx->zone()->runtimeFromAnyThread()->sharedImmutableStrings();
auto deduped = cache.getOrCreate(std::move(compressed), rawLength);
@ -2189,13 +2233,30 @@ MOZ_MUST_USE bool ScriptSource::setCompressedSource(JSContext* cx,
return false;
}
setCompressedSource<Unit>(std::move(*deduped), sourceLength);
MOZ_ASSERT(pinnedUnitsStack_ == nullptr,
"shouldn't be initializing a ScriptSource while its characters "
"are pinned -- that only makes sense with a ScriptSource actively "
"being inspected");
data = SourceType(Compressed<Unit>(std::move(*deduped), sourceLength));
return true;
}
template <typename Unit>
bool ScriptSource::setSourceCopy(JSContext* cx, SourceText<Unit>& srcBuf) {
MOZ_ASSERT(!hasSourceText());
bool ScriptSource::assignSource(JSContext* cx,
const ReadOnlyCompileOptions& options,
SourceText<Unit>& srcBuf) {
MOZ_ASSERT(data.is<Missing>(),
"source assignment should only occur on fresh ScriptSources");
if (cx->realm()->behaviors().discardSource()) {
return true;
}
if (options.sourceIsLazy) {
sourceRetrievable_ = true;
return true;
}
JSRuntime* runtime = cx->zone()->runtimeFromAnyThread();
auto& cache = runtime->sharedImmutableStrings();
@ -2210,14 +2271,16 @@ bool ScriptSource::setSourceCopy(JSContext* cx, SourceText<Unit>& srcBuf) {
return false;
}
setSource<Unit>(std::move(*deduped));
data = SourceType(Uncompressed<Unit>(std::move(*deduped)));
return true;
}
template bool ScriptSource::setSourceCopy(JSContext* cx,
SourceText<char16_t>& srcBuf);
template bool ScriptSource::setSourceCopy(JSContext* cx,
SourceText<Utf8Unit>& srcBuf);
template bool ScriptSource::assignSource(JSContext* cx,
const ReadOnlyCompileOptions& options,
SourceText<char16_t>& srcBuf);
template bool ScriptSource::assignSource(JSContext* cx,
const ReadOnlyCompileOptions& options,
SourceText<Utf8Unit>& srcBuf);
void ScriptSource::trace(JSTracer* trc) {
#ifdef JS_BUILD_BINAST
@ -2349,15 +2412,15 @@ void SourceCompressionTask::runTask() {
source->performTaskWork(this);
}
void ScriptSource::setCompressedSourceFromTask(
void ScriptSource::convertToCompressedSourceFromTask(
SharedImmutableString compressed) {
data.match(SetCompressedSourceFromTask(this, compressed));
data.match(ConvertToCompressedSourceFromTask(this, compressed));
}
void SourceCompressionTask::complete() {
if (!shouldCancel() && resultString_.isSome()) {
ScriptSource* source = sourceHolder_.get();
source->setCompressedSourceFromTask(std::move(*resultString_));
source->convertToCompressedSourceFromTask(std::move(*resultString_));
}
}
@ -2433,6 +2496,13 @@ bool ScriptSource::xdrFinalizeEncoder(JS::TranscodeBuffer& buffer) {
return res.isOk();
}
template <typename Unit>
MOZ_MUST_USE bool ScriptSource::initializeUncompressedSource(
JSContext* cx, EntryUnits<Unit>&& source, size_t length) {
MOZ_ASSERT(data.is<Missing>(), "must be initializing a fresh ScriptSource");
return setUncompressedSourceHelper(cx, std::move(source), length);
}
template <typename Unit>
struct SourceDecoder {
XDRState<XDR_DECODE>* const xdr_;
@ -2455,8 +2525,8 @@ struct SourceDecoder {
MOZ_TRY(xdr_->codeChars(sourceUnits.get(), uncompressedLength_));
if (!scriptSource_->setSource(xdr_->cx(), std::move(sourceUnits),
uncompressedLength_)) {
if (!scriptSource_->initializeUncompressedSource(
xdr_->cx(), std::move(sourceUnits), uncompressedLength_)) {
return xdr_->fail(JS::TranscodeResult_Throw);
}
@ -2616,10 +2686,10 @@ XDRResult ScriptSource::XDR(XDRState<mode>* xdr,
}
MOZ_TRY(xdr->codeBytes(bytes.get(), compressedLength));
if (!(srcCharSize == 1 ? ss->setCompressedSource<Utf8Unit>(
if (!(srcCharSize == 1 ? ss->initializeWithCompressedSource<Utf8Unit>(
xdr->cx(), std::move(bytes),
compressedLength, uncompressedLength)
: ss->setCompressedSource<char16_t>(
: ss->initializeWithCompressedSource<char16_t>(
xdr->cx(), std::move(bytes),
compressedLength, uncompressedLength))) {
return xdr->fail(JS::TranscodeResult_Throw);

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

@ -546,7 +546,7 @@ class ScriptSource {
Uncompressed<char16_t>, Missing, BinAST>;
SourceType data;
// If the GC attempts to call setCompressedSource with PinnedUnits
// If the GC attempts to call convertToCompressedSource with PinnedUnits
// present, the first PinnedUnits (that is, bottom of the stack) will set
// the compressed chars upon destruction.
PinnedUnitsBase* pinnedUnitsStack_;
@ -691,10 +691,22 @@ class ScriptSource {
*/
static constexpr size_t MinimumCompressibleLength = 256;
template <typename Unit>
MOZ_MUST_USE bool setSourceCopy(JSContext* cx, JS::SourceText<Unit>& srcBuf);
private:
class LoadSourceMatcher;
public:
// Attempt to load usable source for |ss| -- source text on which substring
// operations and the like can be performed. On success return true and set
// |*loaded| to indicate whether usable source could be loaded; otherwise
// return false.
static bool loadSource(JSContext* cx, ScriptSource* ss, bool* loaded);
// Assign source data from |srcBuf| to this recently-created |ScriptSource|.
template <typename Unit>
MOZ_MUST_USE bool assignSource(JSContext* cx,
const JS::ReadOnlyCompileOptions& options,
JS::SourceText<Unit>& srcBuf);
void setSourceRetrievable() { sourceRetrievable_ = true; }
bool sourceRetrievable() const { return sourceRetrievable_; }
bool hasSourceText() const {
return hasUncompressedSource() || hasCompressedSource();
@ -946,25 +958,45 @@ class ScriptSource {
void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
JS::ScriptSourceInfo* info) const;
private:
// Overwrites |data| with the uncompressed data from |source|. (This function
// currently asserts |data.is<Missing>()|, but callers should assert it as
// well, because this function shortly will be used in other cases and the
// assertion will have to be removed.)
template <typename Unit>
MOZ_MUST_USE bool setSource(JSContext* cx, EntryUnits<Unit>&& source,
size_t length);
MOZ_MUST_USE bool setUncompressedSourceHelper(JSContext* cx,
EntryUnits<Unit>&& source,
size_t length);
public:
// Initialize a fresh |ScriptSource| with uncompressed source.
template <typename Unit>
void setSource(
typename SourceTypeTraits<Unit>::SharedImmutableString uncompressed);
MOZ_MUST_USE bool initializeUncompressedSource(JSContext* cx,
EntryUnits<Unit>&& source,
size_t length);
// Set the retrieved source for a |ScriptSource| whose source was recorded as
// missing but retrievable.
template <typename Unit>
MOZ_MUST_USE bool setRetrievedSource(JSContext* cx, EntryUnits<Unit>&& source,
size_t length);
MOZ_MUST_USE bool tryCompressOffThread(JSContext* cx);
// The Unit parameter determines which type of compressed source is
// recorded, but raw compressed source is always single-byte.
// Convert this ScriptSource from storing uncompressed source of the given
// type, to storing compressed source. (Raw compressed source is always
// single-byte; |Unit| just records the encoding of the uncompressed source.)
template <typename Unit>
void setCompressedSource(SharedImmutableString compressed,
size_t sourceLength);
void convertToCompressedSource(SharedImmutableString compressed,
size_t sourceLength);
// Initialize a fresh ScriptSource as containing compressed source of the
// indicated original encoding.
template <typename Unit>
MOZ_MUST_USE bool setCompressedSource(JSContext* cx, UniqueChars&& raw,
size_t rawLength, size_t sourceLength);
MOZ_MUST_USE bool initializeWithCompressedSource(JSContext* cx,
UniqueChars&& raw,
size_t rawLength,
size_t sourceLength);
#if defined(JS_BUILD_BINAST)
@ -990,18 +1022,18 @@ class ScriptSource {
private:
void performTaskWork(SourceCompressionTask* task);
struct SetCompressedSourceFromTask {
struct ConvertToCompressedSourceFromTask {
ScriptSource* const source_;
SharedImmutableString& compressed_;
SetCompressedSourceFromTask(ScriptSource* source,
SharedImmutableString& compressed)
ConvertToCompressedSourceFromTask(ScriptSource* source,
SharedImmutableString& compressed)
: source_(source), compressed_(compressed) {}
template <typename Unit>
void operator()(const Uncompressed<Unit>&) {
source_->setCompressedSource<Unit>(std::move(compressed_),
source_->length());
source_->convertToCompressedSource<Unit>(std::move(compressed_),
source_->length());
}
template <typename Unit>
@ -1026,7 +1058,7 @@ class ScriptSource {
}
};
void setCompressedSourceFromTask(SharedImmutableString compressed);
void convertToCompressedSourceFromTask(SharedImmutableString compressed);
private:
// It'd be better to make this function take <XDRMode, Unit>, as both
@ -2494,8 +2526,6 @@ class JSScript : public js::gc::TenuredCell {
MOZ_MUST_USE bool appendSourceDataForToString(JSContext* cx,
js::StringBuffer& buf);
static bool loadSource(JSContext* cx, js::ScriptSource* ss, bool* worked);
void setSourceObject(js::ScriptSourceObject* object);
js::ScriptSourceObject* sourceObject() const { return sourceObject_; }
js::ScriptSource* scriptSource() const;

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

@ -6886,8 +6886,8 @@ static bool HandleInstantiationFailure(JSContext* cx, CallArgs args,
// Source discarding is allowed to affect JS semantics because it is never
// enabled for normal JS content.
bool haveSource = source->hasSourceText();
if (!haveSource && !JSScript::loadSource(cx, source, &haveSource)) {
bool haveSource;
if (!ScriptSource::loadSource(cx, source, &haveSource)) {
return false;
}
if (!haveSource) {
@ -7218,8 +7218,8 @@ JSString* js::AsmJSModuleToString(JSContext* cx, HandleFunction fun,
return nullptr;
}
bool haveSource = source->hasSourceText();
if (!haveSource && !JSScript::loadSource(cx, source, &haveSource)) {
bool haveSource;
if (!ScriptSource::loadSource(cx, source, &haveSource)) {
return nullptr;
}
@ -7269,8 +7269,8 @@ JSString* js::AsmJSFunctionToString(JSContext* cx, HandleFunction fun) {
return nullptr;
}
bool haveSource = source->hasSourceText();
if (!haveSource && !JSScript::loadSource(cx, source, &haveSource)) {
bool haveSource;
if (!ScriptSource::loadSource(cx, source, &haveSource)) {
return nullptr;
}

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

@ -577,13 +577,13 @@ already_AddRefed<gfxPattern> nsSVGRadialGradientFrame::CreateGradient() {
// representation divided by 2 to ensure that we get different cairo
// fractions
double dMax = std::max(0.0, r - 1.0 / 128);
float dx = fx - cx;
float dy = fy - cy;
double d = sqrt((dx * dx) + (dy * dy));
double dx = fx - cx;
double dy = fy - cy;
double d = std::sqrt((dx * dx) + (dy * dy));
if (d > dMax) {
double angle = atan2(dy, dx);
fx = (float)(dMax * cos(angle)) + cx;
fy = (float)(dMax * sin(angle)) + cy;
double angle = std::atan2(dy, dx);
fx = float(dMax * std::cos(angle)) + cx;
fy = float(dMax * std::sin(angle)) + cy;
}
}

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

@ -19,5 +19,5 @@ origin:
license: "ISC"
# update.sh will update this value
release: "3570749942a4fea2b7e372833cb8374ce42cf389 (2019-04-24 13:04:01 +1200)"
release: "64aa80f330a3dc510b1e3ac0e92cc6bed129a9a6 (2019-04-25 17:32:33 +0200)"

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

@ -485,16 +485,12 @@ public:
XASSERT(cubeb_context->output_collection_changed_callback ||
cubeb_context->input_collection_changed_callback);
LOG("collection: Audio device state changed, id = %S, state = %lu.", device_id, new_state);
if (new_state == DEVICE_STATE_ACTIVE ||
new_state == DEVICE_STATE_NOTPRESENT ||
new_state == DEVICE_STATE_UNPLUGGED) {
EDataFlow flow;
HRESULT hr = GetDataFlow(device_id, &flow);
if (FAILED(hr)) {
return hr;
}
monitor_notifications.notify(flow);
EDataFlow flow;
HRESULT hr = GetDataFlow(device_id, &flow);
if (FAILED(hr)) {
return hr;
}
monitor_notifications.notify(flow);
return S_OK;
}

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

@ -399,17 +399,32 @@ test! {
// Start the timer now, the initial job creation may be delayed by BITS service startup.
let start = Instant::now();
// First immediate report
monitor.get_status(timeout).expect("should initially be ok").unwrap();
// First report, immediate
let report_1 = monitor.get_status(timeout);
let elapsed_to_report_1 = start.elapsed();
report_1.as_ref().expect("should initially be ok").as_ref().unwrap();
// Transferred notification should come when the job completes in ~250 ms, otherwise we
// will be stuck until timeout.
let status = monitor.get_status(timeout).expect("should get status update").unwrap();
assert!(start.elapsed() < Duration::from_millis(9_000));
assert_eq!(status.state, BitsJobState::Transferred);
let report_2 = monitor.get_status(timeout).expect("should get status update").unwrap();
let elapsed_to_report_2 = start.elapsed();
assert!(elapsed_to_report_2 < Duration::from_millis(9_000));
assert_eq!(report_2.state, BitsJobState::Transferred);
let short_timeout = 500;
monitor.get_status(short_timeout).expect_err("should be disconnected");
let report_3 = monitor.get_status(short_timeout);
let elapsed_to_report_3 = start.elapsed();
if let Ok(report_3) = report_3 {
panic!("should be disconnected\n\
report_1 ({}.{:03}): {:?}\n\
report_2 ({}.{:03}): {:?}\n\
report_3 ({}.{:03}): {:?}",
elapsed_to_report_1.as_secs(), elapsed_to_report_1.subsec_millis(), report_1,
elapsed_to_report_2.as_secs(), elapsed_to_report_2.subsec_millis(), report_2,
elapsed_to_report_3.as_secs(), elapsed_to_report_3.subsec_millis(), report_3,
);
}
server.shutdown();

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

@ -646,6 +646,7 @@ const isDummyDocument = document.documentURI == "chrome://extensions/content/dum
if (!isDummyDocument) {
for (let script of [
"chrome://global/content/elements/general.js",
"chrome://global/content/elements/button.js",
"chrome://global/content/elements/checkbox.js",
"chrome://global/content/elements/menu.js",
"chrome://global/content/elements/menupopup.js",

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

@ -83,6 +83,7 @@ toolkit.jar:
content/global/elements/autocomplete-popup.js (widgets/autocomplete-popup.js)
content/global/elements/autocomplete-richlistitem.js (widgets/autocomplete-richlistitem.js)
content/global/elements/browser-custom-element.js (widgets/browser-custom-element.js)
content/global/elements/button.js (widgets/button.js)
content/global/elements/checkbox.js (widgets/checkbox.js)
content/global/elements/datetimebox.js (widgets/datetimebox.js)
content/global/elements/findbar.js (widgets/findbar.js)

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

@ -0,0 +1,291 @@
/* 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";
// This is loaded into all XUL windows. Wrap in a block to prevent
// leaking to window scope.
{
class MozButtonBase extends MozElements.BaseText {
constructor() {
super();
/**
* While it would seem we could do this by handling oncommand, we can't
* because any external oncommand handlers might get called before ours,
* and then they would see the incorrect value of checked. Additionally
* a command attribute would redirect the command events anyway.
*/
this.addEventListener("click", (event) => {
if (event.button != 0) {
return;
}
this._handleClick();
});
this.addEventListener("keypress", (event) => {
if (event.key != " ") {
return;
}
this._handleClick();
// Prevent page from scrolling on the space key.
event.preventDefault();
});
this.addEventListener("keypress", (event) => {
if (this.hasMenu()) {
if (this.open)
return;
} else {
if (event.keyCode == KeyEvent.DOM_VK_UP ||
(event.keyCode == KeyEvent.DOM_VK_LEFT &&
document.defaultView.getComputedStyle(this.parentNode)
.direction == "ltr") ||
(event.keyCode == KeyEvent.DOM_VK_RIGHT &&
document.defaultView.getComputedStyle(this.parentNode)
.direction == "rtl")) {
event.preventDefault();
window.document.commandDispatcher.rewindFocus();
return;
}
if (event.keyCode == KeyEvent.DOM_VK_DOWN ||
(event.keyCode == KeyEvent.DOM_VK_RIGHT &&
document.defaultView.getComputedStyle(this.parentNode)
.direction == "ltr") ||
(event.keyCode == KeyEvent.DOM_VK_LEFT &&
document.defaultView.getComputedStyle(this.parentNode)
.direction == "rtl")) {
event.preventDefault();
window.document.commandDispatcher.advanceFocus();
return;
}
}
if (event.keyCode || event.charCode <= 32 || event.altKey ||
event.ctrlKey || event.metaKey)
return; // No printable char pressed, not a potential accesskey
// Possible accesskey pressed
var charPressedLower = String.fromCharCode(event.charCode).toLowerCase();
// If the accesskey of the current button is pressed, just activate it
if (this.accessKey.toLowerCase() == charPressedLower) {
this.click();
return;
}
// Search for accesskey in the list of buttons for this doc and each subdoc
// Get the buttons for the main document and all sub-frames
for (var frameCount = -1; frameCount < window.top.frames.length; frameCount++) {
var doc = (frameCount == -1) ? window.top.document :
window.top.frames[frameCount].document;
if (this.fireAccessKeyButton(doc.documentElement, charPressedLower))
return;
}
// Test anonymous buttons
var dlg = window.top.document;
var buttonBox = dlg.getAnonymousElementByAttribute(dlg.documentElement,
"anonid", "buttons");
if (buttonBox)
this.fireAccessKeyButton(buttonBox, charPressedLower);
});
}
set type(val) {
this.setAttribute("type", val);
return val;
}
get type() {
return this.getAttribute("type");
}
set disabled(val) {
if (val) {
this.setAttribute("disabled", "true");
} else {
this.removeAttribute("disabled");
}
return val;
}
get disabled() {
return (this.getAttribute("disabled") == "true");
}
set dlgType(val) {
this.setAttribute("dlgtype", val);
return val;
}
get dlgType() {
return this.getAttribute("dlgtype");
}
set group(val) {
this.setAttribute("group", val);
return val;
}
get group() {
return this.getAttribute("group");
}
set open(val) {
if (this.hasMenu()) {
this.openMenu(val);
} else if (val) {
// Fall back to just setting the attribute
this.setAttribute("open", "true");
} else {
this.removeAttribute("open");
}
return val;
}
get open() {
return this.hasAttribute("open");
}
set checked(val) {
if (this.type == "radio" && val) {
var sibs = this.parentNode.getElementsByAttribute("group", this.group);
for (var i = 0; i < sibs.length; ++i)
sibs[i].removeAttribute("checked");
}
if (val)
this.setAttribute("checked", "true");
else
this.removeAttribute("checked");
return val;
}
get checked() {
return this.hasAttribute("checked");
}
filterButtons(node) {
// if the node isn't visible, don't descend into it.
var cs = node.ownerGlobal.getComputedStyle(node);
if (cs.visibility != "visible" || cs.display == "none") {
return NodeFilter.FILTER_REJECT;
}
// but it may be a popup element, in which case we look at "state"...
if (cs.display == "-moz-popup" && node.state != "open") {
return NodeFilter.FILTER_REJECT;
}
// OK - the node seems visible, so it is a candidate.
if (node.localName == "button" && node.accessKey && !node.disabled)
return NodeFilter.FILTER_ACCEPT;
return NodeFilter.FILTER_SKIP;
}
fireAccessKeyButton(aSubtree, aAccessKeyLower) {
var iterator = aSubtree.ownerDocument.createTreeWalker(aSubtree,
NodeFilter.SHOW_ELEMENT,
this.filterButtons);
while (iterator.nextNode()) {
var test = iterator.currentNode;
if (test.accessKey.toLowerCase() == aAccessKeyLower &&
!test.disabled && !test.collapsed && !test.hidden) {
test.focus();
test.click();
return true;
}
}
return false;
}
_handleClick() {
if (!this.disabled) {
if (this.type == "checkbox") {
this.checked = !this.checked;
} else if (this.type == "radio") {
this.checked = true;
}
}
}
}
MozXULElement.implementCustomInterface(MozButtonBase, [Ci.nsIDOMXULButtonElement]);
class MozButton extends MozButtonBase {
constructor() {
super();
this.hasConnected = false;
}
static get inheritedAttributes() {
return {
".box-inherit": "align,dir,pack,orient",
".button-icon": "src=image",
".button-text": "value=label,accesskey,crop",
".button-menu-dropmarker": "open,disabled,label",
};
}
get icon() {
return this.querySelector(".button-icon");
}
static get buttonFragment() {
let frag = document.importNode(MozXULElement.parseXULToFragment(`
<hbox class="box-inherit button-box" align="center" pack="center" flex="1" anonid="button-box">
<image class="button-icon"></image>
<label class="button-text"></label>
</hbox>`), true);
Object.defineProperty(this, "buttonFragment", {value: frag});
return frag;
}
static get menuFragment() {
let frag = document.importNode(MozXULElement.parseXULToFragment(`
<hbox class="box-inherit button-box" align="center" pack="center" flex="1">
<hbox class="box-inherit" align="center" pack="center" flex="1">
<image class="button-icon"></image>
<label class="button-text"></label>
</hbox>
<dropmarker class="button-menu-dropmarker"></dropmarker>
</hbox>`), true);
Object.defineProperty(this, "menuFragment", {value: frag});
return frag;
}
connectedCallback() {
if (this.delayConnectedCallback() || this.hasConnected) {
return;
}
this.hasConnected = true;
let fragment;
if (this.type === "menu") {
fragment = MozButton.menuFragment;
this.addEventListener("keypress", (event) => {
if (event.keyCode != KeyEvent.DOM_VK_RETURN && event.key != " ") {
return;
}
this.open = true;
// Prevent page from scrolling on the space key.
if (event.key == " ") {
event.preventDefault();
}
});
} else {
fragment = this.constructor.buttonFragment;
}
this.appendChild(fragment.cloneNode(true));
this.initializeAttributeInheritance();
}
}
customElements.define("button", MozButton);
}

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

@ -189,44 +189,4 @@
</handler>
</handlers>
</binding>
<binding id="button"
extends="chrome://global/content/bindings/button.xml#button-base">
<content>
<children includes="observes|template|menupopup|panel|tooltip"/>
<xul:hbox class="box-inherit button-box" xbl:inherits="align,dir,pack,orient"
align="center" pack="center" flex="1" anonid="button-box">
<xul:image class="button-icon" xbl:inherits="src=image"/>
<xul:label class="button-text" xbl:inherits="value=label,accesskey,crop,highlightable"/>
<xul:label class="button-highlightable-text" xbl:inherits="xbl:text=label,accesskey,crop,highlightable"/>
</xul:hbox>
</content>
</binding>
<binding id="menu"
extends="chrome://global/content/bindings/button.xml#button">
<content>
<children includes="observes|template|menupopup|panel|tooltip"/>
<xul:hbox class="box-inherit button-box" xbl:inherits="align,dir,pack,orient"
align="center" pack="center" flex="1">
<xul:hbox class="box-inherit" xbl:inherits="align,dir,pack,orient"
align="center" pack="center" flex="1">
<xul:image class="button-icon" xbl:inherits="src=image"/>
<xul:label class="button-text" xbl:inherits="value=label,accesskey,crop"/>
</xul:hbox>
<xul:dropmarker class="button-menu-dropmarker" xbl:inherits="open,disabled,label"/>
</xul:hbox>
</content>
<handlers>
<handler event="keypress" keycode="VK_RETURN" action="this.open = true;"/>
<handler event="keypress" key=" ">
<![CDATA[
this.open = true;
// Prevent page from scrolling on the space key.
event.preventDefault();
]]>
</handler>
</handlers>
</binding>
</bindings>

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

@ -105,16 +105,6 @@ label html|span.accesskey {
text-decoration: underline;
}
/********** button **********/
button {
-moz-binding: url("chrome://global/content/bindings/button.xml#button");
}
button[type="menu"] {
-moz-binding: url("chrome://global/content/bindings/button.xml#menu");
}
/********** toolbarbutton **********/
toolbarbutton {
@ -664,8 +654,6 @@ tabmodalprompt {
text-shadow: none;
}
.button-highlightable-text:not([highlightable="true"]),
.button-text[highlightable="true"],
.menulist-highlightable-label:not([highlightable="true"]),
.menulist-label[highlightable="true"],
.menu-iconic-highlightable-text:not([highlightable="true"]),

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

@ -692,6 +692,8 @@
<implementation>
<constructor><![CDATA[
window.customElements.upgrade(this._stateMenulist);
window.customElements.upgrade(this._enableBtn);
window.customElements.upgrade(this._disableBtn);
this._installStatus = document.getAnonymousElementByAttribute(this, "anonid", "install-status");
this._installStatus.mControl = this;

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

@ -67,7 +67,15 @@ void remoteClientNotificationCallback(CFNotificationCenterRef aCenter, void* aOb
// Autorelease pool to prevent memory leaks, in case there is no outer pool.
mozilla::MacAutoreleasePool pool;
NSDictionary* userInfoDict = (__bridge NSDictionary*)aUserInfo;
if (userInfoDict && [userInfoDict objectForKey:@"commandLineArgs"]) {
if (userInfoDict && [userInfoDict objectForKey:@"commandLineArgs"] &&
[userInfoDict objectForKey:@"senderPath"]) {
NSString* senderPath = [userInfoDict objectForKey:@"senderPath"];
if (![senderPath isEqual:[[NSBundle mainBundle] bundlePath]]) {
// The caller is not the process at the same path as we are at. Skipping.
return;
}
NSArray* args = [userInfoDict objectForKey:@"commandLineArgs"];
nsCOMPtr<nsICommandLineRunner> cmdLine(new nsCommandLine());
@ -201,16 +209,28 @@ NS_IMETHODIMP nsNativeAppSupportCocoa::Start(bool* _retval) {
if (!shallProceedLikeNoRemote) {
// We check for other running instances only if -no-remote was not specified.
// The check is needed so the marAppApplyUpdateSuccess.js test doesn't fail on next call.
runningInstanceFound =
[[NSRunningApplication
runningApplicationsWithBundleIdentifier:[[NSBundle mainBundle] bundleIdentifier]]
count] > 1;
NSArray* appsWithMatchingId = [NSRunningApplication runningApplicationsWithBundleIdentifier:
[[NSBundle mainBundle] bundleIdentifier]];
NSString* currentAppBundlePath = [[NSBundle mainBundle] bundlePath];
NSRunningApplication* currentApp = [NSRunningApplication currentApplication];
for (NSRunningApplication* app in appsWithMatchingId) {
if ([currentAppBundlePath isEqual:[[app bundleURL] path]] &&
![currentApp isEqual:app]) {
runningInstanceFound = YES;
break;
}
}
}
if (!shallProceedLikeNoRemote && !mozillaRestarting && runningInstanceFound) {
// There is another instance of this app already running!
NSArray* arguments = [[NSProcessInfo processInfo] arguments];
CFDictionaryRef userInfoDict = (__bridge CFDictionaryRef) @{@"commandLineArgs" : arguments};
NSString* senderPath = [[NSBundle mainBundle] bundlePath];
CFDictionaryRef userInfoDict = (__bridge CFDictionaryRef) @{@"commandLineArgs" :
arguments,
@"senderPath":
senderPath
};
// This code is shared between Firefox, Thunderbird and other Mozilla products.
// So we need a notification name that is unique to the product, so we