mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 00:32:11 +00:00
Merge autoland to mozilla-central. a=merge
This commit is contained in:
commit
31dae823a3
@ -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",
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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}
|
||||
/>
|
||||
);
|
||||
|
@ -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}
|
||||
|
@ -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}
|
||||
|
@ -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>
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
});
|
||||
|
||||
|
@ -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: {
|
||||
|
@ -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",
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -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: {
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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") && (
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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) {
|
||||
|
@ -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(
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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() {
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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(
|
||||
|
@ -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`);
|
||||
}
|
||||
});
|
@ -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");
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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() {
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
});
|
||||
|
@ -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"
|
||||
);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
]
|
||||
}
|
||||
|
@ -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"] += [
|
||||
|
46
browser/extensions/webcompat/shims/webtrends.js
Normal file
46
browser/extensions/webcompat/shims/webtrends.js
Normal 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?.();
|
||||
});
|
||||
}
|
@ -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,
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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]
|
||||
|
@ -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}`
|
||||
);
|
||||
}
|
||||
});
|
@ -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,
|
||||
|
@ -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*
|
||||
|
@ -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:
|
||||
|
@ -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 () {
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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"; });
|
||||
|
@ -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;
|
||||
|
55
devtools/shared/webconsole/messages.js
Normal file
55
devtools/shared/webconsole/messages.js
Normal 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,
|
||||
};
|
@ -28,6 +28,7 @@ GeneratedFile(
|
||||
DevToolsModules(
|
||||
"analyze-input-string.js",
|
||||
"js-property-provider.js",
|
||||
"messages.js",
|
||||
"network-helper.js",
|
||||
"parser-helper.js",
|
||||
"throttle.js",
|
||||
|
@ -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(
|
||||
|
@ -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": [
|
||||
|
@ -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") {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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}");
|
||||
|
@ -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.
|
||||
|
@ -1,4 +1,3 @@
|
||||
// Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
var prefetch = Cc["@mozilla.org/prefetch-service;1"].getService(
|
||||
Ci.nsIPrefetchService
|
||||
);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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> {
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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 = [
|
||||
|
@ -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]
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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)),
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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">
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user