зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound
This commit is contained in:
Коммит
9355025fd5
|
@ -97,9 +97,8 @@ nsCoreUtils::DispatchClickEvent(nsITreeBoxObject *aTreeBoxObj,
|
|||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIContent> tcXULElm(do_QueryInterface(tcElm));
|
||||
nsCOMPtr<nsIBoxObject> tcBoxObj =
|
||||
nsXULElement::FromNode(tcXULElm)->GetBoxObject(IgnoreErrors());
|
||||
nsXULElement::FromNode(tcElm)->GetBoxObject(IgnoreErrors());
|
||||
|
||||
int32_t tcX = 0;
|
||||
tcBoxObj->GetX(&tcX);
|
||||
|
|
|
@ -1131,6 +1131,7 @@ pref("services.sync.prefs.sync.addons.ignoreUserEnabledChanges", true);
|
|||
// could weaken the pref locally, install an add-on from an untrusted
|
||||
// source, and this would propagate automatically to other,
|
||||
// uncompromised Sync-connected devices.
|
||||
pref("services.sync.prefs.sync.browser.contentblocking.enabled", true);
|
||||
pref("services.sync.prefs.sync.browser.ctrlTab.recentlyUsedOrder", true);
|
||||
pref("services.sync.prefs.sync.browser.download.useDownloadDir", true);
|
||||
pref("services.sync.prefs.sync.browser.formfill.enable", true);
|
||||
|
|
|
@ -285,6 +285,7 @@ class TabTracker extends TabTrackerBase {
|
|||
windowTracker.addListener("TabClose", this);
|
||||
windowTracker.addListener("TabOpen", this);
|
||||
windowTracker.addListener("TabSelect", this);
|
||||
windowTracker.addListener("TabMultiSelect", this);
|
||||
windowTracker.addOpenListener(this._handleWindowOpen);
|
||||
windowTracker.addCloseListener(this._handleWindowClose);
|
||||
|
||||
|
@ -456,6 +457,16 @@ class TabTracker extends TabTrackerBase {
|
|||
this.emitActivated(nativeTab);
|
||||
});
|
||||
break;
|
||||
|
||||
case "TabMultiSelect":
|
||||
if (this.has("tabs-highlighted")) {
|
||||
// Because we are delaying calling emitCreated above, we also need to
|
||||
// delay sending this event because it shouldn't fire before onCreated.
|
||||
Promise.resolve().then(() => {
|
||||
this.emitHighlighted(event.target.ownerGlobal);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,6 +525,9 @@ class TabTracker extends TabTrackerBase {
|
|||
|
||||
// emitActivated to trigger tab.onActivated/tab.onHighlighted for a newly opened window.
|
||||
this.emitActivated(window.gBrowser.tabs[0]);
|
||||
if (this.has("tabs-highlighted")) {
|
||||
this.emitHighlighted(window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -548,6 +562,19 @@ class TabTracker extends TabTrackerBase {
|
|||
windowId: windowTracker.getId(nativeTab.ownerGlobal)});
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits a "tabs-highlighted" event for the given tab element.
|
||||
*
|
||||
* @param {ChromeWindow} window
|
||||
* The window in which the active tab or the set of multiselected tabs changed.
|
||||
* @private
|
||||
*/
|
||||
emitHighlighted(window) {
|
||||
let tabIds = window.gBrowser.selectedTabs.map(tab => this.getId(tab));
|
||||
let windowId = windowTracker.getId(window);
|
||||
this.emit("tabs-highlighted", {tabIds, windowId});
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits a "tab-attached" event for the given tab element.
|
||||
*
|
||||
|
|
|
@ -129,6 +129,10 @@ var gMenuBuilder = {
|
|||
// Display the extension icon on the root element.
|
||||
if (root.extension.manifest.icons) {
|
||||
this.setMenuItemIcon(rootElement, root.extension, contextData, root.extension.manifest.icons);
|
||||
} else {
|
||||
// Undo changes from setMenuItemIcon:
|
||||
rootElement.removeAttribute("class");
|
||||
rootElement.removeAttribute("image");
|
||||
}
|
||||
return rootElement;
|
||||
},
|
||||
|
@ -349,14 +353,13 @@ var gMenuBuilder = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!gShownMenuItems.has(extension)) {
|
||||
// The onShown event was not fired for the extension, so the extension
|
||||
// does not know that a menu is being shown, and therefore they should
|
||||
// not care whether the extension menu is updated.
|
||||
return;
|
||||
}
|
||||
|
||||
if (contextData.onBrowserAction || contextData.onPageAction) {
|
||||
if (contextData.extension.id !== extension.id) {
|
||||
// The extension that just called refresh() is not the owner of the
|
||||
// action whose context menu is showing, so it can't have any items in
|
||||
// the menu anyway and nothing will change.
|
||||
return;
|
||||
}
|
||||
// The action menu can only have items from one extension, so remove all
|
||||
// items (including the separator) and rebuild the action menu (if any).
|
||||
for (let item of this.itemsToCleanUp) {
|
||||
|
|
|
@ -411,23 +411,17 @@ this.tabs = class extends ExtensionAPI {
|
|||
},
|
||||
}).api(),
|
||||
|
||||
/**
|
||||
* Since multiple tabs currently can't be highlighted, onHighlighted
|
||||
* essentially acts an alias for self.tabs.onActivated but returns
|
||||
* the tabId in an array to match the API.
|
||||
* @see https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/Tabs/onHighlighted
|
||||
*/
|
||||
onHighlighted: new EventManager({
|
||||
context,
|
||||
name: "tabs.onHighlighted",
|
||||
register: fire => {
|
||||
let listener = (eventName, event) => {
|
||||
fire.async({tabIds: [event.tabId], windowId: event.windowId});
|
||||
fire.async(event);
|
||||
};
|
||||
|
||||
tabTracker.on("tab-activated", listener);
|
||||
tabTracker.on("tabs-highlighted", listener);
|
||||
return () => {
|
||||
tabTracker.off("tab-activated", listener);
|
||||
tabTracker.off("tabs-highlighted", listener);
|
||||
};
|
||||
},
|
||||
}).api(),
|
||||
|
|
|
@ -178,6 +178,7 @@ skip-if = !e10s
|
|||
[browser_ext_tabs_discarded.js]
|
||||
[browser_ext_tabs_duplicate.js]
|
||||
[browser_ext_tabs_events.js]
|
||||
[browser_ext_tabs_events_order.js]
|
||||
[browser_ext_tabs_executeScript.js]
|
||||
skip-if = (verify && !debug && (os == 'mac'))
|
||||
[browser_ext_tabs_executeScript_good.js]
|
||||
|
|
|
@ -174,3 +174,74 @@ add_task(async function test_child_icon() {
|
|||
await extension.unload();
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(async function test_manifest_without_icons() {
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
|
||||
|
||||
let redIconData = "iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAIAAADZrBkAAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QYGEgw1XkM0ygAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAAYSURBVCjPY/zPQA5gYhjVNqptVNsg1wYAItkBI/GNR3YAAAAASUVORK5CYII=";
|
||||
const IMAGE_ARRAYBUFFER_RED = imageBufferFromDataURI(redIconData);
|
||||
|
||||
let greenIconData = "iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAIAAADZrBkAAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QYGEg0rvVc46AAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAAaSURBVCjPY+Q8xkAGYGJgGNU2qm1U2+DWBgBolADz1beTnwAAAABJRU5ErkJggg==";
|
||||
const IMAGE_ARRAYBUFFER_GREEN = imageBufferFromDataURI(greenIconData);
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"name": "contextMenus icons",
|
||||
"permissions": ["contextMenus"],
|
||||
},
|
||||
files: {
|
||||
"red.png": IMAGE_ARRAYBUFFER_RED,
|
||||
"green.png": IMAGE_ARRAYBUFFER_GREEN,
|
||||
},
|
||||
|
||||
background() {
|
||||
browser.contextMenus.create({
|
||||
title: "first item",
|
||||
icons: {
|
||||
18: "red.png",
|
||||
},
|
||||
onclick() {
|
||||
browser.contextMenus.create({
|
||||
title: "second item",
|
||||
icons: {
|
||||
18: "green.png",
|
||||
},
|
||||
}, () => {
|
||||
browser.test.sendMessage("added-second-item");
|
||||
});
|
||||
},
|
||||
}, () => {
|
||||
browser.test.sendMessage("contextmenus-icons");
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
await extension.awaitMessage("contextmenus-icons");
|
||||
|
||||
let menu = await openContextMenu();
|
||||
let items = menu.getElementsByAttribute("label", "first item");
|
||||
is(items.length, 1, "Found first item");
|
||||
// manifest.json does not declare icons, so the root menu item shouldn't have an icon either.
|
||||
is(items[0].getAttribute("image"), "", "Root menu must not have an icon");
|
||||
|
||||
await closeExtensionContextMenu(items[0]);
|
||||
await extension.awaitMessage("added-second-item");
|
||||
|
||||
menu = await openExtensionContextMenu();
|
||||
items = document.querySelectorAll("#contentAreaContextMenu [ext-type='top-level-menu']");
|
||||
is(items.length, 1, "Auto-generated root item exists");
|
||||
is(items[0].getAttribute("image"), "", "Auto-generated menu root must not have an icon");
|
||||
|
||||
items = menu.getElementsByAttribute("label", "first item");
|
||||
is(items.length, 1, "First child item should exist");
|
||||
is(items[0].getAttribute("image").split("/").pop(), "red.png", "First item should have an icon");
|
||||
|
||||
items = menu.getElementsByAttribute("label", "second item");
|
||||
is(items.length, 1, "Secobnd child item should exist");
|
||||
is(items[0].getAttribute("image").split("/").pop(), "green.png", "Second item should have an icon");
|
||||
|
||||
await closeExtensionContextMenu();
|
||||
await extension.unload();
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
|
|
@ -13,12 +13,17 @@ const PAGE = "http://mochi.test:8888/browser/browser/components/extensions/test/
|
|||
// to the menu item ID from the browser.menus API (if existent, null otherwise).
|
||||
function loadExtensionWithMenusApi() {
|
||||
async function background() {
|
||||
browser.menus.onShown.addListener(() => {
|
||||
function shownHandler() {
|
||||
browser.test.sendMessage("onShown fired");
|
||||
});
|
||||
}
|
||||
|
||||
browser.menus.onShown.addListener(shownHandler);
|
||||
browser.test.onMessage.addListener((method, ...params) => {
|
||||
let result;
|
||||
if (method === "create") {
|
||||
if (method === "* remove onShown listener") {
|
||||
browser.menus.onShown.removeListener(shownHandler);
|
||||
result = Promise.resolve();
|
||||
} else if (method === "create") {
|
||||
result = new Promise(resolve => {
|
||||
browser.menus.create(params[0], resolve);
|
||||
});
|
||||
|
@ -45,6 +50,10 @@ function loadExtensionWithMenusApi() {
|
|||
return extension.awaitMessage(`${method}-result`);
|
||||
};
|
||||
|
||||
extension.removeOnShownListener = async function() {
|
||||
extension.callMenuApi("* remove onShown listener");
|
||||
};
|
||||
|
||||
extension.getXULElementByMenuId = id => {
|
||||
// Same implementation as elementId getter in ext-menus.js
|
||||
if (typeof id != "number") {
|
||||
|
@ -157,8 +166,66 @@ async function testRefreshMenusWhileVisible({contexts, doOpenMenu, doCloseMenu,
|
|||
await extension.unload();
|
||||
}
|
||||
|
||||
// Check that one extension calling refresh() doesn't interfere with others.
|
||||
// When expectOtherItems == false, the other extension's menu items should not
|
||||
// show at all (e.g. for browserAction).
|
||||
async function testRefreshOther({contexts, doOpenMenu, doCloseMenu,
|
||||
expectOtherItems}) {
|
||||
let extension = loadExtensionWithMenusApi();
|
||||
let other_extension = loadExtensionWithMenusApi();
|
||||
await extension.startup();
|
||||
await other_extension.startup();
|
||||
|
||||
await extension.callMenuApi("create", {
|
||||
id: "action_item",
|
||||
title: "visible menu item",
|
||||
contexts: contexts,
|
||||
});
|
||||
|
||||
await other_extension.callMenuApi("create", {
|
||||
id: "action_item",
|
||||
title: "other menu item",
|
||||
contexts: contexts,
|
||||
});
|
||||
|
||||
await doOpenMenu(extension);
|
||||
await extension.awaitMessage("onShown fired");
|
||||
if (expectOtherItems) {
|
||||
await other_extension.awaitMessage("onShown fired");
|
||||
}
|
||||
|
||||
let elem = extension.getXULElementByMenuId("action_item");
|
||||
is(elem.getAttribute("label"), "visible menu item", "extension menu shown");
|
||||
elem = other_extension.getXULElementByMenuId("action_item");
|
||||
if (expectOtherItems) {
|
||||
is(elem.getAttribute("label"), "other menu item",
|
||||
"other extension's menu is also shown");
|
||||
} else {
|
||||
is(elem, null, "other extension's menu should be hidden");
|
||||
}
|
||||
|
||||
await extension.callMenuApi("update", "action_item", {title: "changed"});
|
||||
await other_extension.callMenuApi("update", "action_item", {title: "foo"});
|
||||
await other_extension.callMenuApi("refresh");
|
||||
|
||||
// refreshing the menu of an unrelated extension should not affect the menu
|
||||
// of another extension.
|
||||
elem = extension.getXULElementByMenuId("action_item");
|
||||
is(elem.getAttribute("label"), "visible menu item", "extension menu shown");
|
||||
elem = other_extension.getXULElementByMenuId("action_item");
|
||||
if (expectOtherItems) {
|
||||
is(elem.getAttribute("label"), "foo", "other extension's item is updated");
|
||||
} else {
|
||||
is(elem, null, "other extension's menu should still be hidden");
|
||||
}
|
||||
|
||||
await doCloseMenu();
|
||||
await extension.unload();
|
||||
await other_extension.unload();
|
||||
}
|
||||
|
||||
add_task(async function refresh_menus_with_browser_action() {
|
||||
await testRefreshMenusWhileVisible({
|
||||
const args = {
|
||||
contexts: ["browser_action"],
|
||||
async doOpenMenu(extension) {
|
||||
await openActionContextMenu(extension, "browser");
|
||||
|
@ -166,12 +233,15 @@ add_task(async function refresh_menus_with_browser_action() {
|
|||
async doCloseMenu() {
|
||||
await closeActionContextMenu();
|
||||
},
|
||||
});
|
||||
};
|
||||
await testRefreshMenusWhileVisible(args);
|
||||
args.expectOtherItems = false;
|
||||
await testRefreshOther(args);
|
||||
});
|
||||
|
||||
add_task(async function refresh_menus_with_tab() {
|
||||
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
|
||||
await testRefreshMenusWhileVisible({
|
||||
const args = {
|
||||
contexts: ["tab"],
|
||||
async doOpenMenu() {
|
||||
await openTabContextMenu();
|
||||
|
@ -179,12 +249,15 @@ add_task(async function refresh_menus_with_tab() {
|
|||
async doCloseMenu() {
|
||||
await closeTabContextMenu();
|
||||
},
|
||||
});
|
||||
};
|
||||
await testRefreshMenusWhileVisible(args);
|
||||
args.expectOtherItems = true;
|
||||
await testRefreshOther(args);
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(async function refresh_menus_with_tools_menu() {
|
||||
await testRefreshMenusWhileVisible({
|
||||
const args = {
|
||||
contexts: ["tools_menu"],
|
||||
async doOpenMenu() {
|
||||
await openToolsMenu();
|
||||
|
@ -192,12 +265,15 @@ add_task(async function refresh_menus_with_tools_menu() {
|
|||
async doCloseMenu() {
|
||||
await closeToolsMenu();
|
||||
},
|
||||
});
|
||||
};
|
||||
await testRefreshMenusWhileVisible(args);
|
||||
args.expectOtherItems = true;
|
||||
await testRefreshOther(args);
|
||||
});
|
||||
|
||||
add_task(async function refresh_menus_with_page() {
|
||||
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
|
||||
await testRefreshMenusWhileVisible({
|
||||
const args = {
|
||||
contexts: ["page"],
|
||||
async doOpenMenu() {
|
||||
await openContextMenu("body");
|
||||
|
@ -205,7 +281,10 @@ add_task(async function refresh_menus_with_page() {
|
|||
async doCloseMenu() {
|
||||
await closeExtensionContextMenu();
|
||||
},
|
||||
});
|
||||
};
|
||||
await testRefreshMenusWhileVisible(args);
|
||||
args.expectOtherItems = true;
|
||||
await testRefreshOther(args);
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
|
@ -246,46 +325,32 @@ add_task(async function refresh_without_menus_at_onShown() {
|
|||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(async function refresh_menus_with_browser_action() {
|
||||
add_task(async function refresh_without_onShown() {
|
||||
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE);
|
||||
let extension = loadExtensionWithMenusApi();
|
||||
let other_extension = loadExtensionWithMenusApi();
|
||||
await extension.startup();
|
||||
await other_extension.startup();
|
||||
await extension.removeOnShownListener();
|
||||
|
||||
const doOpenMenu = () => openContextMenu("body");
|
||||
const doCloseMenu = () => closeExtensionContextMenu();
|
||||
|
||||
await doOpenMenu();
|
||||
await extension.callMenuApi("create", {
|
||||
id: "action_item",
|
||||
title: "visible menu item",
|
||||
contexts: ["browser_action"],
|
||||
id: "too late",
|
||||
title: "created after shown",
|
||||
});
|
||||
|
||||
await other_extension.callMenuApi("create", {
|
||||
id: "action_item",
|
||||
title: "other menu item",
|
||||
contexts: ["browser_action"],
|
||||
});
|
||||
is(extension.getXULElementByMenuId("too late"), null,
|
||||
"item created after shown is not visible before refresh");
|
||||
|
||||
await openActionContextMenu(extension, "browser");
|
||||
await extension.awaitMessage("onShown fired");
|
||||
await extension.callMenuApi("refresh");
|
||||
let elem = extension.getXULElementByMenuId("too late");
|
||||
is(elem.getAttribute("label"), "created after shown",
|
||||
"refresh updates the menu even without onShown");
|
||||
|
||||
let elem = extension.getXULElementByMenuId("action_item");
|
||||
is(elem.getAttribute("label"), "visible menu item", "extension menu shown");
|
||||
elem = other_extension.getXULElementByMenuId("action_item");
|
||||
is(elem, null, "other extension's menu should be hidden");
|
||||
|
||||
await extension.callMenuApi("update", "action_item", {title: "changed"});
|
||||
await other_extension.callMenuApi("update", "action_item", {title: "foo"});
|
||||
await other_extension.callMenuApi("refresh");
|
||||
|
||||
// refreshing the menu of an unrelated extension should not affect the menu
|
||||
// of another extension.
|
||||
elem = extension.getXULElementByMenuId("action_item");
|
||||
is(elem.getAttribute("label"), "visible menu item", "extension menu shown");
|
||||
elem = other_extension.getXULElementByMenuId("action_item");
|
||||
is(elem, null, "other extension's menu should be hidden");
|
||||
|
||||
await closeActionContextMenu();
|
||||
await doCloseMenu();
|
||||
await extension.unload();
|
||||
await other_extension.unload();
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(async function refresh_menus_during_navigation() {
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
/* eslint-disable mozilla/no-arbitrary-setTimeout */
|
||||
"use strict";
|
||||
|
||||
add_task(async function testTabEvents() {
|
||||
async function background() {
|
||||
/** The list of active tab ID's */
|
||||
let tabIds = [];
|
||||
|
||||
/**
|
||||
* Stores the events that fire for each tab.
|
||||
*
|
||||
* events {
|
||||
* tabId1: [event1, event2, ...],
|
||||
* tabId2: [event1, event2, ...],
|
||||
* }
|
||||
*/
|
||||
let events = {};
|
||||
|
||||
browser.tabs.onActivated.addListener((info) => {
|
||||
if (info.tabId in events) {
|
||||
events[info.tabId].push("onActivated");
|
||||
} else {
|
||||
events[info.tabId] = ["onActivated"];
|
||||
}
|
||||
});
|
||||
|
||||
browser.tabs.onCreated.addListener((info) => {
|
||||
if (info.id in events) {
|
||||
events[info.id].push("onCreated");
|
||||
} else {
|
||||
events[info.id] = ["onCreated"];
|
||||
}
|
||||
});
|
||||
|
||||
browser.tabs.onHighlighted.addListener((info) => {
|
||||
if (info.tabIds[0] in events) {
|
||||
events[info.tabIds[0]].push("onHighlighted");
|
||||
} else {
|
||||
events[info.tabIds[0]] = ["onHighlighted"];
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Asserts that the expected events are fired for the tab with id = tabId.
|
||||
* The events associated to the specified tab are removed after this check is made.
|
||||
*
|
||||
* @param {number} tabId
|
||||
* @param {Array<string>} expectedEvents
|
||||
*/
|
||||
async function expectEvents(tabId, expectedEvents) {
|
||||
browser.test.log(`Expecting events: ${expectedEvents.join(", ")}`);
|
||||
|
||||
// Wait up to 5000 ms for the expected number of events.
|
||||
for (let i = 0; i < 50 && (!events[tabId] || events[tabId].length < expectedEvents.length); i++) {
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
}
|
||||
|
||||
browser.test.assertEq(expectedEvents.length, events[tabId].length,
|
||||
`Got expected number of events for ${tabId}`);
|
||||
|
||||
for (let [i, name] of expectedEvents.entries()) {
|
||||
browser.test.assertEq(name, i in events[tabId] && events[tabId][i],
|
||||
`Got expected ${name} event`);
|
||||
}
|
||||
delete events[tabId];
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new tab and asserts that the correct events are fired.
|
||||
*
|
||||
* @param {number} windowId
|
||||
*/
|
||||
async function openTab(windowId) {
|
||||
browser.test.assertEq(0, Object.keys(events).length,
|
||||
"No events remaining before testing openTab.");
|
||||
|
||||
let tab = await browser.tabs.create({windowId});
|
||||
|
||||
tabIds.push(tab.id);
|
||||
browser.test.log(`Opened tab ${tab.id}`);
|
||||
|
||||
await expectEvents(tab.id, [
|
||||
"onCreated",
|
||||
"onActivated",
|
||||
"onHighlighted",
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new window and asserts that the correct events are fired.
|
||||
*
|
||||
* @param {Array} urls A list of urls for which to open tabs in the new window.
|
||||
*/
|
||||
async function openWindow(urls) {
|
||||
browser.test.assertEq(0, Object.keys(events).length,
|
||||
"No events remaining before testing openWindow.");
|
||||
|
||||
let window = await browser.windows.create({url: urls});
|
||||
browser.test.log(`Opened new window ${window.id}`);
|
||||
|
||||
for (let [i] of urls.entries()) {
|
||||
let tab = window.tabs[i];
|
||||
tabIds.push(tab.id);
|
||||
|
||||
let expectedEvents = [
|
||||
"onCreated",
|
||||
"onActivated",
|
||||
"onHighlighted",
|
||||
];
|
||||
if (i !== 0) {
|
||||
expectedEvents.splice(1);
|
||||
}
|
||||
await expectEvents(window.tabs[i].id, expectedEvents);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights an existing tab and asserts that the correct events are fired.
|
||||
*
|
||||
* @param {number} tabId
|
||||
*/
|
||||
async function highlightTab(tabId) {
|
||||
browser.test.assertEq(0, Object.keys(events).length,
|
||||
"No events remaining before testing highlightTab.");
|
||||
|
||||
browser.test.log(`Highlighting tab ${tabId}`);
|
||||
let tab = await browser.tabs.update(tabId, {active: true});
|
||||
|
||||
browser.test.assertEq(tab.id, tabId, `Tab ${tab.id} highlighted`);
|
||||
|
||||
await expectEvents(tab.id, [
|
||||
"onActivated",
|
||||
"onHighlighted",
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The main entry point to the tests.
|
||||
*/
|
||||
let tabs = await browser.tabs.query({active: true, currentWindow: true});
|
||||
|
||||
let activeWindow = tabs[0].windowId;
|
||||
await Promise.all([
|
||||
openTab(activeWindow),
|
||||
openTab(activeWindow),
|
||||
openTab(activeWindow),
|
||||
]);
|
||||
|
||||
await Promise.all([
|
||||
highlightTab(tabIds[0]),
|
||||
highlightTab(tabIds[1]),
|
||||
highlightTab(tabIds[2]),
|
||||
]);
|
||||
|
||||
await Promise.all([
|
||||
openWindow(["http://example.com"]),
|
||||
openWindow(["http://example.com", "http://example.org"]),
|
||||
openWindow(["http://example.com", "http://example.org", "http://example.net"]),
|
||||
]);
|
||||
|
||||
browser.test.assertEq(0, Object.keys(events).length,
|
||||
"No events remaining after tests.");
|
||||
|
||||
await Promise.all(tabIds.map(id => browser.tabs.remove(id)));
|
||||
|
||||
browser.test.notifyPass("tabs.highlight");
|
||||
}
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"permissions": ["tabs"],
|
||||
},
|
||||
|
||||
background,
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
await extension.awaitFinish("tabs.highlight");
|
||||
await extension.unload();
|
||||
});
|
|
@ -26,7 +26,7 @@ add_task(async function test_highlighted() {
|
|||
let highlightedTabs = await browser.tabs.query({currentWindow: true, highlighted: true});
|
||||
browser.test.assertEq(
|
||||
highlightedIndices.concat(activeIndex).sort((a, b) => a - b).join(),
|
||||
highlightedTabs.map(tab => tab.index).sort((a, b) => a - b).join(),
|
||||
highlightedTabs.map(tab => tab.index).join(),
|
||||
"Check tabs.query with highlighted:true provides the expected tabs");
|
||||
}
|
||||
|
||||
|
|
|
@ -3,180 +3,120 @@
|
|||
/* eslint-disable mozilla/no-arbitrary-setTimeout */
|
||||
"use strict";
|
||||
|
||||
add_task(async function testTabEvents() {
|
||||
async function background() {
|
||||
/** The list of active tab ID's */
|
||||
let tabIds = [];
|
||||
|
||||
/**
|
||||
* Stores the events that fire for each tab.
|
||||
*
|
||||
* events {
|
||||
* tabId1: [event1, event2, ...],
|
||||
* tabId2: [event1, event2, ...],
|
||||
* }
|
||||
*/
|
||||
let events = {};
|
||||
|
||||
browser.tabs.onActivated.addListener((info) => {
|
||||
if (info.tabId in events) {
|
||||
events[info.tabId].push("onActivated");
|
||||
} else {
|
||||
events[info.tabId] = ["onActivated"];
|
||||
}
|
||||
});
|
||||
|
||||
browser.tabs.onCreated.addListener((info) => {
|
||||
if (info.id in events) {
|
||||
events[info.id].push("onCreated");
|
||||
} else {
|
||||
events[info.id] = ["onCreated"];
|
||||
}
|
||||
});
|
||||
|
||||
browser.tabs.onHighlighted.addListener((info) => {
|
||||
if (info.tabIds[0] in events) {
|
||||
events[info.tabIds[0]].push("onHighlighted");
|
||||
} else {
|
||||
events[info.tabIds[0]] = ["onHighlighted"];
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Asserts that the expected events are fired for the tab with id = tabId.
|
||||
* The events associated to the specified tab are removed after this check is made.
|
||||
*
|
||||
* @param {number} tabId
|
||||
* @param {Array<string>} expectedEvents
|
||||
*/
|
||||
async function expectEvents(tabId, expectedEvents) {
|
||||
browser.test.log(`Expecting events: ${expectedEvents.join(", ")}`);
|
||||
|
||||
// Wait up to 5000 ms for the expected number of events.
|
||||
for (let i = 0; i < 50 && (!events[tabId] || events[tabId].length < expectedEvents.length); i++) {
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
}
|
||||
|
||||
browser.test.assertEq(expectedEvents.length, events[tabId].length,
|
||||
`Got expected number of events for ${tabId}`);
|
||||
|
||||
for (let [i, name] of expectedEvents.entries()) {
|
||||
browser.test.assertEq(name, i in events[tabId] && events[tabId][i],
|
||||
`Got expected ${name} event`);
|
||||
}
|
||||
delete events[tabId];
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new tab and asserts that the correct events are fired.
|
||||
*
|
||||
* @param {number} windowId
|
||||
*/
|
||||
async function openTab(windowId) {
|
||||
browser.test.assertEq(0, Object.keys(events).length,
|
||||
"No events remaining before testing openTab.");
|
||||
|
||||
let tab = await browser.tabs.create({windowId});
|
||||
|
||||
tabIds.push(tab.id);
|
||||
browser.test.log(`Opened tab ${tab.id}`);
|
||||
|
||||
await expectEvents(tab.id, [
|
||||
"onCreated",
|
||||
"onActivated",
|
||||
"onHighlighted",
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new window and asserts that the correct events are fired.
|
||||
*
|
||||
* @param {Array} urls A list of urls for which to open tabs in the new window.
|
||||
*/
|
||||
async function openWindow(urls) {
|
||||
browser.test.assertEq(0, Object.keys(events).length,
|
||||
"No events remaining before testing openWindow.");
|
||||
|
||||
let window = await browser.windows.create({url: urls});
|
||||
browser.test.log(`Opened new window ${window.id}`);
|
||||
|
||||
for (let [i] of urls.entries()) {
|
||||
let tab = window.tabs[i];
|
||||
tabIds.push(tab.id);
|
||||
|
||||
let expectedEvents = [
|
||||
"onCreated",
|
||||
"onActivated",
|
||||
"onHighlighted",
|
||||
];
|
||||
if (i !== 0) {
|
||||
expectedEvents.splice(1);
|
||||
}
|
||||
await expectEvents(window.tabs[i].id, expectedEvents);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights an existing tab and asserts that the correct events are fired.
|
||||
*
|
||||
* @param {number} tabId
|
||||
*/
|
||||
async function highlightTab(tabId) {
|
||||
browser.test.assertEq(0, Object.keys(events).length,
|
||||
"No events remaining before testing highlightTab.");
|
||||
|
||||
browser.test.log(`Highlighting tab ${tabId}`);
|
||||
let tab = await browser.tabs.update(tabId, {active: true});
|
||||
|
||||
browser.test.assertEq(tab.id, tabId, `Tab ${tab.id} highlighted`);
|
||||
|
||||
await expectEvents(tab.id, [
|
||||
"onActivated",
|
||||
"onHighlighted",
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The main entry point to the tests.
|
||||
*/
|
||||
let tabs = await browser.tabs.query({active: true, currentWindow: true});
|
||||
|
||||
let activeWindow = tabs[0].windowId;
|
||||
await Promise.all([
|
||||
openTab(activeWindow),
|
||||
openTab(activeWindow),
|
||||
openTab(activeWindow),
|
||||
]);
|
||||
|
||||
await Promise.all([
|
||||
highlightTab(tabIds[0]),
|
||||
highlightTab(tabIds[1]),
|
||||
highlightTab(tabIds[2]),
|
||||
]);
|
||||
|
||||
await Promise.all([
|
||||
openWindow(["http://example.com"]),
|
||||
openWindow(["http://example.com", "http://example.org"]),
|
||||
openWindow(["http://example.com", "http://example.org", "http://example.net"]),
|
||||
]);
|
||||
|
||||
browser.test.assertEq(0, Object.keys(events).length,
|
||||
"No events remaining after tests.");
|
||||
|
||||
await Promise.all(tabIds.map(id => browser.tabs.remove(id)));
|
||||
|
||||
browser.test.notifyPass("tabs.highlight");
|
||||
}
|
||||
add_task(async function test_onHighlighted() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["browser.tabs.multiselect", true],
|
||||
],
|
||||
});
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"permissions": ["tabs"],
|
||||
},
|
||||
|
||||
background,
|
||||
background: async function() {
|
||||
async function expectHighlighted(fn, action) {
|
||||
let resolve;
|
||||
let promise = new Promise((r) => {
|
||||
resolve = r;
|
||||
});
|
||||
let expected;
|
||||
let events = [];
|
||||
let listener = (highlightInfo) => {
|
||||
events.push(highlightInfo);
|
||||
if (expected && expected.length >= events.length) {
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
browser.tabs.onHighlighted.addListener(listener);
|
||||
expected = await fn() || [];
|
||||
if (events.length < expected.length) {
|
||||
await promise;
|
||||
}
|
||||
let unexpected = events.splice(expected.length);
|
||||
browser.test.assertEq(
|
||||
JSON.stringify(expected), JSON.stringify(events),
|
||||
`Should get ${expected.length} expected onHighlighted events when ${action}`);
|
||||
if (unexpected.length) {
|
||||
browser.test.fail(
|
||||
`${unexpected.length} unexpected onHighlighted events when ${action}: ` +
|
||||
JSON.stringify(unexpected));
|
||||
}
|
||||
browser.tabs.onHighlighted.removeListener(listener);
|
||||
}
|
||||
|
||||
let [{id, windowId}] = await browser.tabs.query({active: true, currentWindow: true});
|
||||
let windows = [windowId];
|
||||
let tabs = [id];
|
||||
|
||||
await expectHighlighted(async () => {
|
||||
let tab = await browser.tabs.create({active: true, url: "about:blank?1"});
|
||||
tabs.push(tab.id);
|
||||
return [{tabIds: [tabs[1]], windowId: windows[0]}];
|
||||
}, "creating a new active tab");
|
||||
|
||||
await expectHighlighted(async () => {
|
||||
await browser.tabs.update(tabs[0], {active: true});
|
||||
return [{tabIds: [tabs[0]], windowId: windows[0]}];
|
||||
}, "selecting former tab");
|
||||
|
||||
await expectHighlighted(async () => {
|
||||
await browser.tabs.highlight({tabs: [0, 1]});
|
||||
return [{tabIds: [tabs[0], tabs[1]], windowId: windows[0]}];
|
||||
}, "highlighting both tabs");
|
||||
|
||||
await expectHighlighted(async () => {
|
||||
await browser.tabs.highlight({tabs: [1, 0]});
|
||||
return [{tabIds: [tabs[0], tabs[1]], windowId: windows[0]}];
|
||||
}, "highlighting same tabs but changing selected one");
|
||||
|
||||
await expectHighlighted(async () => {
|
||||
let tab = await browser.tabs.create({active: false, url: "about:blank?2"});
|
||||
tabs.push(tab.id);
|
||||
}, "create a new inactive tab");
|
||||
|
||||
await expectHighlighted(async () => {
|
||||
await browser.tabs.highlight({tabs: [2, 0, 1]});
|
||||
return [{tabIds: [tabs[0], tabs[1], tabs[2]], windowId: windows[0]}];
|
||||
}, "highlighting all tabs");
|
||||
|
||||
await expectHighlighted(async () => {
|
||||
await browser.tabs.move(tabs[1], {index: 0});
|
||||
}, "reordering tabs");
|
||||
|
||||
await expectHighlighted(async () => {
|
||||
await browser.tabs.highlight({tabs: [0]});
|
||||
return [{tabIds: [tabs[1]], windowId: windows[0]}];
|
||||
}, "highlighting moved tab");
|
||||
|
||||
await expectHighlighted(async () => {
|
||||
await browser.tabs.highlight({tabs: [0]});
|
||||
}, "highlighting again");
|
||||
|
||||
await expectHighlighted(async () => {
|
||||
await browser.tabs.highlight({tabs: [2, 1, 0]});
|
||||
return [{tabIds: [tabs[1], tabs[0], tabs[2]], windowId: windows[0]}];
|
||||
}, "highlighting all tabs");
|
||||
|
||||
await expectHighlighted(async () => {
|
||||
await browser.tabs.highlight({tabs: [2, 0, 1]});
|
||||
}, "highlighting same tabs with different order");
|
||||
|
||||
await expectHighlighted(async () => {
|
||||
let window = await browser.windows.create({tabId: tabs[2]});
|
||||
windows.push(window.id);
|
||||
// Bug 1481185: on Chrome it's [tabs[1], tabs[0]] instead of [tabs[0]]
|
||||
return [{tabIds: [tabs[0]], windowId: windows[0]},
|
||||
{tabIds: [tabs[2]], windowId: windows[1]}];
|
||||
}, "moving selected tab into a new window");
|
||||
|
||||
await browser.tabs.remove(tabs.slice(1));
|
||||
browser.test.notifyPass("test-finished");
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
await extension.awaitFinish("tabs.highlight");
|
||||
await extension.awaitFinish("test-finished");
|
||||
await extension.unload();
|
||||
});
|
||||
|
|
|
@ -161,7 +161,7 @@ AboutNewTabService.prototype = {
|
|||
}
|
||||
|
||||
for (let script of scripts) {
|
||||
Services.scriptloader.loadSubScript(script, win); // Synchronous call
|
||||
Services.scriptloader.loadSubScript(script, win, "UTF-8"); // Synchronous call
|
||||
}
|
||||
};
|
||||
subject.addEventListener("DOMContentLoaded", onLoaded, {once: true});
|
||||
|
|
|
@ -381,6 +381,10 @@ MessageManagerTunnel.prototype = {
|
|||
INNER_TO_OUTER_MESSAGES: [
|
||||
// Messages sent to browser.js
|
||||
"Browser:LoadURI",
|
||||
"Link:SetIcon",
|
||||
"Link:SetFailedIcon",
|
||||
"Link:AddFeed",
|
||||
"Link:AddSearch",
|
||||
// Messages sent to RemoteWebProgress.jsm
|
||||
"Content:LoadURIResult",
|
||||
"Content:LocationChange",
|
||||
|
|
|
@ -8,6 +8,8 @@ support-files =
|
|||
contextual_identity.html
|
||||
devices.json
|
||||
doc_page_state.html
|
||||
favicon.html
|
||||
favicon.ico
|
||||
geolocation.html
|
||||
head.js
|
||||
touch.html
|
||||
|
@ -33,6 +35,7 @@ support-files =
|
|||
[browser_exit_button.js]
|
||||
[browser_ext_messaging.js]
|
||||
tags = devtools webextensions
|
||||
[browser_favicon.js]
|
||||
[browser_frame_script_active.js]
|
||||
[browser_hide_container.js]
|
||||
[browser_menu_item_01.js]
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that favicons make it to the parent process.
|
||||
|
||||
const TEST_URL = `${URL_ROOT}favicon.html`;
|
||||
|
||||
function waitForLinkAvailable(browser) {
|
||||
let resolve, reject;
|
||||
|
||||
const listener = {
|
||||
onLinkIconAvailable(b, dataURI, iconURI) {
|
||||
// Ignore icons for other browsers or empty icons.
|
||||
if (browser !== b || !iconURI) {
|
||||
return;
|
||||
}
|
||||
|
||||
gBrowser.removeTabsProgressListener(listener);
|
||||
resolve(iconURI);
|
||||
}
|
||||
};
|
||||
|
||||
const promise = new Promise((res, rej) => {
|
||||
resolve = res;
|
||||
reject = rej;
|
||||
|
||||
gBrowser.addTabsProgressListener(listener);
|
||||
});
|
||||
|
||||
promise.cancel = () => {
|
||||
gBrowser.removeTabsProgressListener(listener);
|
||||
|
||||
reject();
|
||||
};
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
add_task(async function() {
|
||||
const tab = await addTab("about:blank");
|
||||
const browser = tab.linkedBrowser;
|
||||
|
||||
await openRDM(tab);
|
||||
|
||||
const promise = waitForLinkAvailable(browser);
|
||||
await load(browser, TEST_URL);
|
||||
const iconURI = await promise;
|
||||
is(iconURI, `${URL_ROOT}favicon.ico`, "Should have loaded the right icon.");
|
||||
const icon = tab.getAttribute("image");
|
||||
ok(icon.startsWith("data:"), "Should see the data icon on the tab.");
|
||||
|
||||
await closeRDM(tab);
|
||||
|
||||
await removeTab(tab);
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Favicon Test</title>
|
||||
<link rel="icon" href="favicon.ico">
|
||||
</head>
|
||||
<body/>
|
||||
</html>
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.4 KiB |
|
@ -379,7 +379,7 @@ AudioChannelService::GetMediaConfig(nsPIDOMWindowOuter* aWindow) const
|
|||
break;
|
||||
}
|
||||
|
||||
window = do_QueryInterface(win);
|
||||
window = win;
|
||||
|
||||
// If there is no parent, or we are the toplevel we don't continue.
|
||||
} while (window && window != aWindow);
|
||||
|
|
|
@ -748,12 +748,12 @@ DragDataProducer::Produce(DataTransfer* aDataTransfer,
|
|||
linkNode = parentLink;
|
||||
nodeToSerialize = linkNode;
|
||||
} else {
|
||||
nodeToSerialize = do_QueryInterface(draggedNode);
|
||||
nodeToSerialize = draggedNode;
|
||||
}
|
||||
dragNode = nodeToSerialize;
|
||||
} else if (draggedNode && draggedNode->IsHTMLElement(nsGkAtoms::a)) {
|
||||
// set linkNode. The code below will handle this
|
||||
linkNode = do_QueryInterface(draggedNode); // XXX test this
|
||||
linkNode = draggedNode; // XXX test this
|
||||
GetNodeString(draggedNode, mTitleString);
|
||||
} else if (parentLink) {
|
||||
// parentLink will always be null if there's selected content
|
||||
|
|
|
@ -1557,8 +1557,7 @@ nsHTMLCopyEncoder::GetPromotedPoint(Endpoint aWhere, nsINode* aNode,
|
|||
if (aWhere == kStart)
|
||||
{
|
||||
// some special casing for text nodes
|
||||
nsCOMPtr<nsINode> t = aNode;
|
||||
if (auto nodeAsText = t->GetAsText())
|
||||
if (auto nodeAsText = aNode->GetAsText())
|
||||
{
|
||||
// if not at beginning of text node, we are done
|
||||
if (offset > 0)
|
||||
|
@ -1632,11 +1631,10 @@ nsHTMLCopyEncoder::GetPromotedPoint(Endpoint aWhere, nsINode* aNode,
|
|||
if (aWhere == kEnd)
|
||||
{
|
||||
// some special casing for text nodes
|
||||
nsCOMPtr<nsINode> n = do_QueryInterface(aNode);
|
||||
if (auto nodeAsText = n->GetAsText())
|
||||
if (auto nodeAsText = aNode->GetAsText())
|
||||
{
|
||||
// if not at end of text node, we are done
|
||||
uint32_t len = n->Length();
|
||||
uint32_t len = aNode->Length();
|
||||
if (offset < (int32_t)len)
|
||||
{
|
||||
// unless everything after us in just whitespace. NOTE: we need a more
|
||||
|
|
|
@ -1452,10 +1452,8 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
|||
nsCOMPtr<Element> otherFrameElement =
|
||||
otherWindow->GetFrameElementInternal();
|
||||
|
||||
nsCOMPtr<EventTarget> ourChromeEventHandler =
|
||||
do_QueryInterface(ourWindow->GetChromeEventHandler());
|
||||
nsCOMPtr<EventTarget> otherChromeEventHandler =
|
||||
do_QueryInterface(otherWindow->GetChromeEventHandler());
|
||||
nsCOMPtr<EventTarget> ourChromeEventHandler = ourWindow->GetChromeEventHandler();
|
||||
nsCOMPtr<EventTarget> otherChromeEventHandler = otherWindow->GetChromeEventHandler();
|
||||
|
||||
nsCOMPtr<EventTarget> ourEventTarget = ourWindow->GetParentTarget();
|
||||
nsCOMPtr<EventTarget> otherEventTarget = otherWindow->GetParentTarget();
|
||||
|
|
|
@ -2117,7 +2117,7 @@ nsGlobalWindowOuter::SetDocShell(nsIDocShell* aDocShell)
|
|||
// that we can do some forwarding to the chrome document.
|
||||
RefPtr<EventTarget> chromeEventHandler;
|
||||
mDocShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler));
|
||||
mChromeEventHandler = do_QueryInterface(chromeEventHandler);
|
||||
mChromeEventHandler = chromeEventHandler;
|
||||
if (!mChromeEventHandler) {
|
||||
// We have no chrome event handler. If we have a parent,
|
||||
// get our chrome event handler from the parent. If
|
||||
|
|
|
@ -2229,8 +2229,7 @@ nsRange::CutContents(DocumentFragment** aFragment)
|
|||
|
||||
ErrorResult res;
|
||||
if (farthestAncestor) {
|
||||
nsCOMPtr<nsINode> n = do_QueryInterface(commonCloneAncestor);
|
||||
n->AppendChild(*farthestAncestor, res);
|
||||
commonCloneAncestor->AppendChild(*farthestAncestor, res);
|
||||
res.WouldReportJSException();
|
||||
if (NS_WARN_IF(res.Failed())) {
|
||||
return res.StealNSResult();
|
||||
|
@ -3174,8 +3173,8 @@ nsRange::GetUsedFontFaces(nsTArray<nsAutoPtr<InspectorFontFace>>& aResult,
|
|||
{
|
||||
NS_ENSURE_TRUE(mStart.Container(), NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsCOMPtr<nsINode> startContainer = do_QueryInterface(mStart.Container());
|
||||
nsCOMPtr<nsINode> endContainer = do_QueryInterface(mEnd.Container());
|
||||
nsCOMPtr<nsINode> startContainer = mStart.Container();
|
||||
nsCOMPtr<nsINode> endContainer = mEnd.Container();
|
||||
|
||||
// Flush out layout so our frames are up to date.
|
||||
nsIDocument* doc = mStart.Container()->OwnerDoc();
|
||||
|
|
|
@ -1014,7 +1014,7 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
|
|||
} else {
|
||||
// At least the original target can handle the event.
|
||||
// Setting the retarget to the |target| simplifies retargeting code.
|
||||
nsCOMPtr<EventTarget> t = do_QueryInterface(aEvent->mTarget);
|
||||
nsCOMPtr<EventTarget> t = aEvent->mTarget;
|
||||
targetEtci->SetNewTarget(t);
|
||||
// In order to not change the targetTouches array passed to TouchEvents
|
||||
// when dispatching events from JS, we need to store the initial Touch
|
||||
|
|
|
@ -1249,8 +1249,7 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
|||
(aEvent->IsTrusted() || listener->mFlags.mAllowUntrustedEvents)) {
|
||||
if (!*aDOMEvent) {
|
||||
// This is tiny bit slow, but happens only once per event.
|
||||
nsCOMPtr<EventTarget> et =
|
||||
do_QueryInterface(aEvent->mOriginalTarget);
|
||||
nsCOMPtr<EventTarget> et = aEvent->mOriginalTarget;
|
||||
RefPtr<Event> event = EventDispatcher::CreateEvent(et, aPresContext,
|
||||
aEvent,
|
||||
EmptyString());
|
||||
|
@ -1592,7 +1591,7 @@ EventListenerManager::HasListeners() const
|
|||
nsresult
|
||||
EventListenerManager::GetListenerInfo(nsCOMArray<nsIEventListenerInfo>* aList)
|
||||
{
|
||||
nsCOMPtr<EventTarget> target = do_QueryInterface(mTarget);
|
||||
nsCOMPtr<EventTarget> target = mTarget;
|
||||
NS_ENSURE_STATE(target);
|
||||
aList->Clear();
|
||||
nsAutoTObserverArray<Listener, 2>::ForwardIterator iter(mListeners);
|
||||
|
|
|
@ -1638,13 +1638,19 @@ StartMacOSContentSandbox()
|
|||
return false;
|
||||
}
|
||||
|
||||
// Close all current connections to the WindowServer. This ensures that the
|
||||
// Activity Monitor will not label the content process as "Not responding"
|
||||
// because it's not running a native event loop. See bug 1384336.
|
||||
if (!recordreplay::IsRecordingOrReplaying()) {
|
||||
// Because of the WebReplay system for proxying system API calls, for the
|
||||
// time being we skip this when running under WebReplay (bug 1482668).
|
||||
CGSShutdownServerConnections();
|
||||
}
|
||||
// Actual security benefits are only acheived when we additionally deny
|
||||
// future connections, however this currently breaks WebGL so it's not done
|
||||
// by default.
|
||||
if (Preferences::GetBool(
|
||||
"security.sandbox.content.mac.disconnect-windowserver")) {
|
||||
// If we've opened a connection to the window server, shut it down now. Forbid
|
||||
// future connections as well. We do this for sandboxing, but it also ensures
|
||||
// that the Activity Monitor will not label the content process as "Not
|
||||
// responding" because it's not running a native event loop. See bug 1384336.
|
||||
CGSShutdownServerConnections();
|
||||
CGError result = CGSSetDenyWindowServerConnections(true);
|
||||
MOZ_DIAGNOSTIC_ASSERT(result == kCGErrorSuccess);
|
||||
#if !MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
|
|
|
@ -1054,9 +1054,8 @@ static nsIDocShell* GetOpenerDocShellHelper(Element* aFrameElement)
|
|||
{
|
||||
// Propagate the private-browsing status of the element's parent
|
||||
// docshell to the remote docshell, via the chrome flags.
|
||||
nsCOMPtr<Element> frameElement = do_QueryInterface(aFrameElement);
|
||||
MOZ_ASSERT(frameElement);
|
||||
nsPIDOMWindowOuter* win = frameElement->OwnerDoc()->GetWindow();
|
||||
MOZ_ASSERT(aFrameElement);
|
||||
nsPIDOMWindowOuter* win = aFrameElement->OwnerDoc()->GetWindow();
|
||||
if (!win) {
|
||||
NS_WARNING("Remote frame has no window");
|
||||
return nullptr;
|
||||
|
|
|
@ -610,8 +610,7 @@ TabChild::Init()
|
|||
// and all windows, even the root one, will use the docshell one.
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
|
||||
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<EventTarget> chromeHandler =
|
||||
do_QueryInterface(window->GetChromeEventHandler());
|
||||
nsCOMPtr<EventTarget> chromeHandler = window->GetChromeEventHandler();
|
||||
docShell->SetChromeEventHandler(chromeHandler);
|
||||
|
||||
if (window->GetCurrentInnerWindow()) {
|
||||
|
@ -2279,8 +2278,7 @@ TabChild::RecvActivateFrameEvent(const nsString& aType, const bool& capture)
|
|||
{
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
|
||||
NS_ENSURE_TRUE(window, IPC_OK());
|
||||
nsCOMPtr<EventTarget> chromeHandler =
|
||||
do_QueryInterface(window->GetChromeEventHandler());
|
||||
nsCOMPtr<EventTarget> chromeHandler = window->GetChromeEventHandler();
|
||||
NS_ENSURE_TRUE(chromeHandler, IPC_OK());
|
||||
RefPtr<ContentListener> listener = new ContentListener(this);
|
||||
chromeHandler->AddEventListener(aType, listener, capture);
|
||||
|
@ -2742,8 +2740,7 @@ TabChild::InitTabChildGlobal()
|
|||
if (!mTabChildGlobal) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
|
||||
NS_ENSURE_TRUE(window, false);
|
||||
nsCOMPtr<EventTarget> chromeHandler =
|
||||
do_QueryInterface(window->GetChromeEventHandler());
|
||||
nsCOMPtr<EventTarget> chromeHandler = window->GetChromeEventHandler();
|
||||
NS_ENSURE_TRUE(chromeHandler, false);
|
||||
|
||||
RefPtr<TabChildGlobal> scope = mTabChildGlobal = new TabChildGlobal(this);
|
||||
|
|
|
@ -228,8 +228,7 @@ nsXBLWindowKeyHandler::EnsureHandlers()
|
|||
if (mHandler)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(el));
|
||||
BuildHandlerChain(content, &mHandler);
|
||||
BuildHandlerChain(el, &mHandler);
|
||||
} else { // We are an XBL file of handlers.
|
||||
EnsureSpecialDocInfo();
|
||||
|
||||
|
@ -844,38 +843,35 @@ nsXBLWindowKeyHandler::GetElementForHandler(nsXBLPrototypeHandler* aHandler,
|
|||
MOZ_ASSERT(aElementForHandler);
|
||||
*aElementForHandler = nullptr;
|
||||
|
||||
RefPtr<Element> keyContent = aHandler->GetHandlerElement();
|
||||
if (!keyContent) {
|
||||
RefPtr<Element> keyElement = aHandler->GetHandlerElement();
|
||||
if (!keyElement) {
|
||||
return true; // XXX Even though no key element?
|
||||
}
|
||||
|
||||
nsCOMPtr<Element> chromeHandlerElement = GetElement();
|
||||
if (!chromeHandlerElement) {
|
||||
NS_WARNING_ASSERTION(keyContent->IsInUncomposedDoc(), "uncomposed");
|
||||
nsCOMPtr<Element> keyElement = do_QueryInterface(keyContent);
|
||||
NS_WARNING_ASSERTION(keyElement->IsInUncomposedDoc(), "uncomposed");
|
||||
keyElement.swap(*aElementForHandler);
|
||||
return true;
|
||||
}
|
||||
|
||||
// We are in a XUL doc. Obtain our command attribute.
|
||||
nsAutoString command;
|
||||
keyContent->GetAttr(kNameSpaceID_None, nsGkAtoms::command, command);
|
||||
keyElement->GetAttr(kNameSpaceID_None, nsGkAtoms::command, command);
|
||||
if (command.IsEmpty()) {
|
||||
// There is no command element associated with the key element.
|
||||
NS_WARNING_ASSERTION(keyContent->IsInUncomposedDoc(), "uncomposed");
|
||||
nsCOMPtr<Element> keyElement = do_QueryInterface(keyContent);
|
||||
NS_WARNING_ASSERTION(keyElement->IsInUncomposedDoc(), "uncomposed");
|
||||
keyElement.swap(*aElementForHandler);
|
||||
return true;
|
||||
}
|
||||
|
||||
// XXX Shouldn't we check this earlier?
|
||||
nsIDocument* doc = keyContent->GetUncomposedDoc();
|
||||
nsIDocument* doc = keyElement->GetUncomposedDoc();
|
||||
if (NS_WARN_IF(!doc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<Element> commandElement =
|
||||
do_QueryInterface(doc->GetElementById(command));
|
||||
nsCOMPtr<Element> commandElement = doc->GetElementById(command);
|
||||
if (!commandElement) {
|
||||
NS_ERROR("A XUL <key> is observing a command that doesn't exist. "
|
||||
"Unable to execute key binding!");
|
||||
|
|
|
@ -373,8 +373,8 @@ nsXULCommandDispatcher::UpdateCommands(const nsAString& aEventName)
|
|||
if (! Matches(updater->mTargets, id))
|
||||
continue;
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(updater->mElement);
|
||||
NS_ASSERTION(content != nullptr, "not an nsIContent");
|
||||
nsIContent* content = updater->mElement;
|
||||
NS_ASSERTION(content != nullptr, "mElement is null");
|
||||
if (! content)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
|
|
|
@ -334,16 +334,13 @@ nsEditingSession::SetupEditorOnWindow(mozIDOMWindowProxy* aWindow)
|
|||
|
||||
// Flush out frame construction to make sure that the subframe's
|
||||
// presshell is set up if it needs to be.
|
||||
nsCOMPtr<nsIDocument> document = do_QueryInterface(doc);
|
||||
if (document) {
|
||||
document->FlushPendingNotifications(mozilla::FlushType::Frames);
|
||||
if (mMakeWholeDocumentEditable) {
|
||||
document->SetEditableFlag(true);
|
||||
nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(document);
|
||||
if (htmlDocument) {
|
||||
// Enable usage of the execCommand API
|
||||
htmlDocument->SetEditingState(nsIHTMLDocument::eDesignMode);
|
||||
}
|
||||
doc->FlushPendingNotifications(mozilla::FlushType::Frames);
|
||||
if (mMakeWholeDocumentEditable) {
|
||||
doc->SetEditableFlag(true);
|
||||
nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(doc);
|
||||
if (htmlDocument) {
|
||||
// Enable usage of the execCommand API
|
||||
htmlDocument->SetEditingState(nsIHTMLDocument::eDesignMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -428,8 +428,7 @@ HTMLEditor::SetFinalPosition(int32_t aX,
|
|||
// we want one transaction only from a user's point of view
|
||||
AutoPlaceholderBatch batchIt(this);
|
||||
|
||||
nsCOMPtr<Element> absolutelyPositionedObject =
|
||||
do_QueryInterface(mAbsolutelyPositionedObject);
|
||||
nsCOMPtr<Element> absolutelyPositionedObject = mAbsolutelyPositionedObject;
|
||||
NS_ENSURE_STATE(absolutelyPositionedObject);
|
||||
mCSSEditUtils->SetCSSPropertyPixels(*absolutelyPositionedObject,
|
||||
*nsGkAtoms::top, newY);
|
||||
|
|
|
@ -4350,7 +4350,7 @@ HTMLEditor::SetCSSBackgroundColorWithTransaction(const nsAString& aColor)
|
|||
// *whole* nodes.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
for (; !iter->IsDone(); iter->Next()) {
|
||||
node = do_QueryInterface(iter->GetCurrentNode());
|
||||
node = iter->GetCurrentNode();
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
||||
|
||||
if (IsEditable(node)) {
|
||||
|
|
|
@ -1032,7 +1032,7 @@ HTMLEditor::InsertObject(const nsACString& aType,
|
|||
do_GetService("@mozilla.org/editor-utils;1");
|
||||
NS_ENSURE_TRUE(utils, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aDestinationNode);
|
||||
nsCOMPtr<nsINode> node = aDestinationNode;
|
||||
MOZ_ASSERT(node);
|
||||
|
||||
RefPtr<Blob> domBlob = Blob::Create(node->GetOwnerGlobal(), blob);
|
||||
|
|
|
@ -2613,8 +2613,7 @@ nsFrameSelection::SelectRowOrColumn(nsIContent *aCellContent, TableSelection aTa
|
|||
if (NS_FAILED(result)) return result;
|
||||
mStartSelectedCell = firstCell;
|
||||
}
|
||||
nsCOMPtr<nsIContent> lastCellContent = do_QueryInterface(lastCell);
|
||||
result = SelectBlockOfCells(mStartSelectedCell, lastCellContent);
|
||||
result = SelectBlockOfCells(mStartSelectedCell, lastCell);
|
||||
|
||||
// This gets set to the cell at end of row/col,
|
||||
// but we need it to be the cell under cursor
|
||||
|
|
|
@ -2049,11 +2049,7 @@ pref("network.dns.ipv4OnlyDomains", "");
|
|||
pref("network.dns.disableIPv6", false);
|
||||
|
||||
// This is the number of dns cache entries allowed
|
||||
#ifdef ANDROID
|
||||
pref("network.dnsCacheEntries", 400);
|
||||
#else
|
||||
pref("network.dnsCacheEntries", 800);
|
||||
#endif
|
||||
|
||||
// In the absence of OS TTLs, the DNS cache TTL value
|
||||
pref("network.dnsCacheExpiration", 60);
|
||||
|
@ -5382,6 +5378,8 @@ pref("network.trr.blacklist-duration", 60);
|
|||
pref("network.trr.request-timeout", 3000);
|
||||
// Allow AAAA entries to be used "early", before the A results are in
|
||||
pref("network.trr.early-AAAA", false);
|
||||
// Explicitly disable ECS (EDNS Client Subnet, RFC 7871)
|
||||
pref("network.trr.disable-ECS", true);
|
||||
|
||||
pref("captivedetect.canonicalURL", "http://detectportal.firefox.com/success.txt");
|
||||
pref("captivedetect.canonicalContent", "success\n");
|
||||
|
|
|
@ -135,7 +135,7 @@ nsInputStreamPump::EnsureWaiting()
|
|||
? mLabeledMainThreadTarget
|
||||
: do_AddRef(GetMainThreadEventTarget());
|
||||
if (mTargetThread != mainThread) {
|
||||
mTargetThread = do_QueryInterface(mainThread);
|
||||
mTargetThread = mainThread;
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(mTargetThread);
|
||||
|
|
|
@ -58,7 +58,7 @@ TRR::Notify(nsITimer *aTimer)
|
|||
// convert a given host request to a DOH 'body'
|
||||
//
|
||||
nsresult
|
||||
TRR::DohEncode(nsCString &aBody)
|
||||
TRR::DohEncode(nsCString &aBody, bool aDisableECS)
|
||||
{
|
||||
aBody.Truncate();
|
||||
// Header
|
||||
|
@ -72,8 +72,9 @@ TRR::DohEncode(nsCString &aBody)
|
|||
aBody += '\0'; // ANCOUNT
|
||||
aBody += '\0';
|
||||
aBody += '\0'; // NSCOUNT
|
||||
aBody += '\0';
|
||||
|
||||
aBody += '\0'; // ARCOUNT
|
||||
aBody += aDisableECS ? 1 : '\0'; // ARCOUNT low byte for EDNS(0)
|
||||
|
||||
// Question
|
||||
|
||||
|
@ -114,6 +115,38 @@ TRR::DohEncode(nsCString &aBody)
|
|||
aBody += '\0'; // upper 8 bit CLASS
|
||||
aBody += kDNS_CLASS_IN; // IN - "the Internet"
|
||||
|
||||
if (aDisableECS) {
|
||||
// EDNS(0) is RFC 6891, ECS is RFC 7871
|
||||
aBody += '\0'; // NAME | domain name | MUST be 0 (root domain) |
|
||||
aBody += '\0';
|
||||
aBody += 41; // TYPE | u_int16_t | OPT (41) |
|
||||
aBody += 16; // CLASS | u_int16_t | requestor's UDP payload size |
|
||||
aBody += '\0'; // advertise 4K (high-byte: 16 | low-byte: 0), ignored by DoH
|
||||
aBody += '\0'; // TTL | u_int32_t | extended RCODE and flags |
|
||||
aBody += '\0';
|
||||
aBody += '\0';
|
||||
aBody += '\0';
|
||||
|
||||
aBody += '\0'; // upper 8 bit RDLEN
|
||||
aBody += 8; // RDLEN | u_int16_t | length of all RDATA |
|
||||
|
||||
// RDATA | octet stream | {attribute,value} pairs |
|
||||
// The RDATA is just the ECS option setting zero subnet prefix
|
||||
|
||||
aBody += '\0'; // upper 8 bit OPTION-CODE ECS
|
||||
aBody += 8; // OPTION-CODE, 2 octets, for ECS is 8
|
||||
|
||||
aBody += '\0'; // upper 8 bit OPTION-LENGTH
|
||||
aBody += 4; // OPTION-LENGTH, 2 octets, contains the length of the payload
|
||||
// after OPTION-LENGTH
|
||||
aBody += '\0'; // upper 8 bit FAMILY
|
||||
aBody += AF_INET; // FAMILY, 2 octets
|
||||
|
||||
aBody += '\0'; // SOURCE PREFIX-LENGTH | SCOPE PREFIX-LENGTH |
|
||||
aBody += '\0';
|
||||
|
||||
// ADDRESS, minimum number of octets == nothing because zero bits
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -163,12 +196,13 @@ TRR::SendHTTPRequest()
|
|||
bool useGet = gTRRService->UseGET();
|
||||
nsAutoCString body;
|
||||
nsCOMPtr<nsIURI> dnsURI;
|
||||
bool disableECS = gTRRService->DisableECS();
|
||||
|
||||
LOG(("TRR::SendHTTPRequest resolve %s type %u\n", mHost.get(), mType));
|
||||
|
||||
if (useGet) {
|
||||
nsAutoCString tmp;
|
||||
rv = DohEncode(tmp);
|
||||
rv = DohEncode(tmp, disableECS);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
/* For GET requests, the outgoing packet needs to be Base64url-encoded and
|
||||
|
@ -183,7 +217,7 @@ TRR::SendHTTPRequest()
|
|||
uri.Append(body);
|
||||
rv = NS_NewURI(getter_AddRefs(dnsURI), uri);
|
||||
} else {
|
||||
rv = DohEncode(body);
|
||||
rv = DohEncode(body, disableECS);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoCString uri;
|
||||
|
|
|
@ -142,7 +142,7 @@ public:
|
|||
private:
|
||||
~TRR() = default;
|
||||
nsresult SendHTTPRequest();
|
||||
nsresult DohEncode(nsCString &target);
|
||||
nsresult DohEncode(nsCString &target, bool aDisableECS);
|
||||
nsresult PassQName(unsigned int &index);
|
||||
nsresult GetQname(nsAutoCString &aQname, unsigned int &aIndex);
|
||||
nsresult DohDecode(nsCString &aHost);
|
||||
|
|
|
@ -43,6 +43,7 @@ TRRService::TRRService()
|
|||
, mRfc1918(false)
|
||||
, mCaptiveIsPassed(false)
|
||||
, mUseGET(false)
|
||||
, mDisableECS(true)
|
||||
, mClearTRRBLStorage(false)
|
||||
, mConfirmationState(CONFIRM_INIT)
|
||||
, mRetryConfirmInterval(1000)
|
||||
|
@ -225,6 +226,12 @@ TRRService::ReadPrefs(const char *name)
|
|||
mDisableIPv6 = tmp;
|
||||
}
|
||||
}
|
||||
if (!name || !strcmp(name, TRR_PREF("disable-ECS"))) {
|
||||
bool tmp;
|
||||
if (NS_SUCCEEDED(Preferences::GetBool(TRR_PREF("disable-ECS"), &tmp))) {
|
||||
mDisableECS = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
bool UseGET() { return mUseGET; }
|
||||
bool EarlyAAAA() { return mEarlyAAAA; }
|
||||
bool DisableIPv6() { return mDisableIPv6; }
|
||||
bool DisableECS() { return mDisableECS; }
|
||||
nsresult GetURI(nsCString &result);
|
||||
nsresult GetCredentials(nsCString &result);
|
||||
uint32_t GetRequestTimeout() { return mTRRTimeout; }
|
||||
|
@ -71,6 +72,7 @@ private:
|
|||
Atomic<bool, Relaxed> mUseGET; // do DOH using GET requests (instead of POST)
|
||||
Atomic<bool, Relaxed> mEarlyAAAA; // allow use of AAAA results before A is in
|
||||
Atomic<bool, Relaxed> mDisableIPv6; // don't even try
|
||||
Atomic<bool, Relaxed> mDisableECS; // disable EDNS Client Subnet in requests
|
||||
|
||||
// TRR Blacklist storage
|
||||
RefPtr<DataStorage> mTRRBLStorage;
|
||||
|
|
|
@ -688,11 +688,13 @@ nsHttpChannel::CheckFastBlocked()
|
|||
LOG(("nsHttpChannel::CheckFastBlocked [this=%p]\n", this));
|
||||
|
||||
static bool sFastBlockInited = false;
|
||||
static bool sIsContentBlockingEnabled = false;
|
||||
static bool sIsFastBlockEnabled = false;
|
||||
static uint32_t sFastBlockTimeout = 0;
|
||||
|
||||
if (!sFastBlockInited) {
|
||||
sFastBlockInited = true;
|
||||
Preferences::AddBoolVarCache(&sIsContentBlockingEnabled, "browser.contentblocking.enabled");
|
||||
Preferences::AddBoolVarCache(&sIsFastBlockEnabled, "browser.fastblock.enabled");
|
||||
Preferences::AddUintVarCache(&sFastBlockTimeout, "browser.fastblock.timeout");
|
||||
}
|
||||
|
@ -702,7 +704,7 @@ nsHttpChannel::CheckFastBlocked()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!sIsFastBlockEnabled ||
|
||||
if (!sIsContentBlockingEnabled || !sIsFastBlockEnabled ||
|
||||
IsContentPolicyTypeWhitelistedForFastBlock(mLoadInfo) ||
|
||||
!timestamp) {
|
||||
return false;
|
||||
|
|
|
@ -58,6 +58,7 @@ function resetTRRPrefs() {
|
|||
prefs.clearUserPref("network.trr.bootstrapAddress");
|
||||
prefs.clearUserPref("network.trr.blacklist-duration");
|
||||
prefs.clearUserPref("network.trr.request-timeout");
|
||||
prefs.clearUserPref("network.trr.disable-ECS");
|
||||
}
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
|
@ -258,6 +259,18 @@ function test8()
|
|||
listen = dns.asyncResolve("rfc1918.example.com", 0, listenerFine, mainThread, defaultOriginAttributes);
|
||||
}
|
||||
|
||||
// use GET and disable ECS (makes a larger request)
|
||||
function test8b()
|
||||
{
|
||||
prefs.setIntPref("network.trr.mode", 3); // TRR-only
|
||||
prefs.setCharPref("network.trr.uri", "https://foo.example.com:" + h2Port + "/dns-ecs");
|
||||
prefs.clearUserPref("network.trr.allow-rfc1918");
|
||||
prefs.setBoolPref("network.trr.useGET", true);
|
||||
prefs.setBoolPref("network.trr.disable-ECS", true);
|
||||
test_answer = "5.5.5.5";
|
||||
listen = dns.asyncResolve("ecs.example.com", 0, listenerFine, mainThread, defaultOriginAttributes);
|
||||
}
|
||||
|
||||
// use GET
|
||||
function test9()
|
||||
{
|
||||
|
@ -265,6 +278,7 @@ function test9()
|
|||
prefs.setCharPref("network.trr.uri", "https://foo.example.com:" + h2Port + "/dns-get");
|
||||
prefs.clearUserPref("network.trr.allow-rfc1918");
|
||||
prefs.setBoolPref("network.trr.useGET", true);
|
||||
prefs.setBoolPref("network.trr.disable-ECS", false);
|
||||
test_answer = "1.2.3.4";
|
||||
listen = dns.asyncResolve("get.example.com", 0, listenerFine, mainThread, defaultOriginAttributes);
|
||||
}
|
||||
|
@ -275,6 +289,7 @@ function test10()
|
|||
{
|
||||
prefs.setIntPref("network.trr.mode", 3); // TRR-only
|
||||
prefs.clearUserPref("network.trr.useGET");
|
||||
prefs.clearUserPref("network.trr.disable-ECS");
|
||||
prefs.setCharPref("network.trr.uri", "https://foo.example.com:" + h2Port + "/dns-confirm");
|
||||
prefs.setCharPref("network.trr.confirmationNS", "confirm.example.com");
|
||||
test_loops = 100; // set for test10b
|
||||
|
@ -438,6 +453,7 @@ var tests = [ test1,
|
|||
test6,
|
||||
test7,
|
||||
test8,
|
||||
test8b,
|
||||
test9,
|
||||
test10,
|
||||
test10b,
|
||||
|
|
|
@ -268,6 +268,19 @@ class BaseBootstrapper(object):
|
|||
'%s does not yet implement ensure_node_packages()'
|
||||
% __name__)
|
||||
|
||||
def ensure_rust_package(self, crate_name):
|
||||
if self.which(crate_name):
|
||||
return
|
||||
cargo_home, cargo_bin = self.cargo_home()
|
||||
cargo_bin_path = os.path.join(cargo_bin, crate_name)
|
||||
if os.path.exists(cargo_bin_path) and os.access(cargo_bin_path, os.X_OK):
|
||||
return
|
||||
print('%s not found, installing via cargo install.' % crate_name)
|
||||
cargo = self.which('cargo')
|
||||
if not cargo:
|
||||
cargo = os.path.join(cargo_bin, 'cargo')
|
||||
subprocess.check_call([cargo, 'install', crate_name])
|
||||
|
||||
def install_toolchain_artifact(self, state_dir, checkout_root, toolchain_job):
|
||||
mach_binary = os.path.join(checkout_root, 'mach')
|
||||
mach_binary = os.path.abspath(mach_binary)
|
||||
|
|
|
@ -66,8 +66,8 @@ class FreeBSDBootstrapper(BaseBootstrapper):
|
|||
self.pkg_install(*self.browser_packages)
|
||||
|
||||
def ensure_stylo_packages(self, state_dir, checkout_root):
|
||||
# Already installed as browser package
|
||||
pass
|
||||
# Clang / llvm already installed as browser package
|
||||
self.ensure_rust_package('cbindgen')
|
||||
|
||||
def upgrade_mercurial(self, current):
|
||||
self.pkg_install('mercurial')
|
||||
|
|
|
@ -15,7 +15,8 @@ class StyloInstall(object):
|
|||
|
||||
def ensure_stylo_packages(self, state_dir, checkout_root):
|
||||
from mozboot import stylo
|
||||
self.install_toolchain_artifact(state_dir, checkout_root, stylo.LINUX)
|
||||
self.install_toolchain_artifact(state_dir, checkout_root, stylo.LINUX_CLANG)
|
||||
self.install_toolchain_artifact(state_dir, checkout_root, stylo.LINUX_CBINDGEN)
|
||||
|
||||
|
||||
class NodeInstall(object):
|
||||
|
|
|
@ -47,7 +47,8 @@ class MozillaBuildBootstrapper(BaseBootstrapper):
|
|||
|
||||
def ensure_stylo_packages(self, state_dir, checkout_root):
|
||||
from mozboot import stylo
|
||||
self.install_toolchain_artifact(state_dir, checkout_root, stylo.WINDOWS)
|
||||
self.install_toolchain_artifact(state_dir, checkout_root, stylo.WINDOWS_CLANG)
|
||||
self.install_toolchain_artifact(state_dir, checkout_root, stylo.WINDOWS_CBINDGEN)
|
||||
|
||||
def ensure_node_packages(self, state_dir, checkout_root):
|
||||
from mozboot import node
|
||||
|
|
|
@ -48,5 +48,5 @@ class OpenBSDBootstrapper(BaseBootstrapper):
|
|||
self.run_as_root(['pkg_add', '-z'] + self.browser_packages)
|
||||
|
||||
def ensure_stylo_packages(self, state_dir, checkout_root):
|
||||
# Already installed as browser package
|
||||
pass
|
||||
# Clang / llvm already installed as browser package
|
||||
self.ensure_rust_package('cbindgen')
|
||||
|
|
|
@ -503,8 +503,8 @@ class OSXBootstrapper(BaseBootstrapper):
|
|||
return active_name.lower()
|
||||
|
||||
def ensure_stylo_packages(self, state_dir, checkout_root):
|
||||
# We installed these via homebrew earlier.
|
||||
pass
|
||||
# We installed clang via homebrew earlier.
|
||||
self.ensure_rust_package('cbindgen')
|
||||
|
||||
def ensure_node_packages(self, state_dir, checkout_root):
|
||||
# XXX from necessary?
|
||||
|
|
|
@ -4,5 +4,7 @@
|
|||
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
WINDOWS = 'win64-clang-cl'
|
||||
LINUX = 'linux64-clang'
|
||||
WINDOWS_CLANG = 'win64-clang-cl'
|
||||
WINDOWS_CBINDGEN = 'win64-cbindgen'
|
||||
LINUX_CLANG = 'linux64-clang'
|
||||
LINUX_CBINDGEN = 'linux64-cbindgen'
|
||||
|
|
|
@ -73,7 +73,8 @@ class WindowsBootstrapper(BaseBootstrapper):
|
|||
|
||||
def ensure_stylo_packages(self, state_dir, checkout_root):
|
||||
from mozboot import stylo
|
||||
self.install_toolchain_artifact(state_dir, checkout_root, stylo.WINDOWS)
|
||||
self.install_toolchain_artifact(state_dir, checkout_root, stylo.WINDOWS_CLANG)
|
||||
self.install_toolchain_artifact(state_dir, checkout_root, stylo.WINDOWS_CBINDGEN)
|
||||
|
||||
def ensure_node_packages(self, state_dir, checkout_root):
|
||||
from mozboot import node
|
||||
|
|
|
@ -128,9 +128,14 @@ pref("security.cert_pinning.max_max_age_seconds", 5184000);
|
|||
// security.pki.distrust_ca_policy controls what root program distrust policies
|
||||
// are enforced at this time:
|
||||
// 0: No distrust policies enforced
|
||||
// 1: Symantec root distrust policy enforced
|
||||
// 1: Symantec roots distrusted for certificates issued after cutoff
|
||||
// 2: Symantec roots distrusted regardless of date
|
||||
// See https://wiki.mozilla.org/CA/Upcoming_Distrust_Actions for more details.
|
||||
#ifdef NIGHTLY_BUILD
|
||||
pref("security.pki.distrust_ca_policy", 2);
|
||||
#else
|
||||
pref("security.pki.distrust_ca_policy", 1);
|
||||
#endif
|
||||
|
||||
// Issuer we use to detect MitM proxies. Set to the issuer of the cert of the
|
||||
// Firefox update service. The string format is whatever NSS uses to print a DN.
|
||||
|
|
|
@ -27,6 +27,8 @@ add_tls_server_setup("SymantecSanctionsServer", "test_symantec_apple_google");
|
|||
add_test(function() {
|
||||
addCertFromFile(certDB, "test_symantec_apple_google/intermediate-whitelisted.pem", ",,");
|
||||
addCertFromFile(certDB, "test_symantec_apple_google/intermediate-other.pem", ",,");
|
||||
Services.prefs.setIntPref("security.pki.distrust_ca_policy",
|
||||
/* DistrustedCAPolicy::DistrustSymantecRoots */ 0b01);
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ android-api-16/debug:
|
|||
- linux64-clang
|
||||
- linux64-rust-android
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -104,6 +105,7 @@ android-api-16-ccov/debug:
|
|||
- linux64-clang
|
||||
- linux64-rust-android
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -156,6 +158,7 @@ android-x86/opt:
|
|||
- linux64-clang
|
||||
- linux64-rust-android
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -206,6 +209,7 @@ android-x86-fuzzing/debug:
|
|||
- linux64-clang
|
||||
- linux64-rust-android
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -263,6 +267,7 @@ android-x86-nightly/opt:
|
|||
- linux64-clang
|
||||
- linux64-rust-android
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -315,6 +320,7 @@ android-api-16/opt:
|
|||
- linux64-clang
|
||||
- linux64-rust-android
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -364,6 +370,7 @@ android-api-16-without-google-play-services/opt:
|
|||
- linux64-clang
|
||||
- linux64-rust-android
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -421,6 +428,7 @@ android-api-16-nightly/opt:
|
|||
- linux64-clang
|
||||
- linux64-rust-android
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -473,6 +481,7 @@ android-aarch64/opt:
|
|||
- linux64-clang
|
||||
- linux64-rust-android
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -531,4 +540,5 @@ android-aarch64-nightly/opt:
|
|||
- linux64-rust-android
|
||||
- linux64-rust-size
|
||||
- linux64-sccache
|
||||
- linux64-cbindgen
|
||||
- linux64-node
|
||||
|
|
|
@ -26,6 +26,7 @@ linux64/opt:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -57,6 +58,7 @@ linux64-plain/opt:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-node
|
||||
- linux64-cbindgen
|
||||
|
||||
linux64-dmd/opt:
|
||||
description: "Linux64 DMD Opt"
|
||||
|
@ -88,6 +90,7 @@ linux64-dmd/opt:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -120,6 +123,7 @@ linux64/pgo:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -150,6 +154,7 @@ linux64-fuzzing/debug:
|
|||
toolchains:
|
||||
- linux64-clang
|
||||
- linux64-gcc
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
|
@ -182,6 +187,7 @@ linux64/debug:
|
|||
toolchains:
|
||||
- linux64-clang
|
||||
- linux64-gcc
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
|
@ -215,6 +221,7 @@ linux64-plain/debug:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-node
|
||||
- linux64-cbindgen
|
||||
|
||||
linux64-devedition-nightly/opt:
|
||||
description: "Linux64 devedition Nightly"
|
||||
|
@ -251,6 +258,7 @@ linux64-devedition-nightly/opt:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -281,6 +289,7 @@ linux64-base-toolchains/opt:
|
|||
- linux64-clang-3.9
|
||||
- linux64-gcc-6
|
||||
- linux64-rust-1.28
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -312,6 +321,7 @@ linux64-base-toolchains/debug:
|
|||
- linux64-clang-3.9
|
||||
- linux64-gcc-6
|
||||
- linux64-rust-1.28
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -344,6 +354,7 @@ linux/opt:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -377,6 +388,7 @@ linux/debug:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -410,6 +422,7 @@ linux/pgo:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -445,6 +458,7 @@ linux-rusttests/opt:
|
|||
- linux64-clang
|
||||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -480,6 +494,7 @@ linux-rusttests/debug:
|
|||
- linux64-clang
|
||||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -519,6 +534,7 @@ linux-devedition-nightly/opt:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -556,6 +572,7 @@ linux-nightly/opt:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -588,6 +605,7 @@ linux64-asan/opt:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -620,6 +638,7 @@ linux64-asan-fuzzing/opt:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -653,6 +672,7 @@ linux64-asan-fuzzing-ccov/opt:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -689,6 +709,7 @@ linux64-asan-reporter-nightly/opt:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -721,6 +742,7 @@ linux64-asan/debug:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -754,6 +776,7 @@ linux64-lto/opt:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -787,6 +810,7 @@ linux64-lto/debug:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -823,6 +847,7 @@ linux64-nightly/opt:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -856,6 +881,7 @@ linux64-noopt/debug:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -890,6 +916,7 @@ linux64-rusttests/opt:
|
|||
- linux64-clang
|
||||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -924,6 +951,7 @@ linux64-rusttests/debug:
|
|||
- linux64-clang
|
||||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -956,6 +984,7 @@ linux64-tup/opt:
|
|||
- linux64-clang
|
||||
- linux64-gcc
|
||||
- linux64-rust-nightly
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-tup
|
||||
- linux64-node
|
||||
|
@ -987,6 +1016,7 @@ linux64-jsdcov/opt:
|
|||
- linux64-clang
|
||||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -1018,6 +1048,7 @@ linux64-ccov/debug:
|
|||
- linux64-clang-7
|
||||
- linux64-rust-nightly
|
||||
- linux64-gcc
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -1049,6 +1080,7 @@ linux64-ccov/opt:
|
|||
- linux64-clang-7
|
||||
- linux64-rust
|
||||
- linux64-gcc
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -1081,5 +1113,6 @@ linux64-add-on-devel/opt:
|
|||
- linux64-gcc
|
||||
- linux64-rust
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
|
|
@ -32,6 +32,7 @@ macosx64/debug:
|
|||
- linux64-llvm-dsymutil
|
||||
- linux64-rust-macos
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -68,6 +69,7 @@ macosx64/opt:
|
|||
- linux64-llvm-dsymutil
|
||||
- linux64-rust-macos
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -103,6 +105,7 @@ macosx64-asan-fuzzing/opt:
|
|||
- linux64-llvm-dsymutil
|
||||
- linux64-rust-macos
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -140,6 +143,7 @@ macosx64-dmd/opt:
|
|||
- linux64-llvm-dsymutil
|
||||
- linux64-rust-macos
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -183,6 +187,7 @@ macosx64-devedition-nightly/opt:
|
|||
- linux64-llvm-dsymutil
|
||||
- linux64-rust-macos
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -220,6 +225,7 @@ macosx64-noopt/debug:
|
|||
- linux64-llvm-dsymutil
|
||||
- linux64-rust-macos
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -256,6 +262,7 @@ macosx64-add-on-devel/opt:
|
|||
- linux64-llvm-dsymutil
|
||||
- linux64-rust-macos
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -297,6 +304,7 @@ macosx64-nightly/opt:
|
|||
- linux64-llvm-dsymutil
|
||||
- linux64-rust-macos
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -333,5 +341,6 @@ macosx64-ccov/debug:
|
|||
- linux64-llvm-dsymutil
|
||||
- linux64-rust-macos
|
||||
- linux64-rust-size
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
|
|
@ -27,6 +27,7 @@ win32/debug:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -65,6 +66,7 @@ win32/opt:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -98,6 +100,7 @@ win32-dmd/opt:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -130,6 +133,7 @@ win32/pgo:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -162,6 +166,7 @@ win64/debug:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -194,6 +199,7 @@ win64-plain/debug:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-node
|
||||
- win64-cbindgen
|
||||
|
||||
win64/opt:
|
||||
description: "Win64 Opt"
|
||||
|
@ -224,6 +230,7 @@ win64/opt:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -256,6 +263,7 @@ win64-plain/opt:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-node
|
||||
- win64-cbindgen
|
||||
|
||||
win64-dmd/opt:
|
||||
description: "Win64 DMD Opt"
|
||||
|
@ -287,6 +295,7 @@ win64-dmd/opt:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -332,6 +341,7 @@ win32-nightly/opt:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -370,6 +380,7 @@ win64-nightly/opt:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -402,6 +413,7 @@ win64/pgo:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -433,6 +445,7 @@ win32-add-on-devel/opt:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -464,6 +477,7 @@ win64-add-on-devel/opt:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -495,6 +509,7 @@ win64-noopt/debug:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -526,6 +541,7 @@ win32-noopt/debug:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -557,6 +573,7 @@ win32-rusttests/opt:
|
|||
toolchains:
|
||||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -588,6 +605,7 @@ win64-rusttests/opt:
|
|||
toolchains:
|
||||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -619,6 +637,7 @@ win64-ccov/debug:
|
|||
- win64-clang-cl
|
||||
- win64-rust-nightly
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -651,6 +670,7 @@ win64-asan/debug:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -683,6 +703,7 @@ win64-asan/opt:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -718,6 +739,7 @@ win64-asan-reporter-nightly/opt:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -764,6 +786,7 @@ win32-devedition-nightly/opt:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -803,6 +826,7 @@ win64-devedition-nightly/opt:
|
|||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-rust-size
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -834,6 +858,7 @@ win32-mingw32/opt:
|
|||
- mingw32-rust
|
||||
- linux64-upx
|
||||
- linux64-wine
|
||||
- win64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-mingw32-gcc
|
||||
- linux64-mingw32-nsis
|
||||
|
@ -870,6 +895,7 @@ win32-msvc/debug:
|
|||
toolchains:
|
||||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -909,6 +935,7 @@ win32-msvc/opt:
|
|||
toolchains:
|
||||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -942,6 +969,7 @@ win64-msvc/debug:
|
|||
toolchains:
|
||||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -975,6 +1003,7 @@ win64-msvc/opt:
|
|||
toolchains:
|
||||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -1007,6 +1036,7 @@ win32-mingw32/debug:
|
|||
- mingw32-rust
|
||||
- linux64-upx
|
||||
- linux64-wine
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-mingw32-gcc
|
||||
- linux64-mingw32-nsis
|
||||
|
|
|
@ -46,6 +46,7 @@ jobs:
|
|||
toolchains:
|
||||
- linux64-clang
|
||||
- linux64-rust
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -72,6 +73,7 @@ jobs:
|
|||
toolchains:
|
||||
- linux64-clang
|
||||
- linux64-rust
|
||||
- linux64-cbindgen
|
||||
- linux64-sccache
|
||||
- linux64-node
|
||||
|
||||
|
@ -102,6 +104,7 @@ jobs:
|
|||
toolchains:
|
||||
- win32-clang-cl-st-an
|
||||
- win32-rust
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -132,6 +135,7 @@ jobs:
|
|||
toolchains:
|
||||
- win32-clang-cl-st-an
|
||||
- win32-rust
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -162,6 +166,7 @@ jobs:
|
|||
toolchains:
|
||||
- win64-clang-cl-st-an
|
||||
- win64-rust
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
||||
|
@ -192,5 +197,6 @@ jobs:
|
|||
toolchains:
|
||||
- win64-clang-cl-st-an
|
||||
- win64-rust
|
||||
- win64-cbindgen
|
||||
- win64-sccache
|
||||
- win64-node
|
||||
|
|
|
@ -572,6 +572,26 @@ linux64-sccache:
|
|||
toolchains:
|
||||
- linux64-rust-1.28
|
||||
|
||||
linux64-cbindgen:
|
||||
description: "cbindgen toolchain build"
|
||||
treeherder:
|
||||
kind: build
|
||||
platform: toolchains/opt
|
||||
symbol: TL(cbindgen)
|
||||
tier: 1
|
||||
worker-type: aws-provisioner-v1/gecko-{level}-b-linux
|
||||
worker:
|
||||
max-run-time: 1800
|
||||
run:
|
||||
using: toolchain-script
|
||||
script: build-cbindgen.sh
|
||||
arguments: ['x86_64-unknown-linux-gnu']
|
||||
resources:
|
||||
- 'taskcluster/scripts/misc/tooltool-download.sh'
|
||||
toolchain-artifact: public/build/cbindgen.tar.xz
|
||||
toolchains:
|
||||
- linux64-rust-1.28
|
||||
|
||||
linux64-rust-size:
|
||||
description: "rust-size toolchain build"
|
||||
treeherder:
|
||||
|
|
|
@ -256,6 +256,28 @@ win64-sccache:
|
|||
toolchains:
|
||||
- win64-rust-1.28
|
||||
|
||||
win64-cbindgen:
|
||||
description: "cbindgen toolchain build"
|
||||
treeherder:
|
||||
kind: build
|
||||
platform: toolchains/opt
|
||||
symbol: TW64(cbindgen)
|
||||
tier: 1
|
||||
worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
|
||||
worker:
|
||||
max-run-time: 3600
|
||||
env:
|
||||
TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/sccache-build.manifest"
|
||||
run:
|
||||
using: toolchain-script
|
||||
script: build-cbindgen.sh
|
||||
arguments: ['x86_64-pc-windows-msvc']
|
||||
resources:
|
||||
- 'taskcluster/scripts/misc/tooltool-download.sh'
|
||||
toolchain-artifact: public/build/cbindgen.tar.bz2
|
||||
toolchains:
|
||||
- win64-rust-1.28
|
||||
|
||||
win64-rust-size:
|
||||
description: "rust-size toolchain build"
|
||||
treeherder:
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
#!/bin/bash
|
||||
set -x -e -v
|
||||
|
||||
CBINDGEN_VERSION=v0.6.1
|
||||
TARGET="$1"
|
||||
|
||||
case "$(uname -s)" in
|
||||
Linux)
|
||||
WORKSPACE=$HOME/workspace
|
||||
UPLOAD_DIR=$HOME/artifacts
|
||||
COMPRESS_EXT=xz
|
||||
;;
|
||||
MINGW*)
|
||||
WORKSPACE=$PWD
|
||||
UPLOAD_DIR=$WORKSPACE/public/build
|
||||
WIN_WORKSPACE="$(pwd -W)"
|
||||
COMPRESS_EXT=bz2
|
||||
|
||||
export INCLUDE="$WIN_WORKSPACE/build/src/vs2017_15.4.2/VC/include;$WIN_WORKSPACE/build/src/vs2017_15.4.2/VC/atlmfc/include;$WIN_WORKSPACE/build/src/vs2017_15.4.2/SDK/Include/10.0.15063.0/ucrt;$WIN_WORKSPACE/build/src/vs2017_15.4.2/SDK/Include/10.0.15063.0/shared;$WIN_WORKSPACE/build/src/vs2017_15.4.2/SDK/Include/10.0.15063.0/um;$WIN_WORKSPACE/build/src/vs2017_15.4.2/SDK/Include/10.0.15063.0/winrt;$WIN_WORKSPACE/build/src/vs2017_15.4.2/DIA SDK/include"
|
||||
|
||||
export LIB="$WIN_WORKSPACE/build/src/vs2017_15.4.2/VC/lib/x64;$WIN_WORKSPACE/build/src/vs2017_15.4.2/VC/atlmfc/lib/x64;$WIN_WORKSPACE/build/src/vs2017_15.4.2/SDK/lib/10.0.15063.0/um/x64;$WIN_WORKSPACE/build/src/vs2017_15.4.2/SDK/lib/10.0.15063.0/ucrt/x64;$WIN_WORKSPACE/build/src/vs2017_15.4.2/DIA SDK/lib/amd64"
|
||||
|
||||
PATH="$WORKSPACE/build/src/vs2017_15.4.2/VC/bin/Hostx64/x64:$WORKSPACE/build/src/vs2017_15.4.2/VC/bin/Hostx86/x86:$WORKSPACE/build/src/vs2017_15.4.2/SDK/bin/10.0.15063.0/x64:$WORKSPACE/build/src/vs2017_15.4.2/redist/x64/Microsoft.VC141.CRT:$WORKSPACE/build/src/vs2017_15.4.2/SDK/Redist/ucrt/DLLs/x64:$WORKSPACE/build/src/vs2017_15.4.2/DIA SDK/bin/amd64:$WORKSPACE/build/src/mingw64/bin:$PATH"
|
||||
;;
|
||||
esac
|
||||
|
||||
cd $WORKSPACE/build/src
|
||||
|
||||
. taskcluster/scripts/misc/tooltool-download.sh
|
||||
|
||||
PATH="$PWD/rustc/bin:$PATH"
|
||||
|
||||
# XXX On Windows there's a workspace/builds/src/Cargo.toml from the root of
|
||||
# mozilla-central, and cargo complains below if it's not gone...
|
||||
if [ -f Cargo.toml ]; then
|
||||
cat Cargo.toml
|
||||
rm Cargo.toml
|
||||
fi
|
||||
|
||||
git clone https://github.com/eqrion/cbindgen cbindgen
|
||||
|
||||
cd $_
|
||||
|
||||
git checkout $CBINDGEN_VERSION
|
||||
|
||||
cargo build --verbose --release --target "$TARGET"
|
||||
|
||||
mkdir cbindgen
|
||||
cp target/$TARGET/release/cbindgen* cbindgen/
|
||||
tar -acf cbindgen.tar.$COMPRESS_EXT cbindgen
|
||||
mkdir -p $UPLOAD_DIR
|
||||
cp cbindgen.tar.$COMPRESS_EXT $UPLOAD_DIR
|
|
@ -604,7 +604,18 @@ function handleRequest(req, res) {
|
|||
return;
|
||||
|
||||
}
|
||||
|
||||
// for use with test_trr.js, test8b
|
||||
else if (u.path === "/dns-ecs?dns=AAABAAABAAAAAAABA2VjcwdleGFtcGxlA2NvbQAAAQABAAApEAAAAAAAAAgACAAEAAIAAA") {
|
||||
// the query string asks for an A entry for ecs.example.com
|
||||
// ecs.example.com has A entry 5.5.5.5
|
||||
var content= new Buffer("00000100000100010000000003656373076578616D706C6503636F6D0000010001C00C0001000100000037000405050505", "hex");
|
||||
res.setHeader('Content-Type', 'application/dns-message');
|
||||
res.setHeader('Content-Length', content.length);
|
||||
res.writeHead(200);
|
||||
res.write(content);
|
||||
res.end("");
|
||||
return;
|
||||
}
|
||||
// for use with test_trr.js
|
||||
else if (u.path === "/dns-get?dns=AAABAAABAAAAAAAAA2dldAdleGFtcGxlA2NvbQAAAQAB") {
|
||||
// the query string asks for an A entry for get.example.com
|
||||
|
|
|
@ -214,6 +214,17 @@ class EventEmitter {
|
|||
this[ONCE_MAP] = new WeakMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether there is some listener for the given event.
|
||||
*
|
||||
* @param {string} event
|
||||
* The name of the event to listen for.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
has(event) {
|
||||
return this[LISTENERS].has(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given function as a listener for the given event.
|
||||
*
|
||||
|
|
|
@ -541,8 +541,7 @@ nsTypeAheadFind::FindItNow(nsIPresShell *aPresShell, bool aIsLinksOnly,
|
|||
mPresShell = do_GetWeakReference(presShell);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> document =
|
||||
do_QueryInterface(presShell->GetDocument());
|
||||
nsCOMPtr<nsIDocument> document = presShell->GetDocument();
|
||||
NS_ASSERTION(document, "Wow, presShell doesn't have document!");
|
||||
if (!document)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
@ -1086,8 +1085,7 @@ nsTypeAheadFind::Find(const nsAString& aSearchString, bool aLinksOnly,
|
|||
nsPresContext* presContext = presShell->GetPresContext();
|
||||
NS_ENSURE_TRUE(presContext, NS_OK);
|
||||
|
||||
nsCOMPtr<nsIDocument> document =
|
||||
do_QueryInterface(presShell->GetDocument());
|
||||
nsCOMPtr<nsIDocument> document = presShell->GetDocument();
|
||||
if (!document)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ support-files =
|
|||
import.css
|
||||
raptor.jpg
|
||||
track.html
|
||||
trackingRequest.html
|
||||
trackingRequest.js
|
||||
trackingRequest.js^headers^
|
||||
unwantedWorker.js
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var mainWindow = window.docShell.rootTreeItem.domWindow;
|
||||
var contentPage = "http://www.itisatrap.org/tests/toolkit/components/url-classifier/tests/mochitest/trackingRequest.html";
|
||||
var contentPage = "http://www.itisatrap.org/chrome/toolkit/components/url-classifier/tests/mochitest/trackingRequest.html";
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.import("resource://testing-common/UrlClassifierTestUtils.jsm");
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
from mozboot.util import get_state_dir
|
||||
|
@ -49,7 +51,13 @@ def invalidate(cache, root):
|
|||
def generate_tasks(params, full, root):
|
||||
params = params or "project=mozilla-central"
|
||||
|
||||
cache_dir = os.path.join(get_state_dir()[0], 'cache', 'taskgraph')
|
||||
# Try to delete the old taskgraph cache directory.
|
||||
old_cache_dir = os.path.join(get_state_dir()[0], 'cache', 'taskgraph')
|
||||
if os.path.isdir(old_cache_dir):
|
||||
shutil.rmtree(old_cache_dir)
|
||||
|
||||
root_hash = hashlib.sha256(os.path.abspath(root)).hexdigest()
|
||||
cache_dir = os.path.join(get_state_dir()[0], 'cache', root_hash, 'taskgraph')
|
||||
attr = 'full_task_set' if full else 'target_task_set'
|
||||
cache = os.path.join(cache_dir, attr)
|
||||
|
||||
|
|
|
@ -7,7 +7,10 @@ cat > $MACHRC << EOF
|
|||
default=syntax
|
||||
EOF
|
||||
|
||||
cachedir=$MOZBUILD_STATE_PATH/cache/taskgraph
|
||||
calculate_hash='import hashlib, os, sys
|
||||
print hashlib.sha256(os.path.abspath(sys.argv[1])).hexdigest()'
|
||||
roothash=$(python -c "$calculate_hash" "$topsrcdir")
|
||||
cachedir=$MOZBUILD_STATE_PATH/cache/$roothash/taskgraph
|
||||
mkdir -p $cachedir
|
||||
|
||||
cat > $cachedir/target_task_set << EOF
|
||||
|
|
|
@ -728,10 +728,9 @@ nsPrefetchService::Preload(nsIURI *aURI,
|
|||
//
|
||||
|
||||
if (aPolicyType == nsIContentPolicy::TYPE_INVALID) {
|
||||
nsCOMPtr<nsINode> domNode = do_QueryInterface(aSource);
|
||||
if (domNode && domNode->IsInComposedDoc()) {
|
||||
if (aSource && aSource->IsInComposedDoc()) {
|
||||
RefPtr<AsyncEventDispatcher> asyncDispatcher =
|
||||
new AsyncEventDispatcher(domNode,
|
||||
new AsyncEventDispatcher(aSource,
|
||||
NS_LITERAL_STRING("error"),
|
||||
CanBubble::eNo,
|
||||
ChromeOnlyDispatch::eNo);
|
||||
|
@ -772,10 +771,9 @@ nsPrefetchService::Preload(nsIURI *aURI,
|
|||
if (NS_SUCCEEDED(rv)) {
|
||||
mCurrentNodes.AppendElement(enqueuedNode);
|
||||
} else {
|
||||
nsCOMPtr<nsINode> domNode = do_QueryInterface(aSource);
|
||||
if (domNode && domNode->IsInComposedDoc()) {
|
||||
if (aSource && aSource->IsInComposedDoc()) {
|
||||
RefPtr<AsyncEventDispatcher> asyncDispatcher =
|
||||
new AsyncEventDispatcher(domNode,
|
||||
new AsyncEventDispatcher(aSource,
|
||||
NS_LITERAL_STRING("error"),
|
||||
CanBubble::eNo,
|
||||
ChromeOnlyDispatch::eNo);
|
||||
|
|
Загрузка…
Ссылка в новой задаче