Update On Fri Jan 24 19:53:20 CET 2025
This commit is contained in:
parent
1ed0aa2bc4
commit
673f42f59c
509 changed files with 13383 additions and 7473 deletions
|
@ -275,16 +275,16 @@ const nsDependentSubstring AssociatedElementsIterator::NextID() {
|
||||||
return Substring(mIDs, idStartIdx, mCurrIdx++ - idStartIdx);
|
return Substring(mIDs, idStartIdx, mCurrIdx++ - idStartIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIContent* AssociatedElementsIterator::NextElem() {
|
dom::Element* AssociatedElementsIterator::NextElem() {
|
||||||
while (true) {
|
while (true) {
|
||||||
const nsDependentSubstring id = NextID();
|
const nsDependentSubstring id = NextID();
|
||||||
if (id.IsEmpty()) break;
|
if (id.IsEmpty()) break;
|
||||||
|
|
||||||
nsIContent* refContent = GetElem(id);
|
dom::Element* refContent = GetElem(id);
|
||||||
if (refContent) return refContent;
|
if (refContent) return refContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (nsIContent* element = mElements.SafeElementAt(mElemIdx++)) {
|
while (dom::Element* element = mElements.SafeElementAt(mElemIdx++)) {
|
||||||
if (nsCoreUtils::IsDescendantOfAnyShadowIncludingAncestor(element,
|
if (nsCoreUtils::IsDescendantOfAnyShadowIncludingAncestor(element,
|
||||||
mContent)) {
|
mContent)) {
|
||||||
return element;
|
return element;
|
||||||
|
@ -317,7 +317,7 @@ dom::Element* AssociatedElementsIterator::GetElem(
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalAccessible* AssociatedElementsIterator::Next() {
|
LocalAccessible* AssociatedElementsIterator::Next() {
|
||||||
nsIContent* nextEl = nullptr;
|
dom::Element* nextEl = nullptr;
|
||||||
while ((nextEl = NextElem())) {
|
while ((nextEl = NextElem())) {
|
||||||
LocalAccessible* acc = mDoc->GetAccessible(nextEl);
|
LocalAccessible* acc = mDoc->GetAccessible(nextEl);
|
||||||
if (acc) {
|
if (acc) {
|
||||||
|
|
|
@ -225,7 +225,7 @@ class AssociatedElementsIterator : public AccIterable {
|
||||||
/**
|
/**
|
||||||
* Return next element.
|
* Return next element.
|
||||||
*/
|
*/
|
||||||
nsIContent* NextElem();
|
dom::Element* NextElem();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the element with the given ID.
|
* Return the element with the given ID.
|
||||||
|
|
|
@ -595,23 +595,6 @@ void NotificationController::ProcessMutationEvents() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fire menupopup end event before a hide event if a menu goes away.
|
|
||||||
|
|
||||||
// XXX: We don't look into children of hidden subtree to find hiding
|
|
||||||
// menupopup (as we did prior bug 570275) because we don't do that when
|
|
||||||
// menu is showing (and that's impossible until bug 606924 is fixed).
|
|
||||||
// Nevertheless we should do this at least because layout coalesces
|
|
||||||
// the changes before our processing and we may miss some menupopup
|
|
||||||
// events. Now we just want to be consistent in content insertion/removal
|
|
||||||
// handling.
|
|
||||||
if (event->mAccessible->ARIARole() == roles::MENUPOPUP) {
|
|
||||||
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END,
|
|
||||||
event->mAccessible);
|
|
||||||
if (!mDocument) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AccHideEvent* hideEvent = downcast_accEvent(event);
|
AccHideEvent* hideEvent = downcast_accEvent(event);
|
||||||
if (hideEvent->NeedsShutdown()) {
|
if (hideEvent->NeedsShutdown()) {
|
||||||
mDocument->ShutdownChildrenInSubtree(event->mAccessible);
|
mDocument->ShutdownChildrenInSubtree(event->mAccessible);
|
||||||
|
|
|
@ -121,16 +121,6 @@ inline void DocAccessible::CreateSubtree(LocalAccessible* aChild) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Fire events for ARIA elements.
|
|
||||||
if (aChild->HasARIARole()) {
|
|
||||||
roles::Role role = aChild->ARIARole();
|
|
||||||
if (role == roles::MENUPOPUP) {
|
|
||||||
FireDelayedEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START, aChild);
|
|
||||||
} else if (role == roles::ALERT) {
|
|
||||||
FireDelayedEvent(nsIAccessibleEvent::EVENT_ALERT, aChild);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX: do we really want to send focus to focused DOM node not taking into
|
// XXX: do we really want to send focus to focused DOM node not taking into
|
||||||
// account active item?
|
// account active item?
|
||||||
if (focusedAcc) {
|
if (focusedAcc) {
|
||||||
|
|
|
@ -999,22 +999,38 @@ void DocAccessible::ContentAppended(nsIContent* aFirstNewContent) {
|
||||||
void DocAccessible::ElementStateChanged(dom::Document* aDocument,
|
void DocAccessible::ElementStateChanged(dom::Document* aDocument,
|
||||||
dom::Element* aElement,
|
dom::Element* aElement,
|
||||||
dom::ElementState aStateMask) {
|
dom::ElementState aStateMask) {
|
||||||
if (aStateMask.HasState(dom::ElementState::READWRITE) &&
|
LocalAccessible* accessible =
|
||||||
aElement == mDocumentNode->GetRootElement()) {
|
aElement == mContent ? this : GetAccessible(aElement);
|
||||||
// This handles changes to designMode. contentEditable is handled by
|
|
||||||
// LocalAccessible::AttributeChangesState and
|
if (!accessible) {
|
||||||
// LocalAccessible::DOMAttributeChanged.
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aStateMask.HasState(dom::ElementState::READWRITE)) {
|
||||||
const bool isEditable =
|
const bool isEditable =
|
||||||
aElement->State().HasState(dom::ElementState::READWRITE);
|
aElement->State().HasState(dom::ElementState::READWRITE);
|
||||||
RefPtr<AccEvent> event =
|
RefPtr<AccEvent> event =
|
||||||
new AccStateChangeEvent(this, states::EDITABLE, isEditable);
|
new AccStateChangeEvent(accessible, states::EDITABLE, isEditable);
|
||||||
FireDelayedEvent(event);
|
FireDelayedEvent(event);
|
||||||
event = new AccStateChangeEvent(this, states::READONLY, !isEditable);
|
if (accessible == this || aElement->IsHTMLElement(nsGkAtoms::article)) {
|
||||||
FireDelayedEvent(event);
|
// We want <article> to behave like a document in terms of readonly state.
|
||||||
}
|
event =
|
||||||
|
new AccStateChangeEvent(accessible, states::READONLY, !isEditable);
|
||||||
|
FireDelayedEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
LocalAccessible* accessible = GetAccessible(aElement);
|
if (aElement->HasAttr(nsGkAtoms::aria_owns)) {
|
||||||
if (!accessible) return;
|
// If this has aria-owns, update children that are relocated into here.
|
||||||
|
// If we are becoming editable, put them back into their original
|
||||||
|
// containers, if we are becoming readonly, acquire them.
|
||||||
|
mNotificationController->ScheduleRelocation(accessible);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is a node inside of a newly editable subtree, it needs to be
|
||||||
|
// un-aria-owned. And inversely, if the node becomes uneditable, allow the
|
||||||
|
// node to be aria-owned.
|
||||||
|
RelocateARIAOwnedIfNeeded(aElement);
|
||||||
|
}
|
||||||
|
|
||||||
if (aStateMask.HasState(dom::ElementState::CHECKED)) {
|
if (aStateMask.HasState(dom::ElementState::CHECKED)) {
|
||||||
LocalAccessible* widget = accessible->ContainerWidget();
|
LocalAccessible* widget = accessible->ContainerWidget();
|
||||||
|
@ -2456,9 +2472,24 @@ void DocAccessible::DoARIAOwnsRelocation(LocalAccessible* aOwner) {
|
||||||
nsTArray<RefPtr<LocalAccessible>>* owned =
|
nsTArray<RefPtr<LocalAccessible>>* owned =
|
||||||
mARIAOwnsHash.GetOrInsertNew(aOwner);
|
mARIAOwnsHash.GetOrInsertNew(aOwner);
|
||||||
|
|
||||||
|
if (aOwner->Elm()->State().HasState(dom::ElementState::READWRITE)) {
|
||||||
|
// The container is editable.
|
||||||
|
PutChildrenBack(owned, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
AssociatedElementsIterator iter(this, aOwner->Elm(), nsGkAtoms::aria_owns);
|
AssociatedElementsIterator iter(this, aOwner->Elm(), nsGkAtoms::aria_owns);
|
||||||
uint32_t idx = 0;
|
uint32_t idx = 0;
|
||||||
while (nsIContent* childEl = iter.NextElem()) {
|
while (dom::Element* childEl = iter.NextElem()) {
|
||||||
|
if (childEl->State().HasState(dom::ElementState::READWRITE)) {
|
||||||
|
nsINode* parentEl = childEl->GetFlattenedTreeParentNode();
|
||||||
|
if (parentEl->IsElement() && parentEl->AsElement()->State().HasState(
|
||||||
|
dom::ElementState::READWRITE)) {
|
||||||
|
// The child is inside of an editable subtree, don't relocate it.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LocalAccessible* child = GetAccessible(childEl);
|
LocalAccessible* child = GetAccessible(childEl);
|
||||||
auto insertIdx = aOwner->ChildCount() - owned->Length() + idx;
|
auto insertIdx = aOwner->ChildCount() - owned->Length() + idx;
|
||||||
|
|
||||||
|
@ -2808,17 +2839,26 @@ void DocAccessible::CacheChildrenInSubtree(LocalAccessible* aRoot,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: we should delay document load complete event if the ARIA document
|
|
||||||
// has aria-busy.
|
|
||||||
roles::Role role = aRoot->ARIARole();
|
roles::Role role = aRoot->ARIARole();
|
||||||
if (!aRoot->IsDoc() &&
|
if (!aRoot->IsDoc()) {
|
||||||
(role == roles::DIALOG || role == roles::NON_NATIVE_DOCUMENT)) {
|
if (role == roles::DIALOG || role == roles::NON_NATIVE_DOCUMENT) {
|
||||||
FireDelayedEvent(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE, aRoot);
|
// XXX: we should delay document load complete event if the ARIA document
|
||||||
|
// has aria-busy.
|
||||||
|
FireDelayedEvent(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE, aRoot);
|
||||||
|
} else if (role == roles::MENUPOPUP && HasLoadState(eCompletelyLoaded)) {
|
||||||
|
FireDelayedEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START, aRoot);
|
||||||
|
} else if (role == roles::ALERT && HasLoadState(eCompletelyLoaded)) {
|
||||||
|
FireDelayedEvent(nsIAccessibleEvent::EVENT_ALERT, aRoot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocAccessible::UncacheChildrenInSubtree(LocalAccessible* aRoot) {
|
void DocAccessible::UncacheChildrenInSubtree(LocalAccessible* aRoot) {
|
||||||
MaybeFireEventsForChangedPopover(aRoot);
|
MaybeFireEventsForChangedPopover(aRoot);
|
||||||
|
if (aRoot->ARIARole() == roles::MENUPOPUP) {
|
||||||
|
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END, aRoot);
|
||||||
|
}
|
||||||
|
|
||||||
aRoot->mStateFlags |= eIsNotInDocument;
|
aRoot->mStateFlags |= eIsNotInDocument;
|
||||||
RemoveDependentIDsFor(aRoot);
|
RemoveDependentIDsFor(aRoot);
|
||||||
RemoveDependentElementsFor(aRoot);
|
RemoveDependentElementsFor(aRoot);
|
||||||
|
|
|
@ -1298,6 +1298,7 @@ bool LocalAccessible::AttributeChangesState(nsAtom* aAttribute) {
|
||||||
aAttribute == nsGkAtoms::aria_busy ||
|
aAttribute == nsGkAtoms::aria_busy ||
|
||||||
aAttribute == nsGkAtoms::aria_multiline ||
|
aAttribute == nsGkAtoms::aria_multiline ||
|
||||||
aAttribute == nsGkAtoms::aria_multiselectable ||
|
aAttribute == nsGkAtoms::aria_multiselectable ||
|
||||||
|
// We track this for focusable state update
|
||||||
aAttribute == nsGkAtoms::contenteditable ||
|
aAttribute == nsGkAtoms::contenteditable ||
|
||||||
aAttribute == nsGkAtoms::popovertarget;
|
aAttribute == nsGkAtoms::popovertarget;
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,10 +312,12 @@ addAccessibleTask(
|
||||||
* Test caching of the editable state.
|
* Test caching of the editable state.
|
||||||
*/
|
*/
|
||||||
addAccessibleTask(
|
addAccessibleTask(
|
||||||
`<div id="div" contenteditable></div>`,
|
`<div id="div" contenteditable><p id="p">hello</p></div>`,
|
||||||
async function (browser, docAcc) {
|
async function (browser, docAcc) {
|
||||||
const div = findAccessibleChildByID(docAcc, "div");
|
const div = findAccessibleChildByID(docAcc, "div");
|
||||||
|
const p = findAccessibleChildByID(docAcc, "p");
|
||||||
testStates(div, 0, EXT_STATE_EDITABLE, 0, 0);
|
testStates(div, 0, EXT_STATE_EDITABLE, 0, 0);
|
||||||
|
testStates(p, 0, EXT_STATE_EDITABLE, 0, 0);
|
||||||
// Ensure that a contentEditable descendant doesn't cause editable to be
|
// Ensure that a contentEditable descendant doesn't cause editable to be
|
||||||
// exposed on the document.
|
// exposed on the document.
|
||||||
testStates(docAcc, STATE_READONLY, 0, 0, EXT_STATE_EDITABLE);
|
testStates(docAcc, STATE_READONLY, 0, 0, EXT_STATE_EDITABLE);
|
||||||
|
@ -349,6 +351,7 @@ addAccessibleTask(
|
||||||
});
|
});
|
||||||
await stateChanged;
|
await stateChanged;
|
||||||
testStates(div, 0, 0, 0, EXT_STATE_EDITABLE);
|
testStates(div, 0, 0, 0, EXT_STATE_EDITABLE);
|
||||||
|
testStates(p, 0, 0, 0, EXT_STATE_EDITABLE);
|
||||||
|
|
||||||
info("Setting contentEditable on div");
|
info("Setting contentEditable on div");
|
||||||
stateChanged = waitForStateChange(div, EXT_STATE_EDITABLE, true, true);
|
stateChanged = waitForStateChange(div, EXT_STATE_EDITABLE, true, true);
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
/* import-globals-from ../../mochitest/role.js */
|
/* import-globals-from ../../mochitest/role.js */
|
||||||
loadScripts({ name: "role.js", dir: MOCHITESTS_DIR });
|
loadScripts({ name: "role.js", dir: MOCHITESTS_DIR });
|
||||||
|
/* import-globals-from ../../mochitest/states.js */
|
||||||
|
loadScripts({ name: "states.js", dir: MOCHITESTS_DIR });
|
||||||
|
|
||||||
requestLongerTimeout(2);
|
requestLongerTimeout(2);
|
||||||
|
|
||||||
|
@ -606,3 +608,95 @@ addAccessibleTask(`<div id='a'></div>`, async function (browser, accDoc) {
|
||||||
});
|
});
|
||||||
is(getAccessibleDOMNodeID(a.firstChild), "b", "'a' owns relocated child");
|
is(getAccessibleDOMNodeID(a.firstChild), "b", "'a' owns relocated child");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test to assure that aria-owned elements are not relocated into an editable subtree.
|
||||||
|
*/
|
||||||
|
addAccessibleTask(
|
||||||
|
`
|
||||||
|
<button id="btn">World</button>
|
||||||
|
<div contentEditable="true" id="textbox" role="textbox">
|
||||||
|
<p id="p" aria-owns="btn">Hello</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
async function (browser, accDoc) {
|
||||||
|
const p = findAccessibleChildByID(accDoc, "p");
|
||||||
|
const textbox = findAccessibleChildByID(accDoc, "textbox");
|
||||||
|
testStates(textbox, 0, EXT_STATE_EDITABLE, 0, 0);
|
||||||
|
|
||||||
|
isnot(getAccessibleDOMNodeID(p.lastChild), "btn", "'p' owns relocated btn");
|
||||||
|
is(textbox.value, "Hello");
|
||||||
|
|
||||||
|
let expectedEvents = Promise.all([
|
||||||
|
waitForStateChange(textbox, EXT_STATE_EDITABLE, false, true),
|
||||||
|
waitForEvent(EVENT_INNER_REORDER, p),
|
||||||
|
]);
|
||||||
|
await invokeContentTask(browser, [], () => {
|
||||||
|
content.document.getElementById("textbox").contentEditable = false;
|
||||||
|
});
|
||||||
|
await expectedEvents;
|
||||||
|
is(getAccessibleDOMNodeID(p.lastChild), "btn", "'p' owns relocated btn");
|
||||||
|
is(textbox.value, "Hello World");
|
||||||
|
|
||||||
|
expectedEvents = Promise.all([
|
||||||
|
waitForStateChange(textbox, EXT_STATE_EDITABLE, true, true),
|
||||||
|
waitForEvent(EVENT_INNER_REORDER, p),
|
||||||
|
]);
|
||||||
|
await invokeContentTask(browser, [], () => {
|
||||||
|
content.document.getElementById("textbox").contentEditable = true;
|
||||||
|
});
|
||||||
|
await expectedEvents;
|
||||||
|
isnot(getAccessibleDOMNodeID(p.lastChild), "btn", "'p' owns relocated btn");
|
||||||
|
is(textbox.value, "Hello");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test to ensure that aria-owned elements are not relocated out of editable subtree.
|
||||||
|
*/
|
||||||
|
addAccessibleTask(
|
||||||
|
`
|
||||||
|
<div contentEditable="true" id="textbox" role="textbox">
|
||||||
|
<button id="btn">World</button>
|
||||||
|
</div>
|
||||||
|
<p id="p" aria-owns="btn">Hello</p>
|
||||||
|
<p id="p2" aria-owns="textbox"></p>
|
||||||
|
`,
|
||||||
|
async function (browser, accDoc) {
|
||||||
|
const p = findAccessibleChildByID(accDoc, "p");
|
||||||
|
const textbox = findAccessibleChildByID(accDoc, "textbox");
|
||||||
|
testStates(textbox, 0, EXT_STATE_EDITABLE, 0, 0);
|
||||||
|
|
||||||
|
is(
|
||||||
|
getAccessibleDOMNodeID(textbox.parent),
|
||||||
|
"p2",
|
||||||
|
"editable root can be relocated"
|
||||||
|
);
|
||||||
|
isnot(
|
||||||
|
getAccessibleDOMNodeID(p.lastChild),
|
||||||
|
"btn",
|
||||||
|
"editable element cannot be relocated"
|
||||||
|
);
|
||||||
|
is(textbox.value, "World");
|
||||||
|
|
||||||
|
let expectedEvents = Promise.all([
|
||||||
|
waitForStateChange(textbox, EXT_STATE_EDITABLE, false, true),
|
||||||
|
waitForEvent(EVENT_REORDER, p),
|
||||||
|
]);
|
||||||
|
await invokeContentTask(browser, [], () => {
|
||||||
|
content.document.getElementById("textbox").contentEditable = false;
|
||||||
|
});
|
||||||
|
await expectedEvents;
|
||||||
|
is(
|
||||||
|
getAccessibleDOMNodeID(p.lastChild),
|
||||||
|
"btn",
|
||||||
|
"'p' owns readonly relocated btn"
|
||||||
|
);
|
||||||
|
is(textbox.value, "");
|
||||||
|
is(
|
||||||
|
getAccessibleDOMNodeID(textbox.parent),
|
||||||
|
"p2",
|
||||||
|
"textbox is still relocated"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
|
@ -12,6 +12,8 @@ support-files = [
|
||||||
|
|
||||||
["browser_focus_document.js"]
|
["browser_focus_document.js"]
|
||||||
|
|
||||||
|
["browser_menu_and_alerts.js"]
|
||||||
|
|
||||||
["browser_test_A11yUtils_announce.js"]
|
["browser_test_A11yUtils_announce.js"]
|
||||||
|
|
||||||
["browser_test_caret_move_granularity.js"]
|
["browser_test_caret_move_granularity.js"]
|
||||||
|
|
150
accessible/tests/browser/events/browser_menu_and_alerts.js
Normal file
150
accessible/tests/browser/events/browser_menu_and_alerts.js
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
/* 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";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessible menu popup start/end
|
||||||
|
*/
|
||||||
|
addAccessibleTask(
|
||||||
|
`
|
||||||
|
<div id="container">
|
||||||
|
<ul id="menu" role="menu" style="display: none;">
|
||||||
|
<li role="menuitem">Hello</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
async function (browser) {
|
||||||
|
let expectedEvents = waitForEvents(
|
||||||
|
[
|
||||||
|
[EVENT_SHOW],
|
||||||
|
[EVENT_REORDER, "container"],
|
||||||
|
[EVENT_MENUPOPUP_START, "menu"],
|
||||||
|
],
|
||||||
|
"Popup start sequence",
|
||||||
|
true
|
||||||
|
);
|
||||||
|
await invokeContentTask(browser, [], () => {
|
||||||
|
content.document.getElementById("menu").style.display = "block";
|
||||||
|
});
|
||||||
|
await expectedEvents;
|
||||||
|
|
||||||
|
expectedEvents = waitForEvents(
|
||||||
|
[
|
||||||
|
[EVENT_MENUPOPUP_END, "menu"],
|
||||||
|
[EVENT_HIDE],
|
||||||
|
[EVENT_REORDER, "container"],
|
||||||
|
],
|
||||||
|
"Popup end sequence",
|
||||||
|
true
|
||||||
|
);
|
||||||
|
await invokeContentTask(browser, [], () => {
|
||||||
|
content.document.getElementById("menu").style.display = "none";
|
||||||
|
});
|
||||||
|
await expectedEvents;
|
||||||
|
},
|
||||||
|
{ chrome: true, topLevel: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessible menu popup start/end in subtree
|
||||||
|
*/
|
||||||
|
addAccessibleTask(
|
||||||
|
`
|
||||||
|
<div id="container" style="display: none;">
|
||||||
|
<ul id="menu" role="menu">
|
||||||
|
<li role="menuitem">Hello</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
async function (browser, accDoc) {
|
||||||
|
let expectedEvents = waitForEvents(
|
||||||
|
[[EVENT_SHOW], [EVENT_REORDER, accDoc], [EVENT_MENUPOPUP_START, "menu"]],
|
||||||
|
"Embedded popup start sequence",
|
||||||
|
true
|
||||||
|
);
|
||||||
|
await invokeContentTask(browser, [], () => {
|
||||||
|
content.document.getElementById("container").style.display = "block";
|
||||||
|
});
|
||||||
|
await expectedEvents;
|
||||||
|
|
||||||
|
expectedEvents = waitForEvents(
|
||||||
|
[[EVENT_MENUPOPUP_END, "menu"], [EVENT_HIDE], [EVENT_REORDER, accDoc]],
|
||||||
|
"Embedded popup end sequence",
|
||||||
|
true
|
||||||
|
);
|
||||||
|
await invokeContentTask(browser, [], () => {
|
||||||
|
content.document.getElementById("container").style.display = "none";
|
||||||
|
});
|
||||||
|
await expectedEvents;
|
||||||
|
},
|
||||||
|
{ chrome: true, topLevel: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessible alert event
|
||||||
|
*/
|
||||||
|
addAccessibleTask(
|
||||||
|
`
|
||||||
|
<div id="container">
|
||||||
|
<div role="alert" id="alert" style="display: none;">Alert!</div>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
async function (browser, accDoc) {
|
||||||
|
let expectedEvents = waitForEvents(
|
||||||
|
[[EVENT_SHOW], [EVENT_REORDER, "container"], [EVENT_ALERT, "alert"]],
|
||||||
|
"Alert events sequence",
|
||||||
|
true
|
||||||
|
);
|
||||||
|
await invokeContentTask(browser, [], () => {
|
||||||
|
content.document.getElementById("alert").style.display = "block";
|
||||||
|
});
|
||||||
|
await expectedEvents;
|
||||||
|
|
||||||
|
expectedEvents = waitForEvent(EVENT_REORDER, accDoc);
|
||||||
|
await invokeContentTask(browser, [], () => {
|
||||||
|
content.document.getElementById("container").style.display = "none";
|
||||||
|
});
|
||||||
|
await expectedEvents;
|
||||||
|
|
||||||
|
expectedEvents = waitForEvents(
|
||||||
|
[[EVENT_SHOW], [EVENT_REORDER, accDoc], [EVENT_ALERT, "alert"]],
|
||||||
|
"Embedded Alert events sequence",
|
||||||
|
true
|
||||||
|
);
|
||||||
|
await invokeContentTask(browser, [], () => {
|
||||||
|
content.document.getElementById("container").style.display = "block";
|
||||||
|
});
|
||||||
|
await expectedEvents;
|
||||||
|
},
|
||||||
|
{ chrome: true, topLevel: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No alert event at load.
|
||||||
|
*/
|
||||||
|
addAccessibleTask(
|
||||||
|
``,
|
||||||
|
async function (browser) {
|
||||||
|
let onLoadEvents = waitForEvents({
|
||||||
|
expected: [
|
||||||
|
[EVENT_FOCUS, "body2"],
|
||||||
|
[EVENT_DOCUMENT_LOAD_COMPLETE, "body2"],
|
||||||
|
stateChangeEventArgs("body2", STATE_BUSY, false, false),
|
||||||
|
],
|
||||||
|
unexpected: [[EVENT_ALERT]],
|
||||||
|
});
|
||||||
|
|
||||||
|
BrowserTestUtils.startLoadingURIString(
|
||||||
|
browser,
|
||||||
|
`data:text/html;charset=utf-8,
|
||||||
|
<html><body id="body2">
|
||||||
|
<div role="alert" id="alert">Alert!</div>
|
||||||
|
</body></html>`
|
||||||
|
);
|
||||||
|
|
||||||
|
await onLoadEvents;
|
||||||
|
},
|
||||||
|
{ chrome: true, topLevel: true }
|
||||||
|
);
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
async function testComboBox(browser, accDoc, suppressPopupInValueTodo = false) {
|
async function testComboBox(browser, accDoc) {
|
||||||
const box = getNativeInterface(accDoc, "box");
|
const box = getNativeInterface(accDoc, "box");
|
||||||
is(box.getAttributeValue("AXRole"), "AXComboBox");
|
is(box.getAttributeValue("AXRole"), "AXComboBox");
|
||||||
is(box.getAttributeValue("AXValue"), "peach", "Initial value correct");
|
is(box.getAttributeValue("AXValue"), "peach", "Initial value correct");
|
||||||
|
@ -20,19 +20,9 @@ async function testComboBox(browser, accDoc, suppressPopupInValueTodo = false) {
|
||||||
});
|
});
|
||||||
|
|
||||||
await expandedChanged;
|
await expandedChanged;
|
||||||
if (suppressPopupInValueTodo) {
|
|
||||||
todo(
|
ok(!didBoxValueChange, "Value of combobox did not change when it was opened");
|
||||||
!didBoxValueChange,
|
is(box.getAttributeValue("AXValue"), "peach", "After popup value correct");
|
||||||
"Value of combobox did not change when it was opened"
|
|
||||||
);
|
|
||||||
todo_is(box.getAttributeValue("AXValue"), "peach");
|
|
||||||
} else {
|
|
||||||
ok(
|
|
||||||
!didBoxValueChange,
|
|
||||||
"Value of combobox did not change when it was opened"
|
|
||||||
);
|
|
||||||
is(box.getAttributeValue("AXValue"), "peach", "After popup value correct");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addAccessibleTask(
|
addAccessibleTask(
|
||||||
|
@ -74,8 +64,21 @@ addAccessibleTask(
|
||||||
`,
|
`,
|
||||||
async (browser, accDoc) => {
|
async (browser, accDoc) => {
|
||||||
info("Test ARIA 1.0 style combobox (entry aria-owns list)");
|
info("Test ARIA 1.0 style combobox (entry aria-owns list)");
|
||||||
// XXX: Bug 1912520
|
|
||||||
await testComboBox(browser, accDoc, true);
|
const box = getNativeInterface(accDoc, "box");
|
||||||
|
is(
|
||||||
|
box.getAttributeValue("AXChildren").length,
|
||||||
|
1,
|
||||||
|
"owned list is not relocated"
|
||||||
|
);
|
||||||
|
// XXX: Bug 1912520 - Remap from aria-owns to aria-controls
|
||||||
|
todo_is(
|
||||||
|
box.getAttributeValue("AXARIAControls").length,
|
||||||
|
1,
|
||||||
|
"box controls list"
|
||||||
|
);
|
||||||
|
|
||||||
|
await testComboBox(browser, accDoc);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -72,8 +72,8 @@
|
||||||
this.menu = null;
|
this.menu = null;
|
||||||
|
|
||||||
this.eventSeq = [
|
this.eventSeq = [
|
||||||
new invokerChecker(EVENT_HIDE, getMenu, this),
|
|
||||||
new invokerChecker(EVENT_MENUPOPUP_END, getMenu, this),
|
new invokerChecker(EVENT_MENUPOPUP_END, getMenu, this),
|
||||||
|
new invokerChecker(EVENT_HIDE, getMenu, this),
|
||||||
new invokerChecker(EVENT_REORDER, getNode(aParentMenuID)),
|
new invokerChecker(EVENT_REORDER, getNode(aParentMenuID)),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,15 @@
|
||||||
// globals from there.
|
// globals from there.
|
||||||
/* import-globals-from common.js */
|
/* import-globals-from common.js */
|
||||||
|
|
||||||
/* exported EVENT_ANNOUNCEMENT, EVENT_REORDER, EVENT_SCROLLING,
|
/* exported EVENT_ANNOUNCEMENT, EVENT_ALERT, EVENT_REORDER, EVENT_SCROLLING,
|
||||||
EVENT_SCROLLING_END, EVENT_SHOW, EVENT_TEXT_INSERTED,
|
EVENT_SCROLLING_END, EVENT_SHOW, EVENT_TEXT_INSERTED,
|
||||||
EVENT_TEXT_REMOVED, EVENT_DOCUMENT_LOAD_COMPLETE, EVENT_HIDE,
|
EVENT_TEXT_REMOVED, EVENT_DOCUMENT_LOAD_COMPLETE, EVENT_HIDE,
|
||||||
EVENT_TEXT_ATTRIBUTE_CHANGED, EVENT_TEXT_CARET_MOVED, EVENT_SELECTION,
|
EVENT_TEXT_ATTRIBUTE_CHANGED, EVENT_TEXT_CARET_MOVED, EVENT_SELECTION,
|
||||||
EVENT_DESCRIPTION_CHANGE, EVENT_NAME_CHANGE, EVENT_STATE_CHANGE,
|
EVENT_DESCRIPTION_CHANGE, EVENT_NAME_CHANGE, EVENT_STATE_CHANGE,
|
||||||
EVENT_VALUE_CHANGE, EVENT_TEXT_VALUE_CHANGE, EVENT_FOCUS,
|
EVENT_VALUE_CHANGE, EVENT_TEXT_VALUE_CHANGE, EVENT_FOCUS,
|
||||||
EVENT_DOCUMENT_RELOAD, EVENT_VIRTUALCURSOR_CHANGED, EVENT_ALERT,
|
EVENT_DOCUMENT_RELOAD, EVENT_VIRTUALCURSOR_CHANGED, EVENT_ALERT,
|
||||||
EVENT_OBJECT_ATTRIBUTE_CHANGED, UnexpectedEvents, waitForEvent,
|
EVENT_OBJECT_ATTRIBUTE_CHANGED, EVENT_MENUPOPUP_START, EVENT_MENUPOPUP_END,
|
||||||
|
UnexpectedEvents, waitForEvent,
|
||||||
waitForEvents, waitForOrderedEvents, waitForStateChange,
|
waitForEvents, waitForOrderedEvents, waitForStateChange,
|
||||||
stateChangeEventArgs */
|
stateChangeEventArgs */
|
||||||
|
|
||||||
|
@ -52,6 +53,8 @@ const EVENT_LIVE_REGION_REMOVED = nsIAccessibleEvent.EVENT_LIVE_REGION_REMOVED;
|
||||||
const EVENT_OBJECT_ATTRIBUTE_CHANGED =
|
const EVENT_OBJECT_ATTRIBUTE_CHANGED =
|
||||||
nsIAccessibleEvent.EVENT_OBJECT_ATTRIBUTE_CHANGED;
|
nsIAccessibleEvent.EVENT_OBJECT_ATTRIBUTE_CHANGED;
|
||||||
const EVENT_INNER_REORDER = nsIAccessibleEvent.EVENT_INNER_REORDER;
|
const EVENT_INNER_REORDER = nsIAccessibleEvent.EVENT_INNER_REORDER;
|
||||||
|
const EVENT_MENUPOPUP_START = nsIAccessibleEvent.EVENT_MENUPOPUP_START;
|
||||||
|
const EVENT_MENUPOPUP_END = nsIAccessibleEvent.EVENT_MENUPOPUP_END;
|
||||||
|
|
||||||
const EventsLogger = {
|
const EventsLogger = {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
|
|
@ -2474,9 +2474,6 @@ pref("privacy.webrtc.deviceGracePeriodTimeoutMs", 3600000);
|
||||||
// the pref to hide the icons
|
// the pref to hide the icons
|
||||||
pref("privacy.webrtc.showIndicatorsOnMacos14AndAbove", true);
|
pref("privacy.webrtc.showIndicatorsOnMacos14AndAbove", true);
|
||||||
|
|
||||||
// Enable Fingerprinting Protection in private windows..
|
|
||||||
pref("privacy.fingerprintingProtection.pbmode", true);
|
|
||||||
|
|
||||||
// Enable Smartblock embed placeholders
|
// Enable Smartblock embed placeholders
|
||||||
#ifdef NIGHTLY_BUILD
|
#ifdef NIGHTLY_BUILD
|
||||||
pref("extensions.webcompat.smartblockEmbeds.enabled", true);
|
pref("extensions.webcompat.smartblockEmbeds.enabled", true);
|
||||||
|
|
|
@ -208,17 +208,6 @@ const TEST_GLOBAL = {
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"@mozilla.org/security/hash;1": {
|
|
||||||
createInstance() {
|
|
||||||
return {
|
|
||||||
init() {},
|
|
||||||
updateFromStream() {},
|
|
||||||
finish() {
|
|
||||||
return "0";
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"@mozilla.org/updates/update-checker;1": { createInstance() {} },
|
"@mozilla.org/updates/update-checker;1": { createInstance() {} },
|
||||||
"@mozilla.org/widget/useridleservice;1": {
|
"@mozilla.org/widget/useridleservice;1": {
|
||||||
getService() {
|
getService() {
|
||||||
|
|
|
@ -30,7 +30,7 @@ const createStorage = async telemetryFeed => {
|
||||||
// We keep the name "snippets" to avoid having to do an IndexedDB database
|
// We keep the name "snippets" to avoid having to do an IndexedDB database
|
||||||
// migration.
|
// migration.
|
||||||
const dbStore = new ASRouterStorage({
|
const dbStore = new ASRouterStorage({
|
||||||
storeNames: ["sectionPrefs", "snippets"],
|
storeNames: ["snippets"],
|
||||||
telemetry: {
|
telemetry: {
|
||||||
handleUndesiredEvent: e => telemetryFeed.SendASRouterUndesiredEvent(e),
|
handleUndesiredEvent: e => telemetryFeed.SendASRouterUndesiredEvent(e),
|
||||||
},
|
},
|
||||||
|
|
|
@ -219,17 +219,6 @@ const TEST_GLOBAL = {
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"@mozilla.org/security/hash;1": {
|
|
||||||
createInstance() {
|
|
||||||
return {
|
|
||||||
init() {},
|
|
||||||
updateFromStream() {},
|
|
||||||
finish() {
|
|
||||||
return "0";
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"@mozilla.org/updates/update-checker;1": { createInstance() {} },
|
"@mozilla.org/updates/update-checker;1": { createInstance() {} },
|
||||||
"@mozilla.org/widget/useridleservice;1": {
|
"@mozilla.org/widget/useridleservice;1": {
|
||||||
getService() {
|
getService() {
|
||||||
|
|
|
@ -212,25 +212,45 @@ add_task(async function testRecentlyClosedRestoreAllTabs() {
|
||||||
"https://example.com/",
|
"https://example.com/",
|
||||||
"https://example.org/",
|
"https://example.org/",
|
||||||
];
|
];
|
||||||
|
const closedTabGroupUrls = ["about:logo", "about:mozilla"];
|
||||||
|
const closedTabGroupId = "1234567890-1";
|
||||||
const windowState = {
|
const windowState = {
|
||||||
tabs: [
|
tabs: [
|
||||||
{
|
{
|
||||||
entries: [{ url: "about:mozilla", triggeringPrincipal_base64 }],
|
entries: [{ url: "about:mozilla", triggeringPrincipal_base64 }],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
_closedTabs: closedTabUrls.map(url => {
|
_closedTabs: closedTabUrls.map(url => ({
|
||||||
return {
|
title: url,
|
||||||
title: url,
|
state: {
|
||||||
state: {
|
entries: [
|
||||||
entries: [
|
{
|
||||||
{
|
url,
|
||||||
url,
|
triggeringPrincipal_base64,
|
||||||
triggeringPrincipal_base64,
|
},
|
||||||
},
|
],
|
||||||
],
|
},
|
||||||
},
|
})),
|
||||||
};
|
closedGroups: [
|
||||||
}),
|
{
|
||||||
|
collapsed: false,
|
||||||
|
color: "blue",
|
||||||
|
id: closedTabGroupId,
|
||||||
|
name: "",
|
||||||
|
tabs: closedTabGroupUrls.map(url => ({
|
||||||
|
title: url,
|
||||||
|
state: {
|
||||||
|
entries: [
|
||||||
|
{
|
||||||
|
url,
|
||||||
|
triggeringPrincipal_base64,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
groupId: closedTabGroupId,
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
await SessionStoreTestUtils.promiseBrowserState({
|
await SessionStoreTestUtils.promiseBrowserState({
|
||||||
windows: [windowState],
|
windows: [windowState],
|
||||||
|
@ -280,9 +300,19 @@ add_task(async function testRecentlyClosedRestoreAllTabs() {
|
||||||
|
|
||||||
is(
|
is(
|
||||||
gBrowser.tabs.length,
|
gBrowser.tabs.length,
|
||||||
initialTabCount + closedTabUrls.length,
|
initialTabCount + closedTabUrls.length + closedTabGroupUrls.length,
|
||||||
"The expected number of closed tabs were restored"
|
"The expected number of closed tabs were restored"
|
||||||
);
|
);
|
||||||
|
is(
|
||||||
|
gBrowser.tabGroups.length,
|
||||||
|
1,
|
||||||
|
"The expected number of closed tab groups were restored"
|
||||||
|
);
|
||||||
|
is(
|
||||||
|
gBrowser.tabGroups[0].tabs.length,
|
||||||
|
2,
|
||||||
|
"The expected number of tabs were restored to the tab group"
|
||||||
|
);
|
||||||
|
|
||||||
// clean up extra tabs
|
// clean up extra tabs
|
||||||
while (gBrowser.tabs.length > 1) {
|
while (gBrowser.tabs.length > 1) {
|
||||||
|
|
|
@ -137,7 +137,6 @@ for (const type of [
|
||||||
"SECTION_DEREGISTER",
|
"SECTION_DEREGISTER",
|
||||||
"SECTION_DISABLE",
|
"SECTION_DISABLE",
|
||||||
"SECTION_ENABLE",
|
"SECTION_ENABLE",
|
||||||
"SECTION_MOVE",
|
|
||||||
"SECTION_OPTIONS_CHANGED",
|
"SECTION_OPTIONS_CHANGED",
|
||||||
"SECTION_REGISTER",
|
"SECTION_REGISTER",
|
||||||
"SECTION_UPDATE",
|
"SECTION_UPDATE",
|
||||||
|
@ -183,7 +182,6 @@ for (const type of [
|
||||||
"UNINIT",
|
"UNINIT",
|
||||||
"UPDATE_PINNED_SEARCH_SHORTCUTS",
|
"UPDATE_PINNED_SEARCH_SHORTCUTS",
|
||||||
"UPDATE_SEARCH_SHORTCUTS",
|
"UPDATE_SEARCH_SHORTCUTS",
|
||||||
"UPDATE_SECTION_PREFS",
|
|
||||||
"WALLPAPERS_CATEGORY_SET",
|
"WALLPAPERS_CATEGORY_SET",
|
||||||
"WALLPAPERS_FEATURE_HIGHLIGHT_COUNTER_INCREMENT",
|
"WALLPAPERS_FEATURE_HIGHLIGHT_COUNTER_INCREMENT",
|
||||||
"WALLPAPERS_FEATURE_HIGHLIGHT_CTA_CLICKED",
|
"WALLPAPERS_FEATURE_HIGHLIGHT_CTA_CLICKED",
|
||||||
|
|
|
@ -32,7 +32,7 @@ main {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
&.newtab-main {
|
&.newtab-main {
|
||||||
align-items: center;
|
min-width: min-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vertical-center-wrapper {
|
.vertical-center-wrapper {
|
||||||
|
|
|
@ -35,6 +35,14 @@ function getLayoutData(responsiveLayouts, index) {
|
||||||
layoutData.classNames.push(
|
layoutData.classNames.push(
|
||||||
`col-${layout.columnCount}-position-${tileIndex}`
|
`col-${layout.columnCount}-position-${tileIndex}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// The API tells us whether the tile should show the excerpt or not.
|
||||||
|
// Apply extra styles accordingly.
|
||||||
|
if (tile.hasExcerpt) {
|
||||||
|
layoutData.classNames.push(`col-${layout.columnCount}-show-excerpt`);
|
||||||
|
} else {
|
||||||
|
layoutData.classNames.push(`col-${layout.columnCount}-hide-excerpt`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -61,10 +61,6 @@
|
||||||
-webkit-line-clamp: 4;
|
-webkit-line-clamp: 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-wrap .excerpt {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sections-card-footer {
|
.sections-card-footer {
|
||||||
margin-block-start: var(--space-xxsmall);
|
margin-block-start: var(--space-xxsmall);
|
||||||
}
|
}
|
||||||
|
@ -409,6 +405,18 @@
|
||||||
.col-1-large {
|
.col-1-large {
|
||||||
@include section-card-large;
|
@include section-card-large;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.col-1-hide-excerpt {
|
||||||
|
.info-wrap .excerpt {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1-show-excerpt {
|
||||||
|
.info-wrap .excerpt {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: $break-point-layout-variant) {
|
@media (min-width: $break-point-layout-variant) {
|
||||||
|
@ -431,6 +439,18 @@
|
||||||
.col-2-large {
|
.col-2-large {
|
||||||
@include section-card-large;
|
@include section-card-large;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.col-2-hide-excerpt {
|
||||||
|
.info-wrap .excerpt {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-2-show-excerpt {
|
||||||
|
.info-wrap .excerpt {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: $break-point-widest) {
|
@media (min-width: $break-point-widest) {
|
||||||
|
@ -454,6 +474,18 @@
|
||||||
.col-3-large {
|
.col-3-large {
|
||||||
@include section-card-large;
|
@include section-card-large;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.col-3-hide-excerpt {
|
||||||
|
.info-wrap .excerpt {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-3-show-excerpt {
|
||||||
|
.info-wrap .excerpt {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -477,5 +509,17 @@
|
||||||
.col-4-large {
|
.col-4-large {
|
||||||
@include section-card-large;
|
@include section-card-large;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.col-4-hide-excerpt {
|
||||||
|
.info-wrap .excerpt {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-4-show-excerpt {
|
||||||
|
.info-wrap .excerpt {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -360,6 +360,7 @@ export class TopSiteLink extends React.PureComponent {
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
draggable={true}
|
draggable={true}
|
||||||
data-is-sponsored-link={!!link.sponsored_tile_id}
|
data-is-sponsored-link={!!link.sponsored_tile_id}
|
||||||
|
title={title}
|
||||||
>
|
>
|
||||||
<div className="tile" aria-hidden={true}>
|
<div className="tile" aria-hidden={true}>
|
||||||
<div
|
<div
|
||||||
|
@ -391,7 +392,11 @@ export class TopSiteLink extends React.PureComponent {
|
||||||
: ""
|
: ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span dir="auto" {...(isAddButton && { ...addButtonl10n })}>
|
<span
|
||||||
|
className="title-label"
|
||||||
|
dir="auto"
|
||||||
|
{...(isAddButton && { ...addButtonl10n })}
|
||||||
|
>
|
||||||
{link.isPinned && <div className="icon icon-pin-small" />}
|
{link.isPinned && <div className="icon icon-pin-small" />}
|
||||||
{title || <br />}
|
{title || <br />}
|
||||||
</span>
|
</span>
|
||||||
|
@ -583,7 +588,7 @@ export class TopSite extends React.PureComponent {
|
||||||
const { props } = this;
|
const { props } = this;
|
||||||
const { link } = props;
|
const { link } = props;
|
||||||
const isContextMenuOpen = props.activeIndex === props.index;
|
const isContextMenuOpen = props.activeIndex === props.index;
|
||||||
const title = link.label || link.hostname;
|
const title = link.label || link.title || link.hostname;
|
||||||
let menuOptions;
|
let menuOptions;
|
||||||
if (link.sponsored_position) {
|
if (link.sponsored_position) {
|
||||||
menuOptions = TOP_SITES_SPONSORED_POSITION_CONTEXT_MENU_OPTIONS;
|
menuOptions = TOP_SITES_SPONSORED_POSITION_CONTEXT_MENU_OPTIONS;
|
||||||
|
|
|
@ -718,17 +718,21 @@ $calculated-max-width-twice-widest: $break-point-widest + 2 * $card-width;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
|
padding: 0 var(--space-xsmall);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus-within {
|
&:focus-within {
|
||||||
span[dir='auto'] {
|
.title:not(.sponsored) {
|
||||||
overflow: unset;
|
.sponsored-label {
|
||||||
text-overflow: clip;
|
display: none;
|
||||||
white-space: normal;
|
}
|
||||||
text-wrap: balance;
|
|
||||||
contain: size;
|
.title-label {
|
||||||
word-break: break-all;
|
-webkit-line-clamp: 2;
|
||||||
|
white-space: wrap;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -481,7 +481,7 @@ main {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
main.newtab-main {
|
main.newtab-main {
|
||||||
align-items: center;
|
min-width: min-content;
|
||||||
}
|
}
|
||||||
main .vertical-center-wrapper {
|
main .vertical-center-wrapper {
|
||||||
margin: auto 0;
|
margin: auto 0;
|
||||||
|
@ -1345,13 +1345,14 @@ main section {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
|
padding: 0 var(--space-xsmall);
|
||||||
}
|
}
|
||||||
.top-sites-list .top-site-outer:hover span[dir=auto], .top-sites-list .top-site-outer:focus-within span[dir=auto] {
|
.top-sites-list .top-site-outer:hover .title:not(.sponsored) .sponsored-label, .top-sites-list .top-site-outer:focus-within .title:not(.sponsored) .sponsored-label {
|
||||||
overflow: unset;
|
display: none;
|
||||||
text-overflow: clip;
|
}
|
||||||
white-space: normal;
|
.top-sites-list .top-site-outer:hover .title:not(.sponsored) .title-label, .top-sites-list .top-site-outer:focus-within .title:not(.sponsored) .title-label {
|
||||||
text-wrap: balance;
|
-webkit-line-clamp: 2;
|
||||||
contain: size;
|
white-space: wrap;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4884,9 +4885,6 @@ main section {
|
||||||
margin-block: var(--space-xsmall) 0;
|
margin-block: var(--space-xsmall) 0;
|
||||||
-webkit-line-clamp: 4;
|
-webkit-line-clamp: 4;
|
||||||
}
|
}
|
||||||
.ds-section-grid.ds-card-grid .col-1-small .meta .info-wrap .excerpt {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.ds-section-grid.ds-card-grid .col-1-small .meta .sections-card-footer {
|
.ds-section-grid.ds-card-grid .col-1-small .meta .sections-card-footer {
|
||||||
margin-block-start: var(--space-xxsmall);
|
margin-block-start: var(--space-xxsmall);
|
||||||
}
|
}
|
||||||
|
@ -4979,6 +4977,16 @@ main section {
|
||||||
inset-inline-start: 0;
|
inset-inline-start: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@media (min-width: 610px) {
|
||||||
|
.ds-section-grid.ds-card-grid .col-1-hide-excerpt .info-wrap .excerpt {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 610px) {
|
||||||
|
.ds-section-grid.ds-card-grid .col-1-show-excerpt .info-wrap .excerpt {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
@media (min-width: 724px) {
|
@media (min-width: 724px) {
|
||||||
.ds-section-grid.ds-card-grid {
|
.ds-section-grid.ds-card-grid {
|
||||||
grid-template-columns: repeat(2, 300px);
|
grid-template-columns: repeat(2, 300px);
|
||||||
|
@ -5055,9 +5063,6 @@ main section {
|
||||||
margin-block: var(--space-xsmall) 0;
|
margin-block: var(--space-xsmall) 0;
|
||||||
-webkit-line-clamp: 4;
|
-webkit-line-clamp: 4;
|
||||||
}
|
}
|
||||||
.ds-section-grid.ds-card-grid .col-2-small .meta .info-wrap .excerpt {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.ds-section-grid.ds-card-grid .col-2-small .meta .sections-card-footer {
|
.ds-section-grid.ds-card-grid .col-2-small .meta .sections-card-footer {
|
||||||
margin-block-start: var(--space-xxsmall);
|
margin-block-start: var(--space-xxsmall);
|
||||||
}
|
}
|
||||||
|
@ -5150,6 +5155,16 @@ main section {
|
||||||
inset-inline-start: 0;
|
inset-inline-start: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@media (min-width: 724px) {
|
||||||
|
.ds-section-grid.ds-card-grid .col-2-hide-excerpt .info-wrap .excerpt {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 724px) {
|
||||||
|
.ds-section-grid.ds-card-grid .col-2-show-excerpt .info-wrap .excerpt {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
@media (min-width: 1122px) {
|
@media (min-width: 1122px) {
|
||||||
.ds-section-grid.ds-card-grid {
|
.ds-section-grid.ds-card-grid {
|
||||||
grid-template-columns: repeat(3, 300px);
|
grid-template-columns: repeat(3, 300px);
|
||||||
|
@ -5227,9 +5242,6 @@ main section {
|
||||||
margin-block: var(--space-xsmall) 0;
|
margin-block: var(--space-xsmall) 0;
|
||||||
-webkit-line-clamp: 4;
|
-webkit-line-clamp: 4;
|
||||||
}
|
}
|
||||||
.ds-section-grid.ds-card-grid .col-3-small .meta .info-wrap .excerpt {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.ds-section-grid.ds-card-grid .col-3-small .meta .sections-card-footer {
|
.ds-section-grid.ds-card-grid .col-3-small .meta .sections-card-footer {
|
||||||
margin-block-start: var(--space-xxsmall);
|
margin-block-start: var(--space-xxsmall);
|
||||||
}
|
}
|
||||||
|
@ -5322,6 +5334,16 @@ main section {
|
||||||
inset-inline-start: 0;
|
inset-inline-start: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@media (min-width: 1122px) {
|
||||||
|
.ds-section-grid.ds-card-grid .col-3-hide-excerpt .info-wrap .excerpt {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 1122px) {
|
||||||
|
.ds-section-grid.ds-card-grid .col-3-show-excerpt .info-wrap .excerpt {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
@media (min-width: 1390px) {
|
@media (min-width: 1390px) {
|
||||||
.ds-section-grid.ds-card-grid {
|
.ds-section-grid.ds-card-grid {
|
||||||
grid-template-columns: repeat(4, 300px);
|
grid-template-columns: repeat(4, 300px);
|
||||||
|
@ -5398,9 +5420,6 @@ main section {
|
||||||
margin-block: var(--space-xsmall) 0;
|
margin-block: var(--space-xsmall) 0;
|
||||||
-webkit-line-clamp: 4;
|
-webkit-line-clamp: 4;
|
||||||
}
|
}
|
||||||
.ds-section-grid.ds-card-grid .col-4-small .meta .info-wrap .excerpt {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.ds-section-grid.ds-card-grid .col-4-small .meta .sections-card-footer {
|
.ds-section-grid.ds-card-grid .col-4-small .meta .sections-card-footer {
|
||||||
margin-block-start: var(--space-xxsmall);
|
margin-block-start: var(--space-xxsmall);
|
||||||
}
|
}
|
||||||
|
@ -5493,6 +5512,16 @@ main section {
|
||||||
inset-inline-start: 0;
|
inset-inline-start: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@media (min-width: 1390px) {
|
||||||
|
.ds-section-grid.ds-card-grid .col-4-hide-excerpt .info-wrap .excerpt {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 1390px) {
|
||||||
|
.ds-section-grid.ds-card-grid .col-4-show-excerpt .info-wrap .excerpt {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.ds-dismiss.ds-dismiss-ds-collection .ds-dismiss-button {
|
.ds-dismiss.ds-dismiss-ds-collection .ds-dismiss-button {
|
||||||
margin: 15px 0 0;
|
margin: 15px 0 0;
|
||||||
|
|
|
@ -210,7 +210,6 @@ for (const type of [
|
||||||
"SECTION_DEREGISTER",
|
"SECTION_DEREGISTER",
|
||||||
"SECTION_DISABLE",
|
"SECTION_DISABLE",
|
||||||
"SECTION_ENABLE",
|
"SECTION_ENABLE",
|
||||||
"SECTION_MOVE",
|
|
||||||
"SECTION_OPTIONS_CHANGED",
|
"SECTION_OPTIONS_CHANGED",
|
||||||
"SECTION_REGISTER",
|
"SECTION_REGISTER",
|
||||||
"SECTION_UPDATE",
|
"SECTION_UPDATE",
|
||||||
|
@ -256,7 +255,6 @@ for (const type of [
|
||||||
"UNINIT",
|
"UNINIT",
|
||||||
"UPDATE_PINNED_SEARCH_SHORTCUTS",
|
"UPDATE_PINNED_SEARCH_SHORTCUTS",
|
||||||
"UPDATE_SEARCH_SHORTCUTS",
|
"UPDATE_SEARCH_SHORTCUTS",
|
||||||
"UPDATE_SECTION_PREFS",
|
|
||||||
"WALLPAPERS_CATEGORY_SET",
|
"WALLPAPERS_CATEGORY_SET",
|
||||||
"WALLPAPERS_FEATURE_HIGHLIGHT_COUNTER_INCREMENT",
|
"WALLPAPERS_FEATURE_HIGHLIGHT_COUNTER_INCREMENT",
|
||||||
"WALLPAPERS_FEATURE_HIGHLIGHT_CTA_CLICKED",
|
"WALLPAPERS_FEATURE_HIGHLIGHT_CTA_CLICKED",
|
||||||
|
@ -8121,7 +8119,8 @@ class TopSiteLink extends (external_React_default()).PureComponent {
|
||||||
onKeyPress: this.onKeyPress,
|
onKeyPress: this.onKeyPress,
|
||||||
onClick: onClick,
|
onClick: onClick,
|
||||||
draggable: true,
|
draggable: true,
|
||||||
"data-is-sponsored-link": !!link.sponsored_tile_id
|
"data-is-sponsored-link": !!link.sponsored_tile_id,
|
||||||
|
title: title
|
||||||
}, /*#__PURE__*/external_React_default().createElement("div", {
|
}, /*#__PURE__*/external_React_default().createElement("div", {
|
||||||
className: "tile",
|
className: "tile",
|
||||||
"aria-hidden": true
|
"aria-hidden": true
|
||||||
|
@ -8143,6 +8142,7 @@ class TopSiteLink extends (external_React_default()).PureComponent {
|
||||||
})), /*#__PURE__*/external_React_default().createElement("div", {
|
})), /*#__PURE__*/external_React_default().createElement("div", {
|
||||||
className: `title${link.isPinned ? " has-icon pinned" : ""}${link.type === SPOC_TYPE || link.show_sponsored_label ? " sponsored" : ""}`
|
className: `title${link.isPinned ? " has-icon pinned" : ""}${link.type === SPOC_TYPE || link.show_sponsored_label ? " sponsored" : ""}`
|
||||||
}, /*#__PURE__*/external_React_default().createElement("span", TopSite_extends({
|
}, /*#__PURE__*/external_React_default().createElement("span", TopSite_extends({
|
||||||
|
className: "title-label",
|
||||||
dir: "auto"
|
dir: "auto"
|
||||||
}, isAddButton && {
|
}, isAddButton && {
|
||||||
...addButtonl10n
|
...addButtonl10n
|
||||||
|
@ -8321,7 +8321,7 @@ class TopSite extends (external_React_default()).PureComponent {
|
||||||
link
|
link
|
||||||
} = props;
|
} = props;
|
||||||
const isContextMenuOpen = props.activeIndex === props.index;
|
const isContextMenuOpen = props.activeIndex === props.index;
|
||||||
const title = link.label || link.hostname;
|
const title = link.label || link.title || link.hostname;
|
||||||
let menuOptions;
|
let menuOptions;
|
||||||
if (link.sponsored_position) {
|
if (link.sponsored_position) {
|
||||||
menuOptions = TOP_SITES_SPONSORED_POSITION_CONTEXT_MENU_OPTIONS;
|
menuOptions = TOP_SITES_SPONSORED_POSITION_CONTEXT_MENU_OPTIONS;
|
||||||
|
@ -10006,6 +10006,14 @@ function getLayoutData(responsiveLayouts, index) {
|
||||||
if (tile.position === index) {
|
if (tile.position === index) {
|
||||||
layoutData.classNames.push(`col-${layout.columnCount}-${tile.size}`);
|
layoutData.classNames.push(`col-${layout.columnCount}-${tile.size}`);
|
||||||
layoutData.classNames.push(`col-${layout.columnCount}-position-${tileIndex}`);
|
layoutData.classNames.push(`col-${layout.columnCount}-position-${tileIndex}`);
|
||||||
|
|
||||||
|
// The API tells us whether the tile should show the excerpt or not.
|
||||||
|
// Apply extra styles accordingly.
|
||||||
|
if (tile.hasExcerpt) {
|
||||||
|
layoutData.classNames.push(`col-${layout.columnCount}-show-excerpt`);
|
||||||
|
} else {
|
||||||
|
layoutData.classNames.push(`col-${layout.columnCount}-hide-excerpt`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,7 +15,7 @@ const lazy = {};
|
||||||
|
|
||||||
ChromeUtils.defineESModuleGetters(lazy, {
|
ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
DownloadsManager: "resource://activity-stream/lib/DownloadsManager.sys.mjs",
|
DownloadsManager: "resource://activity-stream/lib/DownloadsManager.sys.mjs",
|
||||||
FilterAdult: "resource://activity-stream/lib/FilterAdult.sys.mjs",
|
FilterAdult: "resource:///modules/FilterAdult.sys.mjs",
|
||||||
LinksCache: "resource://activity-stream/lib/LinksCache.sys.mjs",
|
LinksCache: "resource://activity-stream/lib/LinksCache.sys.mjs",
|
||||||
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
|
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
|
||||||
PageThumbs: "resource://gre/modules/PageThumbs.sys.mjs",
|
PageThumbs: "resource://gre/modules/PageThumbs.sys.mjs",
|
||||||
|
|
|
@ -119,8 +119,6 @@ export class PrefsFeed {
|
||||||
lazy.NimbusFeatures.newtab.onUpdate(this.onExperimentUpdated);
|
lazy.NimbusFeatures.newtab.onUpdate(this.onExperimentUpdated);
|
||||||
lazy.NimbusFeatures.pocketNewtab.onUpdate(this.onPocketExperimentUpdated);
|
lazy.NimbusFeatures.pocketNewtab.onUpdate(this.onPocketExperimentUpdated);
|
||||||
|
|
||||||
this._storage = this.store.dbStorage.getDbTable("sectionPrefs");
|
|
||||||
|
|
||||||
// Get the initial value of each activity stream pref
|
// Get the initial value of each activity stream pref
|
||||||
const values = {};
|
const values = {};
|
||||||
for (const name of this._prefMap.keys()) {
|
for (const name of this._prefMap.keys()) {
|
||||||
|
@ -229,15 +227,6 @@ export class PrefsFeed {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _setIndexedDBPref(id, value) {
|
|
||||||
const name = id === "topsites" ? id : `feeds.section.${id}`;
|
|
||||||
try {
|
|
||||||
await this._storage.set(name, value);
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Could not set section preferences.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
observe(subject, topic) {
|
observe(subject, topic) {
|
||||||
switch (topic) {
|
switch (topic) {
|
||||||
case lazy.Region.REGION_TOPIC:
|
case lazy.Region.REGION_TOPIC:
|
||||||
|
@ -265,9 +254,6 @@ export class PrefsFeed {
|
||||||
case at.SET_PREF:
|
case at.SET_PREF:
|
||||||
this._prefs.set(action.data.name, action.data.value);
|
this._prefs.set(action.data.name, action.data.value);
|
||||||
break;
|
break;
|
||||||
case at.UPDATE_SECTION_PREFS:
|
|
||||||
this._setIndexedDBPref(action.data.id, action.data.value);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ import {
|
||||||
actionCreators as ac,
|
actionCreators as ac,
|
||||||
actionTypes as at,
|
actionTypes as at,
|
||||||
} from "resource://activity-stream/common/Actions.mjs";
|
} from "resource://activity-stream/common/Actions.mjs";
|
||||||
import { getDefaultOptions } from "resource:///modules/asrouter/ASRouterStorage.sys.mjs";
|
|
||||||
|
|
||||||
const lazy = {};
|
const lazy = {};
|
||||||
|
|
||||||
|
@ -202,8 +201,7 @@ export const SectionsManager = {
|
||||||
},
|
},
|
||||||
initialized: false,
|
initialized: false,
|
||||||
sections: new Map(),
|
sections: new Map(),
|
||||||
async init(prefs = {}, storage) {
|
async init(prefs = {}) {
|
||||||
this._storage = storage;
|
|
||||||
const featureConfig = {
|
const featureConfig = {
|
||||||
newtab: lazy.NimbusFeatures.newtab.getAllVariables() || {},
|
newtab: lazy.NimbusFeatures.newtab.getAllVariables() || {},
|
||||||
pocketNewtab: lazy.NimbusFeatures.pocketNewtab.getAllVariables() || {},
|
pocketNewtab: lazy.NimbusFeatures.pocketNewtab.getAllVariables() || {},
|
||||||
|
@ -242,20 +240,8 @@ export const SectionsManager = {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateSectionPrefs(id, collapsed) {
|
|
||||||
const section = this.sections.get(id);
|
|
||||||
if (!section) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedSection = Object.assign({}, section, {
|
|
||||||
pref: Object.assign({}, section.pref, collapsed),
|
|
||||||
});
|
|
||||||
this.updateSection(id, updatedSection, true);
|
|
||||||
},
|
|
||||||
async addBuiltInSection(feedPrefName, optionsPrefValue = "{}") {
|
async addBuiltInSection(feedPrefName, optionsPrefValue = "{}") {
|
||||||
let options;
|
let options;
|
||||||
let storedPrefs;
|
|
||||||
const featureConfig = {
|
const featureConfig = {
|
||||||
newtab: lazy.NimbusFeatures.newtab.getAllVariables() || {},
|
newtab: lazy.NimbusFeatures.newtab.getAllVariables() || {},
|
||||||
pocketNewtab: lazy.NimbusFeatures.pocketNewtab.getAllVariables() || {},
|
pocketNewtab: lazy.NimbusFeatures.pocketNewtab.getAllVariables() || {},
|
||||||
|
@ -266,20 +252,11 @@ export const SectionsManager = {
|
||||||
options = {};
|
options = {};
|
||||||
console.error(`Problem parsing options pref for ${feedPrefName}`);
|
console.error(`Problem parsing options pref for ${feedPrefName}`);
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
storedPrefs = (await this._storage.get(feedPrefName)) || {};
|
|
||||||
} catch (e) {
|
|
||||||
storedPrefs = {};
|
|
||||||
console.error(`Problem getting stored prefs for ${feedPrefName}`);
|
|
||||||
}
|
|
||||||
const defaultSection =
|
const defaultSection =
|
||||||
BUILT_IN_SECTIONS(featureConfig)[feedPrefName](options);
|
BUILT_IN_SECTIONS(featureConfig)[feedPrefName](options);
|
||||||
const section = Object.assign({}, defaultSection, {
|
const section = Object.assign({}, defaultSection, {
|
||||||
pref: Object.assign(
|
pref: Object.assign({}, defaultSection.pref),
|
||||||
{},
|
|
||||||
defaultSection.pref,
|
|
||||||
getDefaultOptions(storedPrefs)
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
section.pref.feed = feedPrefName;
|
section.pref.feed = feedPrefName;
|
||||||
this.addSection(section.id, Object.assign(section, { options }));
|
this.addSection(section.id, Object.assign(section, { options }));
|
||||||
|
@ -602,48 +579,6 @@ export class SectionsFeed {
|
||||||
return this.store.getState().Prefs.values.sectionOrder.split(",");
|
return this.store.getState().Prefs.values.sectionOrder.split(",");
|
||||||
}
|
}
|
||||||
|
|
||||||
get enabledSectionIds() {
|
|
||||||
let sections = this.store
|
|
||||||
.getState()
|
|
||||||
.Sections.filter(section => section.enabled)
|
|
||||||
.map(s => s.id);
|
|
||||||
// Top Sites is a special case. Append if the feed is enabled.
|
|
||||||
if (this.store.getState().Prefs.values["feeds.topsites"]) {
|
|
||||||
sections.push("topsites");
|
|
||||||
}
|
|
||||||
return sections;
|
|
||||||
}
|
|
||||||
|
|
||||||
moveSection(id, direction) {
|
|
||||||
const orderedSections = this.orderedSectionIds;
|
|
||||||
const enabledSections = this.enabledSectionIds;
|
|
||||||
let index = orderedSections.indexOf(id);
|
|
||||||
orderedSections.splice(index, 1);
|
|
||||||
if (direction > 0) {
|
|
||||||
// "Move Down"
|
|
||||||
while (index < orderedSections.length) {
|
|
||||||
// If the section at the index is enabled/visible, insert moved section after.
|
|
||||||
// Otherwise, move on to the next spot and check it.
|
|
||||||
if (enabledSections.includes(orderedSections[index++])) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// "Move Up"
|
|
||||||
while (index > 0) {
|
|
||||||
// If the section at the previous index is enabled/visible, insert moved section there.
|
|
||||||
// Otherwise, move on to the previous spot and check it.
|
|
||||||
index--;
|
|
||||||
if (enabledSections.includes(orderedSections[index])) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
orderedSections.splice(index, 0, id);
|
|
||||||
this.store.dispatch(ac.SetPref("sectionOrder", orderedSections.join(",")));
|
|
||||||
}
|
|
||||||
|
|
||||||
async onAction(action) {
|
async onAction(action) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case at.INIT:
|
case at.INIT:
|
||||||
|
@ -651,10 +586,7 @@ export class SectionsFeed {
|
||||||
break;
|
break;
|
||||||
// Wait for pref values, as some sections have options stored in prefs
|
// Wait for pref values, as some sections have options stored in prefs
|
||||||
case at.PREFS_INITIAL_VALUES:
|
case at.PREFS_INITIAL_VALUES:
|
||||||
SectionsManager.init(
|
SectionsManager.init(action.data);
|
||||||
action.data,
|
|
||||||
this.store.dbStorage.getDbTable("sectionPrefs")
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
case at.PREF_CHANGED: {
|
case at.PREF_CHANGED: {
|
||||||
if (action.data) {
|
if (action.data) {
|
||||||
|
@ -674,9 +606,6 @@ export class SectionsFeed {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case at.UPDATE_SECTION_PREFS:
|
|
||||||
SectionsManager.updateSectionPrefs(action.data.id, action.data.value);
|
|
||||||
break;
|
|
||||||
case at.PLACES_BOOKMARK_ADDED:
|
case at.PLACES_BOOKMARK_ADDED:
|
||||||
SectionsManager.updateBookmarkMetadata(action.data);
|
SectionsManager.updateBookmarkMetadata(action.data);
|
||||||
break;
|
break;
|
||||||
|
@ -694,9 +623,6 @@ export class SectionsFeed {
|
||||||
case at.SECTION_ENABLE:
|
case at.SECTION_ENABLE:
|
||||||
SectionsManager.enableSection(action.data);
|
SectionsManager.enableSection(action.data);
|
||||||
break;
|
break;
|
||||||
case at.SECTION_MOVE:
|
|
||||||
this.moveSection(action.data.id, action.data.direction);
|
|
||||||
break;
|
|
||||||
case at.UNINIT:
|
case at.UNINIT:
|
||||||
this.uninit();
|
this.uninit();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
import { ActivityStreamMessageChannel } from "resource://activity-stream/lib/ActivityStreamMessageChannel.sys.mjs";
|
import { ActivityStreamMessageChannel } from "resource://activity-stream/lib/ActivityStreamMessageChannel.sys.mjs";
|
||||||
import { ASRouterStorage } from "resource:///modules/asrouter/ASRouterStorage.sys.mjs";
|
|
||||||
import { Prefs } from "resource://activity-stream/lib/ActivityStreamPrefs.sys.mjs";
|
import { Prefs } from "resource://activity-stream/lib/ActivityStreamPrefs.sys.mjs";
|
||||||
import { reducers } from "resource://activity-stream/common/Reducers.sys.mjs";
|
import { reducers } from "resource://activity-stream/common/Reducers.sys.mjs";
|
||||||
import { redux } from "chrome://global/content/vendor/Redux.sys.mjs";
|
import { redux } from "chrome://global/content/vendor/Redux.sys.mjs";
|
||||||
|
@ -36,7 +35,6 @@ export class Store {
|
||||||
redux.combineReducers(reducers),
|
redux.combineReducers(reducers),
|
||||||
redux.applyMiddleware(this._middleware, this._messageChannel.middleware)
|
redux.applyMiddleware(this._middleware, this._messageChannel.middleware)
|
||||||
);
|
);
|
||||||
this.storage = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -125,8 +123,6 @@ export class Store {
|
||||||
this.initFeed(telemetryKey);
|
this.initFeed(telemetryKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this._initIndexedDB(telemetryKey);
|
|
||||||
|
|
||||||
for (const pref of feedFactories.keys()) {
|
for (const pref of feedFactories.keys()) {
|
||||||
if (pref !== telemetryKey && this._prefs.get(pref)) {
|
if (pref !== telemetryKey && this._prefs.get(pref)) {
|
||||||
this.initFeed(pref);
|
this.initFeed(pref);
|
||||||
|
@ -144,26 +140,6 @@ export class Store {
|
||||||
this._messageChannel.simulateMessagesForExistingTabs();
|
this._messageChannel.simulateMessagesForExistingTabs();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _initIndexedDB() {
|
|
||||||
// "snippets" is the name of one storage space, but these days it is used
|
|
||||||
// not for snippet-related data (snippets were removed in bug 1715158),
|
|
||||||
// but storage for impression or session data for all ASRouter messages.
|
|
||||||
//
|
|
||||||
// We keep the name "snippets" to avoid having to do an IndexedDB database
|
|
||||||
// migration.
|
|
||||||
this.dbStorage = new ASRouterStorage({
|
|
||||||
storeNames: ["sectionPrefs", "snippets"],
|
|
||||||
});
|
|
||||||
// Accessing the db causes the object stores to be created / migrated.
|
|
||||||
// This needs to happen before other instances try to access the db, which
|
|
||||||
// would update only a subset of the stores to the latest version.
|
|
||||||
try {
|
|
||||||
await this.dbStorage.db; // eslint-disable-line no-unused-expressions
|
|
||||||
} catch (e) {
|
|
||||||
this.dbStorage.telemetry = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* uninit - Uninitalizes each feed, clears them, and destroys the message
|
* uninit - Uninitalizes each feed, clears them, and destroys the message
|
||||||
* manager channel.
|
* manager channel.
|
||||||
|
|
|
@ -51,6 +51,7 @@ export const PREF_UNIFIED_ADS_TILES_ENABLED = "unifiedAds.tiles.enabled";
|
||||||
const PREF_ENDPOINTS = "discoverystream.endpoints";
|
const PREF_ENDPOINTS = "discoverystream.endpoints";
|
||||||
const PREF_SHOW_SPONSORED_STORIES = "showSponsored";
|
const PREF_SHOW_SPONSORED_STORIES = "showSponsored";
|
||||||
const PREF_SHOW_SPONSORED_TOPSITES = "showSponsoredTopSites";
|
const PREF_SHOW_SPONSORED_TOPSITES = "showSponsoredTopSites";
|
||||||
|
const BLANK_HOMEPAGE_URL = "chrome://browser/content/blanktab.html";
|
||||||
|
|
||||||
// This is a mapping table between the user preferences and its encoding code
|
// This is a mapping table between the user preferences and its encoding code
|
||||||
export const USER_PREFS_ENCODING = {
|
export const USER_PREFS_ENCODING = {
|
||||||
|
@ -839,7 +840,9 @@ export class TelemetryFeed {
|
||||||
|
|
||||||
const homePageURL = lazy.HomePage.get();
|
const homePageURL = lazy.HomePage.get();
|
||||||
if (
|
if (
|
||||||
!["about:home", "about:blank"].includes(homePageURL) &&
|
!["about:home", "about:blank", BLANK_HOMEPAGE_URL].includes(
|
||||||
|
homePageURL
|
||||||
|
) &&
|
||||||
!homePageURL.startsWith("moz-extension://")
|
!homePageURL.startsWith("moz-extension://")
|
||||||
) {
|
) {
|
||||||
value.home_url_category = await this._classifySite(homePageURL);
|
value.home_url_category = await this._classifySite(homePageURL);
|
||||||
|
|
|
@ -16,7 +16,6 @@ import {
|
||||||
shortURL,
|
shortURL,
|
||||||
shortHostname,
|
shortHostname,
|
||||||
} from "resource://activity-stream/lib/ShortURL.sys.mjs";
|
} from "resource://activity-stream/lib/ShortURL.sys.mjs";
|
||||||
import { getDefaultOptions } from "resource:///modules/asrouter/ASRouterStorage.sys.mjs";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CUSTOM_SEARCH_SHORTCUTS,
|
CUSTOM_SEARCH_SHORTCUTS,
|
||||||
|
@ -30,7 +29,7 @@ import {
|
||||||
const lazy = {};
|
const lazy = {};
|
||||||
|
|
||||||
ChromeUtils.defineESModuleGetters(lazy, {
|
ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
FilterAdult: "resource://activity-stream/lib/FilterAdult.sys.mjs",
|
FilterAdult: "resource:///modules/FilterAdult.sys.mjs",
|
||||||
LinksCache: "resource://activity-stream/lib/LinksCache.sys.mjs",
|
LinksCache: "resource://activity-stream/lib/LinksCache.sys.mjs",
|
||||||
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
|
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
|
||||||
NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs",
|
NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs",
|
||||||
|
@ -71,7 +70,7 @@ const PINNED_FAVICON_PROPS_TO_MIGRATE = [
|
||||||
"faviconRef",
|
"faviconRef",
|
||||||
"faviconSize",
|
"faviconSize",
|
||||||
];
|
];
|
||||||
const SECTION_ID = "topsites";
|
|
||||||
const CACHE_KEY = "contile";
|
const CACHE_KEY = "contile";
|
||||||
const ROWS_PREF = "topSitesRows";
|
const ROWS_PREF = "topSitesRows";
|
||||||
const SHOW_SPONSORED_PREF = "showSponsoredTopSites";
|
const SHOW_SPONSORED_PREF = "showSponsoredTopSites";
|
||||||
|
@ -746,7 +745,6 @@ export class TopSitesFeed {
|
||||||
init() {
|
init() {
|
||||||
// If the feed was previously disabled PREFS_INITIAL_VALUES was never received
|
// If the feed was previously disabled PREFS_INITIAL_VALUES was never received
|
||||||
this._readDefaults({ isStartup: true });
|
this._readDefaults({ isStartup: true });
|
||||||
this._storage = this.store.dbStorage.getDbTable("sectionPrefs");
|
|
||||||
this._contile.refresh();
|
this._contile.refresh();
|
||||||
Services.obs.addObserver(this, "browser-search-engine-modified");
|
Services.obs.addObserver(this, "browser-search-engine-modified");
|
||||||
Services.obs.addObserver(this, "browser-region-updated");
|
Services.obs.addObserver(this, "browser-region-updated");
|
||||||
|
@ -1609,14 +1607,6 @@ export class TopSitesFeed {
|
||||||
isStartup: options.isStartup,
|
isStartup: options.isStartup,
|
||||||
});
|
});
|
||||||
const newAction = { type: at.TOP_SITES_UPDATED, data: { links } };
|
const newAction = { type: at.TOP_SITES_UPDATED, data: { links } };
|
||||||
let storedPrefs;
|
|
||||||
try {
|
|
||||||
storedPrefs = (await this._storage.get(SECTION_ID)) || {};
|
|
||||||
} catch (e) {
|
|
||||||
storedPrefs = {};
|
|
||||||
console.error("Problem getting stored prefs for TopSites");
|
|
||||||
}
|
|
||||||
newAction.data.pref = getDefaultOptions(storedPrefs);
|
|
||||||
|
|
||||||
if (options.isStartup) {
|
if (options.isStartup) {
|
||||||
newAction.meta = {
|
newAction.meta = {
|
||||||
|
@ -1794,15 +1784,6 @@ export class TopSitesFeed {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSectionPrefs(collapsed) {
|
|
||||||
this.store.dispatch(
|
|
||||||
ac.BroadcastToContent({
|
|
||||||
type: at.TOP_SITES_PREFS_UPDATED,
|
|
||||||
data: { pref: collapsed },
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inform others that top sites data has been updated due to pinned changes.
|
* Inform others that top sites data has been updated due to pinned changes.
|
||||||
*/
|
*/
|
||||||
|
@ -2107,11 +2088,6 @@ export class TopSitesFeed {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case at.UPDATE_SECTION_PREFS:
|
|
||||||
if (action.data.id === SECTION_ID) {
|
|
||||||
this.updateSectionPrefs(action.data.value);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case at.PREFS_INITIAL_VALUES:
|
case at.PREFS_INITIAL_VALUES:
|
||||||
if (!this._useRemoteSetting) {
|
if (!this._useRemoteSetting) {
|
||||||
this.refreshDefaults(action.data[DEFAULT_SITES_PREF]);
|
this.refreshDefaults(action.data[DEFAULT_SITES_PREF]);
|
||||||
|
|
|
@ -180,8 +180,30 @@ describe("<CardSections />", () => {
|
||||||
it("should apply correct classNames and position from layout data", () => {
|
it("should apply correct classNames and position from layout data", () => {
|
||||||
const props = wrapper.find(DSCard).at(0).props();
|
const props = wrapper.find(DSCard).at(0).props();
|
||||||
const thirdProps = wrapper.find(DSCard).at(2).props();
|
const thirdProps = wrapper.find(DSCard).at(2).props();
|
||||||
assert.equal(props.sectionsClassNames, "col-1-large col-1-position-0");
|
assert.equal(
|
||||||
assert.equal(thirdProps.sectionsClassNames, "col-1-small col-1-position-1");
|
props.sectionsClassNames,
|
||||||
|
"col-1-large col-1-position-0 col-1-show-excerpt"
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
thirdProps.sectionsClassNames,
|
||||||
|
"col-1-small col-1-position-1 col-1-hide-excerpt"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should apply correct class names for cards with and without excerpts", () => {
|
||||||
|
wrapper.find(DSCard).forEach(card => {
|
||||||
|
const props = card.props();
|
||||||
|
// Small cards don't show excerpts according to the data in DEFAULT_PROPS for this test suite
|
||||||
|
if (props.sectionsClassNames.includes("small")) {
|
||||||
|
assert.include(props.sectionsClassNames, "hide-excerpt");
|
||||||
|
assert.notInclude(props.sectionsClassNames, "show-excerpt");
|
||||||
|
}
|
||||||
|
// The other cards should show excerpts though!
|
||||||
|
else {
|
||||||
|
assert.include(props.sectionsClassNames, "show-excerpt");
|
||||||
|
assert.notInclude(props.sectionsClassNames, "hide-excerpt");
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should dispatch PREF_FOLLOWED_SECTIONS updates with follow and unfollow", () => {
|
it("should dispatch PREF_FOLLOWED_SECTIONS updates with follow and unfollow", () => {
|
||||||
|
|
|
@ -1,112 +0,0 @@
|
||||||
import { FilterAdult } from "lib/FilterAdult.sys.mjs";
|
|
||||||
import { GlobalOverrider } from "test/unit/utils";
|
|
||||||
|
|
||||||
describe("FilterAdult", () => {
|
|
||||||
let hashStub;
|
|
||||||
let hashValue;
|
|
||||||
let globals;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
globals = new GlobalOverrider();
|
|
||||||
hashStub = {
|
|
||||||
finish: sinon.stub().callsFake(() => hashValue),
|
|
||||||
init: sinon.stub(),
|
|
||||||
update: sinon.stub(),
|
|
||||||
};
|
|
||||||
globals.set("Cc", {
|
|
||||||
"@mozilla.org/security/hash;1": {
|
|
||||||
createInstance() {
|
|
||||||
return hashStub;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
globals.set("gFilterAdultEnabled", true);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
hashValue = "";
|
|
||||||
globals.restore();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("filter", () => {
|
|
||||||
it("should default to include on unexpected urls", () => {
|
|
||||||
const empty = {};
|
|
||||||
|
|
||||||
const result = FilterAdult.filter([empty]);
|
|
||||||
|
|
||||||
assert.equal(result.length, 1);
|
|
||||||
assert.equal(result[0], empty);
|
|
||||||
});
|
|
||||||
it("should not filter out non-adult urls", () => {
|
|
||||||
const link = { url: "https://mozilla.org/" };
|
|
||||||
|
|
||||||
const result = FilterAdult.filter([link]);
|
|
||||||
|
|
||||||
assert.equal(result.length, 1);
|
|
||||||
assert.equal(result[0], link);
|
|
||||||
});
|
|
||||||
it("should filter out adult urls", () => {
|
|
||||||
// Use a hash value that is in the adult set
|
|
||||||
hashValue = "+/UCpAhZhz368iGioEO8aQ==";
|
|
||||||
const link = { url: "https://some-adult-site/" };
|
|
||||||
|
|
||||||
const result = FilterAdult.filter([link]);
|
|
||||||
|
|
||||||
assert.equal(result.length, 0);
|
|
||||||
});
|
|
||||||
it("should not filter out adult urls if the preference is turned off", () => {
|
|
||||||
// Use a hash value that is in the adult set
|
|
||||||
hashValue = "+/UCpAhZhz368iGioEO8aQ==";
|
|
||||||
globals.set("gFilterAdultEnabled", false);
|
|
||||||
const link = { url: "https://some-adult-site/" };
|
|
||||||
|
|
||||||
const result = FilterAdult.filter([link]);
|
|
||||||
|
|
||||||
assert.equal(result.length, 1);
|
|
||||||
assert.equal(result[0], link);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("isAdultUrl", () => {
|
|
||||||
it("should default to false on unexpected urls", () => {
|
|
||||||
const result = FilterAdult.isAdultUrl("");
|
|
||||||
|
|
||||||
assert.equal(result, false);
|
|
||||||
});
|
|
||||||
it("should return false for non-adult urls", () => {
|
|
||||||
const result = FilterAdult.isAdultUrl("https://mozilla.org/");
|
|
||||||
|
|
||||||
assert.equal(result, false);
|
|
||||||
});
|
|
||||||
it("should return true for adult urls", () => {
|
|
||||||
// Use a hash value that is in the adult set
|
|
||||||
hashValue = "+/UCpAhZhz368iGioEO8aQ==";
|
|
||||||
const result = FilterAdult.isAdultUrl("https://some-adult-site/");
|
|
||||||
|
|
||||||
assert.equal(result, true);
|
|
||||||
});
|
|
||||||
it("should return false for adult urls when the preference is turned off", () => {
|
|
||||||
// Use a hash value that is in the adult set
|
|
||||||
hashValue = "+/UCpAhZhz368iGioEO8aQ==";
|
|
||||||
globals.set("gFilterAdultEnabled", false);
|
|
||||||
const result = FilterAdult.isAdultUrl("https://some-adult-site/");
|
|
||||||
|
|
||||||
assert.equal(result, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("test functions", () => {
|
|
||||||
it("should add and remove a filter in the adult list", () => {
|
|
||||||
// Use a hash value that is in the adult set
|
|
||||||
FilterAdult.addDomainToList("https://some-adult-site/");
|
|
||||||
let result = FilterAdult.isAdultUrl("https://some-adult-site/");
|
|
||||||
|
|
||||||
assert.equal(result, true);
|
|
||||||
|
|
||||||
FilterAdult.removeDomainFromList("https://some-adult-site/");
|
|
||||||
result = FilterAdult.isAdultUrl("https://some-adult-site/");
|
|
||||||
|
|
||||||
assert.equal(result, false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -18,10 +18,6 @@ describe("PrefsFeed", () => {
|
||||||
["qux", { value: 1, skipBroadcast: true, alsoToPreloaded: true }],
|
["qux", { value: 1, skipBroadcast: true, alsoToPreloaded: true }],
|
||||||
]);
|
]);
|
||||||
feed = new PrefsFeed(FAKE_PREFS);
|
feed = new PrefsFeed(FAKE_PREFS);
|
||||||
const storage = {
|
|
||||||
getAll: sandbox.stub().resolves(),
|
|
||||||
set: sandbox.stub().resolves(),
|
|
||||||
};
|
|
||||||
ServicesStub = {
|
ServicesStub = {
|
||||||
prefs: {
|
prefs: {
|
||||||
clearUserPref: sinon.spy(),
|
clearUserPref: sinon.spy(),
|
||||||
|
@ -40,10 +36,8 @@ describe("PrefsFeed", () => {
|
||||||
getState() {
|
getState() {
|
||||||
return this.state;
|
return this.state;
|
||||||
},
|
},
|
||||||
dbStorage: { getDbTable: sandbox.stub().returns(storage) },
|
|
||||||
};
|
};
|
||||||
// Setup for tests that don't call `init`
|
// Setup for tests that don't call `init`
|
||||||
feed._storage = storage;
|
|
||||||
feed._prefs = {
|
feed._prefs = {
|
||||||
get: sinon.spy(item => FAKE_PREFS.get(item)),
|
get: sinon.spy(item => FAKE_PREFS.get(item)),
|
||||||
set: sinon.spy((name, value) => FAKE_PREFS.set(name, value)),
|
set: sinon.spy((name, value) => FAKE_PREFS.set(name, value)),
|
||||||
|
@ -111,12 +105,6 @@ describe("PrefsFeed", () => {
|
||||||
assert.calledOnce(feed._prefs.observeBranch);
|
assert.calledOnce(feed._prefs.observeBranch);
|
||||||
assert.calledWith(feed._prefs.observeBranch, feed);
|
assert.calledWith(feed._prefs.observeBranch, feed);
|
||||||
});
|
});
|
||||||
it("should initialise the storage on init", () => {
|
|
||||||
feed.init();
|
|
||||||
|
|
||||||
assert.calledOnce(feed.store.dbStorage.getDbTable);
|
|
||||||
assert.calledWithExactly(feed.store.dbStorage.getDbTable, "sectionPrefs");
|
|
||||||
});
|
|
||||||
it("should handle region on init", () => {
|
it("should handle region on init", () => {
|
||||||
feed.init();
|
feed.init();
|
||||||
assert.equal(feed.geo, "US");
|
assert.equal(feed.geo, "US");
|
||||||
|
@ -224,32 +212,6 @@ describe("PrefsFeed", () => {
|
||||||
global.Region.REGION_TOPIC
|
global.Region.REGION_TOPIC
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set storage pref on UPDATE_SECTION_PREFS", async () => {
|
|
||||||
await feed.onAction({
|
|
||||||
type: at.UPDATE_SECTION_PREFS,
|
|
||||||
data: { id: "topsites", value: { collapsed: false } },
|
|
||||||
});
|
|
||||||
assert.calledWith(feed._storage.set, "topsites", { collapsed: false });
|
|
||||||
});
|
|
||||||
it("should set storage pref with section prefix on UPDATE_SECTION_PREFS", async () => {
|
|
||||||
await feed.onAction({
|
|
||||||
type: at.UPDATE_SECTION_PREFS,
|
|
||||||
data: { id: "topstories", value: { collapsed: false } },
|
|
||||||
});
|
|
||||||
assert.calledWith(feed._storage.set, "feeds.section.topstories", {
|
|
||||||
collapsed: false,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("should catch errors on UPDATE_SECTION_PREFS", async () => {
|
|
||||||
feed._storage.set.throws(new Error("foo"));
|
|
||||||
assert.doesNotThrow(async () => {
|
|
||||||
await feed.onAction({
|
|
||||||
type: at.UPDATE_SECTION_PREFS,
|
|
||||||
data: { id: "topstories", value: { collapsed: false } },
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("should send OnlyToMain pref update if config for pref has skipBroadcast: true", async () => {
|
it("should send OnlyToMain pref update if config for pref has skipBroadcast: true", async () => {
|
||||||
feed.onPrefChanged("baz", { value: 2, skipBroadcast: true });
|
feed.onPrefChanged("baz", { value: 2, skipBroadcast: true });
|
||||||
assert.calledWith(
|
assert.calledWith(
|
||||||
|
|
|
@ -25,7 +25,6 @@ describe("SectionsManager", () => {
|
||||||
let fakeServices;
|
let fakeServices;
|
||||||
let fakePlacesUtils;
|
let fakePlacesUtils;
|
||||||
let sandbox;
|
let sandbox;
|
||||||
let storage;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
sandbox = sinon.createSandbox();
|
sandbox = sinon.createSandbox();
|
||||||
|
@ -50,10 +49,6 @@ describe("SectionsManager", () => {
|
||||||
});
|
});
|
||||||
// Redecorate SectionsManager to remove any listeners that have been added
|
// Redecorate SectionsManager to remove any listeners that have been added
|
||||||
EventEmitter.decorate(SectionsManager);
|
EventEmitter.decorate(SectionsManager);
|
||||||
storage = {
|
|
||||||
get: sandbox.stub().resolves(),
|
|
||||||
set: sandbox.stub().resolves(),
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -65,7 +60,7 @@ describe("SectionsManager", () => {
|
||||||
it("should initialise the sections map with the built in sections", async () => {
|
it("should initialise the sections map with the built in sections", async () => {
|
||||||
SectionsManager.sections.clear();
|
SectionsManager.sections.clear();
|
||||||
SectionsManager.initialized = false;
|
SectionsManager.initialized = false;
|
||||||
await SectionsManager.init({}, storage);
|
await SectionsManager.init({});
|
||||||
assert.equal(SectionsManager.sections.size, 2);
|
assert.equal(SectionsManager.sections.size, 2);
|
||||||
assert.ok(SectionsManager.sections.has("topstories"));
|
assert.ok(SectionsManager.sections.has("topstories"));
|
||||||
assert.ok(SectionsManager.sections.has("highlights"));
|
assert.ok(SectionsManager.sections.has("highlights"));
|
||||||
|
@ -73,12 +68,12 @@ describe("SectionsManager", () => {
|
||||||
it("should set .initialized to true", async () => {
|
it("should set .initialized to true", async () => {
|
||||||
SectionsManager.sections.clear();
|
SectionsManager.sections.clear();
|
||||||
SectionsManager.initialized = false;
|
SectionsManager.initialized = false;
|
||||||
await SectionsManager.init({}, storage);
|
await SectionsManager.init({});
|
||||||
assert.ok(SectionsManager.initialized);
|
assert.ok(SectionsManager.initialized);
|
||||||
});
|
});
|
||||||
it("should add observer for context menu prefs", async () => {
|
it("should add observer for context menu prefs", async () => {
|
||||||
SectionsManager.CONTEXT_MENU_PREFS = { MENU_ITEM: "MENU_ITEM_PREF" };
|
SectionsManager.CONTEXT_MENU_PREFS = { MENU_ITEM: "MENU_ITEM_PREF" };
|
||||||
await SectionsManager.init({}, storage);
|
await SectionsManager.init({});
|
||||||
assert.calledOnce(fakeServices.prefs.addObserver);
|
assert.calledOnce(fakeServices.prefs.addObserver);
|
||||||
assert.calledWith(
|
assert.calledWith(
|
||||||
fakeServices.prefs.addObserver,
|
fakeServices.prefs.addObserver,
|
||||||
|
@ -86,11 +81,6 @@ describe("SectionsManager", () => {
|
||||||
SectionsManager
|
SectionsManager
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it("should save the reference to `storage` passed in", async () => {
|
|
||||||
await SectionsManager.init({}, storage);
|
|
||||||
|
|
||||||
assert.equal(SectionsManager._storage, storage);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
describe("#uninit", () => {
|
describe("#uninit", () => {
|
||||||
it("should remove observer for context menu prefs", () => {
|
it("should remove observer for context menu prefs", () => {
|
||||||
|
@ -109,7 +99,6 @@ describe("SectionsManager", () => {
|
||||||
describe("#addBuiltInSection", () => {
|
describe("#addBuiltInSection", () => {
|
||||||
it("should not report an error if options is undefined", async () => {
|
it("should not report an error if options is undefined", async () => {
|
||||||
globals.sandbox.spy(global.console, "error");
|
globals.sandbox.spy(global.console, "error");
|
||||||
SectionsManager._storage.get = sandbox.stub().returns(Promise.resolve());
|
|
||||||
await SectionsManager.addBuiltInSection(
|
await SectionsManager.addBuiltInSection(
|
||||||
"feeds.section.topstories",
|
"feeds.section.topstories",
|
||||||
undefined
|
undefined
|
||||||
|
@ -119,7 +108,6 @@ describe("SectionsManager", () => {
|
||||||
});
|
});
|
||||||
it("should report an error if options is malformed", async () => {
|
it("should report an error if options is malformed", async () => {
|
||||||
globals.sandbox.spy(global.console, "error");
|
globals.sandbox.spy(global.console, "error");
|
||||||
SectionsManager._storage.get = sandbox.stub().returns(Promise.resolve());
|
|
||||||
await SectionsManager.addBuiltInSection(
|
await SectionsManager.addBuiltInSection(
|
||||||
"feeds.section.topstories",
|
"feeds.section.topstories",
|
||||||
"invalid"
|
"invalid"
|
||||||
|
@ -127,40 +115,6 @@ describe("SectionsManager", () => {
|
||||||
|
|
||||||
assert.calledOnce(console.error);
|
assert.calledOnce(console.error);
|
||||||
});
|
});
|
||||||
it("should not throw if the indexedDB operation fails", async () => {
|
|
||||||
globals.sandbox.spy(global.console, "error");
|
|
||||||
storage.get = sandbox.stub().throws();
|
|
||||||
SectionsManager._storage = storage;
|
|
||||||
|
|
||||||
try {
|
|
||||||
await SectionsManager.addBuiltInSection("feeds.section.topstories");
|
|
||||||
} catch (e) {
|
|
||||||
assert.fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.calledOnce(storage.get);
|
|
||||||
assert.calledOnce(console.error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe("#updateSectionPrefs", () => {
|
|
||||||
it("should update the collapsed value of the section", async () => {
|
|
||||||
sandbox.stub(SectionsManager, "updateSection");
|
|
||||||
let topstories = SectionsManager.sections.get("topstories");
|
|
||||||
assert.isFalse(topstories.pref.collapsed);
|
|
||||||
|
|
||||||
await SectionsManager.updateSectionPrefs("topstories", {
|
|
||||||
collapsed: true,
|
|
||||||
});
|
|
||||||
topstories = SectionsManager.sections.get("topstories");
|
|
||||||
|
|
||||||
assert.isTrue(SectionsManager.updateSection.args[0][1].pref.collapsed);
|
|
||||||
});
|
|
||||||
it("should ignore invalid ids", async () => {
|
|
||||||
sandbox.stub(SectionsManager, "updateSection");
|
|
||||||
await SectionsManager.updateSectionPrefs("foo", { collapsed: true });
|
|
||||||
|
|
||||||
assert.notCalled(SectionsManager.updateSection);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
describe("#addSection", () => {
|
describe("#addSection", () => {
|
||||||
it("should add the id to sections and emit an ADD_SECTION event", () => {
|
it("should add the id to sections and emit an ADD_SECTION event", () => {
|
||||||
|
@ -295,7 +249,7 @@ describe("SectionsManager", () => {
|
||||||
|
|
||||||
SectionsManager.updateSections = sinon.spy();
|
SectionsManager.updateSections = sinon.spy();
|
||||||
SectionsManager.CONTEXT_MENU_PREFS = { MENU_ITEM: "MENU_ITEM_PREF" };
|
SectionsManager.CONTEXT_MENU_PREFS = { MENU_ITEM: "MENU_ITEM_PREF" };
|
||||||
await SectionsManager.init({}, storage);
|
await SectionsManager.init({});
|
||||||
observer.observe("", "nsPref:changed", "MENU_ITEM_PREF");
|
observer.observe("", "nsPref:changed", "MENU_ITEM_PREF");
|
||||||
|
|
||||||
assert.calledOnce(SectionsManager.updateSections);
|
assert.calledOnce(SectionsManager.updateSections);
|
||||||
|
@ -518,7 +472,6 @@ describe("SectionsManager", () => {
|
||||||
describe("SectionsFeed", () => {
|
describe("SectionsFeed", () => {
|
||||||
let feed;
|
let feed;
|
||||||
let sandbox;
|
let sandbox;
|
||||||
let storage;
|
|
||||||
let globals;
|
let globals;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -530,10 +483,6 @@ describe("SectionsFeed", () => {
|
||||||
newtab: { getAllVariables: sandbox.stub() },
|
newtab: { getAllVariables: sandbox.stub() },
|
||||||
pocketNewtab: { getAllVariables: sandbox.stub() },
|
pocketNewtab: { getAllVariables: sandbox.stub() },
|
||||||
});
|
});
|
||||||
storage = {
|
|
||||||
get: sandbox.stub().resolves(),
|
|
||||||
set: sandbox.stub().resolves(),
|
|
||||||
};
|
|
||||||
feed = new SectionsFeed();
|
feed = new SectionsFeed();
|
||||||
feed.store = { dispatch: sinon.spy() };
|
feed.store = { dispatch: sinon.spy() };
|
||||||
feed.store = {
|
feed.store = {
|
||||||
|
@ -550,7 +499,6 @@ describe("SectionsFeed", () => {
|
||||||
},
|
},
|
||||||
Sections: [{ initialized: false }],
|
Sections: [{ initialized: false }],
|
||||||
},
|
},
|
||||||
dbStorage: { getDbTable: sandbox.stub().returns(storage) },
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -575,7 +523,7 @@ describe("SectionsFeed", () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it("should call onAddSection for any already added sections in SectionsManager", async () => {
|
it("should call onAddSection for any already added sections in SectionsManager", async () => {
|
||||||
await SectionsManager.init({}, storage);
|
await SectionsManager.init({});
|
||||||
assert.ok(SectionsManager.sections.has("topstories"));
|
assert.ok(SectionsManager.sections.has("topstories"));
|
||||||
assert.ok(SectionsManager.sections.has("highlights"));
|
assert.ok(SectionsManager.sections.has("highlights"));
|
||||||
const topstories = SectionsManager.sections.get("topstories");
|
const topstories = SectionsManager.sections.get("topstories");
|
||||||
|
@ -721,14 +669,6 @@ describe("SectionsFeed", () => {
|
||||||
assert.calledOnce(SectionsManager.once);
|
assert.calledOnce(SectionsManager.once);
|
||||||
assert.calledWith(SectionsManager.once, SectionsManager.INIT, feed.init);
|
assert.calledWith(SectionsManager.once, SectionsManager.INIT, feed.init);
|
||||||
});
|
});
|
||||||
it("should call SectionsManager.init on action PREFS_INITIAL_VALUES", () => {
|
|
||||||
sinon.spy(SectionsManager, "init");
|
|
||||||
feed.onAction({ type: "PREFS_INITIAL_VALUES", data: { foo: "bar" } });
|
|
||||||
assert.calledOnce(SectionsManager.init);
|
|
||||||
assert.calledWith(SectionsManager.init, { foo: "bar" });
|
|
||||||
assert.calledOnce(feed.store.dbStorage.getDbTable);
|
|
||||||
assert.calledWithExactly(feed.store.dbStorage.getDbTable, "sectionPrefs");
|
|
||||||
});
|
|
||||||
it("should call SectionsManager.addBuiltInSection on suitable PREF_CHANGED events", () => {
|
it("should call SectionsManager.addBuiltInSection on suitable PREF_CHANGED events", () => {
|
||||||
sinon.spy(SectionsManager, "addBuiltInSection");
|
sinon.spy(SectionsManager, "addBuiltInSection");
|
||||||
feed.onAction({
|
feed.onAction({
|
||||||
|
@ -802,13 +742,6 @@ describe("SectionsFeed", () => {
|
||||||
|
|
||||||
assert.calledOnce(stub);
|
assert.calledOnce(stub);
|
||||||
});
|
});
|
||||||
it("should call updateSectionPrefs on UPDATE_SECTION_PREFS", () => {
|
|
||||||
const stub = sinon.stub(SectionsManager, "updateSectionPrefs");
|
|
||||||
|
|
||||||
feed.onAction({ type: "UPDATE_SECTION_PREFS", data: {} });
|
|
||||||
|
|
||||||
assert.calledOnce(stub);
|
|
||||||
});
|
|
||||||
it("should call SectionManager.removeSectionCard on WEBEXT_DISMISS", () => {
|
it("should call SectionManager.removeSectionCard on WEBEXT_DISMISS", () => {
|
||||||
const stub = sinon.stub(SectionsManager, "removeSectionCard");
|
const stub = sinon.stub(SectionsManager, "removeSectionCard");
|
||||||
|
|
||||||
|
@ -819,79 +752,5 @@ describe("SectionsFeed", () => {
|
||||||
assert.calledOnce(stub);
|
assert.calledOnce(stub);
|
||||||
assert.calledWith(stub, "Foo", "bar.com");
|
assert.calledWith(stub, "Foo", "bar.com");
|
||||||
});
|
});
|
||||||
it("should call the feed's moveSection on SECTION_MOVE", () => {
|
|
||||||
sinon.stub(feed, "moveSection");
|
|
||||||
const id = "topsites";
|
|
||||||
const direction = +1;
|
|
||||||
feed.onAction({ type: "SECTION_MOVE", data: { id, direction } });
|
|
||||||
|
|
||||||
assert.calledOnce(feed.moveSection);
|
|
||||||
assert.calledWith(feed.moveSection, id, direction);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe("#moveSection", () => {
|
|
||||||
it("should Move Down correctly", () => {
|
|
||||||
feed.store.state.Sections = [
|
|
||||||
{ id: "topstories", enabled: true },
|
|
||||||
{ id: "highlights", enabled: true },
|
|
||||||
];
|
|
||||||
feed.moveSection("topsites", +1);
|
|
||||||
assert.calledOnce(feed.store.dispatch);
|
|
||||||
assert.calledWith(feed.store.dispatch, {
|
|
||||||
data: { name: "sectionOrder", value: "topstories,topsites,highlights" },
|
|
||||||
meta: { from: "ActivityStream:Content", to: "ActivityStream:Main" },
|
|
||||||
type: "SET_PREF",
|
|
||||||
});
|
|
||||||
feed.store.dispatch.resetHistory();
|
|
||||||
feed.moveSection("topstories", +1);
|
|
||||||
assert.calledOnce(feed.store.dispatch);
|
|
||||||
assert.calledWith(feed.store.dispatch, {
|
|
||||||
data: { name: "sectionOrder", value: "topsites,highlights,topstories" },
|
|
||||||
meta: { from: "ActivityStream:Content", to: "ActivityStream:Main" },
|
|
||||||
type: "SET_PREF",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("should Move Up correctly", () => {
|
|
||||||
feed.store.state.Sections = [
|
|
||||||
{ id: "topstories", enabled: true },
|
|
||||||
{ id: "highlights", enabled: true },
|
|
||||||
];
|
|
||||||
feed.moveSection("topstories", -1);
|
|
||||||
assert.calledOnce(feed.store.dispatch);
|
|
||||||
assert.calledWith(feed.store.dispatch, {
|
|
||||||
data: { name: "sectionOrder", value: "topstories,topsites,highlights" },
|
|
||||||
meta: { from: "ActivityStream:Content", to: "ActivityStream:Main" },
|
|
||||||
type: "SET_PREF",
|
|
||||||
});
|
|
||||||
feed.store.dispatch.resetHistory();
|
|
||||||
feed.moveSection("highlights", -1);
|
|
||||||
assert.calledOnce(feed.store.dispatch);
|
|
||||||
assert.calledWith(feed.store.dispatch, {
|
|
||||||
data: { name: "sectionOrder", value: "topsites,highlights,topstories" },
|
|
||||||
meta: { from: "ActivityStream:Content", to: "ActivityStream:Main" },
|
|
||||||
type: "SET_PREF",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("should skip over sections that aren't enabled", () => {
|
|
||||||
feed.store.state.Sections = [
|
|
||||||
{ id: "topstories", enabled: false },
|
|
||||||
{ id: "highlights", enabled: true },
|
|
||||||
];
|
|
||||||
feed.moveSection("highlights", -1);
|
|
||||||
assert.calledOnce(feed.store.dispatch);
|
|
||||||
assert.calledWith(feed.store.dispatch, {
|
|
||||||
data: { name: "sectionOrder", value: "highlights,topsites,topstories" },
|
|
||||||
meta: { from: "ActivityStream:Content", to: "ActivityStream:Main" },
|
|
||||||
type: "SET_PREF",
|
|
||||||
});
|
|
||||||
feed.store.dispatch.resetHistory();
|
|
||||||
feed.moveSection("topsites", +1);
|
|
||||||
assert.calledOnce(feed.store.dispatch);
|
|
||||||
assert.calledWith(feed.store.dispatch, {
|
|
||||||
data: { name: "sectionOrder", value: "topstories,highlights,topsites" },
|
|
||||||
meta: { from: "ActivityStream:Content", to: "ActivityStream:Main" },
|
|
||||||
type: "SET_PREF",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -197,17 +197,6 @@ const TEST_GLOBAL = {
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"@mozilla.org/security/hash;1": {
|
|
||||||
createInstance() {
|
|
||||||
return {
|
|
||||||
init() {},
|
|
||||||
updateFromStream() {},
|
|
||||||
finish() {
|
|
||||||
return "0";
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"@mozilla.org/updates/update-checker;1": { createInstance() {} },
|
"@mozilla.org/updates/update-checker;1": { createInstance() {} },
|
||||||
"@mozilla.org/widget/useridleservice;1": {
|
"@mozilla.org/widget/useridleservice;1": {
|
||||||
getService() {
|
getService() {
|
||||||
|
|
|
@ -8,7 +8,7 @@ const { actionTypes: at } = ChromeUtils.importESModule(
|
||||||
);
|
);
|
||||||
|
|
||||||
ChromeUtils.defineESModuleGetters(this, {
|
ChromeUtils.defineESModuleGetters(this, {
|
||||||
FilterAdult: "resource://activity-stream/lib/FilterAdult.sys.mjs",
|
FilterAdult: "resource:///modules/FilterAdult.sys.mjs",
|
||||||
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
|
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
|
||||||
PageThumbs: "resource://gre/modules/PageThumbs.sys.mjs",
|
PageThumbs: "resource://gre/modules/PageThumbs.sys.mjs",
|
||||||
Screenshots: "resource://activity-stream/lib/Screenshots.sys.mjs",
|
Screenshots: "resource://activity-stream/lib/Screenshots.sys.mjs",
|
||||||
|
|
|
@ -9,9 +9,6 @@ const { Store } = ChromeUtils.importESModule(
|
||||||
const { ActivityStreamMessageChannel } = ChromeUtils.importESModule(
|
const { ActivityStreamMessageChannel } = ChromeUtils.importESModule(
|
||||||
"resource://activity-stream/lib/ActivityStreamMessageChannel.sys.mjs"
|
"resource://activity-stream/lib/ActivityStreamMessageChannel.sys.mjs"
|
||||||
);
|
);
|
||||||
const { ASRouterStorage } = ChromeUtils.importESModule(
|
|
||||||
"resource:///modules/asrouter/ASRouterStorage.sys.mjs"
|
|
||||||
);
|
|
||||||
const { sinon } = ChromeUtils.importESModule(
|
const { sinon } = ChromeUtils.importESModule(
|
||||||
"resource://testing-common/Sinon.sys.mjs"
|
"resource://testing-common/Sinon.sys.mjs"
|
||||||
);
|
);
|
||||||
|
@ -129,54 +126,6 @@ add_task(async function test_initFeed_on_init() {
|
||||||
sandbox.restore();
|
sandbox.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
add_task(async function test_initFeed_calls__initIndexedDB() {
|
|
||||||
info("Store should call _initIndexedDB");
|
|
||||||
let sandbox = sinon.createSandbox();
|
|
||||||
let store = new Store();
|
|
||||||
|
|
||||||
sandbox.spy(store, "_initIndexedDB");
|
|
||||||
|
|
||||||
let dbStub = sandbox.stub(ASRouterStorage.prototype, "db");
|
|
||||||
let dbAccessed = false;
|
|
||||||
dbStub.get(() => {
|
|
||||||
dbAccessed = true;
|
|
||||||
return {};
|
|
||||||
});
|
|
||||||
|
|
||||||
store._prefs.set("testfeed", true);
|
|
||||||
await store.init(
|
|
||||||
new Map([
|
|
||||||
[
|
|
||||||
"testfeed",
|
|
||||||
() => {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
],
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
Assert.ok(store._initIndexedDB.calledOnce, "_initIndexedDB called once");
|
|
||||||
Assert.ok(
|
|
||||||
store._initIndexedDB.calledWithExactly("feeds.telemetry"),
|
|
||||||
"feeds.telemetry was passed"
|
|
||||||
);
|
|
||||||
// Due to what appears to be a bug in sinon when using calledOnce
|
|
||||||
// with a stubbed getter, we can't just use dbStub.calledOnce here.
|
|
||||||
Assert.ok(dbAccessed, "ASRouterStorage was accessed");
|
|
||||||
|
|
||||||
info("Store should reset ASRouterStorage telemetry if opening the db fails");
|
|
||||||
dbStub.rejects();
|
|
||||||
await store.init(new Map());
|
|
||||||
|
|
||||||
Assert.equal(
|
|
||||||
store.dbStorage.telemetry,
|
|
||||||
null,
|
|
||||||
"Telemetry on storage was cleared"
|
|
||||||
);
|
|
||||||
|
|
||||||
sandbox.restore();
|
|
||||||
});
|
|
||||||
|
|
||||||
add_task(async function test_disabled_feed() {
|
add_task(async function test_disabled_feed() {
|
||||||
info("Store should not initialize the feed if the Pref is set to false");
|
info("Store should not initialize the feed if the Pref is set to false");
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ const { actionCreators: ac, actionTypes: at } = ChromeUtils.importESModule(
|
||||||
);
|
);
|
||||||
|
|
||||||
ChromeUtils.defineESModuleGetters(this, {
|
ChromeUtils.defineESModuleGetters(this, {
|
||||||
FilterAdult: "resource://activity-stream/lib/FilterAdult.sys.mjs",
|
FilterAdult: "resource:///modules/FilterAdult.sys.mjs",
|
||||||
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
|
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
|
||||||
NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs",
|
NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs",
|
||||||
PageThumbs: "resource://gre/modules/PageThumbs.sys.mjs",
|
PageThumbs: "resource://gre/modules/PageThumbs.sys.mjs",
|
||||||
|
@ -73,14 +73,7 @@ function getTopSitesFeedForTest(sandbox) {
|
||||||
});
|
});
|
||||||
|
|
||||||
let feed = new TopSitesFeed();
|
let feed = new TopSitesFeed();
|
||||||
const storage = {
|
|
||||||
init: sandbox.stub().resolves(),
|
|
||||||
get: sandbox.stub().resolves(),
|
|
||||||
set: sandbox.stub().resolves(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Setup for tests that don't call `init` but require feed.storage
|
|
||||||
feed._storage = storage;
|
|
||||||
feed.store = {
|
feed.store = {
|
||||||
dispatch: sinon.spy(),
|
dispatch: sinon.spy(),
|
||||||
getState() {
|
getState() {
|
||||||
|
@ -90,7 +83,6 @@ function getTopSitesFeedForTest(sandbox) {
|
||||||
Prefs: { values: { topSitesRows: 2 } },
|
Prefs: { values: { topSitesRows: 2 } },
|
||||||
TopSites: { rows: Array(12).fill("site") },
|
TopSites: { rows: Array(12).fill("site") },
|
||||||
},
|
},
|
||||||
dbStorage: { getDbTable: sandbox.stub().returns(storage) },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return feed;
|
return feed;
|
||||||
|
@ -1026,13 +1018,6 @@ add_task(async function test_init() {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
info("TopSitesFeed.init should initialise the storage");
|
|
||||||
Assert.ok(
|
|
||||||
feed.store.dbStorage.getDbTable.calledOnce,
|
|
||||||
"getDbTable called once"
|
|
||||||
);
|
|
||||||
Assert.ok(feed.store.dbStorage.getDbTable.calledWithExactly("sectionPrefs"));
|
|
||||||
|
|
||||||
info(
|
info(
|
||||||
"TopSitesFeed.init should call onUpdate to set up Nimbus update listener"
|
"TopSitesFeed.init should call onUpdate to set up Nimbus update listener"
|
||||||
);
|
);
|
||||||
|
@ -1089,7 +1074,7 @@ add_task(async function test_refresh() {
|
||||||
feed.store.dispatch.calledWithExactly(
|
feed.store.dispatch.calledWithExactly(
|
||||||
ac.BroadcastToContent({
|
ac.BroadcastToContent({
|
||||||
type: at.TOP_SITES_UPDATED,
|
type: at.TOP_SITES_UPDATED,
|
||||||
data: { links: [], pref: { collapsed: false } },
|
data: { links: [] },
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -1179,7 +1164,7 @@ add_task(async function test_refresh_to_preloaded() {
|
||||||
feed.store.dispatch.calledWithExactly(
|
feed.store.dispatch.calledWithExactly(
|
||||||
ac.AlsoToPreloaded({
|
ac.AlsoToPreloaded({
|
||||||
type: at.TOP_SITES_UPDATED,
|
type: at.TOP_SITES_UPDATED,
|
||||||
data: { links: [], pref: { collapsed: false } },
|
data: { links: [] },
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -1187,25 +1172,6 @@ add_task(async function test_refresh_to_preloaded() {
|
||||||
sandbox.restore();
|
sandbox.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
add_task(async function test_refresh_init_storage() {
|
|
||||||
let sandbox = sinon.createSandbox();
|
|
||||||
|
|
||||||
info(
|
|
||||||
"TopSitesFeed.refresh should not init storage of it's already initialized"
|
|
||||||
);
|
|
||||||
|
|
||||||
let feed = getTopSitesFeedForTest(sandbox);
|
|
||||||
sandbox.stub(feed, "_fetchIcon");
|
|
||||||
feed._startedUp = true;
|
|
||||||
|
|
||||||
feed._storage.initialized = true;
|
|
||||||
|
|
||||||
await feed.refresh({ broadcast: false });
|
|
||||||
|
|
||||||
Assert.ok(feed._storage.init.notCalled, "feed._storage.init was not called.");
|
|
||||||
sandbox.restore();
|
|
||||||
});
|
|
||||||
|
|
||||||
add_task(async function test_refresh_handles_indexedDB_errors() {
|
add_task(async function test_refresh_handles_indexedDB_errors() {
|
||||||
let sandbox = sinon.createSandbox();
|
let sandbox = sinon.createSandbox();
|
||||||
|
|
||||||
|
@ -1217,8 +1183,6 @@ add_task(async function test_refresh_handles_indexedDB_errors() {
|
||||||
sandbox.stub(feed, "_fetchIcon");
|
sandbox.stub(feed, "_fetchIcon");
|
||||||
feed._startedUp = true;
|
feed._startedUp = true;
|
||||||
|
|
||||||
feed._storage.get.throws(new Error());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await feed.refresh({ broadcast: false });
|
await feed.refresh({ broadcast: false });
|
||||||
Assert.ok(true, "refresh should have succeeded");
|
Assert.ok(true, "refresh should have succeeded");
|
||||||
|
@ -1229,51 +1193,6 @@ add_task(async function test_refresh_handles_indexedDB_errors() {
|
||||||
sandbox.restore();
|
sandbox.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
add_task(async function test_updateSectionPrefs_on_UPDATE_SECTION_PREFS() {
|
|
||||||
let sandbox = sinon.createSandbox();
|
|
||||||
|
|
||||||
info(
|
|
||||||
"TopSitesFeed.onAction should call updateSectionPrefs on UPDATE_SECTION_PREFS"
|
|
||||||
);
|
|
||||||
|
|
||||||
let feed = getTopSitesFeedForTest(sandbox);
|
|
||||||
sandbox.stub(feed, "updateSectionPrefs");
|
|
||||||
feed.onAction({
|
|
||||||
type: at.UPDATE_SECTION_PREFS,
|
|
||||||
data: { id: "topsites" },
|
|
||||||
});
|
|
||||||
|
|
||||||
Assert.ok(
|
|
||||||
feed.updateSectionPrefs.calledOnce,
|
|
||||||
"feed.updateSectionPrefs called once"
|
|
||||||
);
|
|
||||||
|
|
||||||
sandbox.restore();
|
|
||||||
});
|
|
||||||
|
|
||||||
add_task(
|
|
||||||
async function test_updateSectionPrefs_dispatch_TOP_SITES_PREFS_UPDATED() {
|
|
||||||
let sandbox = sinon.createSandbox();
|
|
||||||
|
|
||||||
info(
|
|
||||||
"TopSitesFeed.updateSectionPrefs should dispatch TOP_SITES_PREFS_UPDATED"
|
|
||||||
);
|
|
||||||
|
|
||||||
let feed = getTopSitesFeedForTest(sandbox);
|
|
||||||
await feed.updateSectionPrefs({ collapsed: true });
|
|
||||||
Assert.ok(
|
|
||||||
feed.store.dispatch.calledWithExactly(
|
|
||||||
ac.BroadcastToContent({
|
|
||||||
type: at.TOP_SITES_PREFS_UPDATED,
|
|
||||||
data: { pref: { collapsed: true } },
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
sandbox.restore();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
add_task(async function test_allocatePositions() {
|
add_task(async function test_allocatePositions() {
|
||||||
let sandbox = sinon.createSandbox();
|
let sandbox = sinon.createSandbox();
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
const lazy = {};
|
const lazy = {};
|
||||||
|
|
||||||
ChromeUtils.defineESModuleGetters(lazy, {
|
ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
FilterAdult: "resource://activity-stream/lib/FilterAdult.sys.mjs",
|
FilterAdult: "resource:///modules/FilterAdult.sys.mjs",
|
||||||
UrlbarUtils: "resource:///modules/UrlbarUtils.sys.mjs",
|
UrlbarUtils: "resource:///modules/UrlbarUtils.sys.mjs",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ const ALLOWED_TEST_URL = "http://mochi.test:8888/";
|
||||||
const BLOCKED_TEST_URL = "https://example.com/browser";
|
const BLOCKED_TEST_URL = "https://example.com/browser";
|
||||||
|
|
||||||
ChromeUtils.defineESModuleGetters(this, {
|
ChromeUtils.defineESModuleGetters(this, {
|
||||||
FilterAdult: "resource://activity-stream/lib/FilterAdult.sys.mjs",
|
FilterAdult: "resource:///modules/FilterAdult.sys.mjs",
|
||||||
InteractionsBlocklist: "resource:///modules/InteractionsBlocklist.sys.mjs",
|
InteractionsBlocklist: "resource:///modules/InteractionsBlocklist.sys.mjs",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,6 @@ support-files = ["trendingSuggestionEngine.sjs"]
|
||||||
|
|
||||||
["browser_search_discovery.js"]
|
["browser_search_discovery.js"]
|
||||||
|
|
||||||
["browser_search_nimbus_reload.js"]
|
|
||||||
|
|
||||||
["browser_searchbar_addEngine.js"]
|
["browser_searchbar_addEngine.js"]
|
||||||
|
|
||||||
["browser_searchbar_context.js"]
|
["browser_searchbar_context.js"]
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const { ExperimentFakes } = ChromeUtils.importESModule(
|
|
||||||
"resource://testing-common/NimbusTestUtils.sys.mjs"
|
|
||||||
);
|
|
||||||
|
|
||||||
const { SearchService } = ChromeUtils.importESModule(
|
|
||||||
"resource://gre/modules/SearchService.sys.mjs"
|
|
||||||
);
|
|
||||||
const { sinon } = ChromeUtils.importESModule(
|
|
||||||
"resource://testing-common/Sinon.sys.mjs"
|
|
||||||
);
|
|
||||||
|
|
||||||
add_task(async function test_engines_reloaded_nimbus() {
|
|
||||||
let reloadSpy = sinon.spy(SearchService.prototype, "_maybeReloadEngines");
|
|
||||||
let getVariableSpy = sinon.spy(
|
|
||||||
NimbusFeatures.searchConfiguration,
|
|
||||||
"getVariable"
|
|
||||||
);
|
|
||||||
|
|
||||||
let doExperimentCleanup = await ExperimentFakes.enrollWithFeatureConfig({
|
|
||||||
featureId: "searchConfiguration",
|
|
||||||
value: { experiment: "nimbus-search-mochitest" },
|
|
||||||
});
|
|
||||||
|
|
||||||
Assert.equal(reloadSpy.callCount, 1, "Called by experiment enrollment");
|
|
||||||
await BrowserTestUtils.waitForCondition(
|
|
||||||
() => getVariableSpy.calledWith("experiment"),
|
|
||||||
"Wait for SearchService update to run"
|
|
||||||
);
|
|
||||||
Assert.equal(
|
|
||||||
getVariableSpy.callCount,
|
|
||||||
3,
|
|
||||||
"Called by update function to fetch engines"
|
|
||||||
);
|
|
||||||
Assert.ok(
|
|
||||||
getVariableSpy.calledWith("experiment"),
|
|
||||||
"Called by search service observer"
|
|
||||||
);
|
|
||||||
Assert.equal(
|
|
||||||
NimbusFeatures.searchConfiguration.getVariable("experiment"),
|
|
||||||
"nimbus-search-mochitest",
|
|
||||||
"Should have expected value"
|
|
||||||
);
|
|
||||||
|
|
||||||
doExperimentCleanup();
|
|
||||||
|
|
||||||
Assert.equal(reloadSpy.callCount, 2, "Called by experiment unenrollment");
|
|
||||||
|
|
||||||
reloadSpy.restore();
|
|
||||||
getVariableSpy.restore();
|
|
||||||
});
|
|
|
@ -3,7 +3,7 @@ tags = "search-telemetry"
|
||||||
support-files = ["head.js", "head-spa.js"]
|
support-files = ["head.js", "head-spa.js"]
|
||||||
prefs = ["browser.search.log=true"]
|
prefs = ["browser.search.log=true"]
|
||||||
|
|
||||||
["browser_search_glean_serp_event_telemetry_categorization_enabled_by_nimbus_variable.js"]
|
["browser_search_glean_serp_event_telemetry_categorization_enabled_by_pref.js"]
|
||||||
support-files = ["searchTelemetryDomainCategorizationReporting.html"]
|
support-files = ["searchTelemetryDomainCategorizationReporting.html"]
|
||||||
|
|
||||||
["browser_search_telemetry_abandonment.js"]
|
["browser_search_telemetry_abandonment.js"]
|
||||||
|
|
|
@ -9,8 +9,6 @@ const TELEMETRY_PREF =
|
||||||
"browser.search.serpEventTelemetryCategorization.enabled";
|
"browser.search.serpEventTelemetryCategorization.enabled";
|
||||||
|
|
||||||
ChromeUtils.defineESModuleGetters(lazy, {
|
ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
ExperimentAPI: "resource://nimbus/ExperimentAPI.sys.mjs",
|
|
||||||
ExperimentFakes: "resource://testing-common/NimbusTestUtils.sys.mjs",
|
|
||||||
SearchSERPDomainToCategoriesMap:
|
SearchSERPDomainToCategoriesMap:
|
||||||
"resource:///modules/SearchSERPTelemetry.sys.mjs",
|
"resource:///modules/SearchSERPTelemetry.sys.mjs",
|
||||||
});
|
});
|
||||||
|
@ -96,10 +94,8 @@ add_task(async function test_enable_experiment_when_pref_is_not_enabled() {
|
||||||
let originalPrefValue = prefBranch.getBoolPref(TELEMETRY_PREF);
|
let originalPrefValue = prefBranch.getBoolPref(TELEMETRY_PREF);
|
||||||
|
|
||||||
// Ensure the build being tested has the preference value as false.
|
// Ensure the build being tested has the preference value as false.
|
||||||
// Changing the preference in the test must be done on the default branch
|
// We do this on the default branch to simulate the value of the preference
|
||||||
// because in the telemetry code, we're referencing the preference directly
|
// being changed by the user.
|
||||||
// instead of through NimbusFeatures. Enrolling in an experiment will change
|
|
||||||
// the default branch, and not overwrite the user branch.
|
|
||||||
prefBranch.setBoolPref(TELEMETRY_PREF, false);
|
prefBranch.setBoolPref(TELEMETRY_PREF, false);
|
||||||
|
|
||||||
// If it was true, we should wait until the map is fully un-inited.
|
// If it was true, we should wait until the map is fully un-inited.
|
||||||
|
@ -110,28 +106,18 @@ add_task(async function test_enable_experiment_when_pref_is_not_enabled() {
|
||||||
Assert.equal(
|
Assert.equal(
|
||||||
lazy.serpEventsCategorizationEnabled,
|
lazy.serpEventsCategorizationEnabled,
|
||||||
false,
|
false,
|
||||||
"serpEventsCategorizationEnabled should be false when not enrolled in experiment and the default value is false."
|
"serpEventsCategorizationEnabled should be false when the default value is false."
|
||||||
);
|
);
|
||||||
|
|
||||||
await lazy.ExperimentAPI.ready();
|
info("Turn pref on");
|
||||||
|
|
||||||
info("Enroll in experiment.");
|
|
||||||
let updateComplete = waitForDomainToCategoriesUpdate();
|
let updateComplete = waitForDomainToCategoriesUpdate();
|
||||||
|
|
||||||
let doExperimentCleanup = await lazy.ExperimentFakes.enrollWithFeatureConfig(
|
Services.prefs.setBoolPref(TELEMETRY_PREF, true);
|
||||||
{
|
|
||||||
featureId: NimbusFeatures.search.featureId,
|
|
||||||
value: {
|
|
||||||
serpEventTelemetryCategorizationEnabled: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ isRollout: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
Assert.equal(
|
Assert.equal(
|
||||||
lazy.serpEventsCategorizationEnabled,
|
lazy.serpEventsCategorizationEnabled,
|
||||||
true,
|
true,
|
||||||
"serpEventsCategorizationEnabled should be true when enrolled in experiment."
|
"serpEventsCategorizationEnabled should be true when the pref is true."
|
||||||
);
|
);
|
||||||
|
|
||||||
await updateComplete;
|
await updateComplete;
|
||||||
|
@ -169,14 +155,14 @@ add_task(async function test_enable_experiment_when_pref_is_not_enabled() {
|
||||||
]);
|
]);
|
||||||
resetTelemetry();
|
resetTelemetry();
|
||||||
|
|
||||||
info("End experiment.");
|
info("Turn pref off");
|
||||||
doExperimentCleanup();
|
Services.prefs.setBoolPref(TELEMETRY_PREF, false);
|
||||||
await waitForDomainToCategoriesUninit();
|
await waitForDomainToCategoriesUninit();
|
||||||
|
|
||||||
Assert.equal(
|
Assert.equal(
|
||||||
lazy.serpEventsCategorizationEnabled,
|
lazy.serpEventsCategorizationEnabled,
|
||||||
false,
|
false,
|
||||||
"serpEventsCategorizationEnabled should be false after experiment."
|
"serpEventsCategorizationEnabled should be false when the pref is false."
|
||||||
);
|
);
|
||||||
|
|
||||||
Assert.ok(
|
Assert.ok(
|
|
@ -185,9 +185,24 @@ export var RecentlyClosedTabsAndWindowsMenuUtils = {
|
||||||
? lazy.SessionStore.getWindows(currentWindow)
|
? lazy.SessionStore.getWindows(currentWindow)
|
||||||
: [currentWindow];
|
: [currentWindow];
|
||||||
for (const sourceWindow of browserWindows) {
|
for (const sourceWindow of browserWindows) {
|
||||||
let count = lazy.SessionStore.getClosedTabCountForWindow(sourceWindow);
|
let tabData = lazy.SessionStore.getClosedTabDataForWindow(sourceWindow);
|
||||||
while (--count >= 0) {
|
let closedTabGroupsById = getClosedTabGroupsById();
|
||||||
lazy.SessionStore.undoCloseTab(sourceWindow, 0, currentWindow);
|
|
||||||
|
while (tabData.length) {
|
||||||
|
let currentTabGroupId = tabData[0].state.groupId;
|
||||||
|
|
||||||
|
if (currentTabGroupId && closedTabGroupsById.has(currentTabGroupId)) {
|
||||||
|
let currentTabGroup = closedTabGroupsById.get(currentTabGroupId);
|
||||||
|
tabData.splice(0, currentTabGroup.tabs.length);
|
||||||
|
lazy.SessionStore.undoCloseTabGroup(
|
||||||
|
sourceWindow,
|
||||||
|
currentTabGroupId,
|
||||||
|
currentWindow
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
tabData.splice(0, 1);
|
||||||
|
lazy.SessionStore.undoCloseTab(sourceWindow, 0, currentWindow);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lazy.closedTabsFromClosedWindowsEnabled) {
|
if (lazy.closedTabsFromClosedWindowsEnabled) {
|
||||||
|
|
|
@ -37,6 +37,13 @@ add_task(async function test_toggle_collapse_close_button() {
|
||||||
);
|
);
|
||||||
is(computedStyle.opacity, "1", "The active tab is showing the close button.");
|
is(computedStyle.opacity, "1", "The active tab is showing the close button.");
|
||||||
|
|
||||||
|
// Move mouse away from tabstrip to ensure we don't show the close button.
|
||||||
|
EventUtils.synthesizeMouseAtCenter(
|
||||||
|
document.getElementById("tabbrowser-tabbox"),
|
||||||
|
{ type: "mouseover" }
|
||||||
|
);
|
||||||
|
await TestUtils.waitForTick();
|
||||||
|
|
||||||
computedStyle = window.getComputedStyle(
|
computedStyle = window.getComputedStyle(
|
||||||
firstTab.querySelector(".tab-close-button")
|
firstTab.querySelector(".tab-close-button")
|
||||||
);
|
);
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
this.addEventListener("mouseup", this);
|
this.addEventListener("mouseup", this);
|
||||||
this.addEventListener("click", this);
|
this.addEventListener("click", this);
|
||||||
this.addEventListener("dblclick", this, true);
|
this.addEventListener("dblclick", this, true);
|
||||||
|
this.addEventListener("animationstart", this);
|
||||||
this.addEventListener("animationend", this);
|
this.addEventListener("animationend", this);
|
||||||
this.addEventListener("focus", this);
|
this.addEventListener("focus", this);
|
||||||
this.addEventListener("AriaFocus", this);
|
this.addEventListener("AriaFocus", this);
|
||||||
|
@ -570,6 +571,21 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
on_animationstart(event) {
|
||||||
|
if (!event.animationName.startsWith("tab-throbber-animation")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// The animation is on a pseudo-element so we need to use `subtree: true`
|
||||||
|
// to get our hands on it.
|
||||||
|
for (let animation of event.target.getAnimations({ subtree: true })) {
|
||||||
|
if (animation.animationName === event.animationName) {
|
||||||
|
// Ensure all tab throbber animations are synchronized by sharing an
|
||||||
|
// start time.
|
||||||
|
animation.startTime = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
on_animationend(event) {
|
on_animationend(event) {
|
||||||
if (event.target.classList.contains("tab-loading-burst")) {
|
if (event.target.classList.contains("tab-loading-burst")) {
|
||||||
this.removeAttribute("bursting");
|
this.removeAttribute("bursting");
|
||||||
|
|
|
@ -855,50 +855,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
syncThrobberAnimations(aTab) {
|
|
||||||
aTab.ownerGlobal.promiseDocumentFlushed(() => {
|
|
||||||
if (!aTab.container) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const animations = Array.from(
|
|
||||||
aTab.container.getElementsByTagName("tab")
|
|
||||||
)
|
|
||||||
.filter(tab => tab.hasAttribute("busy"))
|
|
||||||
.flatMap(tab => tab.throbber?.getAnimations({ subtree: true }) ?? [])
|
|
||||||
.filter(
|
|
||||||
anim =>
|
|
||||||
CSSAnimation.isInstance(anim) &&
|
|
||||||
(anim.animationName === "tab-throbber-animation" ||
|
|
||||||
anim.animationName === "tab-throbber-animation-rtl") &&
|
|
||||||
anim.playState === "running"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Synchronize with the oldest running animation, if any.
|
|
||||||
const firstStartTime = Math.min(
|
|
||||||
...animations.map(anim =>
|
|
||||||
anim.startTime === null ? Infinity : anim.startTime
|
|
||||||
)
|
|
||||||
);
|
|
||||||
if (firstStartTime === Infinity) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
for (let animation of animations) {
|
|
||||||
// If |animation| has been cancelled since this rAF callback
|
|
||||||
// was scheduled we don't want to set its startTime since
|
|
||||||
// that would restart it. We check for a cancelled animation
|
|
||||||
// by looking for a null currentTime rather than checking
|
|
||||||
// the playState, since reading the playState of
|
|
||||||
// a CSSAnimation object will flush style.
|
|
||||||
if (animation.currentTime !== null) {
|
|
||||||
animation.startTime = firstStartTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getBrowserAtIndex(aIndex) {
|
getBrowserAtIndex(aIndex) {
|
||||||
return this.browsers[aIndex];
|
return this.browsers[aIndex];
|
||||||
}
|
}
|
||||||
|
@ -7454,7 +7410,6 @@
|
||||||
this.mTab.setAttribute("busy", "true");
|
this.mTab.setAttribute("busy", "true");
|
||||||
gBrowser._tabAttrModified(this.mTab, ["busy"]);
|
gBrowser._tabAttrModified(this.mTab, ["busy"]);
|
||||||
this.mTab._notselectedsinceload = !this.mTab.selected;
|
this.mTab._notselectedsinceload = !this.mTab.selected;
|
||||||
gBrowser.syncThrobberAnimations(this.mTab);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.mTab.selected) {
|
if (this.mTab.selected) {
|
||||||
|
|
|
@ -1121,8 +1121,6 @@
|
||||||
dropIndex++;
|
dropIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gBrowser.syncThrobberAnimations(tab);
|
|
||||||
};
|
};
|
||||||
if (gReduceMotion) {
|
if (gReduceMotion) {
|
||||||
postTransitionCleanup();
|
postTransitionCleanup();
|
||||||
|
|
|
@ -116,6 +116,7 @@ add_task(async function test_allTabsView() {
|
||||||
*/
|
*/
|
||||||
async function getContextMenu(triggerNode, contextMenuId) {
|
async function getContextMenu(triggerNode, contextMenuId) {
|
||||||
let win = triggerNode.ownerGlobal;
|
let win = triggerNode.ownerGlobal;
|
||||||
|
triggerNode.scrollIntoView();
|
||||||
const contextMenu = win.document.getElementById(contextMenuId);
|
const contextMenu = win.document.getElementById(contextMenuId);
|
||||||
Assert.equal(contextMenu.state, "closed", "context menu is initially closed");
|
Assert.equal(contextMenu.state, "closed", "context menu is initially closed");
|
||||||
const contextMenuShown = BrowserTestUtils.waitForPopupEvent(
|
const contextMenuShown = BrowserTestUtils.waitForPopupEvent(
|
||||||
|
|
|
@ -23,7 +23,7 @@ const lazy = {};
|
||||||
|
|
||||||
ChromeUtils.defineESModuleGetters(lazy, {
|
ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
FaviconFeed: "resource://activity-stream/lib/FaviconFeed.sys.mjs",
|
FaviconFeed: "resource://activity-stream/lib/FaviconFeed.sys.mjs",
|
||||||
FilterAdult: "resource://activity-stream/lib/FilterAdult.sys.mjs",
|
FilterAdult: "resource:///modules/FilterAdult.sys.mjs",
|
||||||
LinksCache: "resource://activity-stream/lib/LinksCache.sys.mjs",
|
LinksCache: "resource://activity-stream/lib/LinksCache.sys.mjs",
|
||||||
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
|
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
|
||||||
PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
|
PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
|
||||||
|
|
|
@ -12,7 +12,7 @@ const { actionTypes: at } = ChromeUtils.importESModule(
|
||||||
);
|
);
|
||||||
|
|
||||||
ChromeUtils.defineESModuleGetters(this, {
|
ChromeUtils.defineESModuleGetters(this, {
|
||||||
FilterAdult: "resource://activity-stream/lib/FilterAdult.sys.mjs",
|
FilterAdult: "resource:///modules/FilterAdult.sys.mjs",
|
||||||
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
|
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
|
||||||
NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs",
|
NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs",
|
||||||
shortURL: "resource://activity-stream/lib/ShortURL.sys.mjs",
|
shortURL: "resource://activity-stream/lib/ShortURL.sys.mjs",
|
||||||
|
|
|
@ -115,6 +115,7 @@ urlbar:
|
||||||
`merino_amo`,
|
`merino_amo`,
|
||||||
`merino_top_picks`,
|
`merino_top_picks`,
|
||||||
`merino_wikipedia`,
|
`merino_wikipedia`,
|
||||||
|
`ml_yelp`,
|
||||||
`recent_search`,
|
`recent_search`,
|
||||||
`remote_tab`,
|
`remote_tab`,
|
||||||
`restrict_keyword_actions`,
|
`restrict_keyword_actions`,
|
||||||
|
@ -261,6 +262,7 @@ urlbar:
|
||||||
`merino_amo`,
|
`merino_amo`,
|
||||||
`merino_top_picks`,
|
`merino_top_picks`,
|
||||||
`merino_wikipedia`,
|
`merino_wikipedia`,
|
||||||
|
`ml_yelp`,
|
||||||
`recent_search`,
|
`recent_search`,
|
||||||
`remote_tab`,
|
`remote_tab`,
|
||||||
`restrict_keyword_actions`,
|
`restrict_keyword_actions`,
|
||||||
|
@ -381,6 +383,7 @@ urlbar:
|
||||||
`merino_amo`,
|
`merino_amo`,
|
||||||
`merino_top_picks`,
|
`merino_top_picks`,
|
||||||
`merino_wikipedia`,
|
`merino_wikipedia`,
|
||||||
|
`ml_yelp`,
|
||||||
`recent_search`,
|
`recent_search`,
|
||||||
`remote_tab`,
|
`remote_tab`,
|
||||||
`restrict_keyword_actions`,
|
`restrict_keyword_actions`,
|
||||||
|
|
|
@ -30,16 +30,12 @@ const RESULT_MENU_COMMAND = {
|
||||||
* A feature that supports Addon suggestions.
|
* A feature that supports Addon suggestions.
|
||||||
*/
|
*/
|
||||||
export class AddonSuggestions extends SuggestProvider {
|
export class AddonSuggestions extends SuggestProvider {
|
||||||
get shouldEnable() {
|
|
||||||
return (
|
|
||||||
lazy.UrlbarPrefs.get("addonsFeatureGate") &&
|
|
||||||
lazy.UrlbarPrefs.get("suggest.addons") &&
|
|
||||||
lazy.UrlbarPrefs.get("suggest.quicksuggest.nonsponsored")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get enablingPreferences() {
|
get enablingPreferences() {
|
||||||
return ["suggest.addons", "suggest.quicksuggest.nonsponsored"];
|
return [
|
||||||
|
"addonsFeatureGate",
|
||||||
|
"suggest.addons",
|
||||||
|
"suggest.quicksuggest.nonsponsored",
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
get merinoProvider() {
|
get merinoProvider() {
|
||||||
|
|
|
@ -31,10 +31,6 @@ ChromeUtils.defineLazyGetter(lazy, "contextId", () => {
|
||||||
* A feature that manages AMP suggestions.
|
* A feature that manages AMP suggestions.
|
||||||
*/
|
*/
|
||||||
export class AmpSuggestions extends SuggestProvider {
|
export class AmpSuggestions extends SuggestProvider {
|
||||||
get shouldEnable() {
|
|
||||||
return lazy.UrlbarPrefs.get("suggest.quicksuggest.sponsored");
|
|
||||||
}
|
|
||||||
|
|
||||||
get enablingPreferences() {
|
get enablingPreferences() {
|
||||||
return ["suggest.quicksuggest.sponsored"];
|
return ["suggest.quicksuggest.sponsored"];
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,8 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A set of blocked suggestions for quick suggest.
|
* A set of blocked suggestion URLs for Suggest. This feature is always enabled
|
||||||
|
* as long as Suggest is enabled.
|
||||||
*/
|
*/
|
||||||
export class BlockedSuggestions extends SuggestFeature {
|
export class BlockedSuggestions extends SuggestFeature {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -21,14 +22,6 @@ export class BlockedSuggestions extends SuggestFeature {
|
||||||
lazy.UrlbarPrefs.addObserver(this);
|
lazy.UrlbarPrefs.addObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
get shouldEnable() {
|
|
||||||
// Return true so that we'll always load blocked digests when quick suggest
|
|
||||||
// is enabled, even if blocking new suggestions is currently disabled.
|
|
||||||
// Blocking may have been enabled previously, and blocked suggestions should
|
|
||||||
// remain blocked as long as quick suggest as a whole remains enabled.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
enable(enabled) {
|
enable(enabled) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
this.#loadDigests();
|
this.#loadDigests();
|
||||||
|
|
|
@ -16,14 +16,14 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
* A feature for exposure suggestions.
|
* A feature for exposure suggestions.
|
||||||
*/
|
*/
|
||||||
export class ExposureSuggestions extends SuggestProvider {
|
export class ExposureSuggestions extends SuggestProvider {
|
||||||
get shouldEnable() {
|
|
||||||
return !!this.exposureSuggestionTypes.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
get enablingPreferences() {
|
get enablingPreferences() {
|
||||||
return ["quicksuggest.exposureSuggestionTypes"];
|
return ["quicksuggest.exposureSuggestionTypes"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get additionalEnablingPredicate() {
|
||||||
|
return !!this.exposureSuggestionTypes.size;
|
||||||
|
}
|
||||||
|
|
||||||
get rustSuggestionType() {
|
get rustSuggestionType() {
|
||||||
return "Exposure";
|
return "Exposure";
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,16 +84,12 @@ export class FakespotSuggestions extends SuggestProvider {
|
||||||
lazy.UrlbarView.addDynamicViewTemplate("fakespot", VIEW_TEMPLATE);
|
lazy.UrlbarView.addDynamicViewTemplate("fakespot", VIEW_TEMPLATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
get shouldEnable() {
|
|
||||||
return (
|
|
||||||
lazy.UrlbarPrefs.get("suggest.quicksuggest.sponsored") &&
|
|
||||||
lazy.UrlbarPrefs.get("fakespotFeatureGate") &&
|
|
||||||
lazy.UrlbarPrefs.get("suggest.fakespot")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get enablingPreferences() {
|
get enablingPreferences() {
|
||||||
return ["suggest.quicksuggest.sponsored", "suggest.fakespot"];
|
return [
|
||||||
|
"fakespotFeatureGate",
|
||||||
|
"suggest.fakespot",
|
||||||
|
"suggest.quicksuggest.sponsored",
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
get rustSuggestionType() {
|
get rustSuggestionType() {
|
||||||
|
|
|
@ -25,11 +25,11 @@ export class ImpressionCaps extends SuggestFeature {
|
||||||
lazy.UrlbarPrefs.addObserver(this);
|
lazy.UrlbarPrefs.addObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
get shouldEnable() {
|
get enablingPreferences() {
|
||||||
return (
|
return [
|
||||||
lazy.UrlbarPrefs.get("quickSuggestImpressionCapsSponsoredEnabled") ||
|
"quickSuggestImpressionCapsSponsoredEnabled",
|
||||||
lazy.UrlbarPrefs.get("quickSuggestImpressionCapsNonSponsoredEnabled")
|
"quickSuggestImpressionCapsNonSponsoredEnabled",
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
enable(enabled) {
|
enable(enabled) {
|
||||||
|
|
|
@ -23,14 +23,6 @@ const RESULT_MENU_COMMAND = {
|
||||||
* A feature that supports MDN suggestions.
|
* A feature that supports MDN suggestions.
|
||||||
*/
|
*/
|
||||||
export class MDNSuggestions extends SuggestProvider {
|
export class MDNSuggestions extends SuggestProvider {
|
||||||
get shouldEnable() {
|
|
||||||
return (
|
|
||||||
lazy.UrlbarPrefs.get("mdn.featureGate") &&
|
|
||||||
lazy.UrlbarPrefs.get("suggest.mdn") &&
|
|
||||||
lazy.UrlbarPrefs.get("suggest.quicksuggest.nonsponsored")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get enablingPreferences() {
|
get enablingPreferences() {
|
||||||
return [
|
return [
|
||||||
"mdn.featureGate",
|
"mdn.featureGate",
|
||||||
|
|
|
@ -8,7 +8,6 @@ const lazy = {};
|
||||||
|
|
||||||
ChromeUtils.defineESModuleGetters(lazy, {
|
ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
QuickSuggest: "resource:///modules/QuickSuggest.sys.mjs",
|
QuickSuggest: "resource:///modules/QuickSuggest.sys.mjs",
|
||||||
UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
|
|
||||||
UrlbarResult: "resource:///modules/UrlbarResult.sys.mjs",
|
UrlbarResult: "resource:///modules/UrlbarResult.sys.mjs",
|
||||||
UrlbarUtils: "resource:///modules/UrlbarUtils.sys.mjs",
|
UrlbarUtils: "resource:///modules/UrlbarUtils.sys.mjs",
|
||||||
});
|
});
|
||||||
|
@ -19,10 +18,6 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
* Instead they're handled directly by `UrlbarProviderQuickSuggest`.
|
* Instead they're handled directly by `UrlbarProviderQuickSuggest`.
|
||||||
*/
|
*/
|
||||||
export class OfflineWikipediaSuggestions extends SuggestProvider {
|
export class OfflineWikipediaSuggestions extends SuggestProvider {
|
||||||
get shouldEnable() {
|
|
||||||
return lazy.UrlbarPrefs.get("suggest.quicksuggest.nonsponsored");
|
|
||||||
}
|
|
||||||
|
|
||||||
get enablingPreferences() {
|
get enablingPreferences() {
|
||||||
return ["suggest.quicksuggest.nonsponsored"];
|
return ["suggest.quicksuggest.nonsponsored"];
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,16 +24,12 @@ const RESULT_MENU_COMMAND = {
|
||||||
* A feature that manages Pocket suggestions in remote settings.
|
* A feature that manages Pocket suggestions in remote settings.
|
||||||
*/
|
*/
|
||||||
export class PocketSuggestions extends SuggestProvider {
|
export class PocketSuggestions extends SuggestProvider {
|
||||||
get shouldEnable() {
|
|
||||||
return (
|
|
||||||
lazy.UrlbarPrefs.get("pocketFeatureGate") &&
|
|
||||||
lazy.UrlbarPrefs.get("suggest.pocket") &&
|
|
||||||
lazy.UrlbarPrefs.get("suggest.quicksuggest.nonsponsored")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get enablingPreferences() {
|
get enablingPreferences() {
|
||||||
return ["suggest.pocket", "suggest.quicksuggest.nonsponsored"];
|
return [
|
||||||
|
"pocketFeatureGate",
|
||||||
|
"suggest.pocket",
|
||||||
|
"suggest.quicksuggest.nonsponsored",
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
get merinoProvider() {
|
get merinoProvider() {
|
||||||
|
|
|
@ -16,10 +16,6 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
* Merino, also called "online" Suggest.
|
* Merino, also called "online" Suggest.
|
||||||
*/
|
*/
|
||||||
export class SuggestBackendMerino extends SuggestBackend {
|
export class SuggestBackendMerino extends SuggestBackend {
|
||||||
get shouldEnable() {
|
|
||||||
return lazy.UrlbarPrefs.get("quicksuggest.dataCollection.enabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
get enablingPreferences() {
|
get enablingPreferences() {
|
||||||
return ["quicksuggest.dataCollection.enabled"];
|
return ["quicksuggest.dataCollection.enabled"];
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ const lazy = {};
|
||||||
ChromeUtils.defineESModuleGetters(lazy, {
|
ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
MLSuggest: "resource:///modules/urlbar/private/MLSuggest.sys.mjs",
|
MLSuggest: "resource:///modules/urlbar/private/MLSuggest.sys.mjs",
|
||||||
QuickSuggest: "resource:///modules/QuickSuggest.sys.mjs",
|
QuickSuggest: "resource:///modules/QuickSuggest.sys.mjs",
|
||||||
UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,15 +17,8 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
* query.
|
* query.
|
||||||
*/
|
*/
|
||||||
export class SuggestBackendMl extends SuggestBackend {
|
export class SuggestBackendMl extends SuggestBackend {
|
||||||
get shouldEnable() {
|
|
||||||
return (
|
|
||||||
lazy.UrlbarPrefs.get("quickSuggestMlEnabled") &&
|
|
||||||
lazy.UrlbarPrefs.get("browser.ml.enable")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get enablingPreferences() {
|
get enablingPreferences() {
|
||||||
return ["browser.ml.enable"];
|
return ["quickSuggestMlEnabled", "browser.ml.enable"];
|
||||||
}
|
}
|
||||||
|
|
||||||
async enable(enabled) {
|
async enable(enabled) {
|
||||||
|
|
|
@ -112,10 +112,6 @@ export class SuggestBackendRust extends SuggestBackend {
|
||||||
return ["quicksuggest.rustEnabled"];
|
return ["quicksuggest.rustEnabled"];
|
||||||
}
|
}
|
||||||
|
|
||||||
get shouldEnable() {
|
|
||||||
return lazy.UrlbarPrefs.get("quicksuggest.rustEnabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {object}
|
* @returns {object}
|
||||||
* The global Suggest config from the Rust component as returned from
|
* The global Suggest config from the Rust component as returned from
|
||||||
|
|
|
@ -24,33 +24,45 @@ export class SuggestFeature {
|
||||||
// Methods designed for overriding below
|
// Methods designed for overriding below
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {boolean}
|
* @returns {Array}
|
||||||
* Whether the feature should be enabled. Typically the subclass will check
|
* If the feature is conditioned on any prefs or Nimbus variables, the
|
||||||
* the values of one or more Nimbus variables or preferences. `QuickSuggest`
|
* subclass should override this getter and return their names in this array
|
||||||
* will access this getter only when Suggest is enabled. When Suggest is
|
* so that `update()` and `enable()` can be called when they change. Names
|
||||||
* disabled, the feature will be disabled automatically.
|
* should be recognized by `UrlbarPrefs`, i.e., pref names should be
|
||||||
|
* relative to the `browser.urlbar.` branch. For Nimbus variables with
|
||||||
|
* fallback prefs, include only the variable name.
|
||||||
|
*
|
||||||
|
* When Suggest determines whether the feature should be enabled, it will
|
||||||
|
* call `UrlbarPrefs.get()` on each name in this array and disable the
|
||||||
|
* feature if any are falsey. If any of the prefs or variables are not
|
||||||
|
* booleans, the subclass may also need to override
|
||||||
|
* `additionalEnablingPredicate` to perform additional checks on them.
|
||||||
*/
|
*/
|
||||||
get shouldEnable() {
|
get enablingPreferences() {
|
||||||
throw new Error("`shouldEnable` must be overridden");
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {Array}
|
* @returns {boolean}
|
||||||
* If the subclass's `shouldEnable` implementation depends on any prefs that
|
* If the feature is conditioned on any predicate other than the prefs and
|
||||||
* are not fallbacks for Nimbus variables, the subclass should override this
|
* Nimbus variables in `enablingPreferences`, the subclass should override
|
||||||
* getter and return their names in this array so that `update()` can be
|
* this getter and return whether the feature should be enabled. It may also
|
||||||
* called when they change. Names should be recognized by `UrlbarPrefs`. It
|
* need to override this getter if any of the prefs or variables in
|
||||||
* doesn't hurt to include prefs that are fallbacks for Nimbus variables,
|
* `enablingPreferences` are not booleans so that it can perform additional
|
||||||
* it's just not necessary because `QuickSuggest` will update all features
|
* checks on them. (The predicate does not need to check prefs and variables
|
||||||
* whenever a `urlbar` Nimbus variable or its fallback pref changes.
|
* in `enablingPreferences` that are booleans.)
|
||||||
|
*
|
||||||
|
* This getter will be called only when Suggest is enabled and all prefs and
|
||||||
|
* variables in `enablingPreferences` are truthy.
|
||||||
*/
|
*/
|
||||||
get enablingPreferences() {
|
get additionalEnablingPredicate() {
|
||||||
return null;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method should initialize or uninitialize any state related to the
|
* This method should initialize or uninitialize any state related to the
|
||||||
* feature.
|
* feature. It will only be called when the enabled status changes, i.e., when
|
||||||
|
* it goes from false to true or true to false.
|
||||||
*
|
*
|
||||||
* @param {boolean} enabled
|
* @param {boolean} enabled
|
||||||
* Whether the feature should be enabled or not.
|
* Whether the feature should be enabled or not.
|
||||||
|
@ -59,6 +71,17 @@ export class SuggestFeature {
|
||||||
|
|
||||||
// Methods not designed for overriding below
|
// Methods not designed for overriding below
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {boolean}
|
||||||
|
* Whether the feature should be enabled, assuming Suggest is enabled.
|
||||||
|
*/
|
||||||
|
get shouldEnable() {
|
||||||
|
return (
|
||||||
|
this.enablingPreferences.every(p => lazy.UrlbarPrefs.get(p)) &&
|
||||||
|
this.additionalEnablingPredicate
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {Logger}
|
* @returns {Logger}
|
||||||
* The feature's logger.
|
* The feature's logger.
|
||||||
|
@ -92,9 +115,7 @@ export class SuggestFeature {
|
||||||
/**
|
/**
|
||||||
* Enables or disables the feature according to `shouldEnable` and whether
|
* Enables or disables the feature according to `shouldEnable` and whether
|
||||||
* Suggest is enabled. If the feature's enabled status changes, `enable()` is
|
* Suggest is enabled. If the feature's enabled status changes, `enable()` is
|
||||||
* called with the new status; otherwise `enable()` is not called. If the
|
* called with the new status; otherwise `enable()` is not called.
|
||||||
* feature manages any Rust suggestion types that become enabled as a result,
|
|
||||||
* they will be ingested.
|
|
||||||
*/
|
*/
|
||||||
update() {
|
update() {
|
||||||
let enable =
|
let enable =
|
||||||
|
|
|
@ -149,16 +149,12 @@ export class WeatherSuggestions extends SuggestProvider {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get shouldEnable() {
|
|
||||||
return (
|
|
||||||
lazy.UrlbarPrefs.get("suggest.quicksuggest.sponsored") &&
|
|
||||||
lazy.UrlbarPrefs.get("weatherFeatureGate") &&
|
|
||||||
lazy.UrlbarPrefs.get("suggest.weather")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get enablingPreferences() {
|
get enablingPreferences() {
|
||||||
return ["suggest.quicksuggest.sponsored", "suggest.weather"];
|
return [
|
||||||
|
"weatherFeatureGate",
|
||||||
|
"suggest.weather",
|
||||||
|
"suggest.quicksuggest.sponsored",
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
get rustSuggestionType() {
|
get rustSuggestionType() {
|
||||||
|
|
|
@ -29,16 +29,12 @@ const RESULT_MENU_COMMAND = {
|
||||||
* A feature for Yelp suggestions.
|
* A feature for Yelp suggestions.
|
||||||
*/
|
*/
|
||||||
export class YelpSuggestions extends SuggestProvider {
|
export class YelpSuggestions extends SuggestProvider {
|
||||||
get shouldEnable() {
|
|
||||||
return (
|
|
||||||
lazy.UrlbarPrefs.get("suggest.quicksuggest.sponsored") &&
|
|
||||||
lazy.UrlbarPrefs.get("yelpFeatureGate") &&
|
|
||||||
lazy.UrlbarPrefs.get("suggest.yelp")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get enablingPreferences() {
|
get enablingPreferences() {
|
||||||
return ["suggest.quicksuggest.sponsored", "suggest.yelp"];
|
return [
|
||||||
|
"yelpFeatureGate",
|
||||||
|
"suggest.yelp",
|
||||||
|
"suggest.quicksuggest.sponsored",
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
get rustSuggestionType() {
|
get rustSuggestionType() {
|
||||||
|
|
|
@ -630,29 +630,6 @@ add_task(async function nimbusScotchBonnetEnableOverride() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
add_task(async function nimbusLogEnabled() {
|
|
||||||
info("Setup initial local pref");
|
|
||||||
await SpecialPowers.pushPrefEnv({
|
|
||||||
set: [["browser.search.log", false]],
|
|
||||||
});
|
|
||||||
await TestUtils.waitForCondition(() => {
|
|
||||||
return !Services.prefs.getBoolPref("browser.search.log");
|
|
||||||
});
|
|
||||||
|
|
||||||
info("Setup Numbus value");
|
|
||||||
const cleanUpNimbusEnable = await UrlbarTestUtils.initNimbusFeature(
|
|
||||||
{ logEnabled: true },
|
|
||||||
"search"
|
|
||||||
);
|
|
||||||
await TestUtils.waitForCondition(() => {
|
|
||||||
return Services.prefs.getBoolPref("browser.search.log");
|
|
||||||
});
|
|
||||||
Assert.ok(true, "browser.search.log is changed properly");
|
|
||||||
|
|
||||||
await cleanUpNimbusEnable();
|
|
||||||
await SpecialPowers.popPrefEnv();
|
|
||||||
});
|
|
||||||
|
|
||||||
add_task(async function test_button_stuck() {
|
add_task(async function test_button_stuck() {
|
||||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||||
let popup = win.document.getElementById("searchmode-switcher-popup");
|
let popup = win.document.getElementById("searchmode-switcher-popup");
|
||||||
|
|
|
@ -18,6 +18,13 @@ preonboarding-privacy-notice-header-button-title = Read our Privacy Notice
|
||||||
# Label for header style button that toggles showing the data preference checklist
|
# Label for header style button that toggles showing the data preference checklist
|
||||||
preonboarding-manage-data-header-button-title = Manage diagnostic and interaction data
|
preonboarding-manage-data-header-button-title = Manage diagnostic and interaction data
|
||||||
|
|
||||||
|
# Label for header style button that toggles showing the Terms of Use (Variant B)
|
||||||
|
preonboarding-terms-of-use-header-button-title-b = { -brand-product-name } Terms of Use
|
||||||
|
# Label for header style button that toggles showing the Privacy Notice (Variant B)
|
||||||
|
preonboarding-privacy-notice-header-button-title-b = { -brand-product-name } Privacy Notice
|
||||||
|
# Description under label for header style buttons
|
||||||
|
preonboarding-header-button-description = Read More
|
||||||
|
|
||||||
# New user onboarding checklist
|
# New user onboarding checklist
|
||||||
preonboarding-checklist-interaction-data-label = Send technical and interaction data to { -vendor-short-name }
|
preonboarding-checklist-interaction-data-label = Send technical and interaction data to { -vendor-short-name }
|
||||||
preonboarding-checklist-interaction-data-description = Data about your device, hardware configuration, and how you use { -brand-product-name } helps improve features, performance, and stability for users everywhere.
|
preonboarding-checklist-interaction-data-description = Data about your device, hardware configuration, and how you use { -brand-product-name } helps improve features, performance, and stability for users everywhere.
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"af": {
|
"af": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"an": {
|
"an": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ar": {
|
"ar": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ast": {
|
"ast": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -92,7 +92,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"az": {
|
"az": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"be": {
|
"be": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -130,7 +130,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"bg": {
|
"bg": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -149,7 +149,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"bn": {
|
"bn": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -168,7 +168,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"bo": {
|
"bo": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -187,7 +187,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"br": {
|
"br": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -206,7 +206,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"brx": {
|
"brx": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -225,7 +225,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"bs": {
|
"bs": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -244,7 +244,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ca": {
|
"ca": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -263,7 +263,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ca-valencia": {
|
"ca-valencia": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -282,7 +282,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"cak": {
|
"cak": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -301,7 +301,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ckb": {
|
"ckb": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -320,7 +320,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"cs": {
|
"cs": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -339,7 +339,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"cy": {
|
"cy": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -358,7 +358,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"da": {
|
"da": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -377,7 +377,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"de": {
|
"de": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -396,7 +396,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"dsb": {
|
"dsb": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -415,7 +415,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"el": {
|
"el": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -434,7 +434,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"en-CA": {
|
"en-CA": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -453,7 +453,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"en-GB": {
|
"en-GB": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -472,7 +472,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"eo": {
|
"eo": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -491,7 +491,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"es-AR": {
|
"es-AR": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -510,7 +510,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"es-CL": {
|
"es-CL": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -529,7 +529,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"es-ES": {
|
"es-ES": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -548,7 +548,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"es-MX": {
|
"es-MX": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -567,7 +567,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"et": {
|
"et": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -586,7 +586,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"eu": {
|
"eu": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -605,7 +605,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"fa": {
|
"fa": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -624,7 +624,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ff": {
|
"ff": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -643,7 +643,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"fi": {
|
"fi": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -662,7 +662,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"fr": {
|
"fr": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -681,7 +681,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"fur": {
|
"fur": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -700,7 +700,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"fy-NL": {
|
"fy-NL": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -719,7 +719,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ga-IE": {
|
"ga-IE": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -738,7 +738,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"gd": {
|
"gd": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -757,7 +757,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"gl": {
|
"gl": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -776,7 +776,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"gn": {
|
"gn": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -795,7 +795,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"gu-IN": {
|
"gu-IN": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -814,7 +814,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"he": {
|
"he": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -833,7 +833,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"hi-IN": {
|
"hi-IN": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -852,7 +852,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"hr": {
|
"hr": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -871,7 +871,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"hsb": {
|
"hsb": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -890,7 +890,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"hu": {
|
"hu": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -909,7 +909,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"hy-AM": {
|
"hy-AM": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -928,7 +928,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"hye": {
|
"hye": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -947,7 +947,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ia": {
|
"ia": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -966,7 +966,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"id": {
|
"id": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -985,7 +985,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"is": {
|
"is": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1004,7 +1004,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"it": {
|
"it": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1023,7 +1023,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ja": {
|
"ja": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1040,7 +1040,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ja-JP-mac": {
|
"ja-JP-mac": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1048,7 +1048,7 @@
|
||||||
"macosx64",
|
"macosx64",
|
||||||
"macosx64-devedition"
|
"macosx64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ka": {
|
"ka": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1067,7 +1067,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"kab": {
|
"kab": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1086,7 +1086,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"kk": {
|
"kk": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1105,7 +1105,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"km": {
|
"km": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1124,7 +1124,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"kn": {
|
"kn": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1143,7 +1143,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ko": {
|
"ko": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1162,7 +1162,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"lij": {
|
"lij": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1181,7 +1181,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"lo": {
|
"lo": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1200,7 +1200,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"lt": {
|
"lt": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1219,7 +1219,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ltg": {
|
"ltg": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1238,7 +1238,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"lv": {
|
"lv": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1257,7 +1257,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"meh": {
|
"meh": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1276,7 +1276,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"mk": {
|
"mk": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1295,7 +1295,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"mr": {
|
"mr": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1314,7 +1314,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1333,7 +1333,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"my": {
|
"my": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1352,7 +1352,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"nb-NO": {
|
"nb-NO": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1371,7 +1371,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ne-NP": {
|
"ne-NP": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1390,7 +1390,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"nl": {
|
"nl": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1409,7 +1409,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"nn-NO": {
|
"nn-NO": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1428,7 +1428,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"oc": {
|
"oc": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1447,7 +1447,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"pa-IN": {
|
"pa-IN": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1466,7 +1466,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"pl": {
|
"pl": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1485,7 +1485,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"pt-BR": {
|
"pt-BR": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1504,7 +1504,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"pt-PT": {
|
"pt-PT": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1523,7 +1523,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"rm": {
|
"rm": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1542,7 +1542,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ro": {
|
"ro": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1561,7 +1561,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ru": {
|
"ru": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1580,7 +1580,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"sat": {
|
"sat": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1599,7 +1599,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"sc": {
|
"sc": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1618,7 +1618,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"scn": {
|
"scn": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1637,7 +1637,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"sco": {
|
"sco": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1656,7 +1656,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"si": {
|
"si": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1675,7 +1675,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"sk": {
|
"sk": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1694,7 +1694,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"skr": {
|
"skr": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1713,7 +1713,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"sl": {
|
"sl": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1732,7 +1732,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"son": {
|
"son": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1751,7 +1751,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"sq": {
|
"sq": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1770,7 +1770,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"sr": {
|
"sr": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1789,7 +1789,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"sv-SE": {
|
"sv-SE": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1808,7 +1808,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"szl": {
|
"szl": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1827,7 +1827,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ta": {
|
"ta": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1846,7 +1846,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"te": {
|
"te": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1865,7 +1865,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"tg": {
|
"tg": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1884,7 +1884,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"th": {
|
"th": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1903,7 +1903,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"tl": {
|
"tl": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1922,7 +1922,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"tr": {
|
"tr": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1941,7 +1941,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"trs": {
|
"trs": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1960,7 +1960,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"uk": {
|
"uk": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1979,7 +1979,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"ur": {
|
"ur": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -1998,7 +1998,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"uz": {
|
"uz": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -2017,7 +2017,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"vi": {
|
"vi": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -2036,7 +2036,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"wo": {
|
"wo": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -2055,7 +2055,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"xh": {
|
"xh": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -2074,7 +2074,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"zh-CN": {
|
"zh-CN": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -2093,7 +2093,7 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
},
|
},
|
||||||
"zh-TW": {
|
"zh-TW": {
|
||||||
"pin": false,
|
"pin": false,
|
||||||
|
@ -2112,6 +2112,6 @@
|
||||||
"win64-aarch64-devedition",
|
"win64-aarch64-devedition",
|
||||||
"win64-devedition"
|
"win64-devedition"
|
||||||
],
|
],
|
||||||
"revision": "67e3e0da074da1a66f97aeb649d1469373e8b7cf"
|
"revision": "1fc67833f6f1b3390afc9f2834527fb8648bc299"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,16 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
// We use importESModule here instead of static import so that
|
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
|
||||||
// the Karma test environment won't choke on this module. This
|
|
||||||
// is because the Karma test environment already stubs out
|
|
||||||
// XPCOMUtils, and overrides importESModule to be a no-op (which
|
|
||||||
// can't be done for a static import statement).
|
|
||||||
|
|
||||||
// eslint-disable-next-line mozilla/use-static-import
|
|
||||||
const { XPCOMUtils } = ChromeUtils.importESModule(
|
|
||||||
"resource://gre/modules/XPCOMUtils.sys.mjs"
|
|
||||||
);
|
|
||||||
|
|
||||||
const lazy = {};
|
const lazy = {};
|
||||||
|
|
|
@ -123,6 +123,7 @@ EXTRA_JS_MODULES += [
|
||||||
"EveryWindow.sys.mjs",
|
"EveryWindow.sys.mjs",
|
||||||
"ExtensionsUI.sys.mjs",
|
"ExtensionsUI.sys.mjs",
|
||||||
"FaviconLoader.sys.mjs",
|
"FaviconLoader.sys.mjs",
|
||||||
|
"FilterAdult.sys.mjs",
|
||||||
"FirefoxBridgeExtensionUtils.sys.mjs",
|
"FirefoxBridgeExtensionUtils.sys.mjs",
|
||||||
"HomePage.sys.mjs",
|
"HomePage.sys.mjs",
|
||||||
"LaterRun.sys.mjs",
|
"LaterRun.sys.mjs",
|
||||||
|
|
119
browser/modules/test/unit/test_FilterAdult.js
Normal file
119
browser/modules/test/unit/test_FilterAdult.js
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* https://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const { FilterAdult } = ChromeUtils.importESModule(
|
||||||
|
"resource:///modules/FilterAdult.sys.mjs"
|
||||||
|
);
|
||||||
|
|
||||||
|
let originalPrefValue;
|
||||||
|
const FILTER_ADULT_ENABLED_PREF =
|
||||||
|
"browser.newtabpage.activity-stream.filterAdult";
|
||||||
|
const TEST_ADULT_SITE_URL = "https://some-adult-site.com/";
|
||||||
|
|
||||||
|
add_setup(async function setup() {
|
||||||
|
// Save the original preference value to restore later
|
||||||
|
originalPrefValue = Services.prefs.getBoolPref(
|
||||||
|
FILTER_ADULT_ENABLED_PREF,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
// Enable the filter preference for testing
|
||||||
|
Services.prefs.setBoolPref(FILTER_ADULT_ENABLED_PREF, true);
|
||||||
|
registerCleanupFunction(() => {
|
||||||
|
// Restore the original preference value after all tests
|
||||||
|
Services.prefs.setBoolPref(FILTER_ADULT_ENABLED_PREF, originalPrefValue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_defaults_to_include_unexpected_urls() {
|
||||||
|
const empty = {};
|
||||||
|
const result = FilterAdult.filter([empty]);
|
||||||
|
Assert.equal(result.length, 1);
|
||||||
|
Assert.equal(result[0], empty);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_does_not_filter_non_adult_urls() {
|
||||||
|
const link = { url: "https://mozilla.org/" };
|
||||||
|
const result = FilterAdult.filter([link]);
|
||||||
|
Assert.equal(result.length, 1);
|
||||||
|
Assert.equal(result[0], link);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_filters_out_adult_urls() {
|
||||||
|
// Add a domain to the adult list
|
||||||
|
FilterAdult.addDomainToList(TEST_ADULT_SITE_URL);
|
||||||
|
const link = { url: TEST_ADULT_SITE_URL };
|
||||||
|
const result = FilterAdult.filter([link]);
|
||||||
|
Assert.equal(result.length, 0);
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
FilterAdult.removeDomainFromList(TEST_ADULT_SITE_URL);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_does_not_filter_adult_urls_when_pref_off() {
|
||||||
|
// Disable the filter preference
|
||||||
|
Services.prefs.setBoolPref(FILTER_ADULT_ENABLED_PREF, false);
|
||||||
|
|
||||||
|
// Add a domain to the adult list
|
||||||
|
FilterAdult.addDomainToList(TEST_ADULT_SITE_URL);
|
||||||
|
const link = { url: TEST_ADULT_SITE_URL };
|
||||||
|
const result = FilterAdult.filter([link]);
|
||||||
|
Assert.equal(result.length, 1);
|
||||||
|
Assert.equal(result[0], link);
|
||||||
|
|
||||||
|
// Re-enable the preference
|
||||||
|
Services.prefs.setBoolPref(FILTER_ADULT_ENABLED_PREF, true);
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
FilterAdult.removeDomainFromList(TEST_ADULT_SITE_URL);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_isAdultUrl_returns_false_for_unexpected_urls() {
|
||||||
|
const result = FilterAdult.isAdultUrl("");
|
||||||
|
Assert.equal(result, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_isAdultUrl_returns_false_for_non_adult_urls() {
|
||||||
|
const result = FilterAdult.isAdultUrl("https://mozilla.org/");
|
||||||
|
Assert.equal(result, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_isAdultUrl_returns_true_for_adult_urls() {
|
||||||
|
// Add a domain to the adult list
|
||||||
|
FilterAdult.addDomainToList(TEST_ADULT_SITE_URL);
|
||||||
|
const result = FilterAdult.isAdultUrl(TEST_ADULT_SITE_URL);
|
||||||
|
Assert.equal(result, true);
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
FilterAdult.removeDomainFromList(TEST_ADULT_SITE_URL);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_isAdultUrl_returns_false_when_pref_off() {
|
||||||
|
// Disable the filter preference
|
||||||
|
Services.prefs.setBoolPref(FILTER_ADULT_ENABLED_PREF, false);
|
||||||
|
|
||||||
|
// Add a domain to the adult list
|
||||||
|
FilterAdult.addDomainToList(TEST_ADULT_SITE_URL);
|
||||||
|
const result = FilterAdult.isAdultUrl(TEST_ADULT_SITE_URL);
|
||||||
|
Assert.equal(result, false);
|
||||||
|
|
||||||
|
// Re-enable the preference
|
||||||
|
Services.prefs.setBoolPref(FILTER_ADULT_ENABLED_PREF, true);
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
FilterAdult.removeDomainFromList(TEST_ADULT_SITE_URL);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_add_and_remove_from_adult_list() {
|
||||||
|
// Add a domain to the adult list
|
||||||
|
FilterAdult.addDomainToList(TEST_ADULT_SITE_URL);
|
||||||
|
let result = FilterAdult.isAdultUrl(TEST_ADULT_SITE_URL);
|
||||||
|
Assert.equal(result, true);
|
||||||
|
|
||||||
|
// Remove the domain from the list
|
||||||
|
FilterAdult.removeDomainFromList(TEST_ADULT_SITE_URL);
|
||||||
|
result = FilterAdult.isAdultUrl(TEST_ADULT_SITE_URL);
|
||||||
|
Assert.equal(result, false);
|
||||||
|
});
|
|
@ -6,6 +6,8 @@ tags = "os_integration"
|
||||||
|
|
||||||
["test_E10SUtils_nested_URIs.js"]
|
["test_E10SUtils_nested_URIs.js"]
|
||||||
|
|
||||||
|
["test_FilterAdult.js"]
|
||||||
|
|
||||||
["test_FirefoxBridgeExtensionUtils.js"]
|
["test_FirefoxBridgeExtensionUtils.js"]
|
||||||
run-if = ["os == 'win'"] # Test of a Windows-specific feature
|
run-if = ["os == 'win'"] # Test of a Windows-specific feature
|
||||||
|
|
||||||
|
|
|
@ -439,7 +439,7 @@ def assert_rust_compile(host_or_target, rustc_target, rustc):
|
||||||
suffix=".rlib"
|
suffix=".rlib"
|
||||||
) as out_path:
|
) as out_path:
|
||||||
with open(in_path, "w") as fd:
|
with open(in_path, "w") as fd:
|
||||||
source = b'pub extern fn hello() { println!("Hello world"); }'
|
source = b'pub extern "C" fn hello() { println!("Hello world"); }'
|
||||||
log.debug("Creating `%s` with content:", in_path)
|
log.debug("Creating `%s` with content:", in_path)
|
||||||
with LineIO(lambda l: log.debug("| %s", l)) as out:
|
with LineIO(lambda l: log.debug("| %s", l)) as out:
|
||||||
out.write(source)
|
out.write(source)
|
||||||
|
|
|
@ -18,6 +18,10 @@ const {
|
||||||
const {
|
const {
|
||||||
getFormattedTime,
|
getFormattedTime,
|
||||||
} = require("resource://devtools/client/netmonitor/src/utils/format-utils.js");
|
} = require("resource://devtools/client/netmonitor/src/utils/format-utils.js");
|
||||||
|
const { truncateString } = require("resource://devtools/shared/string.js");
|
||||||
|
const {
|
||||||
|
MAX_UI_STRING_LENGTH,
|
||||||
|
} = require("resource://devtools/client/netmonitor/src/constants.js");
|
||||||
|
|
||||||
const UPDATED_FILE_PROPS = ["urlDetails", "waitingTime"];
|
const UPDATED_FILE_PROPS = ["urlDetails", "waitingTime"];
|
||||||
|
|
||||||
|
@ -66,9 +70,9 @@ module.exports = class RequestListColumnFile extends Component {
|
||||||
return dom.td(
|
return dom.td(
|
||||||
{
|
{
|
||||||
className: "requests-list-column requests-list-file",
|
className: "requests-list-column requests-list-file",
|
||||||
title: fileToolTip,
|
title: truncateString(fileToolTip, MAX_UI_STRING_LENGTH),
|
||||||
},
|
},
|
||||||
dom.div({}, requestedFile),
|
dom.div({}, truncateString(requestedFile, MAX_UI_STRING_LENGTH)),
|
||||||
isSlow &&
|
isSlow &&
|
||||||
dom.div({
|
dom.div({
|
||||||
title: L10N.getFormatStr(
|
title: L10N.getFormatStr(
|
||||||
|
|
|
@ -24,6 +24,11 @@ const {
|
||||||
const SecurityState = createFactory(
|
const SecurityState = createFactory(
|
||||||
require("resource://devtools/client/netmonitor/src/components/SecurityState.js")
|
require("resource://devtools/client/netmonitor/src/components/SecurityState.js")
|
||||||
);
|
);
|
||||||
|
const { truncateString } = require("resource://devtools/shared/string.js");
|
||||||
|
const {
|
||||||
|
MAX_UI_STRING_LENGTH,
|
||||||
|
} = require("resource://devtools/client/netmonitor/src/constants.js");
|
||||||
|
|
||||||
const UPDATED_FILE_PROPS = ["remoteAddress", "securityState", "urlDetails"];
|
const UPDATED_FILE_PROPS = ["remoteAddress", "securityState", "urlDetails"];
|
||||||
|
|
||||||
class RequestListColumnUrl extends Component {
|
class RequestListColumnUrl extends Component {
|
||||||
|
@ -78,10 +83,10 @@ class RequestListColumnUrl extends Component {
|
||||||
return td(
|
return td(
|
||||||
{
|
{
|
||||||
className: "requests-list-column requests-list-url",
|
className: "requests-list-column requests-list-url",
|
||||||
title: urlToolTip + title,
|
title: truncateString(urlToolTip, MAX_UI_STRING_LENGTH) + title,
|
||||||
},
|
},
|
||||||
SecurityState({ item, onSecurityIconMouseDown, isLocal }),
|
SecurityState({ item, onSecurityIconMouseDown, isLocal }),
|
||||||
originalURL
|
truncateString(originalURL, MAX_UI_STRING_LENGTH)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -384,7 +384,16 @@ class RequestListContent extends Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.contextMenu.open(evt, clickedRequest, displayedRequests, blockedUrls);
|
const filteredBlockedUrls = blockedUrls
|
||||||
|
.map(({ enabled, url }) => (enabled ? url : null))
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
|
this.contextMenu.open(
|
||||||
|
evt,
|
||||||
|
clickedRequest,
|
||||||
|
displayedRequests,
|
||||||
|
filteredBlockedUrls
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -471,9 +480,7 @@ class RequestListContent extends Component {
|
||||||
|
|
||||||
module.exports = connect(
|
module.exports = connect(
|
||||||
state => ({
|
state => ({
|
||||||
blockedUrls: state.requestBlocking.blockedUrls
|
blockedUrls: state.requestBlocking.blockedUrls,
|
||||||
.map(({ enabled, url }) => (enabled ? url : null))
|
|
||||||
.filter(Boolean),
|
|
||||||
columns: getColumns(state),
|
columns: getColumns(state),
|
||||||
networkActionOpen: state.ui.networkActionOpen,
|
networkActionOpen: state.ui.networkActionOpen,
|
||||||
networkDetailsOpen: state.ui.networkDetailsOpen,
|
networkDetailsOpen: state.ui.networkDetailsOpen,
|
||||||
|
|
|
@ -610,6 +610,9 @@ const general = {
|
||||||
AUTO_EXPAND_MAX_NODES: 50,
|
AUTO_EXPAND_MAX_NODES: 50,
|
||||||
CHANNEL_TYPE,
|
CHANNEL_TYPE,
|
||||||
WEB_SOCKET_OPCODE,
|
WEB_SOCKET_OPCODE,
|
||||||
|
// Arbitrary limit for rendering strings in the netmonitor table.
|
||||||
|
// Useful for instance for very big data URIs.
|
||||||
|
MAX_UI_STRING_LENGTH: 10000,
|
||||||
};
|
};
|
||||||
|
|
||||||
// flatten constants
|
// flatten constants
|
||||||
|
|
|
@ -44,44 +44,39 @@ function sortWithClones(requests, sorter, a, b) {
|
||||||
return sorter ? sorter(a, b) : defaultSorter;
|
return sorter ? sorter(a, b) : defaultSorter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getActiveFilters = createSelector(
|
||||||
|
state => state.filters.requestFilterTypes,
|
||||||
|
requestFilterTypes =>
|
||||||
|
Object.keys(requestFilterTypes)
|
||||||
|
.filter(type => requestFilterTypes[type] && Filters[type])
|
||||||
|
.map(type => Filters[type])
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take clones into account when filtering. If a request is
|
* Take clones into account when filtering. If a request is
|
||||||
* a clone, it's not filtered out.
|
* a clone, it's not filtered out.
|
||||||
*/
|
*/
|
||||||
const getFilterWithCloneFn = createSelector(
|
const getFilterWithCloneFn = createSelector(
|
||||||
state => state.filters,
|
getActiveFilters,
|
||||||
filters => r => {
|
state => state.filters.requestFilterText,
|
||||||
const matchesType = Object.keys(filters.requestFilterTypes).some(filter => {
|
(activeFilters, requestFilterText) => {
|
||||||
if (r.id.endsWith("-clone")) {
|
return r => {
|
||||||
return true;
|
const isClone = r.id.endsWith("-clone");
|
||||||
}
|
const matchesType = activeFilters.some(filter => filter(r));
|
||||||
return (
|
return (isClone || matchesType) && isFreetextMatch(r, requestFilterText);
|
||||||
filters.requestFilterTypes[filter] &&
|
};
|
||||||
Filters[filter] &&
|
|
||||||
Filters[filter](r)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
return matchesType && isFreetextMatch(r, filters.requestFilterText);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const getTypeFilterFn = createSelector(
|
const getTypeFilterFn = createSelector(
|
||||||
state => state.filters,
|
getActiveFilters,
|
||||||
filters => r => {
|
activeFilters => r => activeFilters.some(filter => filter(r))
|
||||||
return Object.keys(filters.requestFilterTypes).some(filter => {
|
|
||||||
return (
|
|
||||||
filters.requestFilterTypes[filter] &&
|
|
||||||
Filters[filter] &&
|
|
||||||
Filters[filter](r)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const getSortFn = createSelector(
|
const getSortFn = createSelector(
|
||||||
state => state.requests,
|
state => state.requests.requests,
|
||||||
state => state.sort,
|
state => state.sort,
|
||||||
({ requests }, sort) => {
|
(requests, sort) => {
|
||||||
const sorter = Sorters[sort.type || "waterfall"];
|
const sorter = Sorters[sort.type || "waterfall"];
|
||||||
const ascending = sort.ascending ? +1 : -1;
|
const ascending = sort.ascending ? +1 : -1;
|
||||||
return (a, b) => ascending * sortWithClones(requests, sorter, a, b);
|
return (a, b) => ascending * sortWithClones(requests, sorter, a, b);
|
||||||
|
@ -89,22 +84,22 @@ const getSortFn = createSelector(
|
||||||
);
|
);
|
||||||
|
|
||||||
const getSortedRequests = createSelector(
|
const getSortedRequests = createSelector(
|
||||||
state => state.requests,
|
state => state.requests.requests,
|
||||||
getSortFn,
|
getSortFn,
|
||||||
({ requests }, sortFn) => [...requests].sort(sortFn)
|
(requests, sortFn) => [...requests].sort(sortFn)
|
||||||
);
|
);
|
||||||
|
|
||||||
const getDisplayedRequests = createSelector(
|
const getDisplayedRequests = createSelector(
|
||||||
state => state.requests,
|
state => state.requests.requests,
|
||||||
getFilterWithCloneFn,
|
getFilterWithCloneFn,
|
||||||
getSortFn,
|
getSortFn,
|
||||||
({ requests }, filterFn, sortFn) => requests.filter(filterFn).sort(sortFn)
|
(requests, filterFn, sortFn) => requests.filter(filterFn).sort(sortFn)
|
||||||
);
|
);
|
||||||
|
|
||||||
const getTypeFilteredRequests = createSelector(
|
const getTypeFilteredRequests = createSelector(
|
||||||
state => state.requests,
|
state => state.requests.requests,
|
||||||
getTypeFilterFn,
|
getTypeFilterFn,
|
||||||
({ requests }, filterFn) => requests.filter(filterFn)
|
(requests, filterFn) => requests.filter(filterFn)
|
||||||
);
|
);
|
||||||
|
|
||||||
const getDisplayedRequestsSummary = createSelector(
|
const getDisplayedRequestsSummary = createSelector(
|
||||||
|
@ -143,15 +138,16 @@ const getDisplayedRequestsSummary = createSelector(
|
||||||
);
|
);
|
||||||
|
|
||||||
const getSelectedRequest = createSelector(
|
const getSelectedRequest = createSelector(
|
||||||
state => state.requests,
|
state => state.requests.requests,
|
||||||
({ selectedId, requests }) =>
|
state => state.requests.selectedId,
|
||||||
|
(requests, selectedId) =>
|
||||||
selectedId ? requests.find(item => item.id === selectedId) : undefined
|
selectedId ? requests.find(item => item.id === selectedId) : undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
const isSelectedRequestVisible = createSelector(
|
const isSelectedRequestVisible = createSelector(
|
||||||
state => state.requests,
|
state => state.requests.selectedId,
|
||||||
getDisplayedRequests,
|
getDisplayedRequests,
|
||||||
({ selectedId }, displayedRequests) =>
|
(selectedId, displayedRequests) =>
|
||||||
displayedRequests.some(r => r.id === selectedId)
|
displayedRequests.some(r => r.id === selectedId)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -178,8 +174,9 @@ function getRecordingState(state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const getClickedRequest = createSelector(
|
const getClickedRequest = createSelector(
|
||||||
state => state.requests,
|
state => state.requests.requests,
|
||||||
({ requests, clickedRequestId }) =>
|
state => state.requests.clickedRequestId,
|
||||||
|
(requests, clickedRequestId) =>
|
||||||
requests.find(request => request.id == clickedRequestId)
|
requests.find(request => request.id == clickedRequestId)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -53,23 +53,17 @@ function getVisibleColumns(columns) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const getColumns = createSelector(
|
const getColumns = createSelector(
|
||||||
state => state.ui,
|
state => state.ui.columns,
|
||||||
state => state.search,
|
state => state.ui.networkDetailsOpen || state.search.panelOpen,
|
||||||
(ui, search) => {
|
(columns, isSidePanelOpen) => {
|
||||||
if (
|
const isWaterfallOnly =
|
||||||
((ui.networkDetailsOpen || search.panelOpen) &&
|
getVisibleColumns(columns).length === 1 && columns.waterfall;
|
||||||
getVisibleColumns(ui.columns).length === 1 &&
|
if (isSidePanelOpen && !isWaterfallOnly) {
|
||||||
ui.columns.waterfall) ||
|
// Remove the Waterfall column if it is not the only column and a side
|
||||||
(!ui.networkDetailsOpen && !search.panelOpen)
|
// panel is open.
|
||||||
) {
|
columns = { ...columns };
|
||||||
return ui.columns;
|
delete columns.waterfall;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the Waterfall/Timeline column from the list of available
|
|
||||||
// columns if the details side-bar is opened and more than one column is
|
|
||||||
// visible.
|
|
||||||
const columns = { ...ui.columns };
|
|
||||||
delete columns.waterfall;
|
|
||||||
return columns;
|
return columns;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -48,7 +48,6 @@ function trimUrlQuery(url) {
|
||||||
// Map suffix to content type.
|
// Map suffix to content type.
|
||||||
const contentMap = {
|
const contentMap = {
|
||||||
js: "text/javascript",
|
js: "text/javascript",
|
||||||
jsm: "text/javascript",
|
|
||||||
mjs: "text/javascript",
|
mjs: "text/javascript",
|
||||||
ts: "text/typescript",
|
ts: "text/typescript",
|
||||||
tsx: "text/typescript-jsx",
|
tsx: "text/typescript-jsx",
|
||||||
|
|
|
@ -32,10 +32,10 @@ frame-script
|
||||||
|
|
||||||
Defines the environment for scripts loaded by ``Services.mm.loadFrameScript``.
|
Defines the environment for scripts loaded by ``Services.mm.loadFrameScript``.
|
||||||
|
|
||||||
jsm
|
sysmjs
|
||||||
---
|
---
|
||||||
|
|
||||||
Defines the environment for jsm files (javascript modules).
|
Defines the environment for system module files (.sys.mjs).
|
||||||
|
|
||||||
privileged
|
privileged
|
||||||
----------
|
----------
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
mark-exported-symbols-as-used
|
|
||||||
=============================
|
|
||||||
|
|
||||||
Marks variables listed in ``EXPORTED_SYMBOLS`` as used so that ``no-unused-vars``
|
|
||||||
does not complain about them.
|
|
||||||
|
|
||||||
This rule also checks that ``EXPORTED_SYMBOLS`` is not defined using ``let`` as
|
|
||||||
``let`` isn't allowed as the lexical scope may die after the script executes.
|
|
||||||
|
|
||||||
Examples of incorrect code for this rule:
|
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
.. code-block:: js
|
|
||||||
|
|
||||||
let EXPORTED_SYMBOLS = ["foo"];
|
|
||||||
|
|
||||||
Examples of correct code for this rule:
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
.. code-block:: js
|
|
||||||
|
|
||||||
var EXPORTED_SYMBOLS = ["foo"];
|
|
||||||
const EXPORTED_SYMBOLS = ["foo"];
|
|
|
@ -1,22 +0,0 @@
|
||||||
reject-chromeutils-import-params
|
|
||||||
================================
|
|
||||||
|
|
||||||
``ChromeUtils.import`` used to be able to be called with two arguments, however
|
|
||||||
the second argument is no longer supported. Exports from modules should now be
|
|
||||||
explicit, and the imported symbols being accessed from the returned object.
|
|
||||||
|
|
||||||
Examples of incorrect code for this rule:
|
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
.. code-block:: js
|
|
||||||
|
|
||||||
ChromeUtils.import("resource://gre/modules/AppConstants.jsm", this);
|
|
||||||
ChromeUtils.import("resource://gre/modules/AppConstants.jsm", null);
|
|
||||||
ChromeUtils.import("resource://gre/modules/AppConstants.jsm", {});
|
|
||||||
|
|
||||||
Examples of correct code for this rule:
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
.. code-block:: js
|
|
||||||
|
|
||||||
const { AppConstants } = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
|
|
@ -1,27 +0,0 @@
|
||||||
reject-chromeutils-import
|
|
||||||
================================
|
|
||||||
|
|
||||||
While ``ChromeUtils.import`` supports the fallback to ESMified module,
|
|
||||||
in-tree files should use ``ChromeUtils.importESModule`` for ESMified modules.
|
|
||||||
|
|
||||||
Examples of incorrect code for this rule:
|
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
.. code-block:: js
|
|
||||||
|
|
||||||
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
|
||||||
|
|
||||||
ChromeUtils.defineModuleGetter(
|
|
||||||
obj, "AppConstants", "resource://gre/modules/AppConstants.jsm");
|
|
||||||
XPCOMUtils.defineLazyModuleGetters(
|
|
||||||
obj, { AppConstants: "resource://gre/modules/AppConstants.jsm" });
|
|
||||||
|
|
||||||
Examples of correct code for this rule:
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
.. code-block:: js
|
|
||||||
|
|
||||||
ChromeUtils.importESModule("resource://gre/modules/AppConstants.sys.mjs");
|
|
||||||
|
|
||||||
ChromeUtils.defineESModuleGetters(
|
|
||||||
obj, { AppConstants: "resource://gre/modules/AppConstants.sys.mjs" });
|
|
|
@ -12,9 +12,6 @@ Examples of incorrect code for this rule:
|
||||||
ChromeUtils.defineESModuleGetters(lazy, {
|
ChromeUtils.defineESModuleGetters(lazy, {
|
||||||
AppConstants: "resource://gre/modules/AppConstants.sys.mjs",
|
AppConstants: "resource://gre/modules/AppConstants.sys.mjs",
|
||||||
});
|
});
|
||||||
XPCOMUtils.defineLazyModuleGetters(lazy, {
|
|
||||||
XPCOMUtils: "resource://gre/modules/XPCOMUtils.jsm",
|
|
||||||
});
|
|
||||||
|
|
||||||
Examples of correct code for this rule:
|
Examples of correct code for this rule:
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
@ -22,9 +19,6 @@ Examples of correct code for this rule:
|
||||||
.. code-block:: js
|
.. code-block:: js
|
||||||
|
|
||||||
import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
|
import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
|
||||||
const { XPCOMUtils } = ChromeUtils.import(
|
const { AppConstants } = ChromeUtils.importESModule(
|
||||||
"resource://gre/modules/XPCOMUtils.jsm"
|
"resource://gre/modules/AppConstants.sys.mjs"
|
||||||
);
|
|
||||||
const { AppConstants } = ChromeUtils.import(
|
|
||||||
"resource://gre/modules/AppConstants.jsm"
|
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
reject-global-this
|
|
||||||
======================
|
|
||||||
|
|
||||||
Rejects global ``this`` usage in JSM files. The global ``this`` is not
|
|
||||||
available in ESM, and this is a preparation for the migration.
|
|
||||||
|
|
||||||
Examples of incorrect code for this rule:
|
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
.. code-block:: js
|
|
||||||
|
|
||||||
this.EXPORTED_SYMBOLS = ["foo"];
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
|
||||||
AddonManager: "resource://gre/modules/AddonManager.jsm",
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
Examples of correct code for this rule:
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
.. code-block:: js
|
|
||||||
|
|
||||||
const EXPORTED_SYMBOLS = ["foo"];
|
|
||||||
|
|
||||||
const lazy = {};
|
|
||||||
XPCOMUtils.defineLazyModuleGetters(lazy, {
|
|
||||||
AddonManager: "resource://gre/modules/AddonManager.jsm",
|
|
||||||
});
|
|
|
@ -1,19 +0,0 @@
|
||||||
use-chromeutils-import
|
|
||||||
======================
|
|
||||||
|
|
||||||
Require use of ``ChromeUtils.import`` rather than ``Components.utils.import``.
|
|
||||||
|
|
||||||
Examples of incorrect code for this rule:
|
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
.. code-block:: js
|
|
||||||
|
|
||||||
Components.utils.import("resource://gre/modules/AppConstants.jsm", this);
|
|
||||||
|
|
||||||
Examples of correct code for this rule:
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
.. code-block:: js
|
|
||||||
|
|
||||||
ChromeUtils.import("resource://gre/modules/AppConstants.jsm", this);
|
|
||||||
ChromeUtils.defineModuleGetter(this, "AppConstants", "resource://gre/modules/AppConstants.jsm");
|
|
|
@ -8,7 +8,6 @@ is created from a different context.
|
||||||
These files are covered:
|
These files are covered:
|
||||||
|
|
||||||
- ``*.sys.mjs``
|
- ``*.sys.mjs``
|
||||||
- ``*.jsm``
|
|
||||||
- ``*.xhtml`` with ``there.is.only.xul``
|
- ``*.xhtml`` with ``there.is.only.xul``
|
||||||
- ``*.js`` with a heuristic
|
- ``*.js`` with a heuristic
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
#include "mozilla/dom/UserActivationIPCUtils.h"
|
#include "mozilla/dom/UserActivationIPCUtils.h"
|
||||||
#include "mozilla/PermissionDelegateIPCUtils.h"
|
#include "mozilla/PermissionDelegateIPCUtils.h"
|
||||||
#include "mozilla/RFPTargetIPCUtils.h"
|
|
||||||
#include "mozilla/StaticPrefs_dom.h"
|
#include "mozilla/StaticPrefs_dom.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
#include "mozilla/ClearOnShutdown.h"
|
#include "mozilla/ClearOnShutdown.h"
|
||||||
|
@ -22,6 +21,7 @@
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
#include "nsIWebProgressListener.h"
|
#include "nsIWebProgressListener.h"
|
||||||
#include "nsIXULRuntime.h"
|
#include "nsIXULRuntime.h"
|
||||||
|
#include "nsRFPTargetSetIDL.h"
|
||||||
#include "nsRefPtrHashtable.h"
|
#include "nsRefPtrHashtable.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
|
|
||||||
|
@ -78,6 +78,19 @@ bool WindowContext::IsInBFCache() {
|
||||||
return TopWindowContext()->GetWindowStateSaved();
|
return TopWindowContext()->GetWindowStateSaved();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsIRFPTargetSetIDL>
|
||||||
|
WindowContext::GetOverriddenFingerprintingSettingsWebIDL() const {
|
||||||
|
Maybe<RFPTargetSet> overriddenFingerprintingSettings =
|
||||||
|
GetOverriddenFingerprintingSettings();
|
||||||
|
if (overriddenFingerprintingSettings.isNothing()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIRFPTargetSetIDL> protections =
|
||||||
|
new nsRFPTargetSetIDL(overriddenFingerprintingSettings.ref());
|
||||||
|
return protections.forget();
|
||||||
|
}
|
||||||
|
|
||||||
nsGlobalWindowInner* WindowContext::GetInnerWindow() const {
|
nsGlobalWindowInner* WindowContext::GetInnerWindow() const {
|
||||||
return mWindowGlobalChild ? mWindowGlobalChild->GetWindowGlobal() : nullptr;
|
return mWindowGlobalChild ? mWindowGlobalChild->GetWindowGlobal() : nullptr;
|
||||||
}
|
}
|
||||||
|
@ -241,7 +254,7 @@ bool WindowContext::CanSet(FieldIndex<IDX_ShouldResistFingerprinting>,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WindowContext::CanSet(FieldIndex<IDX_OverriddenFingerprintingSettings>,
|
bool WindowContext::CanSet(FieldIndex<IDX_OverriddenFingerprintingSettings>,
|
||||||
const Maybe<RFPTarget>& aValue,
|
const Maybe<RFPTargetSet>& aValue,
|
||||||
ContentParent* aSource) {
|
ContentParent* aSource) {
|
||||||
return CheckOnlyOwningProcessCanSet(aSource);
|
return CheckOnlyOwningProcessCanSet(aSource);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ class nsGlobalWindowInner;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class LogModule;
|
class LogModule;
|
||||||
|
class nsRFPTargetSetIDL;
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ class BrowsingContextGroup;
|
||||||
* the Storage Access API */ \
|
* the Storage Access API */ \
|
||||||
FIELD(UsingStorageAccess, bool) \
|
FIELD(UsingStorageAccess, bool) \
|
||||||
FIELD(ShouldResistFingerprinting, bool) \
|
FIELD(ShouldResistFingerprinting, bool) \
|
||||||
FIELD(OverriddenFingerprintingSettings, Maybe<RFPTarget>) \
|
FIELD(OverriddenFingerprintingSettings, Maybe<RFPTargetSet>) \
|
||||||
FIELD(IsSecureContext, bool) \
|
FIELD(IsSecureContext, bool) \
|
||||||
FIELD(IsOriginalFrameSource, bool) \
|
FIELD(IsOriginalFrameSource, bool) \
|
||||||
/* Mixed-Content: If the corresponding documentURI is https, \
|
/* Mixed-Content: If the corresponding documentURI is https, \
|
||||||
|
@ -139,15 +140,8 @@ class WindowContext : public nsISupports, public nsWrapperCache {
|
||||||
|
|
||||||
bool UsingStorageAccess() const { return GetUsingStorageAccess(); }
|
bool UsingStorageAccess() const { return GetUsingStorageAccess(); }
|
||||||
|
|
||||||
Nullable<uint64_t> GetOverriddenFingerprintingSettingsWebIDL() const {
|
already_AddRefed<nsIRFPTargetSetIDL>
|
||||||
Maybe<RFPTarget> overriddenFingerprintingSettings =
|
GetOverriddenFingerprintingSettingsWebIDL() const;
|
||||||
GetOverriddenFingerprintingSettings();
|
|
||||||
|
|
||||||
return overriddenFingerprintingSettings.isSome()
|
|
||||||
? Nullable<uint64_t>(
|
|
||||||
uint64_t(overriddenFingerprintingSettings.ref()))
|
|
||||||
: Nullable<uint64_t>();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsGlobalWindowInner* GetInnerWindow() const;
|
nsGlobalWindowInner* GetInnerWindow() const;
|
||||||
Document* GetDocument() const;
|
Document* GetDocument() const;
|
||||||
|
@ -305,7 +299,7 @@ class WindowContext : public nsISupports, public nsWrapperCache {
|
||||||
bool CanSet(FieldIndex<IDX_ShouldResistFingerprinting>,
|
bool CanSet(FieldIndex<IDX_ShouldResistFingerprinting>,
|
||||||
const bool& aShouldResistFingerprinting, ContentParent* aSource);
|
const bool& aShouldResistFingerprinting, ContentParent* aSource);
|
||||||
bool CanSet(FieldIndex<IDX_OverriddenFingerprintingSettings>,
|
bool CanSet(FieldIndex<IDX_OverriddenFingerprintingSettings>,
|
||||||
const Maybe<RFPTarget>& aValue, ContentParent* aSource);
|
const Maybe<RFPTargetSet>& aValue, ContentParent* aSource);
|
||||||
bool CanSet(FieldIndex<IDX_IsSecureContext>, const bool& aIsSecureContext,
|
bool CanSet(FieldIndex<IDX_IsSecureContext>, const bool& aIsSecureContext,
|
||||||
ContentParent* aSource);
|
ContentParent* aSource);
|
||||||
bool CanSet(FieldIndex<IDX_IsOriginalFrameSource>,
|
bool CanSet(FieldIndex<IDX_IsOriginalFrameSource>,
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
#include "mozilla/RemoteDecoderManagerChild.h"
|
#include "mozilla/RemoteDecoderManagerChild.h"
|
||||||
#include "mozilla/KeySystemConfig.h"
|
#include "mozilla/KeySystemConfig.h"
|
||||||
#include "mozilla/WheelHandlingHelper.h"
|
#include "mozilla/WheelHandlingHelper.h"
|
||||||
|
#include "nsIRFPTargetSetIDL.h"
|
||||||
#include "nsContentSecurityUtils.h"
|
#include "nsContentSecurityUtils.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsNativeTheme.h"
|
#include "nsNativeTheme.h"
|
||||||
|
@ -2317,7 +2318,7 @@ void ChromeUtils::GetAllPossibleUtilityActorNames(GlobalObject& aGlobal,
|
||||||
/* static */
|
/* static */
|
||||||
bool ChromeUtils::ShouldResistFingerprinting(
|
bool ChromeUtils::ShouldResistFingerprinting(
|
||||||
GlobalObject& aGlobal, JSRFPTarget aTarget,
|
GlobalObject& aGlobal, JSRFPTarget aTarget,
|
||||||
const Nullable<uint64_t>& aOverriddenFingerprintingSettings,
|
nsIRFPTargetSetIDL* aOverriddenFingerprintingSettings,
|
||||||
const Optional<bool>& aIsPBM) {
|
const Optional<bool>& aIsPBM) {
|
||||||
RFPTarget target;
|
RFPTarget target;
|
||||||
switch (aTarget) {
|
switch (aTarget) {
|
||||||
|
@ -2351,10 +2352,16 @@ bool ChromeUtils::ShouldResistFingerprinting(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<RFPTarget> overriddenFingerprintingSettings;
|
Maybe<RFPTargetSet> overriddenFingerprintingSettings;
|
||||||
if (!aOverriddenFingerprintingSettings.IsNull()) {
|
if (aOverriddenFingerprintingSettings) {
|
||||||
overriddenFingerprintingSettings.emplace(
|
uint64_t low, hi;
|
||||||
RFPTarget(aOverriddenFingerprintingSettings.Value()));
|
aOverriddenFingerprintingSettings->GetLow(&low);
|
||||||
|
aOverriddenFingerprintingSettings->GetHigh(&hi);
|
||||||
|
std::bitset<128> bitset;
|
||||||
|
bitset |= hi;
|
||||||
|
bitset <<= 64;
|
||||||
|
bitset |= low;
|
||||||
|
overriddenFingerprintingSettings.emplace(RFPTargetSet(bitset));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This global object appears to be the global window, not for individual
|
// This global object appears to be the global window, not for individual
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#include "nsIDOMProcessChild.h"
|
#include "nsIDOMProcessChild.h"
|
||||||
#include "nsIDOMProcessParent.h"
|
#include "nsIDOMProcessParent.h"
|
||||||
|
|
||||||
|
class nsIRFPTargetSetIDL;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
class ErrorResult;
|
class ErrorResult;
|
||||||
|
@ -326,7 +328,7 @@ class ChromeUtils {
|
||||||
|
|
||||||
static bool ShouldResistFingerprinting(
|
static bool ShouldResistFingerprinting(
|
||||||
GlobalObject& aGlobal, JSRFPTarget aTarget,
|
GlobalObject& aGlobal, JSRFPTarget aTarget,
|
||||||
const Nullable<uint64_t>& aOverriddenFingerprintingSettings,
|
nsIRFPTargetSetIDL* aOverriddenFingerprintingSettings,
|
||||||
const Optional<bool>& aIsPBM);
|
const Optional<bool>& aIsPBM);
|
||||||
|
|
||||||
static void SanitizeTelemetryFileURL(GlobalObject& aGlobal,
|
static void SanitizeTelemetryFileURL(GlobalObject& aGlobal,
|
||||||
|
|
|
@ -4200,7 +4200,7 @@ class Document : public nsINode,
|
||||||
bool ShouldResistFingerprinting(RFPTarget aTarget) const;
|
bool ShouldResistFingerprinting(RFPTarget aTarget) const;
|
||||||
bool IsInPrivateBrowsing() const;
|
bool IsInPrivateBrowsing() const;
|
||||||
|
|
||||||
const Maybe<RFPTarget>& GetOverriddenFingerprintingSettings() const {
|
const Maybe<RFPTargetSet>& GetOverriddenFingerprintingSettings() const {
|
||||||
return mOverriddenFingerprintingSettings;
|
return mOverriddenFingerprintingSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4986,7 +4986,7 @@ class Document : public nsINode,
|
||||||
// This will only get populated if these is one that comes from the local
|
// This will only get populated if these is one that comes from the local
|
||||||
// fingerprinting protection override pref or WebCompat. Otherwise, a value of
|
// fingerprinting protection override pref or WebCompat. Otherwise, a value of
|
||||||
// Nothing() indicates no overrides are present for this document.
|
// Nothing() indicates no overrides are present for this document.
|
||||||
Maybe<RFPTarget> mOverriddenFingerprintingSettings;
|
Maybe<RFPTargetSet> mOverriddenFingerprintingSettings;
|
||||||
|
|
||||||
uint8_t mXMLDeclarationBits;
|
uint8_t mXMLDeclarationBits;
|
||||||
|
|
||||||
|
|
|
@ -5495,7 +5495,7 @@ bool Element::Translate() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorBase* Element::GetEditorWithoutCreation() const {
|
EditorBase* Element::GetExtantEditor() const {
|
||||||
if (!IsInComposedDoc()) {
|
if (!IsInComposedDoc()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -5507,8 +5507,7 @@ EditorBase* Element::GetEditorWithoutCreation() const {
|
||||||
if (!isInDesignMode) {
|
if (!isInDesignMode) {
|
||||||
if (const auto* textControlElement = TextControlElement::FromNode(this)) {
|
if (const auto* textControlElement = TextControlElement::FromNode(this)) {
|
||||||
if (textControlElement->IsSingleLineTextControlOrTextArea()) {
|
if (textControlElement->IsSingleLineTextControlOrTextArea()) {
|
||||||
return static_cast<const TextControlElement*>(this)
|
return textControlElement->GetExtantTextEditor();
|
||||||
->GetTextEditorWithoutCreation();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5517,7 +5516,7 @@ EditorBase* Element::GetEditorWithoutCreation() const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
// FYI: This never creates HTMLEditor immediately.
|
// FYI: This never creates HTMLEditor immediately.
|
||||||
nsDocShell* docShell = nsDocShell::Cast(OwnerDoc()->GetDocShell());
|
nsDocShell* const docShell = nsDocShell::Cast(OwnerDoc()->GetDocShell());
|
||||||
return docShell ? docShell->GetHTMLEditorInternal() : nullptr;
|
return docShell ? docShell->GetHTMLEditorInternal() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -238,12 +238,8 @@ class TrustedHTMLOrNullIsEmptyString;
|
||||||
class TrustedHTMLOrTrustedScriptOrTrustedScriptURLOrString;
|
class TrustedHTMLOrTrustedScriptOrTrustedScriptURLOrString;
|
||||||
|
|
||||||
// IID for the dom::Element interface
|
// IID for the dom::Element interface
|
||||||
#define NS_ELEMENT_IID \
|
#define NS_ELEMENT_IID \
|
||||||
{ \
|
{0xc67ed254, 0xfd3b, 0x4b10, {0x96, 0xa2, 0xc5, 0x8b, 0x7b, 0x64, 0x97, 0xd1}}
|
||||||
0xc67ed254, 0xfd3b, 0x4b10, { \
|
|
||||||
0x96, 0xa2, 0xc5, 0x8b, 0x7b, 0x64, 0x97, 0xd1 \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define REFLECT_NULLABLE_DOMSTRING_ATTR(method, attr) \
|
#define REFLECT_NULLABLE_DOMSTRING_ATTR(method, attr) \
|
||||||
void Get##method(nsAString& aValue) const { \
|
void Get##method(nsAString& aValue) const { \
|
||||||
|
@ -1397,13 +1393,13 @@ class Element : public FragmentOrElement {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an editor which handles user inputs when this element has focus.
|
* Get an editor which handles user inputs when this element has focus.
|
||||||
* If this is a text control, return a TextEditor if it's already created.
|
* If this is a text control, return a TextEditor if it's already created and
|
||||||
* Otherwise, return nullptr.
|
* it's not in the design mode.
|
||||||
* If this is not a text control but this is editable, return
|
* If this is editable, return HTMLEditor which should've already been
|
||||||
* HTMLEditor which should've already been created.
|
* created.
|
||||||
* Otherwise, return nullptr.
|
* Otherwise, return nullptr.
|
||||||
*/
|
*/
|
||||||
EditorBase* GetEditorWithoutCreation() const;
|
EditorBase* GetExtantEditor() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue