icecat: add release icecat-140.6.0-1gnu1 for ecne
This commit is contained in:
parent
618c9f4145
commit
7d0f5dab3b
3382 changed files with 457689 additions and 569094 deletions
|
|
@ -969,13 +969,6 @@ export default class LoginItem extends HTMLElement {
|
|||
}
|
||||
|
||||
_updatePasswordRevealState() {
|
||||
if (
|
||||
window.AboutLoginsUtils &&
|
||||
window.AboutLoginsUtils.passwordRevealVisible === false
|
||||
) {
|
||||
this._revealCheckbox.hidden = true;
|
||||
}
|
||||
|
||||
let { checked } = this._revealCheckbox;
|
||||
let inputType = checked ? "text" : "password";
|
||||
this._passwordInput.type = inputType;
|
||||
|
|
@ -988,6 +981,13 @@ export default class LoginItem extends HTMLElement {
|
|||
this._revealCheckbox.hidden = false;
|
||||
}
|
||||
|
||||
if (
|
||||
window.AboutLoginsUtils &&
|
||||
window.AboutLoginsUtils.passwordRevealVisible === false
|
||||
) {
|
||||
this._revealCheckbox.hidden = true;
|
||||
}
|
||||
|
||||
// Swap which <input> is in the document depending on whether we need the
|
||||
// real .value (which means that the primary password was already entered,
|
||||
// if applicable)
|
||||
|
|
|
|||
|
|
@ -1576,6 +1576,27 @@ export var Policies = {
|
|||
},
|
||||
},
|
||||
|
||||
GenerativeAI: {
|
||||
onBeforeAddons(manager, param) {
|
||||
const defaultValue = "Enabled" in param ? param.Enabled : undefined;
|
||||
|
||||
const features = [
|
||||
["Chatbot", ["browser.ml.chat.enabled", "browser.ml.chat.page"]],
|
||||
["LinkPreviews", ["browser.ml.linkPreview.optin"]],
|
||||
["TabGroups", ["browser.tabs.groups.smart.userEnabled"]],
|
||||
];
|
||||
|
||||
for (const [key, prefs] of features) {
|
||||
const value = key in param ? param[key] : defaultValue;
|
||||
if (value !== undefined) {
|
||||
for (const pref of prefs) {
|
||||
PoliciesUtils.setDefaultPref(pref, value, param.Locked);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
GoToIntranetSiteForSingleWordEntryInAddressBar: {
|
||||
onBeforeAddons(manager, param) {
|
||||
setAndLockPref("browser.fixup.dns_first_for_single_words", param);
|
||||
|
|
@ -2080,6 +2101,7 @@ export var Policies = {
|
|||
"security.tls.hello_downgrade_check",
|
||||
"security.tls.version.enable-deprecated",
|
||||
"security.warn_submit_secure_to_insecure",
|
||||
"security.webauthn.always_allow_direct_attestation",
|
||||
];
|
||||
const blockedPrefs = [
|
||||
"app.update.channel",
|
||||
|
|
|
|||
|
|
@ -850,6 +850,27 @@
|
|||
}
|
||||
},
|
||||
|
||||
"GenerativeAI": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Chatbot": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"LinkPreviews": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"TabGroups": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"Enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"Locked": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"GoToIntranetSiteForSingleWordEntryInAddressBar": {
|
||||
"type": "boolean"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,6 +4,41 @@
|
|||
"use strict";
|
||||
|
||||
add_task(async function test_hidden_reveal_password() {
|
||||
let login = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance(
|
||||
Ci.nsILoginInfo
|
||||
);
|
||||
login.init("https://example.com", "", null, "username", "password");
|
||||
login.QueryInterface(Ci.nsILoginMetaInfo);
|
||||
login.timePasswordChanged = Date.now();
|
||||
await Services.logins.addLoginAsync(login);
|
||||
|
||||
await setupPolicyEngineWithJson({
|
||||
policies: {
|
||||
DisablePasswordReveal: true,
|
||||
},
|
||||
});
|
||||
|
||||
let aboutLoginsTab = await BrowserTestUtils.openNewForegroundTab({
|
||||
gBrowser,
|
||||
url: "about:logins",
|
||||
});
|
||||
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
let loginItem = Cu.waiveXrays(content.document.querySelector("login-item"));
|
||||
|
||||
let passwordReveal = loginItem.shadowRoot.querySelector(
|
||||
".reveal-password-checkbox"
|
||||
);
|
||||
is(passwordReveal.hidden, true, "Password reveal button should be hidden");
|
||||
});
|
||||
BrowserTestUtils.removeTab(aboutLoginsTab);
|
||||
|
||||
await Services.logins.removeAllLogins();
|
||||
});
|
||||
|
||||
add_task(async function test_bug_1696948() {
|
||||
await setupPolicyEngineWithJson({
|
||||
policies: {
|
||||
DisablePasswordReveal: true,
|
||||
|
|
|
|||
|
|
@ -1184,6 +1184,38 @@ const POLICIES_TESTS = [
|
|||
// browser/components/enterprisepolicies/tests/browser/browser_policy_usermessaging.js
|
||||
},
|
||||
},
|
||||
|
||||
// Bug 1981587
|
||||
{
|
||||
policies: {
|
||||
Preferences: {
|
||||
"security.webauthn.always_allow_direct_attestation": {
|
||||
Value: true,
|
||||
Status: "locked",
|
||||
},
|
||||
},
|
||||
},
|
||||
lockedPrefs: {
|
||||
"security.webauthn.always_allow_direct_attestation": true,
|
||||
},
|
||||
},
|
||||
|
||||
// GenerativeAI
|
||||
{
|
||||
policies: {
|
||||
GenerativeAI: {
|
||||
Enabled: false,
|
||||
Chatbot: true,
|
||||
Locked: true,
|
||||
},
|
||||
},
|
||||
lockedPrefs: {
|
||||
"browser.ml.chat.enabled": true,
|
||||
"browser.ml.chat.page": true,
|
||||
"browser.ml.linkPreview.optin": false,
|
||||
"browser.tabs.groups.smart.userEnabled": false,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
add_task(async function test_policy_simple_prefs() {
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ export const LinkPreview = {
|
|||
},
|
||||
|
||||
get canShowKeyPoints() {
|
||||
return this._isRegionSupported();
|
||||
return this._isRegionSupported() && !this._isDisabledByPolicy();
|
||||
},
|
||||
|
||||
get canShowLegacy() {
|
||||
|
|
@ -751,6 +751,17 @@ export const LinkPreview = {
|
|||
return !disallowedRegions.includes(userRegion);
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if key points generation is disabled by policy.
|
||||
*
|
||||
* @returns {boolean} True if disabled by policy, false otherwise.
|
||||
*/
|
||||
_isDisabledByPolicy() {
|
||||
return (
|
||||
!lazy.optin && Services.prefs.prefIsLocked("browser.ml.linkPreview.optin")
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates an Open Graph (OG) card using meta information from the page.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -419,6 +419,13 @@ class LinkPreviewCard extends MozLitElement {
|
|||
return "";
|
||||
}
|
||||
|
||||
if (
|
||||
!this.optin &&
|
||||
Services.prefs.prefIsLocked("browser.ml.linkPreview.optin")
|
||||
) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Determine if there's any generation error state
|
||||
const isGenerationError =
|
||||
this.isMissingDataErrorState || this.generationError;
|
||||
|
|
|
|||
|
|
@ -450,3 +450,54 @@ add_task(async function test_no_optin_or_keypoints_in_disallowed_region() {
|
|||
panel.remove();
|
||||
generateStub.restore();
|
||||
});
|
||||
|
||||
/**
|
||||
* Test when the preference is false and locked, the opt-in prompt will not
|
||||
* be shown and no attempt will be made to generate key points.
|
||||
*/
|
||||
add_task(async function test_locked_preference() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["browser.ml.linkPreview.enabled", true],
|
||||
["browser.ml.linkPreview.optin", false],
|
||||
["browser.ml.linkPreview.collapsed", false],
|
||||
],
|
||||
});
|
||||
|
||||
Services.prefs.lockPref("browser.ml.linkPreview.optin");
|
||||
|
||||
const generateStub = sinon.stub(LinkPreviewModel, "generateTextAI");
|
||||
|
||||
LinkPreview.keyboardComboActive = true;
|
||||
XULBrowserWindow.setOverLink(
|
||||
"https://example.com/browser/browser/components/genai/tests/browser/data/readableEn.html",
|
||||
{}
|
||||
);
|
||||
|
||||
let panel = await TestUtils.waitForCondition(() =>
|
||||
document.getElementById("link-preview-panel")
|
||||
);
|
||||
await BrowserTestUtils.waitForEvent(panel, "popupshown");
|
||||
const card = panel.querySelector("link-preview-card");
|
||||
ok(card, "card created for link preview");
|
||||
|
||||
ok(
|
||||
!LinkPreview.canShowKeyPoints,
|
||||
"LinkPreview should indicate key points cannot be shown"
|
||||
);
|
||||
|
||||
// Verify that the opt-in element is NOT present
|
||||
const modelOptinElement = card.shadowRoot.querySelector("model-optin");
|
||||
ok(!modelOptinElement, "model-optin element should NOT be present");
|
||||
|
||||
is(
|
||||
generateStub.callCount,
|
||||
0,
|
||||
"generateTextAI should not be called in a disallowed region"
|
||||
);
|
||||
|
||||
panel.remove();
|
||||
generateStub.restore();
|
||||
|
||||
Services.prefs.unlockPref("browser.ml.linkPreview.optin");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -214,7 +214,8 @@ class HistoryInView extends ViewPage {
|
|||
return (
|
||||
this.profileAge < 8 &&
|
||||
!this.hasImportedHistoryPref &&
|
||||
!this.importHistoryDismissedPref
|
||||
!this.importHistoryDismissedPref &&
|
||||
Services.policies.isAllowed("profileImport")
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
#include placesContextMenu.inc.xhtml
|
||||
#include bookmarksHistoryTooltip.inc.xhtml
|
||||
<box id="sidebar-panel-header" align="center">
|
||||
<h4 data-l10n-id="sidebar-menu-bookmarks-2"></h4>
|
||||
<html:h4 data-l10n-id="sidebar-menu-bookmarks-2"></html:h4>
|
||||
<html:moz-button
|
||||
id="sidebar-panel-close"
|
||||
type="icon ghost"
|
||||
|
|
|
|||
|
|
@ -797,6 +797,15 @@ class PlacesViewBase {
|
|||
}
|
||||
|
||||
if (popup._placesNode && PlacesUIUtils.getViewForNode(popup) == this) {
|
||||
if (this.#isPopupForRecursiveFolderShortcut(popup)) {
|
||||
// Show as an empty container for now. We may want to show a better
|
||||
// message in the future, but since we are likely to remove recursive
|
||||
// shortcuts in maintenance at a certain point, this should be enough.
|
||||
this._setEmptyPopupStatus(popup, true);
|
||||
popup._built = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!popup._placesNode.containerOpen) {
|
||||
popup._placesNode.containerOpen = true;
|
||||
}
|
||||
|
|
@ -819,6 +828,33 @@ class PlacesViewBase {
|
|||
aObject.removeEventListener(aEventNames[i], this, aCapturing);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks up the parent chain to detect whether a folder shortcut resolves to
|
||||
* a folder already present in the ancestry.
|
||||
*
|
||||
* @param {DOMElement} popup
|
||||
* @returns {boolean} Whether this popup is for a recursive folder shortcut.
|
||||
*/
|
||||
#isPopupForRecursiveFolderShortcut(popup) {
|
||||
if (
|
||||
!popup._placesNode ||
|
||||
!PlacesUtils.nodeIsFolderOrShortcut(popup._placesNode)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
let guid = PlacesUtils.getConcreteItemGuid(popup._placesNode);
|
||||
for (
|
||||
let parentView = popup.parentNode?.parentNode;
|
||||
parentView?._placesNode;
|
||||
parentView = parentView.parentNode?.parentNode
|
||||
) {
|
||||
if (PlacesUtils.getConcreteItemGuid(parentView._placesNode) == guid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -214,6 +214,8 @@ skip-if = ["verify && debug && os == 'win'"]
|
|||
|
||||
["browser_paste_resets_cut_highlights.js"]
|
||||
|
||||
["browser_recursive_hierarchies.js"]
|
||||
|
||||
["browser_remove_bookmarks.js"]
|
||||
|
||||
["browser_sidebar_bookmarks_telemetry.js"]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,160 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Verify that menu popups are not populated when doing so would create a
|
||||
* recursive hierarchy. Some consumers may walk menu trees and could enter an
|
||||
* infinite loop if recursion were allowed.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
async function openMenuAndWaitForPopup(menu) {
|
||||
let popup = menu.menupopup;
|
||||
let popupShown = BrowserTestUtils.waitForEvent(popup, "popupshown");
|
||||
// This seems necessary, at least for the toolbar.
|
||||
EventUtils.synthesizeNativeMouseEvent({
|
||||
type: "mousemove",
|
||||
target: menu,
|
||||
atCenter: true,
|
||||
});
|
||||
menu.open = true;
|
||||
await popupShown;
|
||||
return popup;
|
||||
}
|
||||
|
||||
function findNode(guid, view) {
|
||||
for (let node of view.childNodes) {
|
||||
console.log("visiting node", node, node._placesNode?.bookmarkGuid);
|
||||
if (node._placesNode?.bookmarkGuid == guid) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function fakeOpenMenu(popup) {
|
||||
popup.dispatchEvent(new MouseEvent("popupshowing", { bubbles: true }));
|
||||
popup.dispatchEvent(new MouseEvent("popupshown", { bubbles: true }));
|
||||
}
|
||||
|
||||
function findPlacesNode(guid, container) {
|
||||
for (let i = 0; i < container.childCount; i++) {
|
||||
let node = container.getChild(i);
|
||||
if (node.bookmarkGuid == guid) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
add_task(async function test() {
|
||||
// Make sure the bookmarks bar is visible and restore its state on cleanup.
|
||||
let toolbar = document.getElementById("PersonalToolbar");
|
||||
ok(toolbar, "PersonalToolbar should not be null");
|
||||
if (toolbar.collapsed) {
|
||||
await promiseSetToolbarVisibility(toolbar, true);
|
||||
registerCleanupFunction(function () {
|
||||
return promiseSetToolbarVisibility(toolbar, false);
|
||||
});
|
||||
}
|
||||
|
||||
let menubar = document.getElementById("toolbar-menubar");
|
||||
// Force the menu to be shown.
|
||||
const kAutohide = menubar.getAttribute("autohide");
|
||||
menubar.removeAttribute("autohide");
|
||||
registerCleanupFunction(function () {
|
||||
menubar.setAttribute("autohide", kAutohide);
|
||||
});
|
||||
|
||||
registerCleanupFunction(PlacesUtils.bookmarks.eraseEverything);
|
||||
|
||||
// Create a folder structure with a recursive shortcut.
|
||||
let folderA = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
title: "Folder A",
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
});
|
||||
let selfShortcut = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: folderA.guid,
|
||||
title: "Shortcut to A",
|
||||
url: `place:parent=${folderA.guid}`,
|
||||
});
|
||||
let toolbarShortcut = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: folderA.guid,
|
||||
title: "Shortcut to toolbar",
|
||||
url: `place:parent=${PlacesUtils.bookmarks.toolbarGuid}`,
|
||||
});
|
||||
|
||||
// This also ensures that toolbar content is updated.
|
||||
Assert.ok(!(await PlacesToolbarHelper.getIsEmpty()), "Toolbar is not empty");
|
||||
|
||||
// Open the popup for the shortcut from the bookmarks toolbar.
|
||||
let toolbarItems = document.getElementById("PlacesToolbarItems");
|
||||
let folderANode = findNode(folderA.guid, toolbarItems);
|
||||
let folderAPopup = await openMenuAndWaitForPopup(folderANode);
|
||||
let selfShortcutNode = findNode(selfShortcut.guid, folderAPopup);
|
||||
let selfShortcutPopup = await openMenuAndWaitForPopup(selfShortcutNode);
|
||||
|
||||
Assert.ok(
|
||||
!selfShortcutPopup._placesNode.containerOpen,
|
||||
"Self shortcut container is not open"
|
||||
);
|
||||
Assert.ok(
|
||||
selfShortcutPopup.hasAttribute("emptyplacesresult"),
|
||||
"Self shortcut popup is empty"
|
||||
);
|
||||
|
||||
let toolbarShortcutNode = findNode(
|
||||
toolbarShortcut.guid,
|
||||
folderANode.menupopup
|
||||
);
|
||||
let toolbarShortcutPopup = await openMenuAndWaitForPopup(toolbarShortcutNode);
|
||||
|
||||
Assert.ok(
|
||||
!toolbarShortcutPopup._placesNode.containerOpen,
|
||||
"Toolbar shortcut container is not open"
|
||||
);
|
||||
Assert.ok(
|
||||
toolbarShortcutPopup.hasAttribute("emptyplacesresult"),
|
||||
"Toolbar shortcut popup is empty"
|
||||
);
|
||||
|
||||
// Also insert a toolbar shortcut in the bookmarks menu and check the
|
||||
// previously inserted recursive toolbar shortcut there.
|
||||
info("Test native bookmarks menu");
|
||||
let shortcutInMenu = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.menuGuid,
|
||||
title: "Shortcut to menu",
|
||||
url: `place:parent=${PlacesUtils.bookmarks.menuGuid}`,
|
||||
});
|
||||
|
||||
if (Services.appinfo.nativeMenubar) {
|
||||
// With native menubar we can only simulate popupshowing as we cannot
|
||||
// directly open menus.
|
||||
let bookmarksMenuPopup = document.getElementById("bookmarksMenuPopup");
|
||||
fakeOpenMenu(bookmarksMenuPopup);
|
||||
let shortcutInMenuNode = findNode(shortcutInMenu.guid, bookmarksMenuPopup);
|
||||
fakeOpenMenu(shortcutInMenuNode.menupopup);
|
||||
Assert.ok(
|
||||
!shortcutInMenuNode.menupopup._placesNode.containerOpen,
|
||||
"menu shortcut container is not open"
|
||||
);
|
||||
} else {
|
||||
let bookmarksMenu = document.getElementById("bookmarksMenu");
|
||||
let bookmarksPopup = await openMenuAndWaitForPopup(bookmarksMenu);
|
||||
let shortcutInMenuNode = findNode(shortcutInMenu.guid, bookmarksPopup);
|
||||
let shortcutInMenuPopup = await openMenuAndWaitForPopup(
|
||||
shortcutInMenuNode,
|
||||
true
|
||||
);
|
||||
Assert.ok(
|
||||
!shortcutInMenuPopup._placesNode.containerOpen,
|
||||
"Toolbar shortcut container is not open"
|
||||
);
|
||||
Assert.ok(
|
||||
shortcutInMenuPopup.hasAttribute("emptyplacesresult"),
|
||||
"Toolbar shortcut popup is empty"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
@ -3,10 +3,14 @@
|
|||
const PATH_NET = TEST_PATH + "file_dummy.html";
|
||||
const PATH_ORG = PATH_NET.replace("example.net", "example.org");
|
||||
|
||||
add_task(async function () {
|
||||
async function runTest(defaultZoom) {
|
||||
let tab1, tab1Zoom;
|
||||
|
||||
tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, PATH_NET);
|
||||
|
||||
tab1Zoom = ZoomManager.getZoomForBrowser(tab1.linkedBrowser);
|
||||
is(tab1Zoom, defaultZoom, "We are starting with the default zoom.");
|
||||
|
||||
await FullZoom.setZoom(1.25, tab1.linkedBrowser);
|
||||
tab1Zoom = ZoomManager.getZoomForBrowser(tab1.linkedBrowser);
|
||||
|
||||
|
|
@ -46,7 +50,7 @@ add_task(async function () {
|
|||
|
||||
is(
|
||||
tab1Zoom,
|
||||
1.0,
|
||||
defaultZoom,
|
||||
"privacy.resistFingerprinting is true, site-specific zoom should be reset when clearing FPP state for tab1"
|
||||
);
|
||||
|
||||
|
|
@ -55,4 +59,29 @@ add_task(async function () {
|
|||
BrowserTestUtils.removeTab(tab1);
|
||||
|
||||
await SpecialPowers.popPrefEnv();
|
||||
}
|
||||
|
||||
add_task(async function () {
|
||||
await runTest(1.0);
|
||||
|
||||
let defaultZoom = 1.5;
|
||||
let context = Cu.createLoadContext();
|
||||
let cps2 = Cc["@mozilla.org/content-pref/service;1"].getService(
|
||||
Ci.nsIContentPrefService2
|
||||
);
|
||||
let { promise, resolve, reject } = Promise.withResolvers();
|
||||
cps2.setGlobal(FullZoom.name, defaultZoom, context, {
|
||||
handleError(error) {
|
||||
reject(error);
|
||||
},
|
||||
handleCompletion() {
|
||||
resolve();
|
||||
},
|
||||
});
|
||||
await promise;
|
||||
try {
|
||||
await runTest(defaultZoom);
|
||||
} finally {
|
||||
cps2.removeGlobal(FullZoom.name, context);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import { SidebarPage } from "./sidebar-page.mjs";
|
|||
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
HistoryController: "resource:///modules/HistoryController.sys.mjs",
|
||||
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
|
||||
Sanitizer: "resource:///modules/Sanitizer.sys.mjs",
|
||||
});
|
||||
|
||||
|
|
@ -72,6 +73,10 @@ export class SidebarHistory extends SidebarPage {
|
|||
if (!this.triggerNode) {
|
||||
e.preventDefault();
|
||||
}
|
||||
let privateWindowMenuItem = this._contextMenu.querySelector(
|
||||
"#sidebar-history-context-open-in-private-window"
|
||||
);
|
||||
privateWindowMenuItem.hidden = !lazy.PrivateBrowsingUtils.enabled;
|
||||
}
|
||||
|
||||
handleCommandEvent(e) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
const lazy = {};
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
|
||||
SyncedTabsController: "resource:///modules/SyncedTabsController.sys.mjs",
|
||||
});
|
||||
|
||||
|
|
@ -75,6 +76,11 @@ class SyncedTabsInSidebar extends SidebarPage {
|
|||
);
|
||||
// Enable the feature only if the device supports it
|
||||
closeTabMenuItem.disabled = !this.triggerNode.canClose;
|
||||
|
||||
let privateWindowMenuItem = contextMenu.querySelector(
|
||||
"#sidebar-synced-tabs-context-open-in-private-window"
|
||||
);
|
||||
privateWindowMenuItem.hidden = !lazy.PrivateBrowsingUtils.enabled;
|
||||
}
|
||||
|
||||
handleCommandEvent(e) {
|
||||
|
|
|
|||
|
|
@ -159,6 +159,9 @@ const DEFAULT_ACTIONS = {
|
|||
l10nCommands: ["quickactions-cmd-print"],
|
||||
label: "quickactions-print2",
|
||||
icon: "chrome://global/skin/icons/print.svg",
|
||||
isVisible: () => {
|
||||
return Services.prefs.getBoolPref("print.enabled");
|
||||
},
|
||||
onPick: () => {
|
||||
lazy.BrowserWindowTracker.getTopWindow()
|
||||
.document.getElementById("cmd_print")
|
||||
|
|
@ -193,6 +196,9 @@ const DEFAULT_ACTIONS = {
|
|||
l10nCommands: ["quickactions-cmd-savepdf2"],
|
||||
label: "quickactions-savepdf",
|
||||
icon: "chrome://global/skin/icons/print.svg",
|
||||
isVisible: () => {
|
||||
return Services.prefs.getBoolPref("print.enabled");
|
||||
},
|
||||
onPick: () => {
|
||||
// This writes over the users last used printer which we
|
||||
// should not do. Refactor to launch the print preview with
|
||||
|
|
|
|||
|
|
@ -82,11 +82,6 @@ export class AddonSuggestions extends SuggestProvider {
|
|||
return null;
|
||||
}
|
||||
|
||||
if (suggestion.source == "rust") {
|
||||
suggestion.icon = suggestion.iconUrl;
|
||||
delete suggestion.iconUrl;
|
||||
}
|
||||
|
||||
// Set UTM params unless they're already defined. This allows remote
|
||||
// settings or Merino to override them if need be.
|
||||
let url = new URL(suggestion.url);
|
||||
|
|
@ -100,6 +95,8 @@ export class AddonSuggestions extends SuggestProvider {
|
|||
url: url.href,
|
||||
originalUrl: suggestion.url,
|
||||
shouldShowUrl: true,
|
||||
// Rust uses `iconUrl` but Merino uses `icon`.
|
||||
icon: suggestion.iconUrl ?? suggestion.icon,
|
||||
title: suggestion.title,
|
||||
description: suggestion.description,
|
||||
bottomTextL10n: { id: "icecat-suggest-addons-recommended" },
|
||||
|
|
|
|||
|
|
@ -943,8 +943,10 @@ class _QuickSuggestTestUtils {
|
|||
source = "rust",
|
||||
provider = "Yelp",
|
||||
isTopPick = false,
|
||||
// The default Yelp suggestedIndex is 0, unlike most other Suggest
|
||||
// suggestion types, which use -1.
|
||||
// The logic for the default Yelp `suggestedIndex` is complex and depends on
|
||||
// whether `UrlbarProviderSearchSuggestions` is active and whether search
|
||||
// suggestions are shown first. By default -- when the answer to both of
|
||||
// those questions is Yes -- Yelp's `suggestedIndex` is 0.
|
||||
suggestedIndex = 0,
|
||||
isSuggestedIndexRelativeToGroup = true,
|
||||
originalUrl = undefined,
|
||||
|
|
|
|||
|
|
@ -263,10 +263,16 @@ async function doDismissOneTest({
|
|||
"quicksuggest-dismissals-changed"
|
||||
);
|
||||
|
||||
let actualResult = await getActualResult({
|
||||
providers: [UrlbarProviderQuickSuggest.name],
|
||||
query: queriesForDismissals[0].query,
|
||||
expectedResult: result,
|
||||
});
|
||||
|
||||
triggerCommand({
|
||||
result,
|
||||
command,
|
||||
feature,
|
||||
result: actualResult,
|
||||
expectedCountsByCall: {
|
||||
removeResult: 1,
|
||||
},
|
||||
|
|
@ -280,7 +286,7 @@ async function doDismissOneTest({
|
|||
"canClearDismissedSuggestions should return true after triggering command"
|
||||
);
|
||||
Assert.ok(
|
||||
await QuickSuggest.isResultDismissed(result),
|
||||
await QuickSuggest.isResultDismissed(actualResult),
|
||||
"The result should be dismissed"
|
||||
);
|
||||
|
||||
|
|
@ -374,10 +380,16 @@ async function doDismissAllTest({ feature, result, command, pref, queries }) {
|
|||
"quicksuggest-dismissals-changed"
|
||||
);
|
||||
|
||||
let actualResult = await getActualResult({
|
||||
providers: [UrlbarProviderQuickSuggest.name],
|
||||
query: queries[0].query,
|
||||
expectedResult: result,
|
||||
});
|
||||
|
||||
triggerCommand({
|
||||
result,
|
||||
command,
|
||||
feature,
|
||||
result: actualResult,
|
||||
expectedCountsByCall: {
|
||||
removeResult: 1,
|
||||
},
|
||||
|
|
@ -442,6 +454,44 @@ async function doDismissAllTest({ feature, result, command, pref, queries }) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a search, asserts an actual result exists that matches the given result,
|
||||
* and returns it.
|
||||
*
|
||||
* @param {object} options
|
||||
* Options object.
|
||||
* @param {SuggestFeature} options.query
|
||||
* The search string.
|
||||
* @param {UrlbarResult} options.expectedResult
|
||||
* The expected result.
|
||||
* @param {string[]} [options.providers]
|
||||
* The providers to query.
|
||||
*/
|
||||
async function getActualResult({
|
||||
query,
|
||||
expectedResult,
|
||||
providers = [UrlbarProviderQuickSuggest.name],
|
||||
}) {
|
||||
info("Doing search to get an actual result: " + JSON.stringify(query));
|
||||
let context = createContext(query, {
|
||||
providers,
|
||||
isPrivate: false,
|
||||
});
|
||||
await check_results({
|
||||
context,
|
||||
matches: [expectedResult],
|
||||
});
|
||||
|
||||
let actualResult = context.results.find(
|
||||
r =>
|
||||
r.providerName == UrlbarProviderQuickSuggest.name &&
|
||||
r.payload.provider == expectedResult.payload.provider
|
||||
);
|
||||
Assert.ok(actualResult, "Search should have returned a matching result");
|
||||
|
||||
return actualResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does some "show less frequently" tests where the cap is set in remote
|
||||
* settings and Nimbus. See `doOneShowLessFrequentlyTest()`. This function
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue