Merge autoland to mozilla-central. a=merge

This commit is contained in:
Cristian Tuns 2022-05-03 05:40:42 -04:00
commit 31dae823a3
714 changed files with 18181 additions and 10453 deletions

View File

@ -359,7 +359,6 @@ module.exports = {
"mozilla/reject-importGlobalProperties": "off",
"mozilla/use-cc-etc": "off",
"mozilla/use-chromeutils-generateqi": "off",
"mozilla/use-chromeutils-import": "off",
"mozilla/use-includes-instead-of-indexOf": "off",
"mozilla/use-ownerGlobal": "off",
"mozilla/use-services": "off",

View File

@ -1424,7 +1424,7 @@ void DocAccessible::ProcessQueuedCacheUpdates() {
for (auto iter = mQueuedCacheUpdates.Iter(); !iter.Done(); iter.Next()) {
LocalAccessible* acc = iter.Key();
uint64_t domain = iter.UserData();
if (!acc->IsDefunct()) {
if (acc->IsInDocument() && !acc->IsDefunct()) {
RefPtr<AccAttributes> fields =
acc->BundleFieldsForCache(domain, CacheUpdateType::Update);

View File

@ -191,20 +191,28 @@ Derived* RemoteAccessibleBase<Derived>::RemoteParent() const {
template <class Derived>
ENameValueFlag RemoteAccessibleBase<Derived>::Name(nsString& aName) const {
ENameValueFlag nameFlag = eNameOK;
if (mCachedFields) {
if (IsText()) {
mCachedFields->GetAttribute(nsGkAtoms::text, aName);
return eNameOK;
}
auto cachedNameFlag =
mCachedFields->GetAttribute<int32_t>(nsGkAtoms::explicit_name);
if (cachedNameFlag) {
nameFlag = static_cast<ENameValueFlag>(*cachedNameFlag);
}
if (mCachedFields->GetAttribute(nsGkAtoms::name, aName)) {
auto nameFlag =
mCachedFields->GetAttribute<int32_t>(nsGkAtoms::explicit_name);
VERIFY_CACHE(CacheDomain::NameAndDescription);
return nameFlag ? static_cast<ENameValueFlag>(*nameFlag) : eNameOK;
return nameFlag;
}
}
return eNameOK;
MOZ_ASSERT(aName.IsEmpty());
if (nameFlag != eNoNameOnPurpose) {
aName.SetIsVoid(true);
}
return nameFlag;
}
template <class Derived>

View File

@ -240,6 +240,9 @@ addAccessibleTask(
<h1 id="h1">content</h1>
<button id="buttonContent">content</button>
<button id="buttonLabel" aria-label="label">content</button>
<button id="buttonEmpty"></button>
<button id="buttonSummary"><details><summary>test</summary></details></button>
<div id="div"></div>
`,
async function(browser, docAcc) {
const h1 = findAccessibleChildByID(docAcc, "h1");
@ -248,6 +251,12 @@ addAccessibleTask(
testAbsentAttrs(buttonContent, { "explicit-name": "" });
const buttonLabel = findAccessibleChildByID(docAcc, "buttonLabel");
testAttrs(buttonLabel, { "explicit-name": "true" }, true);
const buttonEmpty = findAccessibleChildByID(docAcc, "buttonEmpty");
testAbsentAttrs(buttonEmpty, { "explicit-name": "" });
const buttonSummary = findAccessibleChildByID(docAcc, "buttonSummary");
testAbsentAttrs(buttonSummary, { "explicit-name": "" });
const div = findAccessibleChildByID(docAcc, "div");
testAbsentAttrs(div, { "explicit-name": "" });
info("Setting aria-label on h1");
let nameChanged = waitForEvent(EVENT_NAME_CHANGE, h1);

View File

@ -26,9 +26,8 @@ function openContextMenuFor(element, shiftkey, waitForSpellCheck) {
}
if (waitForSpellCheck) {
var { onSpellCheck } = SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm",
{}
var { onSpellCheck } = SpecialPowers.ChromeUtils.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm"
);
onSpellCheck(element, actuallyOpenContextMenuFor);
} else {

View File

@ -185,7 +185,9 @@ class TestFirefoxRefresh(MarionetteTestCase):
let resolve = arguments[arguments.length - 1];
const COMPLETE_STATE = Ci.nsIWebProgressListener.STATE_STOP +
Ci.nsIWebProgressListener.STATE_IS_NETWORK;
let {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
let { TabStateFlusher } = ChromeUtils.import(
"resource:///modules/sessionstore/TabStateFlusher.jsm"
);
let expectedURLs = Array.from(arguments[0])
gBrowser.addTabsProgressListener({
onStateChange(browser, webprogress, request, flags, status) {
@ -228,7 +230,9 @@ class TestFirefoxRefresh(MarionetteTestCase):
self.runAsyncCode(
"""
let resolve = arguments[arguments.length - 1];
Cu.import("resource://gre/modules/FxAccountsStorage.jsm");
let { FxAccountsStorageManager } = ChromeUtils.import(
"resource://gre/modules/FxAccountsStorage.jsm"
);
let storage = new FxAccountsStorageManager();
let data = {email: "test@test.com", uid: "uid", keyFetchToken: "top-secret"};
storage.initialize(data);
@ -465,7 +469,9 @@ class TestFirefoxRefresh(MarionetteTestCase):
def checkFxA(self):
result = self.runAsyncCode(
"""
Cu.import("resource://gre/modules/FxAccountsStorage.jsm");
let { FxAccountsStorageManager } = ChromeUtils.import(
"resource://gre/modules/FxAccountsStorage.jsm"
);
let resolve = arguments[arguments.length - 1];
let storage = new FxAccountsStorageManager();
let result = {};
@ -528,14 +534,20 @@ class TestFirefoxRefresh(MarionetteTestCase):
window.global = {};
global.LoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1", "nsILoginInfo", "init");
global.profSvc = Cc["@mozilla.org/toolkit/profile-service;1"].getService(Ci.nsIToolkitProfileService);
global.Preferences = Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
global.FormHistory = Cu.import("resource://gre/modules/FormHistory.jsm", {}).FormHistory;
global.Preferences = ChromeUtils.import(
"resource://gre/modules/Preferences.jsm"
).Preferences;
global.FormHistory = ChromeUtils.import(
"resource://gre/modules/FormHistory.jsm"
).FormHistory;
""" # NOQA: E501
)
self._formAutofillAvailable = self.runCode(
"""
try {
global.formAutofillStorage = Cu.import("resource://formautofill/FormAutofillStorage.jsm", {}).formAutofillStorage;
global.formAutofillStorage = ChromeUtils.import(
"resource://formautofill/FormAutofillStorage.jsm"
).formAutofillStorage;
} catch(e) {
return false;
}

View File

@ -716,7 +716,7 @@ body[lwt-newtab-brighttext] {
}
.onboardingContainer .secondary-cta.top {
justify-content: end;
padding-inline-end: 30px;
padding-inline-end: min(150px, 500px - 70vh);
padding-top: 4px;
position: absolute;
top: 10px;
@ -727,19 +727,8 @@ body[lwt-newtab-brighttext] {
color: #FFF;
}
.onboardingContainer .secondary-cta.top button:hover {
background-color: #5B5B66;
color: #E0E0E6;
}
@media (max-height: 570px) {
.onboardingContainer .secondary-cta.top button {
color: var(--in-content-link-color);
}
.onboardingContainer .secondary-cta.top button:hover {
background-color: #5B5B66;
color: var(--in-content-link-color-hover);
text-decoration: underline;
}
}
.onboardingContainer .secondary-cta span {
color: var(--grey-subtitle-1);
margin: 0 4px;

View File

@ -882,7 +882,7 @@ body {
&.top {
justify-content: end;
padding-inline-end: 30px;
padding-inline-end: min(150px, 500px - 70vh);
padding-top: 4px;
position: absolute;
top: 10px;
@ -893,19 +893,8 @@ body {
color: #FFF;
&:hover {
background-color: #5B5B66;
color: #E0E0E6;
}
@media (max-height: $break-point-small) {
color: var(--in-content-link-color);
&:hover {
background-color: #5B5B66;
color: var(--in-content-link-color-hover);
text-decoration: underline;
}
}
}
}

View File

@ -191,6 +191,7 @@ export class _DiscoveryStreamBase extends React.PureComponent {
type={component.type}
items={component.properties.items}
cta_variant={component.cta_variant}
pocket_button_enabled={component.pocketButtonEnabled}
display_engagement_labels={ENGAGEMENT_LABEL_ENABLED}
dismissible={this.props.DiscoveryStream.isCollectionDismissible}
dispatch={this.props.dispatch}
@ -227,6 +228,7 @@ export class _DiscoveryStreamBase extends React.PureComponent {
lastCardMessageEnabled={component.lastCardMessageEnabled}
saveToPocketCard={component.saveToPocketCard}
cta_variant={component.cta_variant}
pocket_button_enabled={component.pocketButtonEnabled}
display_engagement_labels={ENGAGEMENT_LABEL_ENABLED}
/>
);

View File

@ -110,6 +110,7 @@ export class CardGrid extends React.PureComponent {
context_type={rec.context_type}
bookmarkGuid={rec.bookmarkGuid}
engagement={rec.engagement}
pocket_button_enabled={this.props.pocket_button_enabled}
display_engagement_labels={this.props.display_engagement_labels}
hideDescriptions={hideDescriptions}
saveToPocketCard={saveToPocketCard}

View File

@ -52,7 +52,7 @@ export class CollectionCardGrid extends React.PureComponent {
}
render() {
const { data, dismissible } = this.props;
const { data, dismissible, pocket_button_enabled } = this.props;
if (
this.state.dismissed ||
!data ||
@ -111,6 +111,7 @@ export class CollectionCardGrid extends React.PureComponent {
const collectionGrid = (
<div className="ds-collection-card-grid">
<CardGrid
pocket_button_enabled={pocket_button_enabled}
title={title}
context={sponsoredByMessage}
data={recsData}

View File

@ -538,6 +538,7 @@ export class _DSCard extends React.PureComponent {
onMenuUpdate={this.onMenuUpdate}
onMenuShow={this.onMenuShow}
saveToPocketCard={saveToPocketCard}
pocket_button_enabled={this.props.pocket_button_enabled}
/>
</div>
</div>
@ -561,6 +562,7 @@ export class _DSCard extends React.PureComponent {
hostRef={this.contextMenuButtonHostRef}
onMenuUpdate={this.onMenuUpdate}
onMenuShow={this.onMenuShow}
pocket_button_enabled={this.props.pocket_button_enabled}
/>
)}
</div>

View File

@ -9,12 +9,16 @@ import React from "react";
export class DSLinkMenu extends React.PureComponent {
render() {
const { index, dispatch } = this.props;
let pocketMenuOptions = [];
if (this.props.pocket_button_enabled) {
pocketMenuOptions = this.props.saveToPocketCard
? ["CheckDeleteFromPocket"]
: ["CheckSavedToPocket"];
}
const TOP_STORIES_CONTEXT_MENU_OPTIONS = [
"CheckBookmark",
"CheckArchiveFromPocket",
...(this.props.saveToPocketCard
? ["CheckDeleteFromPocket"]
: ["CheckSavedToPocket"]),
...pocketMenuOptions,
"Separator",
"OpenInNewWindow",
"OpenInPrivateWindow",

View File

@ -6864,7 +6864,13 @@ class DSLinkMenu extends (external_React_default()).PureComponent {
index,
dispatch
} = this.props;
const TOP_STORIES_CONTEXT_MENU_OPTIONS = ["CheckBookmark", "CheckArchiveFromPocket", ...(this.props.saveToPocketCard ? ["CheckDeleteFromPocket"] : ["CheckSavedToPocket"]), "Separator", "OpenInNewWindow", "OpenInPrivateWindow", "Separator", "BlockUrl", ...(this.props.showPrivacyInfo ? ["ShowPrivacyInfo"] : [])];
let pocketMenuOptions = [];
if (this.props.pocket_button_enabled) {
pocketMenuOptions = this.props.saveToPocketCard ? ["CheckDeleteFromPocket"] : ["CheckSavedToPocket"];
}
const TOP_STORIES_CONTEXT_MENU_OPTIONS = ["CheckBookmark", "CheckArchiveFromPocket", ...pocketMenuOptions, "Separator", "OpenInNewWindow", "OpenInPrivateWindow", "Separator", "BlockUrl", ...(this.props.showPrivacyInfo ? ["ShowPrivacyInfo"] : [])];
const type = this.props.type || "DISCOVERY_STREAM";
const title = this.props.title || this.props.source;
return /*#__PURE__*/external_React_default().createElement("div", {
@ -7869,7 +7875,8 @@ class _DSCard extends (external_React_default()).PureComponent {
showPrivacyInfo: !!this.props.flightId,
onMenuUpdate: this.onMenuUpdate,
onMenuShow: this.onMenuShow,
saveToPocketCard: saveToPocketCard
saveToPocketCard: saveToPocketCard,
pocket_button_enabled: this.props.pocket_button_enabled
}))), !saveToPocketCard && /*#__PURE__*/external_React_default().createElement(DSLinkMenu, {
id: this.props.id,
index: this.props.pos,
@ -7885,7 +7892,8 @@ class _DSCard extends (external_React_default()).PureComponent {
showPrivacyInfo: !!this.props.flightId,
hostRef: this.contextMenuButtonHostRef,
onMenuUpdate: this.onMenuUpdate,
onMenuShow: this.onMenuShow
onMenuShow: this.onMenuShow,
pocket_button_enabled: this.props.pocket_button_enabled
}));
}
@ -8107,6 +8115,7 @@ class CardGrid extends (external_React_default()).PureComponent {
context_type: rec.context_type,
bookmarkGuid: rec.bookmarkGuid,
engagement: rec.engagement,
pocket_button_enabled: this.props.pocket_button_enabled,
display_engagement_labels: this.props.display_engagement_labels,
hideDescriptions: hideDescriptions,
saveToPocketCard: saveToPocketCard,
@ -8306,7 +8315,8 @@ class CollectionCardGrid extends (external_React_default()).PureComponent {
render() {
const {
data,
dismissible
dismissible,
pocket_button_enabled
} = this.props;
if (this.state.dismissed || !data || !data.spocs || !data.spocs[0] || // We only display complete collections.
@ -8369,6 +8379,7 @@ class CollectionCardGrid extends (external_React_default()).PureComponent {
const collectionGrid = /*#__PURE__*/external_React_default().createElement("div", {
className: "ds-collection-card-grid"
}, /*#__PURE__*/external_React_default().createElement(CardGrid, {
pocket_button_enabled: pocket_button_enabled,
title: title,
context: sponsoredByMessage,
data: recsData,
@ -13503,6 +13514,7 @@ class _DiscoveryStreamBase extends (external_React_default()).PureComponent {
type: component.type,
items: component.properties.items,
cta_variant: component.cta_variant,
pocket_button_enabled: component.pocketButtonEnabled,
display_engagement_labels: ENGAGEMENT_LABEL_ENABLED,
dismissible: this.props.DiscoveryStream.isCollectionDismissible,
dispatch: this.props.dispatch
@ -13536,6 +13548,7 @@ class _DiscoveryStreamBase extends (external_React_default()).PureComponent {
lastCardMessageEnabled: component.lastCardMessageEnabled,
saveToPocketCard: component.saveToPocketCard,
cta_variant: component.cta_variant,
pocket_button_enabled: component.pocketButtonEnabled,
display_engagement_labels: ENGAGEMENT_LABEL_ENABLED
});

View File

@ -65,6 +65,7 @@ const PREF_FLIGHT_BLOCKS = "discoverystream.flight.blocks";
const PREF_REC_IMPRESSIONS = "discoverystream.rec.impressions";
const PREF_COLLECTIONS_ENABLED =
"discoverystream.sponsored-collections.enabled";
const PREF_POCKET_BUTTON = "extensions.pocket.enabled";
const PREF_COLLECTION_DISMISSIBLE = "discoverystream.isCollectionDismissible";
const PREF_PERSONALIZATION = "discoverystream.personalization.enabled";
const PREF_PERSONALIZATION_OVERRIDE =
@ -455,6 +456,10 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
PREF_COLLECTIONS_ENABLED
];
const pocketButtonEnabled = Services.prefs.getBoolPref(
PREF_POCKET_BUTTON
);
const pocketConfig =
this.store.getState().Prefs.values?.pocketConfig || {};
@ -481,7 +486,8 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
fourCardLayout: pocketConfig.fourCardLayout,
loadMore: pocketConfig.loadMore,
lastCardMessageEnabled: pocketConfig.lastCardMessageEnabled,
saveToPocketCard: pocketConfig.saveToPocketCard,
pocketButtonEnabled,
saveToPocketCard: pocketButtonEnabled && pocketConfig.saveToPocketCard,
newFooterSection: pocketConfig.newFooterSection,
hideDescriptions: pocketConfig.hideDescriptions,
compactGrid: pocketConfig.compactGrid,
@ -1002,6 +1008,13 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
case "idle-daily":
this.updatePersonalizationScores();
break;
case "nsPref:changed":
// If the Pocket button was turned on or off, we need to update the cards
// because cards show menu options for the Pocket button that need to be removed.
if (data === PREF_POCKET_BUTTON) {
this.configReset();
}
break;
}
}
@ -1657,6 +1670,7 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
if (this.config.enabled) {
await this.enable();
}
Services.prefs.addObserver(PREF_POCKET_BUTTON, this);
break;
case at.DISCOVERY_STREAM_DEV_SYSTEM_TICK:
case at.SYSTEM_TICK:
@ -1835,6 +1849,7 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
// When this feed is shutting down:
this.uninitPrefs();
this._recommendationProvider = null;
Services.prefs.removeObserver(PREF_POCKET_BUTTON, this);
break;
case at.BLOCK_URL: {
// If we block a story that also has a flight_id
@ -1873,6 +1888,7 @@ this.DiscoveryStreamFeed = class DiscoveryStreamFeed {
`loadMore` Hide half the Pocket stories behind a load more button.
`lastCardMessageEnabled` Shows a message card at the end of the feed.
`newFooterSection` Changes the layout of the topics section.
`pocketButtonEnabled` Removes Pocket context menu items from cards.
`saveToPocketCard` Cards have a save to Pocket button over their thumbnail on hover.
`hideDescriptions` Hide or display descriptions for Pocket stories.
`compactGrid` Reduce the number of pixels between the Pocket cards.
@ -1895,6 +1911,7 @@ getHardcodedLayout = ({
loadMore = false,
lastCardMessageEnabled = false,
newFooterSection = false,
pocketButtonEnabled = false,
saveToPocketCard = false,
hideDescriptions = true,
compactGrid = false,
@ -1931,6 +1948,7 @@ getHardcodedLayout = ({
properties: {
items: 3,
},
pocketButtonEnabled,
header: {
title: "",
},
@ -1997,6 +2015,7 @@ getHardcodedLayout = ({
},
loadMore,
lastCardMessageEnabled,
pocketButtonEnabled,
saveToPocketCard,
cta_variant: "link",
header: {

View File

@ -30,6 +30,7 @@ describe("<DSLinkMenu>", () => {
describe("DS context menu options", () => {
const ValidDSLinkMenuProps = {
site: {},
pocket_button_enabled: true,
};
beforeEach(() => {
@ -110,11 +111,7 @@ describe("<DSLinkMenu>", () => {
it("should pass through the correct menu options to LinkMenu for save to Pocket button", () => {
wrapper = shallow(
<DSLinkMenu
{...ValidDSLinkMenuProps}
flightId="1234"
saveToPocketCard={true}
/>
<DSLinkMenu {...ValidDSLinkMenuProps} saveToPocketCard={true} />
);
wrapper
.find(ContextMenuButton)
@ -131,5 +128,24 @@ describe("<DSLinkMenu>", () => {
"BlockUrl",
]);
});
it("should pass through the correct menu options to LinkMenu if Pocket is disabled", () => {
wrapper = shallow(
<DSLinkMenu {...ValidDSLinkMenuProps} pocket_button_enabled={false} />
);
wrapper
.find(ContextMenuButton)
.simulate("click", { preventDefault: () => {} });
const linkMenuProps = wrapper.find(LinkMenu).props();
assert.deepEqual(linkMenuProps.options, [
"CheckBookmark",
"CheckArchiveFromPocket",
"Separator",
"OpenInNewWindow",
"OpenInPrivateWindow",
"Separator",
"BlockUrl",
]);
});
});
});

View File

@ -2846,12 +2846,20 @@ describe("DiscoveryStreamFeed", () => {
});
});
describe("#updatePersonalizationScores", () => {
describe("#observe", () => {
it("should call updatePersonalizationScores on idle daily", async () => {
sandbox.stub(feed, "updatePersonalizationScores").returns();
feed.observe(null, "idle-daily");
assert.calledOnce(feed.updatePersonalizationScores);
});
it("should call configReset on Pocket button pref change", async () => {
sandbox.stub(feed, "configReset").returns();
feed.observe(null, "nsPref:changed", "extensions.pocket.enabled");
assert.calledOnce(feed.configReset);
});
});
describe("#updatePersonalizationScores", () => {
it("should update recommendationProvider on updatePersonalizationScores", async () => {
feed.store.getState = () => ({
Prefs: {

View File

@ -34,7 +34,15 @@ function Article(props) {
: null;
}
const { article, savedArticle, position, source, model, utmParams } = props;
const {
article,
savedArticle,
position,
source,
model,
utmParams,
openInPocketReader,
} = props;
const url = new URL(article.url || article.resolved_url || "");
const urlSearchParams = new URLSearchParams(utmParams);
for (let [key, val] of urlSearchParams.entries()) {
@ -51,10 +59,21 @@ function Article(props) {
article.publisher ||
article.domain_metadata?.name ||
article.resolved_domain;
let constructedURL = url.href;
if (
openInPocketReader &&
article.item_id &&
!url.href.match(/getpocket\.com\/read/)
) {
constructedURL = `https://getpocket.com/read/${article.item_id}`;
}
return (
<li className="stp_article_list_item">
<ArticleUrl
url={url.href}
url={constructedURL}
savedArticle={savedArticle}
position={position}
source={source}
@ -94,6 +113,7 @@ function ArticleList(props) {
source={props.source}
model={props.model}
utmParams={props.utmParams}
openInPocketReader={props.openInPocketReader}
/>
))}
</ul>

View File

@ -95,6 +95,7 @@ function Home(props) {
articles={articles.slice(0, 3)}
source="home_recent_save"
utmParams={utmParams}
openInPocketReader={true}
/>
<span className="stp_button_wide">
<Button

View File

@ -138,7 +138,7 @@ function Saved(props) {
</Button>
</h3>
{savedStory && (
<ArticleList articles={[savedStory]} savedArticle={true} />
<ArticleList articles={[savedStory]} openInPocketReader={true} />
)}
<TagPicker tags={[]} itemUrl={itemUrl} />
{similarRecs?.length && locale?.startsWith("en") && (

View File

@ -168,7 +168,8 @@ function Article(props) {
position,
source,
model,
utmParams
utmParams,
openInPocketReader
} = props;
const url = new URL(article.url || article.resolved_url || "");
const urlSearchParams = new URLSearchParams(utmParams);
@ -183,10 +184,16 @@ function Article(props) {
const title = article.title || article.resolved_title; // Sometimes domain_metadata is not there, depending on the source.
const publisher = article.publisher || article.domain_metadata?.name || article.resolved_domain;
let constructedURL = url.href;
if (openInPocketReader && article.item_id && !url.href.match(/getpocket\.com\/read/)) {
constructedURL = `https://getpocket.com/read/${article.item_id}`;
}
return /*#__PURE__*/react.createElement("li", {
className: "stp_article_list_item"
}, /*#__PURE__*/react.createElement(ArticleUrl, {
url: url.href,
url: constructedURL,
savedArticle: savedArticle,
position: position,
source: source,
@ -218,7 +225,8 @@ function ArticleList(props) {
position: position,
source: props.source,
model: props.model,
utmParams: props.utmParams
utmParams: props.utmParams,
openInPocketReader: props.openInPocketReader
})));
}
@ -344,7 +352,8 @@ function Home(props) {
}), articles.length > 3 ? /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement(ArticleList_ArticleList, {
articles: articles.slice(0, 3),
source: "home_recent_save",
utmParams: utmParams
utmParams: utmParams,
openInPocketReader: true
}), /*#__PURE__*/react.createElement("span", {
className: "stp_button_wide"
}, /*#__PURE__*/react.createElement(Button_Button, {
@ -999,7 +1008,7 @@ function Saved(props) {
"data-l10n-id": "pocket-panel-button-remove"
}))), savedStory && /*#__PURE__*/react.createElement(ArticleList_ArticleList, {
articles: [savedStory],
savedArticle: true
openInPocketReader: true
}), /*#__PURE__*/react.createElement(TagPicker_TagPicker, {
tags: [],
itemUrl: itemUrl

View File

@ -4,10 +4,12 @@ const URL = BASE_URL + "autocomplete_basic.html";
const PRIVACY_PREF_URL = "about:preferences#privacy";
add_task(async function setup_storage() {
await saveAddress(TEST_ADDRESS_2);
await saveAddress(TEST_ADDRESS_3);
await saveAddress(TEST_ADDRESS_4);
await saveAddress(TEST_ADDRESS_5);
await setStorage(
TEST_ADDRESS_2,
TEST_ADDRESS_3,
TEST_ADDRESS_4,
TEST_ADDRESS_5
);
});
add_task(async function test_press_enter_on_footer() {
@ -101,7 +103,6 @@ add_task(async function test_phishing_warning_single_category() {
".autocomplete-richlistitem:last-child"
)._warningTextBox;
ok(warningBox, "Got phishing warning box");
await expectWarningText(browser, "Autofills phone");
is(
warningBox.ownerGlobal.getComputedStyle(warningBox).backgroundColor,

View File

@ -21,9 +21,7 @@ function checkPopup(autoCompletePopup) {
}
add_task(async function setup_storage() {
await saveAddress(TEST_ADDRESS_1);
await saveAddress(TEST_ADDRESS_2);
await saveAddress(TEST_ADDRESS_3);
await setStorage(TEST_ADDRESS_1, TEST_ADDRESS_2, TEST_ADDRESS_3);
});
add_task(async function test_back_forward() {

View File

@ -21,9 +21,7 @@ function checkPopup(autoCompletePopup) {
}
add_task(async function setup_storage() {
await saveAddress(TEST_ADDRESS_1);
await saveAddress(TEST_ADDRESS_2);
await saveAddress(TEST_ADDRESS_3);
await setStorage(TEST_ADDRESS_1, TEST_ADDRESS_2, TEST_ADDRESS_3);
});
add_task(async function test_detach_tab_marked() {

View File

@ -4,9 +4,7 @@ const URL =
"http://example.org/browser/browser/extensions/formautofill/test/browser/autocomplete_basic.html";
add_task(async function setup_storage() {
await saveAddress(TEST_ADDRESS_1);
await saveAddress(TEST_ADDRESS_2);
await saveAddress(TEST_ADDRESS_3);
await setStorage(TEST_ADDRESS_1, TEST_ADDRESS_2, TEST_ADDRESS_3);
});
async function reopenPopupWithResizedInput(browser, selector, newSize) {

View File

@ -168,7 +168,7 @@ add_task(
async function test_editAddressFrenchCanadianChangedToEnglishRepresentation() {
let addressClone = Object.assign({}, TEST_ADDRESS_CA_1);
addressClone["address-level1"] = "Colombie-Britannique";
await saveAddress(addressClone);
await setStorage(addressClone);
let addresses = await getAddresses();
await testDialog(

View File

@ -38,9 +38,7 @@ add_task(async function test_cancelManageAddressDialogWithESC() {
});
add_task(async function test_removingSingleAndMultipleAddresses() {
await saveAddress(TEST_ADDRESS_1);
await saveAddress(TEST_ADDRESS_2);
await saveAddress(TEST_ADDRESS_3);
await setStorage(TEST_ADDRESS_1, TEST_ADDRESS_2, TEST_ADDRESS_3);
let win = window.openDialog(MANAGE_ADDRESSES_DIALOG_URL, null, DIALOG_SIZE);
await waitForFocusAndFormReady(win);
@ -74,7 +72,7 @@ add_task(async function test_removingSingleAndMultipleAddresses() {
});
add_task(async function test_removingAdressViaKeyboardDelete() {
await saveAddress(TEST_ADDRESS_1);
await setStorage(TEST_ADDRESS_1);
let win = window.openDialog(MANAGE_ADDRESSES_DIALOG_URL, null, DIALOG_SIZE);
await waitForFocusAndFormReady(win);
@ -96,7 +94,7 @@ add_task(async function test_addressesDialogWatchesStorageChanges() {
let selRecords = win.document.querySelector(TEST_SELECTORS.selRecords);
await saveAddress(TEST_ADDRESS_1);
await setStorage(TEST_ADDRESS_1);
await BrowserTestUtils.waitForEvent(selRecords, "RecordsLoaded");
is(selRecords.length, 1, "One address is shown");

View File

@ -13,9 +13,7 @@ add_task(async function setup_storage() {
[ENABLED_AUTOFILL_ADDRESSES_CAPTURE_PREF, true],
],
});
await saveAddress(TEST_ADDRESS_2);
await saveAddress(TEST_ADDRESS_4);
await saveAddress(TEST_ADDRESS_5);
await setStorage(TEST_ADDRESS_2, TEST_ADDRESS_4, TEST_ADDRESS_5);
});
// Verify that form fillin works in a remote iframe, and that changing

View File

@ -2,7 +2,7 @@
"use strict";
add_task(async function test_update_address() {
await saveAddress(TEST_ADDRESS_1);
await setStorage(TEST_ADDRESS_1);
let addresses = await getAddresses();
is(addresses.length, 1, "1 address in storage");

View File

@ -18,6 +18,8 @@ skip-if = (!debug && os == "mac") || (os == "win" && ccov) # perma-fail see Bug
skip-if = ((os == "mac") || (os == 'linux') || (os == 'win'))
[browser_creditCard_fill_cancel_login.js]
skip-if = ((!debug && os == "mac") || (os == 'linux') || (os == 'win'))
[browser_creditCard_submission_normalized.js]
skip-if = apple_silicon && !debug
[browser_editCreditCardDialog.js]
skip-if = ((os == 'linux') || (os == "mac") || (os == 'win')) # perma-fail see Bug 1600059
[browser_insecure_form.js]

View File

@ -6,13 +6,14 @@ const CC_URL =
"https://example.org/browser/browser/extensions/formautofill/test/browser/creditCard/autocomplete_creditcard_basic.html";
add_task(async function setup_storage() {
await saveAddress(TEST_ADDRESS_1);
await saveAddress(TEST_ADDRESS_2);
await saveAddress(TEST_ADDRESS_3);
await saveCreditCard(TEST_CREDIT_CARD_1);
await saveCreditCard(TEST_CREDIT_CARD_2);
await saveCreditCard(TEST_CREDIT_CARD_3);
await setStorage(
TEST_ADDRESS_1,
TEST_ADDRESS_2,
TEST_ADDRESS_3,
TEST_CREDIT_CARD_1,
TEST_CREDIT_CARD_2,
TEST_CREDIT_CARD_3
);
});
add_task(async function test_active_delay() {

View File

@ -95,7 +95,7 @@ add_task(async function test_submit_untouched_creditCard_form() {
await SpecialPowers.pushPrefEnv({
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
});
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
@ -147,7 +147,7 @@ add_task(async function test_submit_untouched_creditCard_form_iframe() {
await SpecialPowers.pushPrefEnv({
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
});
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
@ -260,7 +260,7 @@ add_task(async function test_submit_changed_subset_creditCard_form() {
await SpecialPowers.pushPrefEnv({
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
});
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
@ -301,7 +301,7 @@ add_task(async function test_submit_duplicate_creditCard_form() {
await SpecialPowers.pushPrefEnv({
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
});
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
@ -344,7 +344,7 @@ add_task(async function test_submit_duplicate_creditCard_form() {
});
add_task(async function test_submit_unnormailzed_creditCard_form() {
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
@ -537,7 +537,7 @@ add_task(async function test_submit_manual_mergeable_creditCard_form() {
await SpecialPowers.pushPrefEnv({
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
});
await saveCreditCard(TEST_CREDIT_CARD_3);
await setStorage(TEST_CREDIT_CARD_3);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
@ -586,7 +586,7 @@ add_task(async function test_update_autofill_form_name() {
await SpecialPowers.pushPrefEnv({
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
});
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
@ -647,7 +647,7 @@ add_task(async function test_update_autofill_form_exp_date() {
await SpecialPowers.pushPrefEnv({
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
});
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
let onChanged = waitForStorageChangedEvents("update", "notifyUsed");
@ -706,7 +706,7 @@ add_task(async function test_create_new_autofill_form() {
await SpecialPowers.pushPrefEnv({
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
});
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
let onChanged = waitForStorageChangedEvents("add");
@ -765,12 +765,10 @@ add_task(async function test_update_duplicate_autofill_form() {
await SpecialPowers.pushPrefEnv({
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
});
await saveCreditCard({
"cc-number": "6387060366272981",
});
await saveCreditCard({
"cc-number": "5038146897157463",
});
await setStorage(
{ "cc-number": "6387060366272981" },
{ "cc-number": "5038146897157463" }
);
let creditCards = await getCreditCards();
is(creditCards.length, 2, "2 credit card in storage");
let onUsed = waitForStorageChangedEvents("notifyUsed");
@ -924,7 +922,7 @@ add_task(async function test_update_third_party_creditCard_logo() {
"cc-name": "John Doe",
};
await saveCreditCard(amexCard);
await setStorage(amexCard);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
@ -1000,7 +998,7 @@ add_task(async function test_update_generic_creditCard_logo() {
"cc-name": "John Doe",
};
await saveCreditCard(genericCard);
await setStorage(genericCard);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
@ -1076,7 +1074,7 @@ add_task(async function test_update_panel_with_spaces_in_cc_number_logo() {
"cc-name": "John Doe",
};
await saveCreditCard(amexCard);
await setStorage(amexCard);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");

View File

@ -4,9 +4,7 @@ const CC_URL =
"https://example.org/browser/browser/extensions/formautofill/test/browser/creditCard/autocomplete_creditcard_basic.html";
add_task(async function setup_storage() {
await saveCreditCard(TEST_CREDIT_CARD_1);
await saveCreditCard(TEST_CREDIT_CARD_2);
await saveCreditCard(TEST_CREDIT_CARD_3);
await setStorage(TEST_CREDIT_CARD_1, TEST_CREDIT_CARD_2, TEST_CREDIT_CARD_3);
});
async function reopenPopupWithResizedInput(browser, selector, newSize) {

View File

@ -9,7 +9,7 @@ add_task(async function test_fill_creditCard_but_cancel_login() {
return;
}
await saveCreditCard(TEST_CREDIT_CARD_2);
await setStorage(TEST_CREDIT_CARD_2);
let osKeyStoreLoginShown = OSKeyStoreTestUtils.waitForOSKeyStoreLogin(false); // cancel
await BrowserTestUtils.withNewTab(

View File

@ -0,0 +1,113 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// We want to ensure that non-normalized credit card data is normalized
// correctly as part of the save credit card flow
add_task(async function test_new_submitted_card_is_normalized() {
await SpecialPowers.pushPrefEnv({
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
});
const testCard = {
"cc-name": "Test User",
"cc-number": "5038146897157463",
"cc-exp-month": "4",
"cc-exp-year": "25",
};
const expectedData = {
"cc-name": "Test User",
"cc-number": "5038146897157463",
"cc-exp-month": "4",
// cc-exp-year should be normalized to 2025
"cc-exp-year": "2025",
};
let onChanged = waitForStorageChangedEvents("add");
await BrowserTestUtils.withNewTab(
{ gBrowser, url: CREDITCARD_FORM_URL },
async function(browser) {
let promiseShown = promiseNotificationShown();
await focusUpdateSubmitForm(browser, {
focusSelector: "#cc-name",
newValues: {
"#cc-name": testCard["cc-name"],
"#cc-number": testCard["cc-number"],
"#cc-exp-month": testCard["cc-exp-month"],
"#cc-exp-year": testCard["cc-exp-year"],
},
});
await promiseShown;
await clickDoorhangerButton(MAIN_BUTTON);
}
);
await onChanged;
let creditCards = await getCreditCards();
let savedCreditCard = creditCards[0];
let decryptedNumber = await OSKeyStore.decrypt(
savedCreditCard["cc-number-encrypted"]
);
savedCreditCard["cc-number"] = decryptedNumber;
for (let key in testCard) {
let expected = expectedData[key];
let actual = savedCreditCard[key];
Assert.equal(expected, actual, `${key} should match`);
}
});
add_task(async function test_updated_card_is_normalized() {
await SpecialPowers.pushPrefEnv({
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
});
const testCard = {
"cc-name": "Test User",
"cc-number": "5038146897157463",
"cc-exp-month": "11",
"cc-exp-year": "20",
};
await saveCreditCard(testCard);
const expectedData = {
"cc-name": "Test User",
"cc-number": "5038146897157463",
"cc-exp-month": "10",
// cc-exp-year should be normalized to 2027
"cc-exp-year": "2027",
};
let onChanged = waitForStorageChangedEvents("update");
await BrowserTestUtils.withNewTab(
{ gBrowser, url: CREDITCARD_FORM_URL },
async function(browser) {
let promiseShown = promiseNotificationShown();
await focusUpdateSubmitForm(browser, {
focusSelector: "#cc-name",
newValues: {
"#cc-name": testCard["cc-name"],
"#cc-number": testCard["cc-number"],
"#cc-exp-month": "10",
"#cc-exp-year": "27",
},
});
await promiseShown;
await clickDoorhangerButton(MAIN_BUTTON);
}
);
await onChanged;
let creditCards = await getCreditCards();
let savedCreditCard = creditCards[0];
savedCreditCard["cc-number"] = await OSKeyStore.decrypt(
savedCreditCard["cc-number-encrypted"]
);
for (let key in testCard) {
let expected = expectedData[key];
let actual = savedCreditCard[key];
Assert.equal(expected, actual, `${key} should match`);
}
});

View File

@ -156,7 +156,7 @@ add_task(async function test_popup_opened() {
Services.telemetry.clearScalars();
Services.telemetry.setEventRecordingEnabled("creditcard", true);
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
await BrowserTestUtils.withNewTab(
{ gBrowser, url: CREDITCARD_FORM_URL },
@ -312,7 +312,7 @@ add_task(async function test_submit_creditCard_autofill() {
],
});
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
@ -374,7 +374,7 @@ add_task(async function test_submit_creditCard_update() {
],
});
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");
@ -478,7 +478,7 @@ add_task(async function test_removingCreditCardsViaKeyboardDelete() {
set: [[ENABLED_AUTOFILL_CREDITCARDS_PREF, true]],
});
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let win = window.openDialog(
MANAGE_CREDIT_CARDS_DIALOG_URL,
null,
@ -555,7 +555,7 @@ add_task(async function test_editCreditCard() {
set: [[ENABLED_AUTOFILL_CREDITCARDS_PREF, true]],
});
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "only one credit card is in storage");
@ -600,9 +600,7 @@ add_task(async function test_histogram() {
Services.telemetry.getHistogramById(CC_NUM_USES_HISTOGRAM).clear();
Services.telemetry.setEventRecordingEnabled("creditcard", true);
await saveCreditCard(TEST_CREDIT_CARD_1);
await saveCreditCard(TEST_CREDIT_CARD_2);
await saveCreditCard(TEST_CREDIT_CARD_5);
await setStorage(TEST_CREDIT_CARD_1, TEST_CREDIT_CARD_2, TEST_CREDIT_CARD_5);
let creditCards = await getCreditCards();
is(creditCards.length, 3, "3 credit cards in storage");
@ -665,7 +663,7 @@ add_task(async function test_submit_creditCard_new_with_hidden_ui() {
],
});
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
await BrowserTestUtils.withNewTab(
{ gBrowser, url: CREDITCARD_FORM_URL },
@ -755,7 +753,7 @@ add_task(async function test_clear_creditCard_autofill() {
],
});
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "1 credit card in storage");

View File

@ -109,8 +109,7 @@ add_task(async function test_saveCreditCardWithMaxYear() {
});
add_task(async function test_saveCreditCardWithBillingAddress() {
await saveAddress(TEST_ADDRESS_4);
await saveAddress(TEST_ADDRESS_1);
await setStorage(TEST_ADDRESS_4, TEST_ADDRESS_1);
let addresses = await getAddresses();
let billingAddress = addresses[0];
@ -200,7 +199,7 @@ add_task(async function test_editCreditCardWithMissingBillingAddress() {
const TEST_CREDIT_CARD = Object.assign({}, TEST_CREDIT_CARD_2, {
billingAddressGUID: "unknown-guid",
});
await saveCreditCard(TEST_CREDIT_CARD);
await setStorage(TEST_CREDIT_CARD);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "one credit card in storage");
@ -287,7 +286,7 @@ add_task(async function test_editCardWithInvalidNetwork() {
const TEST_CREDIT_CARD = Object.assign({}, TEST_CREDIT_CARD_2, {
"cc-type": "asiv",
});
await saveCreditCard(TEST_CREDIT_CARD);
await setStorage(TEST_CREDIT_CARD);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "one credit card in storage");
@ -332,7 +331,7 @@ add_task(async function test_editCardWithInvalidNetwork() {
});
add_task(async function test_editInvalidCreditCardNumber() {
await saveAddress(TEST_ADDRESS_4);
await setStorage(TEST_ADDRESS_4);
let addresses = await getAddresses();
let billingAddress = addresses[0];
@ -404,7 +403,7 @@ add_task(async function test_editInvalidCreditCardNumber() {
add_task(async function test_editCreditCardWithInvalidNumber() {
const TEST_CREDIT_CARD = Object.assign({}, TEST_CREDIT_CARD_1);
await saveCreditCard(TEST_CREDIT_CARD);
await setStorage(TEST_CREDIT_CARD);
let creditCards = await getCreditCards();
is(creditCards.length, 1, "only one credit card is in storage");

View File

@ -9,13 +9,14 @@ const TEST_URL_PATH =
"://example.org" + HTTP_TEST_PATH + "autocomplete_basic.html";
add_task(async function setup_storage() {
await saveAddress(TEST_ADDRESS_1);
await saveAddress(TEST_ADDRESS_2);
await saveAddress(TEST_ADDRESS_3);
await saveCreditCard(TEST_CREDIT_CARD_1);
await saveCreditCard(TEST_CREDIT_CARD_2);
await saveCreditCard(TEST_CREDIT_CARD_3);
await setStorage(
TEST_ADDRESS_1,
TEST_ADDRESS_2,
TEST_ADDRESS_3,
TEST_CREDIT_CARD_1,
TEST_CREDIT_CARD_2,
TEST_CREDIT_CARD_3
);
});
add_task(async function test_insecure_form() {

View File

@ -41,11 +41,13 @@ add_task(async function test_removingSingleAndMultipleCreditCards() {
await SpecialPowers.pushPrefEnv({
set: [["privacy.reduceTimerPrecision", false]],
});
await saveCreditCard(TEST_CREDIT_CARD_1);
await saveCreditCard(TEST_CREDIT_CARD_2);
await saveCreditCard(TEST_CREDIT_CARD_3);
await saveCreditCard(TEST_CREDIT_CARD_4);
await saveCreditCard(TEST_CREDIT_CARD_5);
await setStorage(
TEST_CREDIT_CARD_1,
TEST_CREDIT_CARD_2,
TEST_CREDIT_CARD_3,
TEST_CREDIT_CARD_4,
TEST_CREDIT_CARD_5
);
let win = window.openDialog(
MANAGE_CREDIT_CARDS_DIALOG_URL,
@ -142,7 +144,7 @@ add_task(async function test_removingSingleAndMultipleCreditCards() {
});
add_task(async function test_removingCreditCardsViaKeyboardDelete() {
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let win = window.openDialog(
MANAGE_CREDIT_CARDS_DIALOG_URL,
null,
@ -172,7 +174,7 @@ add_task(async function test_creditCardsDialogWatchesStorageChanges() {
let selRecords = win.document.querySelector(TEST_SELECTORS.selRecords);
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
await BrowserTestUtils.waitForEvent(selRecords, "RecordsLoaded");
is(selRecords.length, 1, "One credit card is shown");
@ -186,11 +188,11 @@ add_task(async function test_showCreditCardIcons() {
await SpecialPowers.pushPrefEnv({
set: [["privacy.reduceTimerPrecision", false]],
});
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let unknownCard = Object.assign({}, TEST_CREDIT_CARD_3, {
"cc-type": "gringotts",
});
await saveCreditCard(unknownCard);
await setStorage(unknownCard);
let win = window.openDialog(
MANAGE_CREDIT_CARDS_DIALOG_URL,
@ -251,7 +253,7 @@ add_task(async function test_hasEditLoginPrompt() {
return;
}
await saveCreditCard(TEST_CREDIT_CARD_1);
await setStorage(TEST_CREDIT_CARD_1);
let win = window.openDialog(
MANAGE_CREDIT_CARDS_DIALOG_URL,

View File

@ -11,7 +11,7 @@
SYNC_USERNAME_PREF, SYNC_ADDRESSES_PREF, SYNC_CREDITCARDS_PREF, SYNC_CREDITCARDS_AVAILABLE_PREF, CREDITCARDS_USED_STATUS_PREF,
sleep, waitForStorageChangedEvents, waitForAutofill, focusUpdateSubmitForm, runAndWaitForAutocompletePopupOpen,
openPopupOn, openPopupForSubframe, closePopup, closePopupForSubframe,
clickDoorhangerButton, getAddresses, saveAddress, removeAddresses, saveCreditCard,
clickDoorhangerButton, getAddresses, saveAddress, removeAddresses, saveCreditCard, setStorage,
getDisplayedPopupItems, getDoorhangerCheckbox, waitForPopupEnabled,
getNotification, promiseNotificationShown, getDoorhangerButton, removeAllRecords, expectWarningText, testDialog */
@ -759,6 +759,22 @@ async function testDialog(url, testFn, arg = undefined) {
return unloadPromise;
}
/**
* Initializes the test storage for a task.
*
* @param {...Object} items Can either be credit card or address objects
*/
async function setStorage(...items) {
await removeAllRecords();
for (let item of items) {
if (item["cc-number"]) {
await saveCreditCard(item);
} else {
await saveAddress(item);
}
}
}
add_setup(function() {
OSKeyStoreTestUtils.setup();
});

View File

@ -9,7 +9,7 @@ let formFillChromeScript;
let defaultTextColor;
let expectingPopup = null;
const { FormAutofillUtils } = SpecialPowers.Cu.import(
const { FormAutofillUtils } = SpecialPowers.ChromeUtils.import(
"resource://autofill/FormAutofillUtils.jsm"
);

View File

@ -65,8 +65,7 @@ const TESTCASES = [
},
},
{
description:
'"country" using @autocomplete shouldn\'t be identified aggressively',
description: `"country" using @autocomplete shouldn't be identified aggressively`,
document: `<form>
<input id="given-name" autocomplete="given-name">
<input id="organization" autocomplete="organization">
@ -84,7 +83,7 @@ const TESTCASES = [
},
},
{
description: '"country" using heuristics should be identified aggressively',
description: `"country" using heuristics should be identified aggressively`,
document: `<form>
<input id="given-name" autocomplete="given-name">
<input id="organization" autocomplete="organization">
@ -107,7 +106,7 @@ const TESTCASES = [
},
},
{
description: '"tel" related fields should be concatenated',
description: `"tel" related fields should be concatenated`,
document: `<form>
<input id="given-name" autocomplete="given-name">
<input id="organization" autocomplete="organization">
@ -132,7 +131,7 @@ const TESTCASES = [
},
},
{
description: '"tel" should be removed if it\'s too short',
description: `"tel" should be removed if it's too short`,
document: `<form>
<input id="given-name" autocomplete="given-name">
<input id="organization" autocomplete="organization">
@ -158,7 +157,7 @@ const TESTCASES = [
},
},
{
description: '"tel" should be removed if it\'s too long',
description: `"tel" should be removed if it's too long`,
document: `<form>
<input id="given-name" autocomplete="given-name">
<input id="organization" autocomplete="organization">
@ -184,7 +183,7 @@ const TESTCASES = [
},
},
{
description: '"tel" should be removed if it contains invalid characters',
description: `"tel" should be removed if it contains invalid characters`,
document: `<form>
<input id="given-name" autocomplete="given-name">
<input id="organization" autocomplete="organization">
@ -446,6 +445,53 @@ const TESTCASES = [
],
},
},
{
description:
"A credit card form with separate expiry fields should have normalized expiry data.",
document: `<form>
<input id="cc-number" autocomplete="cc-number">
<input id="cc-exp-month" autocomplete="cc-exp-month">
<input id="cc-exp-year" autocomplete="cc-exp-year">
</form>`,
formValue: {
"cc-number": "5105105105105100",
"cc-exp-month": "05",
"cc-exp-year": "26",
},
expectedRecord: {
address: [],
creditCard: [
{
"cc-number": "5105105105105100",
"cc-exp-month": "5",
"cc-exp-year": "2026",
},
],
},
},
{
description:
"A credit card form with combined expiry fields should have normalized expiry data.",
document: `<form>
<input id="cc-number" autocomplete="cc-number">
<input id="cc-exp" autocomplete="cc-exp">
</form>`,
formValue: {
"cc-number": "5105105105105100",
"cc-exp": "07/27",
},
expectedRecord: {
address: [],
creditCard: [
{
"cc-number": "5105105105105100",
"cc-exp": "07/27",
"cc-exp-month": "7",
"cc-exp-year": "2027",
},
],
},
},
];
for (let testcase of TESTCASES) {

View File

@ -608,6 +608,19 @@ const AVAILABLE_SHIMS = [
matches: ["*://js.maxmind.com/js/apis/geoip2/*/geoip2.js"],
onlyIfBlockedByETP: true,
},
{
id: "WebTrends",
platform: "all",
name: "WebTrends",
bug: "1766414",
file: "webtrends.js",
matches: [
"*://s.webtrends.com/js/advancedLinkTracking.js",
"*://s.webtrends.com/js/webtrends.js",
"*://s.webtrends.com/js/webtrends.min.js",
],
onlyIfBlockedByETP: true,
},
];
module.exports = AVAILABLE_SHIMS;

View File

@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "Web Compatibility Interventions",
"description": "Urgent post-release fixes for web compatibility.",
"version": "101.0.0",
"version": "101.1.0",
"applications": {
"gecko": {
"id": "webcompat@mozilla.org",
@ -135,6 +135,7 @@
"shims/vast2.xml",
"shims/vast3.xml",
"shims/vidible.js",
"shims/vmad.xml"
"shims/vmad.xml",
"shims/webtrends.js"
]
}

View File

@ -133,6 +133,7 @@ FINAL_TARGET_FILES.features["webcompat@mozilla.org"]["shims"] += [
"shims/vast3.xml",
"shims/vidible.js",
"shims/vmad.xml",
"shims/webtrends.js",
]
FINAL_TARGET_FILES.features["webcompat@mozilla.org"]["lib"] += [

View File

@ -0,0 +1,46 @@
/* 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";
/**
* Bug 1766414 - Shim WebTrends Core Tag and Advanced Link Tracking
*
* Sites using WebTrends Core Tag or Link Tracking can break if they are
* are blocked. This shim mitigates that breakage by loading an empty module.
*/
if (!window.dcsMultiTrack) {
window.dcsMultiTrack = o => {
o?.callback?.({});
};
}
if (!window.WebTrends) {
class dcs {
addSelector() {
return this;
}
addTransform() {
return this;
}
DCSext = {};
init(obj) {
return this;
}
track() {
return this;
}
}
window.Webtrends = window.WebTrends = {
dcs,
multiTrack: window.dcsMultiTrack,
};
window.requestAnimationFrame(() => {
window.webtrendsAsyncLoad?.(dcs);
window.webtrendsAsyncInit?.();
});
}

View File

@ -20,8 +20,12 @@ var EXPORTED_SYMBOLS = ["PermissionUI"];
* permission request is coming up from content by way of the
* nsContentPermissionHelper. The system add-on could then do the following:
*
* Cu.import("resource://gre/modules/Integration.jsm");
* Cu.import("resource:///modules/PermissionUI.jsm");
* const { Integration } = ChromeUtils.import(
* "resource://gre/modules/Integration.jsm"
* );
* const { PermissionUI } = ChromeUtils.import(
* "resource:///modules/PermissionUI.jsm"
* );
*
* const SoundCardIntegration = (base) => ({
* __proto__: base,

View File

@ -36,8 +36,12 @@
var isInChrome = window.location.href.includes("chrome:");
if (isInChrome) {
var exports = {};
var { require, loader } = Cu.import("resource://devtools/shared/loader/Loader.jsm");
var { BrowserLoader } = Cu.import("resource://devtools/shared/loader/browser-loader.js");
var { require, loader } = ChromeUtils.import(
"resource://devtools/shared/loader/Loader.jsm"
);
var { BrowserLoader } = ChromeUtils.import(
"resource://devtools/shared/loader/browser-loader.js"
);
}
</script>

View File

@ -8,9 +8,9 @@ const {
createFactory,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const { getArrayTypeNames } = require("devtools/shared/webconsole/messages");
const {
l10n,
getArrayTypeNames,
getDescriptorValue,
} = require("devtools/client/webconsole/utils/messages");
loader.lazyGetter(this, "MODE", function() {

View File

@ -427,3 +427,4 @@ skip-if = (os == "win" && bits == 32) && !debug # Bug 1560261
[browser_webconsole_worker_evaluate.js]
[browser_webconsole_worker_promise_error.js]
[browser_webconsole_worklet_error.js]
[browser_webconsole_console_table_fallback.js]

View File

@ -0,0 +1,40 @@
/* 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/. */
// console.table fallback to console.log for unsupported parameters.
"use strict";
const tests = [
[`console.table(10, 20, 30, 40, 50)`, `10 20 30 40 50`],
[`console.table(1.2, 3.4, 5.6)`, `1.2 3.4 5.6`],
[`console.table(10n, 20n, 30n)`, `10n 20n 30n`],
[`console.table(true, false)`, `true false`],
[`console.table("foo", "bar", "baz")`, `foo bar baz`],
[`console.table(null, undefined, null)`, `null undefined null`],
[`console.table(undefined, null, undefined)`, `undefined null undefined`],
[`console.table(Symbol.iterator)`, `Symbol(Symbol.iterator)`],
[`console.table(/pattern/i)`, `/pattern/i`],
[`console.table(function f() {})`, `function f()`],
];
add_task(async function() {
const TEST_URI = "data:text/html,<!DOCTYPE html><meta charset=utf8>";
const hud = await openNewTabAndConsole(TEST_URI);
for (const [input, output] of tests) {
execute(hud, input);
const message = await waitFor(
() => findMessage(hud, output, ".console-api"),
`Waiting for output for ${input}`
);
is(
message.querySelector(".message-body").textContent,
output,
`Expected messages are displayed for ${input}`
);
}
});

View File

@ -7,6 +7,9 @@
const Services = require("Services");
const l10n = require("devtools/client/webconsole/utils/l10n");
const ResourceCommand = require("devtools/shared/commands/resource/resource-command");
const {
isSupportedByConsoleTable,
} = require("devtools/shared/webconsole/messages");
// URL Regex, common idioms:
//
@ -201,21 +204,7 @@ function transformConsoleAPICallResource(consoleMessageResource) {
}
break;
case "table":
const supportedClasses = [
"Object",
"Map",
"Set",
"WeakMap",
"WeakSet",
].concat(getArrayTypeNames());
if (
!Array.isArray(parameters) ||
parameters.length === 0 ||
!parameters[0] ||
!parameters[0].getGrip ||
!supportedClasses.includes(parameters[0].getGrip().class)
) {
if (!isSupportedByConsoleTable(parameters)) {
// If the class of the first parameter is not supported,
// we handle the call as a simple console.log
type = "log";
@ -825,23 +814,6 @@ function isCookieSameSiteMessage(message) {
return category == "cookieSameSite";
}
function getArrayTypeNames() {
return [
"Array",
"Int8Array",
"Uint8Array",
"Int16Array",
"Uint16Array",
"Int32Array",
"Uint32Array",
"Float32Array",
"Float64Array",
"Uint8ClampedArray",
"BigInt64Array",
"BigUint64Array",
];
}
function getDescriptorValue(descriptor) {
if (!descriptor) {
return descriptor;
@ -903,7 +875,6 @@ module.exports = {
areMessagesSimilar,
createWarningGroupMessage,
createSimpleTableMessage,
getArrayTypeNames,
getDescriptorValue,
getNaturalOrder,
getParentWarningGroupMessageId,

View File

@ -53,7 +53,7 @@ const Services = require("Services");
In the rare event where you don't have access to the DevTools' require method, you can use
```javascript
const { Services } = Components.utils.import("resource://gre/modules/Services.jsm");
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
```
### Services.pref.get* and Services.pref.set*

View File

@ -82,7 +82,7 @@ One exported symbol from ``Console.jsm`` is ``console``. Below is an example of
.. code-block:: JavaScript
Components.utils.import("resource://gre/modules/Console.jsm");
const { console } = ChromeUtils.import("resource://gre/modules/Console.jsm");
console.log("Hello from Firefox code"); //output messages to the console</pre>
Learn more:

View File

@ -34,7 +34,9 @@ This page shows how to use the :doc:`Debugger API <../index>` to show how many o
// This defines the 'Debugger' constructor in this
// Scratchpad; it doesn't actually start debugging anything.
Components.utils.import('resource://gre/modules/jsdebugger.jsm');
const { addDebuggerToGlobal } = ChromeUtils.import(
'resource://gre/modules/jsdebugger.jsm'
);
addDebuggerToGlobal(window);
(function () {

View File

@ -40,8 +40,12 @@ This tutorial was tested against Firefox 58 Beta and Nightly. It does not work i
.. code-block:: javascript
Components.utils.import("resource://gre/modules/jsdebugger.jsm");
Components.utils.import("resource://gre/modules/Console.jsm");
const { addDebuggerToGlobal } = ChromeUtils.import(
"resource://gre/modules/jsdebugger.jsm"
);
const { console } = ChromeUtils.import(
"resource://gre/modules/Console.jsm"
);
// This defines 'Debugger' in this Scratchpad;
// it doesn't actually start debugging anything.

View File

@ -25,6 +25,10 @@ const {
getActorIdForInternalSourceId,
} = require("devtools/server/actors/utils/dbg-source");
const {
isSupportedByConsoleTable,
} = require("devtools/shared/webconsole/messages");
/**
* Start watching for all console messages related to a given Target Actor.
* This will notify about existing console messages, but also the one created in future.
@ -141,14 +145,6 @@ module.exports = ConsoleMessageWatcher;
* console.table call.
*/
function getConsoleTableMessageItems(targetActor, result) {
if (
!result ||
!Array.isArray(result.arguments) ||
result.arguments.length == 0
) {
return null;
}
const [tableItemGrip] = result.arguments;
const dataType = tableItemGrip.class;
const needEntries = ["Map", "WeakMap", "Set", "WeakSet"].includes(dataType);
@ -262,14 +258,17 @@ function prepareConsoleMessageForRemote(targetActor, message) {
}
if (message.level === "table") {
const tableItems = getConsoleTableMessageItems(targetActor, result);
if (tableItems) {
result.arguments[0].ownProperties = tableItems;
result.arguments[0].preview = null;
}
if (result && isSupportedByConsoleTable(result.arguments)) {
const tableItems = getConsoleTableMessageItems(targetActor, result);
if (tableItems) {
result.arguments[0].ownProperties = tableItems;
result.arguments[0].preview = null;
// Only return the 2 first params.
result.arguments = result.arguments.slice(0, 2);
// Only return the 2 first params.
result.arguments = result.arguments.slice(0, 2);
}
}
// NOTE: See transformConsoleAPICallResource for not-supported case.
}
return result;

View File

@ -166,10 +166,15 @@ function createLongStringFront(conn, form) {
return front;
}
function createTestGlobal(name) {
const sandbox = Cu.Sandbox(
Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal)
function createTestGlobal(name, options) {
const principal = Cc["@mozilla.org/systemprincipal;1"].createInstance(
Ci.nsIPrincipal
);
// NOTE: The Sandbox constructor behaves differently based on the argument
// length.
const sandbox = options
? Cu.Sandbox(principal, options)
: Cu.Sandbox(principal);
sandbox.__name = name;
// Expose a few mocks to better represent a Window object.
// These attributes will be used by DOCUMENT_EVENT resource listener.

View File

@ -8,7 +8,9 @@ function run_test() {
"resource://gre/modules/jsdebugger.jsm"
);
addDebuggerToGlobal(this);
const g = createTestGlobal("test");
const g = createTestGlobal("test", {
wantGlobalProperties: ["ChromeUtils"],
});
const dbg = new Debugger();
const gw = dbg.addDebuggee(g);
@ -20,7 +22,9 @@ function run_test() {
enumerable: true
});
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
// This is a CCW.
XPCOMUtils.defineLazyGetter(this, "foo", function() { return "foo"; });

View File

@ -403,10 +403,16 @@ var {
// To ensure that the this passed to addDebuggerToGlobal is a global, the
// Debugger object needs to be defined in a sandbox.
const sandbox = Cu.Sandbox(principal, {});
const sandbox = Cu.Sandbox(principal, {
wantGlobalProperties: ["ChromeUtils"],
});
Cu.evalInSandbox(
"Components.utils.import('resource://gre/modules/jsdebugger.jsm');" +
"addDebuggerToGlobal(this);",
`
const { addDebuggerToGlobal } = ChromeUtils.import(
'resource://gre/modules/jsdebugger.jsm'
);
addDebuggerToGlobal(this);
`,
sandbox
);
const Debugger = sandbox.Debugger;

View File

@ -0,0 +1,55 @@
/* 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";
function getArrayTypeNames() {
return [
"Array",
"Int8Array",
"Uint8Array",
"Int16Array",
"Uint16Array",
"Int32Array",
"Uint32Array",
"Float32Array",
"Float64Array",
"Uint8ClampedArray",
"BigInt64Array",
"BigUint64Array",
];
}
/**
* Return true if the parameters passed to console.log is supported.
* The parameters can be either from server side (without getGrip) or client
* side (with getGrip).
*
* @param {Message} parameters
* @returns {Boolean}
*/
function isSupportedByConsoleTable(parameters) {
const supportedClasses = [
"Object",
"Map",
"Set",
"WeakMap",
"WeakSet",
].concat(getArrayTypeNames());
if (!Array.isArray(parameters) || parameters.length === 0 || !parameters[0]) {
return false;
}
if (parameters[0].getGrip) {
return supportedClasses.includes(parameters[0].getGrip().class);
}
return supportedClasses.includes(parameters[0].class);
}
module.exports = {
getArrayTypeNames,
isSupportedByConsoleTable,
};

View File

@ -28,6 +28,7 @@ GeneratedFile(
DevToolsModules(
"analyze-input-string.js",
"js-property-provider.js",
"messages.js",
"network-helper.js",
"parser-helper.js",
"throttle.js",

View File

@ -2,8 +2,7 @@
let self = this;
// eslint-disable-next-line mozilla/use-chromeutils-import
let { setTimeout } = Cu.import("resource://gre/modules/Timer.jsm");
let { setTimeout } = ChromeUtils.import("resource://gre/modules/Timer.jsm");
const CC = Components.Constructor;
const BinaryInputStream = CC(

View File

@ -35,7 +35,9 @@ var gStringBundle;
W3CTest.runner.requestLongerTimeout(2);
const { Services } = SpecialPowers.Cu.import("resource://gre/modules/Services.jsm");
const { Services } = SpecialPowers.ChromeUtils.import(
"resource://gre/modules/Services.jsm"
);
Services.locale.requestedLocales = ["en-US"];
SpecialPowers.pushPrefEnv({ "set": [

View File

@ -27,9 +27,8 @@ test(function() {
});
async_test(function(t) {
const { AppConstants } = SpecialPowers.Cu.import(
"resource://gre/modules/AppConstants.jsm",
{}
const { AppConstants } = SpecialPowers.ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
if (AppConstants.platform == "android") {

View File

@ -66,8 +66,9 @@ function getXHRDoc(t) {
});
}
const {AppConstants} =
SpecialPowers.Cu.import("resource://gre/modules/AppConstants.jsm", {});
const { AppConstants } = SpecialPowers.ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
if (AppConstants.NIGHTLY_BUILD) {
promise_test(t => {
let anim;

View File

@ -545,8 +545,9 @@ promise_test(t => {
}, 'Transform value for animation with no keyframe at offset 1 and its ' +
'iterationComposite is accumulate');
const {AppConstants} =
SpecialPowers.Cu.import("resource://gre/modules/AppConstants.jsm", {});
const { AppConstants } = SpecialPowers.ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
if (AppConstants.NIGHTLY_BUILD) {
promise_test(t => {
var div;

View File

@ -107,82 +107,6 @@
* various kinds.
*/
#ifdef MOZ_GECKO_PROFILER
namespace geckoprofiler::markers {
struct CCIntervalMarker {
static constexpr mozilla::Span<const char> MarkerTypeName() {
return mozilla::MakeStringSpan("CC");
}
static void StreamJSONMarkerData(
mozilla::baseprofiler::SpliceableJSONWriter& aWriter, bool aIsStart,
const mozilla::ProfilerString8View& aReason,
uint32_t aForgetSkippableBeforeCC, uint32_t aSuspectedAtCCStart,
uint32_t aRemovedPurples, const mozilla::CycleCollectorResults& aResults,
mozilla::TimeDuration aMaxSliceTime) {
if (aIsStart) {
aWriter.StringProperty("mReason", aReason);
aWriter.IntProperty("mSuspected", aSuspectedAtCCStart);
aWriter.IntProperty("mForgetSkippable", aForgetSkippableBeforeCC);
aWriter.IntProperty("mRemovedPurples", aRemovedPurples);
} else {
aWriter.TimeDoubleMsProperty("mMaxSliceTime",
aMaxSliceTime.ToMilliseconds());
aWriter.IntProperty("mSlices", aResults.mNumSlices);
aWriter.BoolProperty("mAnyManual", aResults.mAnyManual);
aWriter.BoolProperty("mForcedGC", aResults.mForcedGC);
aWriter.BoolProperty("mMergedZones", aResults.mMergedZones);
aWriter.IntProperty("mVisitedRefCounted", aResults.mVisitedRefCounted);
aWriter.IntProperty("mVisitedGCed", aResults.mVisitedGCed);
aWriter.IntProperty("mFreedRefCounted", aResults.mFreedRefCounted);
aWriter.IntProperty("mFreedGCed", aResults.mFreedGCed);
aWriter.IntProperty("mFreedJSZones", aResults.mFreedJSZones);
}
}
static mozilla::MarkerSchema MarkerTypeDisplay() {
using MS = mozilla::MarkerSchema;
MS schema{MS::Location::MarkerChart, MS::Location::MarkerTable,
MS::Location::TimelineMemory};
schema.AddStaticLabelValue(
"Description",
"Summary data for the core part of a cycle collection, possibly "
"encompassing a set of incremental slices. The main thread is not "
"blocked for the entire major CC interval, only for the individual "
"slices.");
schema.AddKeyLabelFormatSearchable("mReason", "Reason", MS::Format::String,
MS::Searchable::Searchable);
schema.AddKeyLabelFormat("mMaxSliceTime", "Max Slice Time",
MS::Format::Duration);
schema.AddKeyLabelFormat("mSuspected", "Suspected Objects",
MS::Format::Integer);
schema.AddKeyLabelFormat("mSlices", "Number of Slices",
MS::Format::Integer);
schema.AddKeyLabelFormat("mAnyManual", "Manually Triggered",
MS::Format::Integer);
schema.AddKeyLabelFormat("mForcedGC", "GC Forced", MS::Format::Integer);
schema.AddKeyLabelFormat("mMergedZones", "Zones Merged",
MS::Format::Integer);
schema.AddKeyLabelFormat("mForgetSkippable", "Forget Skippables",
MS::Format::Integer);
schema.AddKeyLabelFormat("mVisitedRefCounted", "Refcounted Objects Visited",
MS::Format::Integer);
schema.AddKeyLabelFormat("mVisitedGCed", "GC Objects Visited",
MS::Format::Integer);
schema.AddKeyLabelFormat("mFreedRefCounted", "Refcounted Objects Freed",
MS::Format::Integer);
schema.AddKeyLabelFormat("mFreedGCed", "GC Objects Freed",
MS::Format::Integer);
schema.AddKeyLabelFormat("mCollectedGCZones", "JS Zones Freed",
MS::Format::Integer);
schema.AddKeyLabelFormat("mRemovedPurples",
"Objects Removed From Purple Buffer",
MS::Format::Integer);
return schema;
}
};
} // namespace geckoprofiler::markers
#endif
namespace mozilla {
void CCGCScheduler::NoteGCBegin() {
@ -223,30 +147,52 @@ void CCGCScheduler::NoteGCEnd() {
}
}
void CCGCScheduler::NoteCCBegin(CCReason aReason, TimeStamp aWhen,
uint32_t aNumForgetSkippables,
uint32_t aSuspected, uint32_t aRemovedPurples) {
CycleCollectorResults ignoredResults;
PROFILER_MARKER(
"CC", GCCC, MarkerOptions(MarkerTiming::IntervalStart(aWhen)),
CCIntervalMarker,
/* aIsStart */ true,
ProfilerString8View::WrapNullTerminatedString(CCReasonToString(aReason)),
aNumForgetSkippables, aSuspected, aRemovedPurples, ignoredResults,
TimeDuration());
#ifdef MOZ_GECKO_PROFILER
struct CCIntervalMarker {
static constexpr mozilla::Span<const char> MarkerTypeName() {
return mozilla::MakeStringSpan("CC");
}
static void StreamJSONMarkerData(
baseprofiler::SpliceableJSONWriter& aWriter,
const mozilla::ProfilerString8View& aReason) {
if (aReason.Length()) {
aWriter.StringProperty("reason", aReason);
}
}
static mozilla::MarkerSchema MarkerTypeDisplay() {
using MS = mozilla::MarkerSchema;
MS schema{MS::Location::MarkerChart, MS::Location::MarkerTable,
MS::Location::TimelineMemory};
schema.AddStaticLabelValue(
"Description",
"Summary data for the core part of a cycle collection, possibly "
"encompassing a set of incremental slices. The main thread is not "
"blocked for the entire major CC interval, only for the individual "
"slices.");
schema.AddKeyLabelFormatSearchable("reason", "Reason", MS::Format::String,
MS::Searchable::Searchable);
return schema;
}
};
#endif
void CCGCScheduler::NoteCCBegin(CCReason aReason, TimeStamp aWhen) {
#ifdef MOZ_GECKO_PROFILER
profiler_add_marker(
"CC", baseprofiler::category::GCCC,
MarkerOptions(MarkerTiming::IntervalStart(aWhen)), CCIntervalMarker{},
ProfilerString8View::WrapNullTerminatedString(CCReasonToString(aReason)));
#endif
mIsCollectingCycles = true;
}
void CCGCScheduler::NoteCCEnd(const CycleCollectorResults& aResults,
TimeStamp aWhen,
mozilla::TimeDuration aMaxSliceTime) {
mCCollectedWaitingForGC += aResults.mFreedGCed;
mCCollectedZonesWaitingForGC += aResults.mFreedJSZones;
PROFILER_MARKER("CC", GCCC, MarkerOptions(MarkerTiming::IntervalEnd(aWhen)),
CCIntervalMarker, /* aIsStart */ false, nullptr, 0, 0, 0,
aResults, aMaxSliceTime);
void CCGCScheduler::NoteCCEnd(TimeStamp aWhen) {
#ifdef MOZ_GECKO_PROFILER
profiler_add_marker("CC", baseprofiler::category::GCCC,
MarkerOptions(MarkerTiming::IntervalEnd(aWhen)),
CCIntervalMarker{}, nullptr);
#endif
mIsCollectingCycles = false;
mLastCCEndTime = aWhen;
@ -658,8 +604,8 @@ js::SliceBudget CCGCScheduler::ComputeCCSliceBudget(
TimeDuration baseBudget =
aDeadline.IsNull() ? kICCSliceBudget : aDeadline - aNow;
if (aPrevSliceEndTime.IsNull()) {
// The first slice gets the standard slice time.
if (aCCBeginTime.IsNull()) {
// If no CC is in progress, use the standard slice time.
return js::SliceBudget(js::TimeBudget(baseBudget));
}

View File

@ -245,16 +245,13 @@ class CCGCScheduler {
// This is invoked when we reach the actual cycle collection portion of the
// overall cycle collection.
void NoteCCBegin(CCReason aReason, TimeStamp aWhen,
uint32_t aNumForgetSkippables, uint32_t aSuspected,
uint32_t aRemovedPurples);
void NoteCCBegin(CCReason aReason, TimeStamp aWhen);
// This is invoked when the whole process of collection is done -- i.e., CC
// preparation (eg ForgetSkippables) in addition to the CC itself. There
// really ought to be a separate name for the overall CC as opposed to the
// actual cycle collection portion.
void NoteCCEnd(const CycleCollectorResults& aResults, TimeStamp aWhen,
mozilla::TimeDuration aMaxSliceTime);
void NoteCCEnd(TimeStamp aWhen);
void NoteGCSliceEnd(TimeDuration aSliceDuration) {
if (mMajorGCReason == JS::GCReason::NO_REASON) {
@ -307,6 +304,13 @@ class CCGCScheduler {
return aSuspectedBeforeForgetSkippable - aSuspectedCCObjects;
}
// After collecting cycles, record the results that are used in scheduling
// decisions.
void NoteCycleCollected(const CycleCollectorResults& aResults) {
mCCollectedWaitingForGC += aResults.mFreedGCed;
mCCollectedZonesWaitingForGC += aResults.mFreedJSZones;
}
// Test if we are in the NoteCCBegin .. NoteCCEnd interval.
bool IsCollectingCycles() const { return mIsCollectingCycles; }

View File

@ -3611,7 +3611,7 @@ nsDOMWindowUtils::HandleFullscreenRequests(bool* aRetVal) {
return NS_OK;
}
nsresult nsDOMWindowUtils::ExitFullscreen() {
nsresult nsDOMWindowUtils::ExitFullscreen(bool aDontRestoreViewSize) {
PROFILER_MARKER_UNTYPED("Exit fullscreen", DOM);
nsCOMPtr<Document> doc = GetDocument();
NS_ENSURE_STATE(doc);
@ -3627,7 +3627,8 @@ nsresult nsDOMWindowUtils::ExitFullscreen() {
// set the window dimensions in advance. Since the resize message
// comes after the fullscreen change call, doing so could avoid an
// extra resize reflow after this point.
PrepareForFullscreenChange(GetDocShell(), oldSize);
PrepareForFullscreenChange(GetDocShell(),
aDontRestoreViewSize ? nsSize() : oldSize);
Document::ExitFullscreenInDocTree(doc);
return NS_OK;
}

View File

@ -106,7 +106,6 @@ struct CycleCollectorStats {
constexpr CycleCollectorStats() = default;
void Init();
void Clear();
void PrepareForCycleCollection(TimeStamp aNow);
void AfterPrepareForCycleCollectionSlice(TimeStamp aDeadline,
TimeStamp aBeginTime,
TimeStamp aMaybeAfterGCTime);
@ -1243,11 +1242,6 @@ void CycleCollectorStats::AfterCycleCollectionSlice() {
mBeginSliceTime = TimeStamp();
}
void CycleCollectorStats::PrepareForCycleCollection(TimeStamp aNow) {
mBeginTime = aNow;
mSuspected = nsCycleCollector_suspectedCount();
}
void CycleCollectorStats::AfterPrepareForCycleCollectionSlice(
TimeStamp aDeadline, TimeStamp aBeginTime, TimeStamp aMaybeAfterGCTime) {
mBeginSliceTime = aBeginTime;
@ -1433,10 +1427,7 @@ void nsJSContext::PrepareForCycleCollectionSlice(CCReason aReason,
}
if (!sScheduler.IsCollectingCycles()) {
sCCStats.PrepareForCycleCollection(beginTime);
sScheduler.NoteCCBegin(aReason, beginTime,
sCCStats.mForgetSkippableBeforeCC,
sCCStats.mSuspected, sCCStats.mRemovedPurples);
sScheduler.NoteCCBegin(aReason, beginTime);
}
sCCStats.AfterPrepareForCycleCollectionSlice(aDeadline, beginTime,
@ -1496,7 +1487,9 @@ void nsJSContext::BeginCycleCollectionCallback(CCReason aReason) {
MOZ_ASSERT(NS_IsMainThread());
TimeStamp startTime = TimeStamp::Now();
sCCStats.PrepareForCycleCollection(startTime);
sCCStats.mBeginTime =
sCCStats.mBeginSliceTime.IsNull() ? startTime : sCCStats.mBeginSliceTime;
sCCStats.mSuspected = nsCycleCollector_suspectedCount();
// Run forgetSkippable synchronously to reduce the size of the CC graph. This
// is particularly useful if we recently finished a GC.
@ -1517,8 +1510,7 @@ void nsJSContext::BeginCycleCollectionCallback(CCReason aReason) {
}
// static
void nsJSContext::EndCycleCollectionCallback(
const CycleCollectorResults& aResults) {
void nsJSContext::EndCycleCollectionCallback(CycleCollectorResults& aResults) {
MOZ_ASSERT(NS_IsMainThread());
sScheduler.KillCCRunner();
@ -1527,6 +1519,7 @@ void nsJSContext::EndCycleCollectionCallback(
// we previously called PrepareForCycleCollectionSlice(). During shutdown
// CCs, this won't happen.
sCCStats.AfterCycleCollectionSlice();
sScheduler.NoteCycleCollected(aResults);
TimeStamp endCCTimeStamp = TimeStamp::Now();
TimeDuration ccNowDuration = TimeBetween(sCCStats.mBeginTime, endCCTimeStamp);
@ -1546,7 +1539,6 @@ void nsJSContext::EndCycleCollectionCallback(
// Log information about the CC via telemetry, JSON and the console.
sCCStats.SendTelemetry(ccNowDuration);
sScheduler.NoteCCEnd(aResults, endCCTimeStamp, sCCStats.mMaxSliceTime);
uint32_t cleanups = std::max(sCCStats.mForgetSkippableBeforeCC, 1u);
@ -1555,6 +1547,7 @@ void nsJSContext::EndCycleCollectionCallback(
sCCStats.MaybeNotifyStats(aResults, ccNowDuration, cleanups);
// Update global state to indicate we have just run a cycle collection.
sScheduler.NoteCCEnd(endCCTimeStamp);
sCCStats.Clear();
}
@ -1752,7 +1745,8 @@ static void DOMGCSliceCallback(JSContext* aCx, JS::GCProgress aProgress,
// May need to kill the GC runner
sScheduler.KillGCRunner();
nsJSContext::MaybePokeCC();
TimeStamp now = TimeStamp::Now();
sScheduler.MaybePokeCC(now, nsCycleCollector_suspectedCount());
if (aDesc.isZone_) {
sScheduler.PokeFullGC();
@ -1761,8 +1755,7 @@ static void DOMGCSliceCallback(JSContext* aCx, JS::GCProgress aProgress,
sScheduler.KillFullGCTimer();
}
if (sScheduler.IsCCNeeded(TimeStamp::Now(),
nsCycleCollector_suspectedCount()) !=
if (sScheduler.IsCCNeeded(now, nsCycleCollector_suspectedCount()) !=
CCReason::NO_REASON) {
nsCycleCollector_dispatchDeferredDeletion();
}

View File

@ -86,7 +86,7 @@ class nsJSContext : public nsIScriptContext {
static void BeginCycleCollectionCallback(mozilla::CCReason aReason);
static void EndCycleCollectionCallback(
const mozilla::CycleCollectorResults& aResults);
mozilla::CycleCollectorResults& aResults);
// Return the longest CC slice time since ClearMaxCCSliceTime() was last
// called.

View File

@ -147,7 +147,6 @@ void TestCC::TimerFires(int aNumSlices) {
step = mScheduler.AdvanceCCRunner(idleDeadline, Now(), SuspectedCCObjects());
EXPECT_EQ(step.mAction, CCRunnerAction::CleanupDeferred);
mScheduler.NoteCCBegin(CCReason::API, Now(), 0, sSuspected, 0);
RunSlices(aNumSlices);
}
@ -178,7 +177,8 @@ void TestCC::EndCycleCollectionCallback() {
CycleCollectorResults results;
results.mFreedGCed = 10;
results.mFreedJSZones = 2;
mScheduler.NoteCCEnd(results, Now(), TimeDuration());
mScheduler.NoteCycleCollected(results);
mScheduler.NoteCCEnd(Now());
// Because > 0 zones were freed.
EXPECT_TRUE(mScheduler.NeedsGCAfterCC());
@ -186,6 +186,7 @@ void TestCC::EndCycleCollectionCallback() {
void TestCC::KillCCRunner() {
// nsJSContext::KillCCRunner
mScheduler.NoteCCEnd(Now());
mScheduler.KillCCRunner();
}

View File

@ -23,7 +23,9 @@ var lastContentType = -1;
const testURL = window.location.href + "/this/is/the/test/url";
const Cc = SpecialPowers.Cc;
const Ci = SpecialPowers.Ci;
var {AppConstants} = SpecialPowers.Cu.import("resource://gre/modules/AppConstants.jsm", {});
var { AppConstants } = SpecialPowers.ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
// Content policy / factory implementation for the test
var policyID = SpecialPowers.wrap(SpecialPowers.Components).ID("{b80e19d0-878f-d41b-2654-194714a4115c}");

View File

@ -10,7 +10,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107443
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
var {AppConstants} = SpecialPowers.Cu.import("resource://gre/modules/AppConstants.jsm", {});
var { AppConstants } = SpecialPowers.ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
/**
* Test for Bug 1107443, modified when it was backed out in bug 1329323.

View File

@ -1,4 +1,3 @@
// Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
var prefetch = Cc["@mozilla.org/prefetch-service;1"].getService(
Ci.nsIPrefetchService
);

View File

@ -837,11 +837,20 @@ ClientWebGLContext::SetContextOptions(JSContext* cx,
newOpts.antialias = attributes.mAntialias.Value();
}
if (attributes.mColorSpace.WasPassed()) {
newOpts.colorSpace = attributes.mColorSpace.Value();
}
if (StaticPrefs::gfx_color_management_native_srgb()) {
newOpts.ignoreColorSpace = false;
}
// Don't do antialiasing if we've disabled MSAA.
if (!StaticPrefs::webgl_msaa_samples()) {
newOpts.antialias = false;
}
// -
if (mInitialOptions && *mInitialOptions != newOpts) {
// Err if the options asked for aren't the same as what they were
// originally.

View File

@ -196,9 +196,9 @@ template <typename Arg>
struct QueueParamTraits {
template <typename U>
static bool Write(ProducerView<U>& aProducerView, const Arg& aArg) {
static_assert(mozilla::webgl::template IsTriviallySerializable<Arg>::value,
static_assert(std::is_trivially_copyable<Arg>::value,
"No QueueParamTraits specialization was found for this type "
"and it does not satisfy IsTriviallySerializable.");
"and it does not satisfy is_trivially_copyable.");
// Write self as binary
const auto begin = &aArg;
return aProducerView.Write(begin, begin + 1);
@ -206,9 +206,9 @@ struct QueueParamTraits {
template <typename U>
static bool Read(ConsumerView<U>& aConsumerView, Arg* aArg) {
static_assert(mozilla::webgl::template IsTriviallySerializable<Arg>::value,
static_assert(std::is_trivially_copyable<Arg>::value,
"No QueueParamTraits specialization was found for this type "
"and it does not satisfy IsTriviallySerializable.");
"and it does not satisfy is_trivially_copyable.");
// Read self as binary
return aConsumerView.Read(aArg, aArg + 1);
}

View File

@ -113,6 +113,8 @@ bool WebGLContextOptions::operator==(const WebGLContextOptions& r) const {
eq &= (failIfMajorPerformanceCaveat == r.failIfMajorPerformanceCaveat);
eq &= (xrCompatible == r.xrCompatible);
eq &= (powerPreference == r.powerPreference);
eq &= (colorSpace == r.colorSpace);
eq &= (ignoreColorSpace == r.ignoreColorSpace);
return eq;
}
@ -865,6 +867,13 @@ constexpr auto MakeArray(Args... args) -> std::array<T, sizeof...(Args)> {
return {{static_cast<T>(args)...}};
}
inline gfx::ColorSpace2 ToColorSpace2(const WebGLContextOptions& options) {
if (options.ignoreColorSpace) {
return gfx::ColorSpace2::UNKNOWN;
}
return gfx::ToColorSpace2(options.colorSpace);
}
// -
// For an overview of how WebGL compositing works, see:
@ -875,7 +884,8 @@ bool WebGLContext::PresentInto(gl::SwapChain& swapChain) {
if (!ValidateAndInitFB(nullptr)) return false;
{
auto presenter = swapChain.Acquire(mDefaultFB->mSize);
const auto colorSpace = ToColorSpace2(mOptions);
auto presenter = swapChain.Acquire(mDefaultFB->mSize, colorSpace);
if (!presenter) {
GenerateWarning("Swap chain surface creation failed.");
LoseContext();
@ -916,7 +926,8 @@ bool WebGLContext::PresentIntoXR(gl::SwapChain& swapChain,
const gl::MozFramebuffer& fb) {
OnEndOfFrame();
auto presenter = swapChain.Acquire(fb.mSize);
const auto colorSpace = ToColorSpace2(mOptions);
auto presenter = swapChain.Acquire(fb.mSize, colorSpace);
if (!presenter) {
GenerateWarning("Swap chain surface creation failed.");
LoseContext();
@ -1002,7 +1013,9 @@ void WebGLContext::CopyToSwapChain(WebGLFramebuffer* const srcFb,
InitSwapChain(*gl, srcFb->mSwapChain, consumerType);
auto presenter = srcFb->mSwapChain.Acquire(size);
// ColorSpace will need to be part of SwapChainOptions for DTWebgl.
const auto colorSpace = ToColorSpace2(mOptions);
auto presenter = srcFb->mSwapChain.Acquire(size, colorSpace);
if (!presenter) {
GenerateWarning("Swap chain surface creation failed.");
LoseContext();

View File

@ -248,7 +248,7 @@ struct ParamTraits<mozilla::WebGLContextOptions> final
using T = mozilla::WebGLContextOptions;
static bool Validate(const T& val) {
return ValidateParam(val.powerPreference);
return ValidateParam(val.powerPreference) && ValidateParam(val.colorSpace);
}
};
@ -261,6 +261,15 @@ struct ParamTraits<mozilla::dom::WebGLPowerPreference> final
static bool Validate(const T& val) { return val <= T::High_performance; }
};
template <>
struct ParamTraits<mozilla::dom::PredefinedColorSpace> final
: public ValidatedPlainOldDataSerializer<
mozilla::dom::PredefinedColorSpace> {
using T = mozilla::dom::PredefinedColorSpace;
static bool Validate(const T& val) { return val < T::EndGuard_; }
};
template <>
struct ParamTraits<mozilla::webgl::OpaqueFramebufferOptions> final
: public PlainOldDataSerializer<mozilla::webgl::OpaqueFramebufferOptions> {

View File

@ -339,18 +339,13 @@ enum class BufferKind : uint8_t {
struct FloatOrInt final // For TexParameter[fi] and friends.
{
const bool isFloat;
const GLfloat f;
const GLint i;
bool isFloat = false;
GLfloat f = 0;
GLint i = 0;
explicit FloatOrInt(GLint x = 0) : isFloat(false), f(x), i(x) {}
explicit FloatOrInt(GLfloat x) : isFloat(true), f(x), i(roundf(x)) {}
FloatOrInt& operator=(const FloatOrInt& x) {
memcpy(this, &x, sizeof(x));
return *this;
}
};
struct WebGLContextOptions {
@ -364,6 +359,8 @@ struct WebGLContextOptions {
bool xrCompatible = false;
dom::WebGLPowerPreference powerPreference =
dom::WebGLPowerPreference::Default;
dom::PredefinedColorSpace colorSpace = dom::PredefinedColorSpace::Srgb;
bool ignoreColorSpace = true; // Our legacy behavior.
bool shouldResistFingerprinting = true;
bool enableDebugRendererInfo = false;
@ -376,6 +373,22 @@ struct WebGLContextOptions {
}
};
namespace gfx {
inline ColorSpace2 ToColorSpace2(const dom::PredefinedColorSpace cs) {
switch (cs) {
case dom::PredefinedColorSpace::Srgb:
return ColorSpace2::SRGB;
case dom::PredefinedColorSpace::Display_p3:
return ColorSpace2::DISPLAY_P3;
case dom::PredefinedColorSpace::EndGuard_:
break;
}
MOZ_CRASH("Exhaustive switch");
}
} // namespace gfx
// -
template <typename _T>

View File

@ -2261,7 +2261,9 @@ Here's an example JS implementation of the above interface. The
usable by the doNothing() method.
``` js
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
function MyNumberInner() {
this.value = 111;

View File

@ -1,7 +1,9 @@
SimpleTest.waitForExplicitFinish();
// The main testing function.
var test = function(isContent) {
var test = async function(isContent) {
await SpecialPowers.contentTransformsReceived(window);
// Each definition is [eventType, prefSetting]
// Where we are setting the "privacy.resistFingerprinting" pref.
let eventDefs = [

View File

@ -49,7 +49,6 @@ support-files = test_bug336682.js
skip-if = toolkit == 'android' # android: TIMED_OUT
[test_bug412567.html]
[test_bug418986-3.html]
skip-if = e10s && os == 'win' # bug 1764560
[test_bug422132.html]
[test_bug426082.html]
[test_bug427537.html]
@ -193,9 +192,6 @@ skip-if = toolkit == 'android' # not supported
[test_error_events.html]
skip-if = toolkit == 'android' #TIMED_OUT
[test_event_handler_cc.html]
skip-if =
os == "linux" && bits == 64 && !debug # Bug 1564622
win10_2004 && bits == 64 && !debug # Bug 1564622
[test_eventctors.html]
skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
[test_eventctors_sensors.html]

View File

@ -49,14 +49,21 @@
return make_weak_ref(b);
}
addLoadEvent(function() {
let ref1 = setupTarget1();
let ref2 = setupTarget2();
var ref1;
var ref2;
var maxCounter = 10;
function GCCCUntilCollected() {
SpecialPowers.exactGC(function () {
SpecialPowers.forceCC();
SpecialPowers.forceGC();
SpecialPowers.forceGC();
if ((!weak_ref_dead(ref1) || !weak_ref_dead(ref2)) && --maxCounter > 0) {
requestIdleCallback(GCCCUntilCollected, {timeout: 250});
return;
}
ok(weak_ref_dead(ref1),
"Should collect cycle through callback global");
ok(weak_ref_dead(ref2),
@ -64,6 +71,12 @@
SimpleTest.finish();
});
}
addLoadEvent(function() {
ref1 = setupTarget1();
ref2 = setupTarget2();
GCCCUntilCollected();
});
</script>
</head>

View File

@ -631,7 +631,7 @@ nsresult MutableBlobStorage::DispatchToIOThread(
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(target);
mTaskQueue = new TaskQueue(target.forget(), "BlobStorage");
mTaskQueue = TaskQueue::Create(target.forget(), "BlobStorage");
}
nsCOMPtr<nsIRunnable> runnable(aRunnable);

View File

@ -12,7 +12,9 @@
<script type="application/javascript">
const { AppConstants } = SpecialPowers.Cu.import("resource://gre/modules/AppConstants.jsm", {});
const { AppConstants } = SpecialPowers.ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
let promptHandler;

View File

@ -31,7 +31,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=702949
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
var FileUtils = SpecialPowers.Cu.import("resource://gre/modules/FileUtils.jsm").FileUtils;
var { FileUtils } = SpecialPowers.ChromeUtils.import(
"resource://gre/modules/FileUtils.jsm"
);
var i = document.getElementsByTagName('input')[0];

View File

@ -2662,7 +2662,7 @@ nsresult BackgroundRequestChild::PreprocessHelper::Init(
// We use a TaskQueue here in order to be sure that the events are dispatched
// in the correct order. This is not guaranteed in case we use the I/O thread
// directly.
mTaskQueue = MakeRefPtr<TaskQueue>(target.forget(), "BackgroundRequestChild");
mTaskQueue = TaskQueue::Create(target.forget(), "BackgroundRequestChild");
ErrorResult errorResult;

View File

@ -27,6 +27,12 @@ interface nsIBrowserChild : nsISupports
void remoteDropLinks(in Array<nsIDroppedLinkItem> links);
/**
* Resolved after content has received a PBrowser::ChildToParentMatrix.
*/
[implicit_jscontext]
Promise contentTransformsReceived();
readonly attribute uint64_t tabId;
/*

View File

@ -1393,8 +1393,12 @@ interface nsIDOMWindowUtils : nsISupports {
/**
* Called when the child frame has fully exit fullscreen, so that the parent
* process can also fully exit.
*
* @param aDontResoreViewSize false if content view size is restored by
* original view size that is on entering full
* screen.
*/
void exitFullscreen();
void exitFullscreen([optional] in boolean aDontRestoreViewSize);
/**
* If sendQueryContentEvent()'s aAdditionalFlags argument is

View File

@ -539,6 +539,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BrowserChild)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWebNav)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowsingContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSessionStoreChild)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mContentTransformPromise)
NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_REFERENCE
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -548,6 +549,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(BrowserChild)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebNav)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowsingContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSessionStoreChild)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContentTransformPromise)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(BrowserChild)
@ -1300,6 +1302,11 @@ mozilla::ipc::IPCResult BrowserChild::RecvChildToParentMatrix(
mTopLevelViewportVisibleRectInBrowserCoords =
aTopLevelViewportVisibleRectInBrowserCoords;
if (mContentTransformPromise) {
mContentTransformPromise->MaybeResolveWithUndefined();
mContentTransformPromise = nullptr;
}
// Trigger an intersection observation update since ancestor viewports
// changed.
if (RefPtr<Document> toplevelDoc = GetTopLevelDocument()) {
@ -3849,6 +3856,28 @@ void BrowserChild::NotifyContentBlockingEvent(
}
}
NS_IMETHODIMP
BrowserChild::ContentTransformsReceived(JSContext* aCx,
dom::Promise** aPromise) {
auto* globalObject = xpc::CurrentNativeGlobal(aCx);
ErrorResult rv;
if (mChildToParentConversionMatrix) {
// Already received content transforms
RefPtr<Promise> promise =
Promise::CreateResolvedWithUndefined(globalObject, rv);
promise.forget(aPromise);
return rv.StealNSResult();
}
if (!mContentTransformPromise) {
mContentTransformPromise = Promise::Create(globalObject, rv);
}
MOZ_ASSERT(globalObject == mContentTransformPromise->GetGlobalObject());
NS_IF_ADDREF(*aPromise = mContentTransformPromise);
return rv.StealNSResult();
}
BrowserChildMessageManager::BrowserChildMessageManager(
BrowserChild* aBrowserChild)
: ContentFrameMessageManager(new nsFrameMessageManager(aBrowserChild)),

View File

@ -920,6 +920,9 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
Maybe<bool> mWindowSupportsProtectedMedia;
#endif
// If set, resolve when we receive ChildToParentMatrix.
RefPtr<dom::Promise> mContentTransformPromise;
DISALLOW_EVIL_CONSTRUCTORS(BrowserChild);
};

View File

@ -110,7 +110,7 @@
#include "mozilla/layers/ContentProcessController.h"
#include "mozilla/layers/ImageBridgeChild.h"
#ifdef NS_PRINTING
#include "mozilla/layout/RemotePrintJobChild.h"
# include "mozilla/layout/RemotePrintJobChild.h"
#endif
#include "mozilla/loader/ScriptCacheActors.h"
#include "mozilla/media/MediaChild.h"

View File

@ -215,7 +215,9 @@
messageManager.loadFrameScript("data:,addEventListener('MozAfterPaint', function(e) { sendAsyncMessage('MozAfterPaint'); },true);", false);
}
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
</script>
<toolbar id="controls">

View File

@ -296,12 +296,12 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ElementTranslationHandler)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
already_AddRefed<Promise> DOMLocalization::TranslateElements(
const Sequence<OwningNonNull<Element>>& aElements, ErrorResult& aRv) {
const nsTArray<OwningNonNull<Element>>& aElements, ErrorResult& aRv) {
return TranslateElements(aElements, nullptr, aRv);
}
already_AddRefed<Promise> DOMLocalization::TranslateElements(
const Sequence<OwningNonNull<Element>>& aElements,
const nsTArray<OwningNonNull<Element>>& aElements,
nsXULPrototypeDocument* aProto, ErrorResult& aRv) {
Sequence<OwningUTF8StringOrL10nIdArgs> l10nKeys;
RefPtr<ElementTranslationHandler> nativeHandler =
@ -315,7 +315,7 @@ already_AddRefed<Promise> DOMLocalization::TranslateElements(
}
for (auto& domElement : aElements) {
if (!domElement->HasAttr(kNameSpaceID_None, nsGkAtoms::datal10nid)) {
if (!domElement->HasAttr(nsGkAtoms::datal10nid)) {
continue;
}
@ -331,6 +331,7 @@ already_AddRefed<Promise> DOMLocalization::TranslateElements(
}
if (!domElements.AppendElement(domElement, fallible)) {
// This can't really happen, we SetCapacity'd above...
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}

View File

@ -64,9 +64,9 @@ class DOMLocalization : public intl::Localization {
already_AddRefed<Promise> TranslateFragment(nsINode& aNode, ErrorResult& aRv);
already_AddRefed<Promise> TranslateElements(
const Sequence<OwningNonNull<Element>>& aElements, ErrorResult& aRv);
const nsTArray<OwningNonNull<Element>>& aElements, ErrorResult& aRv);
already_AddRefed<Promise> TranslateElements(
const Sequence<OwningNonNull<Element>>& aElements,
const nsTArray<OwningNonNull<Element>>& aElements,
nsXULPrototypeDocument* aProto, ErrorResult& aRv);
already_AddRefed<Promise> TranslateRoots(ErrorResult& aRv);

View File

@ -197,15 +197,10 @@ void L10nMutations::FlushPendingTranslations() {
return;
}
Sequence<OwningNonNull<Element>> elements;
nsTArray<OwningNonNull<Element>> elements;
for (auto& elem : mPendingElements) {
if (!elem->HasAttr(kNameSpaceID_None, nsGkAtoms::datal10nid)) {
continue;
}
if (!elements.AppendElement(*elem, fallible)) {
mozalloc_handle_oom(0);
if (elem->HasAttr(nsGkAtoms::datal10nid)) {
elements.AppendElement(*elem);
}
}

View File

@ -2,7 +2,7 @@
* Common infrastructure for manifest tests.
**/
"use strict";
const { ManifestProcessor } = SpecialPowers.Cu.import(
const { ManifestProcessor } = SpecialPowers.ChromeUtils.import(
"resource://gre/modules/ManifestProcessor.jsm"
);
const processor = ManifestProcessor;

View File

@ -126,8 +126,9 @@ bool VP9Benchmark::IsVP9DecodeFast(bool aDefault) {
}
Benchmark::Benchmark(MediaDataDemuxer* aDemuxer, const Parameters& aParameters)
: QueueObject(new TaskQueue(GetMediaThreadPool(MediaThreadType::SUPERVISOR),
"Benchmark::QueueObject")),
: QueueObject(
TaskQueue::Create(GetMediaThreadPool(MediaThreadType::SUPERVISOR),
"Benchmark::QueueObject")),
mParameters(aParameters),
mKeepAliveUntilComplete(this),
mPlaybackState(this, aDemuxer) {
@ -171,12 +172,13 @@ void Benchmark::Init() {
BenchmarkPlayback::BenchmarkPlayback(Benchmark* aGlobalState,
MediaDataDemuxer* aDemuxer)
: QueueObject(new TaskQueue(GetMediaThreadPool(MediaThreadType::SUPERVISOR),
"BenchmarkPlayback::QueueObject")),
: QueueObject(
TaskQueue::Create(GetMediaThreadPool(MediaThreadType::SUPERVISOR),
"BenchmarkPlayback::QueueObject")),
mGlobalState(aGlobalState),
mDecoderTaskQueue(
new TaskQueue(GetMediaThreadPool(MediaThreadType::PLATFORM_DECODER),
"BenchmarkPlayback::mDecoderTaskQueue")),
mDecoderTaskQueue(TaskQueue::Create(
GetMediaThreadPool(MediaThreadType::PLATFORM_DECODER),
"BenchmarkPlayback::mDecoderTaskQueue")),
mDemuxer(aDemuxer),
mSampleIndex(0),
mFrameCount(0),

Some files were not shown because too many files have changed in this diff Show More