Merge autoland to mozilla-central. a=merge

This commit is contained in:
dvarga 2018-08-02 01:07:53 +03:00
commit d050f46b93
247 changed files with 1832 additions and 1240 deletions

View File

@ -399,9 +399,8 @@ var PlacesCommandHook = {
info.guid = await PlacesTransactions.NewBookmark(info).transact();
// Set the character-set
if (charset && !PrivateBrowsingUtils.isBrowserPrivate(browser)) {
PlacesUtils.setCharsetForURI(makeURI(url.href), charset);
if (charset) {
PlacesUIUtils.setCharsetForPage(url, charset, window).catch(Cu.reportError);
}
}

View File

@ -6225,8 +6225,9 @@ function BrowserSetForcedCharacterSet(aCharset) {
if (aCharset) {
gBrowser.selectedBrowser.characterSet = aCharset;
// Save the forced character-set
if (!PrivateBrowsingUtils.isWindowPrivate(window))
PlacesUtils.setCharsetForURI(getWebNavigation().currentURI, aCharset);
PlacesUIUtils.setCharsetForPage(getWebNavigation().currentURI,
aCharset,
window).catch(Cu.reportError);
}
BrowserCharsetReload();
}
@ -8244,4 +8245,3 @@ var ConfirmationHint = {
return this._message = document.getElementById("confirmation-hint-message");
},
};

View File

@ -32,7 +32,7 @@ class ContextMenusClickPropHandler {
// No need for runSafe or anything because we are already being run inside
// an event handler -- the event is just being forwarded to the actual
// handler.
onclick(info, tab);
withHandlingUserInput(this.context.contentWindow, () => onclick(info, tab));
}
}

View File

@ -210,7 +210,6 @@ skip-if = os == 'mac' # Save as PDF not supported on Mac OS X
[browser_ext_themes_validation.js]
[browser_ext_url_overrides_newtab.js]
[browser_ext_user_events.js]
skip-if = debug || os == "linux" #Bug 1381305
[browser_ext_webRequest.js]
[browser_ext_webNavigation_frameId0.js]
[browser_ext_webNavigation_getFrames.js]

View File

@ -48,20 +48,29 @@ add_task(async function testSources() {
browser.pageAction.onClicked.addListener(() => request("bookmarks"));
browser.browserAction.onClicked.addListener(() => request("tabs"));
browser.contextMenus.create({
id: "menu",
title: "test user events",
contexts: ["page"],
});
browser.contextMenus.onClicked.addListener(() => request("webNavigation"));
browser.test.onMessage.addListener(msg => {
if (msg === "contextMenus.update") {
browser.contextMenus.onClicked.addListener(() => request("webNavigation"));
browser.contextMenus.update("menu", {
title: "test user events in onClicked",
onclick: null,
}, () => browser.test.sendMessage("contextMenus.update-done"));
}
if (msg === "openOptionsPage") {
browser.runtime.openOptionsPage();
}
});
browser.test.sendMessage("actions-ready");
browser.contextMenus.create({
id: "menu",
title: "test user events in onclick",
contexts: ["page"],
onclick() {
request("cookies");
},
}, () => {
browser.test.sendMessage("actions-ready");
});
},
files: {
@ -81,8 +90,11 @@ add_task(async function testSources() {
addEventListener("load", async () => {
let link = document.getElementById("link");
link.onclick = async event => {
link.onclick = null;
event.preventDefault();
browser.test.log("Calling permission.request from options page.");
try {
let result = await browser.permissions.request({
permissions: ["webRequest"],
@ -98,12 +110,12 @@ add_task(async function testSources() {
// we don't really have a reliable way to detect this from the
// options page side, and synthetic click events won't work
// until it is.
for (let i = 0; i < 10; i++) {
do {
browser.test.log("Waiting for the options browser to be visible...");
await new Promise(resolve => setTimeout(resolve, 0));
}
synthesizeMouseAtCenter(link, {});
}, {once: true});
synthesizeMouseAtCenter(link, {});
} while (link.onclick !== null);
});
},
},
@ -111,7 +123,7 @@ add_task(async function testSources() {
browser_action: {default_title: "test"},
page_action: {default_title: "test"},
permissions: ["contextMenus"],
optional_permissions: ["bookmarks", "tabs", "webNavigation", "webRequest"],
optional_permissions: ["bookmarks", "tabs", "webNavigation", "webRequest", "cookies"],
options_ui: {page: "options.html"},
content_security_policy: "script-src 'self' https://example.com; object-src 'none';",
},
@ -153,15 +165,23 @@ add_task(async function testSources() {
gBrowser.selectedTab = tab;
let menu = await openContextMenu("body");
let items = menu.getElementsByAttribute("label", "test user events");
let items = menu.getElementsByAttribute("label", "test user events in onclick");
is(items.length, 1, "Found context menu item");
EventUtils.synthesizeMouseAtCenter(items[0], {});
await check("context menu click");
await check("context menu in onclick");
extension.sendMessage("contextMenus.update");
await extension.awaitMessage("contextMenus.update-done");
menu = await openContextMenu("body");
items = menu.getElementsByAttribute("label", "test user events in onClicked");
is(items.length, 1, "Found context menu item again");
EventUtils.synthesizeMouseAtCenter(items[0], {});
await check("context menu in onClicked");
extension.sendMessage("openOptionsPage");
promisePopupNotificationShown("addon-webext-permissions").then(panel => {
panel.button.click();
});
extension.sendMessage("openOptionsPage");
await check("options page link click");
await BrowserTestUtils.removeTab(gBrowser.selectedTab);

View File

@ -1,7 +1,5 @@
"use strict";
/* exported gProfD, promiseMigration, registerFakePath, URL */
ChromeUtils.import("resource:///modules/MigrationUtils.jsm");
ChromeUtils.import("resource://gre/modules/LoginHelper.jsm");
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
@ -15,10 +13,8 @@ ChromeUtils.import("resource://testing-common/PlacesTestUtils.jsm");
XPCOMUtils.defineLazyGlobalGetters(this, [ "URL" ]);
// eslint-disable-next-line no-unused-vars
ChromeUtils.defineModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
// eslint-disable-next-line no-unused-vars
ChromeUtils.defineModuleGetter(this, "Sqlite",
"resource://gre/modules/Sqlite.jsm");

View File

@ -1811,7 +1811,7 @@ BrowserGlue.prototype = {
_migrateUI: function BG__migrateUI() {
// Use an increasing number to keep track of the current migration state.
// Completely unrelated to the current Firefox release number.
const UI_VERSION = 71;
const UI_VERSION = 72;
const BROWSER_DOCURL = AppConstants.BROWSER_CHROME_URL;
let currentUIVersion;
@ -2142,6 +2142,12 @@ BrowserGlue.prototype = {
}
}
if (currentUIVersion < 72) {
// Migrate performance tool's recording interval value from msec to usec.
let pref = "devtools.performance.recording.interval";
Services.prefs.setIntPref(pref, Services.prefs.getIntPref(pref, 1) * 1000);
}
// Update the migration version.
Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
},

View File

@ -19,7 +19,6 @@
/* eslint-env mozilla/frame-script */
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.defineModuleGetter(this, "FormAutofill",

View File

@ -174,3 +174,16 @@ payment-dialog[changes-prevented][complete-status="success"] #pay {
bottom: 0;
left: 0;
}
#branding {
background-image: url(chrome://branding/content/icon32.png);
background-size: 16px;
background-repeat: no-repeat;
background-position: left center;
padding-inline-start: 20px;
line-height: 20px;
}
body[dir="rtl"] #branding {
background-position: right center;
}

View File

@ -66,6 +66,7 @@
<!ENTITY timeoutErrorPage.suggestion2 "Check your network connection." >
<!ENTITY timeoutErrorPage.suggestion3 "If no other solutions work, check with **host-name**.">
<!ENTITY timeoutErrorPage.doneButton.label "OK">
<!ENTITY webPaymentsBranding.label "&brandShortName; Checkout">
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
@ -133,6 +134,7 @@
</div>
<footer>
<span id="branding">&webPaymentsBranding.label;</span>
<button id="cancel">&cancelPaymentButton.label;</button>
<button id="pay"
class="primary"

View File

@ -459,6 +459,32 @@ var PlacesUIUtils = {
PlacesUtils.history.markPageAsFollowedLink(this.createFixedURI(aURL));
},
/**
* Sets the character-set for a page. The character set will not be saved
* if the window is determined to be a private browsing window.
*
* @param {string|URL|nsIURI} url The URL of the page to set the charset on.
* @param {String} charset character-set value.
* @param {window} window The window that the charset is being set from.
* @return {Promise}
*/
async setCharsetForPage(url, charset, window) {
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
return;
}
// UTF-8 is the default. If we are passed the value then set it to null,
// to ensure any charset is removed from the database.
if (charset.toLowerCase() == "utf-8") {
charset = null;
}
await PlacesUtils.history.update({
url,
annotations: new Map([[PlacesUtils.CHARSET_ANNO, charset]])
});
},
/**
* Allows opening of javascript/data URI only if the given node is
* bookmarked (see bug 224521).

View File

@ -468,8 +468,9 @@ var BookmarkPropertiesPanel = {
if (this._postData)
info.postData = this._postData;
if (this._charSet && !PrivateBrowsingUtils.isWindowPrivate(window))
PlacesUtils.setCharsetForURI(this._uri, this._charSet);
if (this._charSet) {
PlacesUIUtils.setCharsetForPage(this._uri, this._charSet, window).catch(Cu.reportError);
}
itemGuid = await PlacesTransactions.NewBookmark(info).transact();
} else if (this._itemType == LIVEMARK_CONTAINER) {

View File

@ -0,0 +1,101 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const {PrivateBrowsingUtils} =
ChromeUtils.import("resource://gre/modules/PrivateBrowsingUtils.jsm", {});
const UTF8 = "UTF-8";
const UTF16 = "UTF-16";
const CHARSET_ANNO = PlacesUtils.CHARSET_ANNO;
const TEST_URI = "http://foo.com";
const TEST_BOOKMARKED_URI = "http://bar.com";
add_task(function setup() {
let savedIsWindowPrivateFunc = PrivateBrowsingUtils.isWindowPrivate;
PrivateBrowsingUtils.isWindowPrivate = () => false;
registerCleanupFunction(() => {
PrivateBrowsingUtils.isWindowPrivate = savedIsWindowPrivateFunc;
});
});
add_task(async function test_simple_add() {
// add pages to history
await PlacesTestUtils.addVisits(TEST_URI);
await PlacesTestUtils.addVisits(TEST_BOOKMARKED_URI);
// create bookmarks on TEST_BOOKMARKED_URI
await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
url: TEST_BOOKMARKED_URI,
title: TEST_BOOKMARKED_URI.spec,
});
await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
url: TEST_BOOKMARKED_URI,
title: TEST_BOOKMARKED_URI.spec,
});
// set charset on not-bookmarked page
await PlacesUIUtils.setCharsetForPage(TEST_URI, UTF16, {});
// set charset on bookmarked page
await PlacesUIUtils.setCharsetForPage(TEST_BOOKMARKED_URI, UTF16, {});
let pageInfo = await PlacesUtils.history.fetch(TEST_URI, {includeAnnotations: true});
Assert.equal(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), UTF16,
"Should return correct charset for a not-bookmarked page");
pageInfo = await PlacesUtils.history.fetch(TEST_BOOKMARKED_URI, {includeAnnotations: true});
Assert.equal(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), UTF16,
"Should return correct charset for a bookmarked page");
await PlacesUtils.history.clear();
pageInfo = await PlacesUtils.history.fetch(TEST_URI, {includeAnnotations: true});
Assert.ok(!pageInfo, "Should not return pageInfo for a page after history cleared");
pageInfo = await PlacesUtils.history.fetch(TEST_BOOKMARKED_URI, {includeAnnotations: true});
Assert.equal(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), UTF16,
"Charset should still be set for a bookmarked page after history clear");
await PlacesUIUtils.setCharsetForPage(TEST_BOOKMARKED_URI, "");
pageInfo = await PlacesUtils.history.fetch(TEST_BOOKMARKED_URI, {includeAnnotations: true});
Assert.strictEqual(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), undefined,
"Should not have a charset after it has been removed from the page");
});
add_task(async function test_utf8_clears_saved_anno() {
await PlacesUtils.history.clear();
await PlacesTestUtils.addVisits(TEST_URI);
// set charset on bookmarked page
await PlacesUIUtils.setCharsetForPage(TEST_URI, UTF16, {});
let pageInfo = await PlacesUtils.history.fetch(TEST_URI, {includeAnnotations: true});
Assert.equal(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), UTF16,
"Should return correct charset for a not-bookmarked page");
// Now set the bookmark to a UTF-8 charset.
await PlacesUIUtils.setCharsetForPage(TEST_URI, UTF8, {});
pageInfo = await PlacesUtils.history.fetch(TEST_URI, {includeAnnotations: true});
Assert.strictEqual(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), undefined,
"Should have removed the charset for a UTF-8 page.");
});
add_task(async function test_private_browsing_not_saved() {
await PlacesUtils.history.clear();
await PlacesTestUtils.addVisits(TEST_URI);
// set charset on bookmarked page, but pretend this is a private browsing window.
PrivateBrowsingUtils.isWindowPrivate = () => true;
await PlacesUIUtils.setCharsetForPage(TEST_URI, UTF16, {});
let pageInfo = await PlacesUtils.history.fetch(TEST_URI, {includeAnnotations: true});
Assert.strictEqual(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), undefined,
"Should not have set the charset in a private browsing window.");
});

View File

@ -18,3 +18,4 @@ support-files =
[test_browserGlue_restore.js]
[test_clearHistory_shutdown.js]
[test_PUIU_batchUpdatesForNode.js]
[test_PUIU_setCharsetForPage.js]

View File

@ -1,6 +1,7 @@
ac_add_options --with-l10n-base=../../l10n
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --with-branding=browser/branding/nightly
ac_add_options --disable-nodejs
. "$topsrcdir/build/mozconfig.no-compile"

View File

@ -1,6 +1,7 @@
ac_add_options --with-l10n-base=../../l10n
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --with-branding=browser/branding/aurora
ac_add_options --disable-nodejs
. "$topsrcdir/build/mozconfig.no-compile"

View File

@ -40,4 +40,6 @@ CFLAGS="$CFLAGS -Wno-attributes"
CPPFLAGS="$CPPFLAGS -Wno-attributes"
CXXFLAGS="$CXXFLAGS -Wno-attributes"
NODEJS="$TOOLTOOL_DIR/node/bin/node"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -3,6 +3,7 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --with-branding=browser/branding/nightly
. "$topsrcdir/build/mozconfig.no-compile"
ac_add_options --disable-nodejs
export MOZILLA_OFFICIAL=1

View File

@ -3,6 +3,7 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --with-branding=browser/branding/aurora
. "$topsrcdir/build/mozconfig.no-compile"
ac_add_options --disable-nodejs
export MOZILLA_OFFICIAL=1

View File

@ -6,6 +6,8 @@ RUSTC="${TOOLTOOL_DIR}/rustc/bin/rustc"
RUSTDOC="${TOOLTOOL_DIR}/rustc/bin/rustdoc"
RUSTFMT="${TOOLTOOL_DIR}/rustc/bin/rustfmt"
export NODEJS="${TOOLTOOL_DIR}/node/bin/node"
CC="${TOOLTOOL_DIR}/gcc/bin/gcc"
CXX="${TOOLTOOL_DIR}/gcc/bin/g++"

View File

@ -13,6 +13,9 @@ ac_add_options --with-l10n-base=../../l10n
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --with-branding=browser/branding/nightly
ac_add_options --disable-nodejs
unset NODEJS
export MOZILLA_OFFICIAL=1
# Enable Telemetry

View File

@ -13,6 +13,9 @@ ac_add_options --with-l10n-base=../../l10n
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --with-branding=browser/branding/aurora
ac_add_options --disable-nodejs
unset NODEJS
if test "${MOZ_UPDATE_CHANNEL}" = "nightly"; then
ac_add_options --with-macbundlename-prefix=Firefox
fi

View File

@ -4,4 +4,5 @@
export MKFSHFS=$topsrcdir/hfsplus-tools/newfs_hfs
export DMG_TOOL=$topsrcdir/dmg/dmg
export HFS_TOOL=$topsrcdir/dmg/hfsplus
export NODEJS=$topsrcdir/node/bin/node
ac_add_options --disable-compile-environment

View File

@ -5,6 +5,9 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --with-l10n-base=../../l10n
ac_add_options --with-branding=browser/branding/nightly
ac_add_options --disable-nodejs
unset NODEJS
export MOZILLA_OFFICIAL=1
# Enable Telemetry

View File

@ -5,6 +5,9 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --with-l10n-base=../../l10n
ac_add_options --with-branding=browser/branding/aurora
ac_add_options --disable-nodejs
unset NODEJS
export MOZILLA_OFFICIAL=1
# Enable Telemetry

View File

@ -6,6 +6,9 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --with-l10n-base=../../l10n
ac_add_options --with-branding=browser/branding/nightly
ac_add_options --disable-nodejs
unset NODEJS
export MOZILLA_OFFICIAL=1
# Enable Telemetry

View File

@ -6,6 +6,9 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --with-l10n-base=../../l10n
ac_add_options --with-branding=browser/branding/aurora
ac_add_options --disable-nodejs
unset NODEJS
export MOZILLA_OFFICIAL=1
# Enable Telemetry

View File

@ -7,6 +7,8 @@ CARGO="${TOOLTOOL_DIR}/rustc/bin/cargo"
RUSTDOC="${TOOLTOOL_DIR}/rustc/bin/rustdoc"
RUSTFMT="${TOOLTOOL_DIR}/rustc/bin/rustfmt"
NODEJS="${TOOLTOOL_DIR}/node/node.exe"
ac_add_options --target=x86_64-pc-mingw32
ac_add_options --host=x86_64-pc-mingw32

View File

@ -126,10 +126,11 @@ function startup(data) {
Services.mm.addMessageListener("FormAutoComplete:MaybeOpenPopup", onMaybeOpenPopup);
formAutofillParent.init().catch(Cu.reportError);
/* exported FormAutofillContent */
/* eslint-disable no-unused-vars */
Services.ppmm.loadProcessScript("data:,new " + function() {
ChromeUtils.import("resource://formautofill/FormAutofillContent.jsm");
}, true);
/* eslint-enable no-unused-vars */
Services.mm.loadFrameScript("chrome://formautofill/content/FormAutofillFrameScript.js", true);
}

View File

@ -7,6 +7,7 @@
"use strict";
// eslint-disable-next-line no-unused-vars
ChromeUtils.import("resource://formautofill/FormAutofill.jsm");
ChromeUtils.import("resource://formautofill/FormAutofillUtils.jsm");

View File

@ -10,7 +10,6 @@ const EDIT_ADDRESS_URL = "chrome://formautofill/content/editAddress.xhtml";
const EDIT_CREDIT_CARD_URL = "chrome://formautofill/content/editCreditCard.xhtml";
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://formautofill/FormAutofill.jsm");
ChromeUtils.defineModuleGetter(this, "CreditCard",

View File

@ -2,25 +2,18 @@
* Provides infrastructure for automated formautofill components tests.
*/
/* exported getTempFile, loadFormAutofillContent, runHeuristicsTest, sinon,
* initProfileStorage, getSyncChangeCounter, objectMatches, bootstrapURI
*/
"use strict";
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
ChromeUtils.import("resource://gre/modules/ObjectUtils.jsm");
ChromeUtils.import("resource://gre/modules/FormLikeFactory.jsm");
ChromeUtils.import("resource://testing-common/FileTestUtils.jsm");
ChromeUtils.import("resource://testing-common/MockDocument.jsm");
ChromeUtils.import("resource://testing-common/TestUtils.jsm");
// eslint-disable-next-line no-unused-vars
ChromeUtils.defineModuleGetter(this, "DownloadPaths",
"resource://gre/modules/DownloadPaths.jsm");
// eslint-disable-next-line no-unused-vars
ChromeUtils.defineModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");

View File

@ -1,6 +1,7 @@
"use strict";
/* global AddressResult, CreditCardResult */
// eslint-disable-next-line no-unused-vars
ChromeUtils.import("resource://formautofill/ProfileAutoCompleteResult.jsm");
let matchingProfiles = [{

View File

@ -19,8 +19,6 @@ var EXPORTED_SYMBOLS = ["PdfJsRegistration"];
const Cm = Components.manager;
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.defineModuleGetter(this, "PdfStreamConverter",
"resource://pdf.js/PdfStreamConverter.jsm");

View File

@ -173,7 +173,7 @@
}
@media (-moz-windows-default-theme) {
#main-menubar > menu {
#main-menubar > menu[_moz-menuactive="true"] {
color: inherit;
}

View File

@ -19,6 +19,7 @@ MOZ_REQUIRE_SIGNING=${MOZ_REQUIRE_SIGNING-0}
ac_add_options --enable-js-shell
. "$topsrcdir/build/mozconfig.node"
. "$topsrcdir/build/mozconfig.automation"
. "$topsrcdir/build/mozconfig.rust"
. "$topsrcdir/build/mozconfig.cache"

12
build/mozconfig.node Normal file
View File

@ -0,0 +1,12 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
case "$(uname -s)" in
MINGW*)
export NODEJS=$topsrcdir/node/node.exe
;;
*)
export NODEJS=$topsrcdir/node/bin/node
;;
esac

View File

@ -317,7 +317,6 @@ skip-if = e10s && debug
uses-unsafe-cpows = true
skip-if = e10s && debug
[browser_dbg_globalactor.js]
skip-if = e10s # TODO
[browser_dbg_hide-toolbar-buttons.js]
skip-if = e10s
[browser_dbg_host-layout.js]
@ -341,7 +340,6 @@ skip-if = e10s && debug
skip-if = e10s && debug
tags = addons
[browser_dbg_listtabs-01.js]
skip-if = e10s # TODO
[browser_dbg_listtabs-02.js]
skip-if = true # Never worked for remote frames, needs a mock DebuggerServerConnection
[browser_dbg_listtabs-03.js]
@ -358,6 +356,5 @@ skip-if = e10s # TODO
[browser_dbg_location-changes-04-breakpoint.js]
skip-if = e10s # TODO
[browser_dbg_multiple-windows.js]
skip-if = e10s # TODO
[browser_dbg_navigation.js]
skip-if = e10s && debug

View File

@ -401,7 +401,6 @@ uses-unsafe-cpows = true
skip-if = e10s && debug
[browser_dbg_target-scoped-actor-01.js]
[browser_dbg_target-scoped-actor-02.js]
skip-if = e10s # TODO
[browser_dbg_terminate-on-tab-close.js]
uses-unsafe-cpows = true
skip-if = e10s && debug

View File

@ -9,9 +9,7 @@
const ACTORS_URL = CHROME_URL + "testactors.js";
function test() {
let gClient;
add_task(async function() {
DebuggerServer.init();
DebuggerServer.registerAllActors();
@ -21,43 +19,39 @@ function test() {
type: { global: true },
});
let transport = DebuggerServer.connectPipe();
gClient = new DebuggerClient(transport);
gClient.connect().then(([aType, aTraits]) => {
is(aType, "browser",
"Root actor should identify itself as a browser.");
const transport = DebuggerServer.connectPipe();
const client = new DebuggerClient(transport);
const [type] = await client.connect();
is(type, "browser",
"Root actor should identify itself as a browser.");
gClient.listTabs().then(aResponse => {
let globalActor = aResponse.testOneActor;
ok(globalActor, "Found the test global actor.");
ok(globalActor.includes("testOne"),
"testGlobalActor1's actorPrefix should be used.");
let response = await client.listTabs();
const globalActor = response.testOneActor;
ok(globalActor, "Found the test global actor.");
ok(globalActor.includes("testOne"),
"testGlobalActor1's actorPrefix should be used.");
gClient.request({ to: globalActor, type: "ping" }, aResponse => {
is(aResponse.pong, "pong", "Actor should respond to requests.");
response = await client.request({ to: globalActor, type: "ping" });
is(response.pong, "pong", "Actor should respond to requests.");
// Send another ping to see if the same actor is used.
gClient.request({ to: globalActor, type: "ping" }, aResponse => {
is(aResponse.pong, "pong", "Actor should respond to requests.");
// Send another ping to see if the same actor is used.
response = await client.request({ to: globalActor, type: "ping" });
is(response.pong, "pong", "Actor should respond to requests.");
// Make sure that lazily-created actors are created only once.
let count = 0;
for (let connID of Object.getOwnPropertyNames(DebuggerServer._connections)) {
let conn = DebuggerServer._connections[connID];
let actorPrefix = conn._prefix + "testOne";
for (let pool of conn._extraPools) {
count += Object.keys(pool._actors).filter(e => {
return e.startsWith(actorPrefix);
}).length;
}
}
// Make sure that lazily-created actors are created only once.
let count = 0;
for (const connID of Object.getOwnPropertyNames(DebuggerServer._connections)) {
const conn = DebuggerServer._connections[connID];
const actorPrefix = conn._prefix + "testOne";
for (let pool of conn._extraPools) {
count += Object.keys(pool._actors).filter(e => {
return e.startsWith(actorPrefix);
}).length;
}
}
is(count, 1,
"Only one actor exists in all pools. One global actor.");
is(count, 1,
"Only one actor exists in all pools. One global actor.");
gClient.close().then(finish);
});
});
});
});
}
await client.close();
});

View File

@ -11,153 +11,92 @@
const TAB1_URL = EXAMPLE_URL + "doc_script-switching-01.html";
const TAB2_URL = EXAMPLE_URL + "doc_script-switching-02.html";
var gNewTab, gNewWindow;
var gClient;
function test() {
add_task(async function() {
DebuggerServer.init();
DebuggerServer.registerAllActors();
let transport = DebuggerServer.connectPipe();
gClient = new DebuggerClient(transport);
gClient.connect().then(([aType, aTraits]) => {
is(aType, "browser",
"Root actor should identify itself as a browser.");
const transport = DebuggerServer.connectPipe();
const client = new DebuggerClient(transport);
const [type] = await client.connect();
is(type, "browser", "Root actor should identify itself as a browser.");
promise.resolve(null)
.then(() => addTab(TAB1_URL))
.then(testFirstTab)
.then(() => addWindow(TAB2_URL))
.then(testNewWindow)
.then(testFocusFirst)
.then(testRemoveTab)
.then(() => gClient.close())
.then(finish)
.catch(aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
});
const tab = await addTab(TAB1_URL);
await testFirstTab(client, tab);
const win = await addWindow(TAB2_URL);
await testNewWindow(client, win);
testFocusFirst(client);
await testRemoveTab(client, win, tab);
await client.close();
});
async function testFirstTab(client, tab) {
ok(!!tab, "Second tab created.");
const response = await client.listTabs();
const targetActor = response.tabs.filter(grip => grip.url == TAB1_URL).pop();
ok(targetActor, "Should find a target actor for the first tab.");
is(response.selected, 1, "The first tab is selected.");
}
function testFirstTab(aTab) {
let deferred = promise.defer();
async function testNewWindow(client, win) {
ok(!!win, "Second window created.");
gNewTab = aTab;
ok(!!gNewTab, "Second tab created.");
win.focus();
gClient.listTabs().then(aResponse => {
let targetActor = aResponse.tabs.filter(aGrip => aGrip.url == TAB1_URL).pop();
ok(targetActor,
"Should find a target actor for the first tab.");
const topWindow = Services.wm.getMostRecentWindow("navigator:browser");
is(topWindow, win, "The second window is on top.");
is(aResponse.selected, 1,
"The first tab is selected.");
deferred.resolve();
});
return deferred.promise;
}
function testNewWindow(aWindow) {
let deferred = promise.defer();
gNewWindow = aWindow;
ok(!!gNewWindow, "Second window created.");
gNewWindow.focus();
let topWindow = Services.wm.getMostRecentWindow("navigator:browser");
is(topWindow, gNewWindow,
"The second window is on top.");
let isActive = promise.defer();
let isLoaded = promise.defer();
promise.all([isActive.promise, isLoaded.promise]).then(() => {
gClient.listTabs().then(aResponse => {
is(aResponse.selected, 2,
"The second tab is selected.");
deferred.resolve();
if (Services.focus.activeWindow != win) {
await new Promise(resolve => {
win.addEventListener("activate", function onActivate(event) {
if (event.target != win) {
return;
}
win.removeEventListener("activate", onActivate, true);
resolve();
}, true);
});
});
if (Services.focus.activeWindow != gNewWindow) {
gNewWindow.addEventListener("activate", function onActivate(aEvent) {
if (aEvent.target != gNewWindow) {
return;
}
gNewWindow.removeEventListener("activate", onActivate, true);
isActive.resolve();
}, true);
} else {
isActive.resolve();
}
let contentLocation = gNewWindow.content.location.href;
if (contentLocation != TAB2_URL) {
gNewWindow.document.addEventListener("load", function onLoad(aEvent) {
if (aEvent.target.documentURI != TAB2_URL) {
return;
}
gNewWindow.document.removeEventListener("load", onLoad, true);
isLoaded.resolve();
}, true);
} else {
isLoaded.resolve();
}
const tab = win.gBrowser.selectedTab;
await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
return deferred.promise;
const response = await client.listTabs();
is(response.selected, 2, "The second tab is selected.");
}
function testFocusFirst() {
let deferred = promise.defer();
once(window.content, "focus").then(() => {
gClient.listTabs().then(aResponse => {
is(aResponse.selected, 1,
"The first tab is selected after focusing on it.");
deferred.resolve();
async function testFocusFirst(client) {
const tab = window.gBrowser.selectedTab;
await ContentTask.spawn(tab.linkedBrowser, {}, async function() {
const onFocus = new Promise(resolve => {
content.addEventListener("focus", resolve, { once: true });
});
await onFocus;
});
window.content.focus();
return deferred.promise;
const response = await client.listTabs();
is(response.selected, 1, "The first tab is selected after focusing on it.");
}
function testRemoveTab() {
let deferred = promise.defer();
gNewWindow.close();
async function testRemoveTab(client, win, tab) {
win.close();
// give it time to close
executeSoon(function () { continue_remove_tab(deferred); });
return deferred.promise;
await new Promise(resolve => executeSoon(resolve));
await continue_remove_tab(client, tab);
}
function continue_remove_tab(deferred)
async function continue_remove_tab(client, tab)
{
removeTab(gNewTab);
removeTab(tab);
gClient.listTabs().then(aResponse => {
// Verify that tabs are no longer included in listTabs.
let foundTab1 = aResponse.tabs.some(aGrip => aGrip.url == TAB1_URL);
let foundTab2 = aResponse.tabs.some(aGrip => aGrip.url == TAB2_URL);
ok(!foundTab1, "Tab1 should be gone.");
ok(!foundTab2, "Tab2 should be gone.");
const response = await client.listTabs();
// Verify that tabs are no longer included in listTabs.
const foundTab1 = response.tabs.some(grip => grip.url == TAB1_URL);
const foundTab2 = response.tabs.some(grip => grip.url == TAB2_URL);
ok(!foundTab1, "Tab1 should be gone.");
ok(!foundTab2, "Tab2 should be gone.");
is(aResponse.selected, 0,
"The original tab is selected.");
deferred.resolve();
});
is(response.selected, 0, "The original tab is selected.");
}
registerCleanupFunction(function () {
gNewTab = null;
gNewWindow = null;
gClient = null;
});

View File

@ -10,72 +10,46 @@
const ACTORS_URL = CHROME_URL + "testactors.js";
const TAB_URL = EXAMPLE_URL + "doc_empty-tab-01.html";
var gClient;
add_task(async function() {
await addTab(TAB_URL);
function test() {
DebuggerServer.init();
DebuggerServer.registerAllActors();
DebuggerServer.registerModule(ACTORS_URL, {
await registerActorInContentProcess(ACTORS_URL, {
prefix: "testOne",
constructor: "TestActor1",
type: { target: true },
});
let transport = DebuggerServer.connectPipe();
gClient = new DebuggerClient(transport);
gClient.connect().then(([aType, aTraits]) => {
is(aType, "browser",
"Root actor should identify itself as a browser.");
const transport = DebuggerServer.connectPipe();
const client = new DebuggerClient(transport);
const [type] = await client.connect();
is(type, "browser",
"Root actor should identify itself as a browser.");
addTab(TAB_URL)
.then(() => attachTargetActorForUrl(gClient, TAB_URL))
.then(testTargetScopedActor)
.then(closeTab)
.then(() => gClient.close())
.then(finish)
.catch(aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
});
}
const [grip] = await attachTargetActorForUrl(client, TAB_URL);
await testTargetScopedActor(client, grip);
await closeTab(client, grip);
await client.close();
});
function testTargetScopedActor([aGrip, aResponse]) {
let deferred = promise.defer();
ok(aGrip.testOneActor,
async function testTargetScopedActor(client, grip) {
ok(grip.testOneActor,
"Found the test target-scoped actor.");
ok(aGrip.testOneActor.includes("testOne"),
ok(grip.testOneActor.includes("testOne"),
"testOneActor's actorPrefix should be used.");
gClient.request({ to: aGrip.testOneActor, type: "ping" }, aResponse => {
is(aResponse.pong, "pong",
"Actor should respond to requests.");
deferred.resolve(aResponse.actor);
});
return deferred.promise;
const response = await client.request({ to: grip.testOneActor, type: "ping" });
is(response.pong, "pong",
"Actor should respond to requests.");
}
function closeTab(aTestActor) {
return removeTab(gBrowser.selectedTab).then(() => {
let deferred = promise.defer();
try {
gClient.request({ to: aTestActor, type: "ping" }, aResponse => {
ok(false, "testTargetScopedActor1 didn't go away with the tab.");
deferred.reject(aResponse);
});
} catch (e) {
is(e.message, "'ping' request packet has no destination.", "testOnActor went away.");
deferred.resolve();
}
return deferred.promise;
});
async function closeTab(client, grip) {
await removeTab(gBrowser.selectedTab);
await Assert.rejects(
client.request({ to: grip.testOneActor, type: "ping" }),
err => err.message === `'ping' active request packet to '${grip.testOneActor}' ` +
`can't be sent as the connection just closed.`,
"testOneActor went away.");
}
registerCleanupFunction(function () {
gClient = null;
});

View File

@ -180,6 +180,7 @@ subsuite = clipboard
[browser_markup_shadowdom_open_debugger.js]
[browser_markup_shadowdom_shadowroot_mode.js]
[browser_markup_shadowdom_show_nodes_button.js]
[browser_markup_shadowdom_slotted_keyboard_focus.js]
[browser_markup_shadowdom_slotupdate.js]
[browser_markup_tag_delete_whitespace_node.js]
[browser_markup_tag_edit_01.js]

View File

@ -0,0 +1,72 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that cycling focus with keyboard (via TAB key) in slotted nodes works.
const TEST_URL = `data:text/html;charset=utf-8,
<test-component>
<div slot="slot1" id="el1">slot1-1</div>
</test-component>
<script>
'use strict';
customElements.define('test-component', class extends HTMLElement {
constructor() {
super();
let shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = '<slot name="slot1"></slot>';
}
});
</script>`;
add_task(async function() {
await enableWebComponents();
const { inspector } = await openInspectorForURL(TEST_URL);
const { markup } = inspector;
const win = inspector.markup.doc.defaultView;
info("Find and expand the test-component shadow DOM host.");
const hostFront = await getNodeFront("test-component", inspector);
const hostContainer = markup.getContainer(hostFront);
await expandContainer(inspector, hostContainer);
info("Expand the shadow root");
const shadowRootContainer = hostContainer.getChildContainers()[0];
await expandContainer(inspector, shadowRootContainer);
info("Expand the slot");
const slotContainer = shadowRootContainer.getChildContainers()[0];
await expandContainer(inspector, slotContainer);
info("Select the slotted container for the element");
const node = slotContainer.getChildContainers()[0].node;
const container = inspector.markup.getContainer(node, true);
await selectNode(node, inspector, "no-reason", true);
const root = inspector.markup.getContainer(inspector.markup._rootNode);
root.elt.focus();
const tagSpan = container.elt.querySelector(".tag");
const revealLink = container.elt.querySelector(".reveal-link");
info("Hit Enter to focus on the first element");
let tagFocused = once(tagSpan, "focus");
EventUtils.synthesizeAndWaitKey("KEY_Enter", {}, win);
await tagFocused;
info("Hit Tab to focus on the next element");
const linkFocused = once(revealLink, "focus");
EventUtils.synthesizeKey("KEY_Tab", {}, win);
await linkFocused;
info("Hit Tab again to cycle focus to the first element");
tagFocused = once(tagSpan, "focus");
EventUtils.synthesizeKey("KEY_Tab", {}, win);
await tagFocused;
ok(inspector.markup.doc.activeElement === tagSpan,
"Focus has gone back to first element");
});

View File

@ -41,6 +41,8 @@ SlottedNodeContainer.prototype = extend(MarkupContainer.prototype, {
},
_onKeyDown: function(event) {
MarkupContainer.prototype._onKeyDown.call(this, event);
const isActionKey = event.code == "Enter" || event.code == "Space";
if (event.target.classList.contains("reveal-link") && isActionKey) {
this._revealFromSlot();

View File

@ -111,7 +111,9 @@ async function getRecordingPreferences(preferenceFront, defaultSettings = {}) {
),
]);
return { entries, interval, features, threads };
// The pref stores the value in usec.
const newInterval = interval / 1000;
return { entries, interval: newInterval, features, threads };
}
/**
@ -130,7 +132,8 @@ async function setRecordingPreferences(preferenceFront, settings) {
),
preferenceFront.setIntPref(
`devtools.performance.recording.interval`,
settings.interval
// The pref stores the value in usec.
settings.interval * 1000
),
preferenceFront.setCharPref(
`devtools.performance.recording.features`,

View File

@ -55,10 +55,10 @@ function isSupportedPlatform(state = null, action) {
// is opened. These should be persisted between sessions. See Bug 1453014.
/**
* The setting for the recording interval.
* The setting for the recording interval. Defaults to 1ms.
* @param {number} state
*/
function interval(state = 1, action) {
function interval(state = 1000, action) {
switch (action.type) {
case "CHANGE_INTERVAL":
return action.interval;

View File

@ -31,8 +31,8 @@
await mountAndInitializeComponent();
is(selectors.getInterval(getState()), 1,
"The interval starts out as 1");
is(selectors.getInterval(getState()), 1000,
"The interval starts out as 1000");
is(recordingPreferencesCalls.length, 0,
"No calls have been made");

View File

@ -7,7 +7,9 @@
// Test the xpcshell-test debug support. Ideally we should have this test
// next to the xpcshell support code, but that's tricky...
function run_test() {
const {getDeviceFront} = require("devtools/shared/fronts/device");
add_task(async function() {
const testFile = do_get_file("xpcshell_debugging_script.js");
// _setupDebuggerServer is from xpcshell-test's head.js
@ -18,37 +20,45 @@ function run_test() {
});
const transport = DebuggerServer.connectPipe();
const client = new DebuggerClient(transport);
client.connect().then(() => {
// Even though we have no tabs, listTabs gives us the chromeDebugger.
client.getProcess().then(response => {
const actor = response.form.actor;
client.attachTab(actor).then(([response, tabClient]) => {
tabClient.attachThread(null).then(([response, threadClient]) => {
threadClient.addOneTimeListener("paused", (event, packet) => {
equal(packet.why.type, "breakpoint",
"yay - hit the breakpoint at the first line in our script");
// Resume again - next stop should be our "debugger" statement.
threadClient.addOneTimeListener("paused", (event, packet) => {
equal(packet.why.type, "debuggerStatement",
"yay - hit the 'debugger' statement in our script");
threadClient.resume(() => {
finishClient(client);
});
});
threadClient.resume();
});
// tell the thread to do the initial resume. This would cause the
// xpcshell test harness to resume and load the file under test.
threadClient.resume(response => {
// should have been told to resume the test itself.
ok(testResumed);
// Now load our test script.
load(testFile.path);
// and our "paused" listener above should get hit.
});
});
await client.connect();
// Ensure that global actors are available. Just test the device actor.
const rootForm = await client.mainRoot.getRoot();
const deviceFront = await getDeviceFront(client, rootForm);
const desc = await deviceFront.getDescription();
equal(desc.geckobuildid, Services.appinfo.platformBuildID, "device actor works");
// Even though we have no tabs, getProcess gives us the chromeDebugger.
const response = await client.getProcess();
const actor = response.form.actor;
const [, tabClient] = await client.attachTab(actor);
const [, threadClient] = await tabClient.attachThread(null);
const onResumed = new Promise(resolve => {
threadClient.addOneTimeListener("paused", (event, packet) => {
equal(packet.why.type, "breakpoint",
"yay - hit the breakpoint at the first line in our script");
// Resume again - next stop should be our "debugger" statement.
threadClient.addOneTimeListener("paused", (event, packet) => {
equal(packet.why.type, "debuggerStatement",
"yay - hit the 'debugger' statement in our script");
threadClient.resume(resolve);
});
threadClient.resume();
});
});
do_test_pending();
}
// tell the thread to do the initial resume. This would cause the
// xpcshell test harness to resume and load the file under test.
threadClient.resume(() => {
// should have been told to resume the test itself.
ok(testResumed);
// Now load our test script.
load(testFile.path);
// and our "paused" listener above should get hit.
});
await onResumed;
finishClient(client);
});

View File

@ -2104,6 +2104,10 @@ Selection::RemoveAllRangesTemporarily()
RemoveAllRanges(result);
if (result.Failed()) {
mCachedRange = nullptr;
} else if (mCachedRange) {
// To save the computing cost to keep valid DOM point against DOM tree
// changes, we should clear the range temporarily.
mCachedRange->ResetTemporarily();
}
return result.StealNSResult();
}

View File

@ -662,6 +662,12 @@ private:
// released by Clear(), RemoveAllRangesTemporarily() stores it with this.
// If Collapse() is called without existing ranges, it'll reuse this range
// for saving the creation cost.
// Note that while the range is cached by this, we keep the range being
// a mutation observer because it is not so cheap to register the range
// as a mutation observer again. On the other hand, we make it not
// positioned because it is not so cheap to keep valid DOM point against
// mutations. This does not cause any problems because we will set new
// DOM point when we treat it as a range of Selection again.
RefPtr<nsRange> mCachedRange;
RefPtr<nsFrameSelection> mFrameSelection;
RefPtr<nsAutoScrollTimer> mAutoScrollTimer;

View File

@ -5654,6 +5654,10 @@ nsIDocument::CreateXULElement(const nsAString& aTagName,
}
RefPtr<Element> elem = CreateElem(aTagName, nullptr, kNameSpaceID_XUL, is);
if (!elem) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return nullptr;
}
return elem.forget();
}
@ -9578,6 +9582,13 @@ nsIDocument::CreateStaticClone(nsIDocShell* aCloneContainer)
}
}
}
// Font faces created with the JS API will not be reflected in the
// stylesheets and need to be copied over to the cloned document.
if (const FontFaceSet* set = GetFonts()) {
set->CopyNonRuleFacesTo(clonedDoc->Fonts());
}
}
}
mCreatingStaticClone = false;

View File

@ -491,9 +491,15 @@ void
nsRange::CharacterDataChanged(nsIContent* aContent,
const CharacterDataChangeInfo& aInfo)
{
// If this is called when this is not positioned, it means that this range
// will be initialized again or destroyed soon. See Selection::mCachedRange.
if (!mIsPositioned) {
MOZ_ASSERT(mRoot);
return;
}
MOZ_ASSERT(!mNextEndRef);
MOZ_ASSERT(!mNextStartRef);
MOZ_ASSERT(mIsPositioned, "shouldn't be notified if not positioned");
nsINode* newRoot = nullptr;
RawRangeBoundary newStart;
@ -645,7 +651,12 @@ nsRange::CharacterDataChanged(nsIContent* aContent,
void
nsRange::ContentAppended(nsIContent* aFirstNewContent)
{
NS_ASSERTION(mIsPositioned, "shouldn't be notified if not positioned");
// If this is called when this is not positioned, it means that this range
// will be initialized again or destroyed soon. See Selection::mCachedRange.
if (!mIsPositioned) {
MOZ_ASSERT(mRoot);
return;
}
nsINode* container = aFirstNewContent->GetParentNode();
MOZ_ASSERT(container);
@ -680,7 +691,12 @@ nsRange::ContentAppended(nsIContent* aFirstNewContent)
void
nsRange::ContentInserted(nsIContent* aChild)
{
MOZ_ASSERT(mIsPositioned, "shouldn't be notified if not positioned");
// If this is called when this is not positioned, it means that this range
// will be initialized again or destroyed soon. See Selection::mCachedRange.
if (!mIsPositioned) {
MOZ_ASSERT(mRoot);
return;
}
bool updateBoundaries = false;
nsINode* container = aChild->GetParentNode();
@ -730,7 +746,13 @@ nsRange::ContentInserted(nsIContent* aChild)
void
nsRange::ContentRemoved(nsIContent* aChild, nsIContent* aPreviousSibling)
{
MOZ_ASSERT(mIsPositioned, "shouldn't be notified if not positioned");
// If this is called when this is not positioned, it means that this range
// will be initialized again or destroyed soon. See Selection::mCachedRange.
if (!mIsPositioned) {
MOZ_ASSERT(mRoot);
return;
}
nsINode* container = aChild->GetParentNode();
MOZ_ASSERT(container);
@ -937,17 +959,17 @@ nsRange::DoSetRange(const RawRangeBoundary& aStart,
nsINode* aRoot, bool aNotInsertedYet)
{
MOZ_ASSERT((aStart.IsSet() && aEnd.IsSet() && aRoot) ||
(!aStart.IsSet() && !aEnd.IsSet() && !aRoot),
(!aStart.IsSet() && !aEnd.IsSet()),
"Set all or none");
MOZ_ASSERT(!aRoot || aNotInsertedYet ||
MOZ_ASSERT(!aRoot || (!aStart.IsSet() && !aEnd.IsSet()) || aNotInsertedYet ||
(nsContentUtils::ContentIsDescendantOf(aStart.Container(), aRoot) &&
nsContentUtils::ContentIsDescendantOf(aEnd.Container(), aRoot) &&
aRoot == IsValidBoundary(aStart.Container()) &&
aRoot == IsValidBoundary(aEnd.Container())),
"Wrong root");
MOZ_ASSERT(!aRoot ||
MOZ_ASSERT(!aRoot || (!aStart.IsSet() && !aEnd.IsSet()) ||
(aStart.Container()->IsContent() &&
aEnd.Container()->IsContent() &&
aRoot ==

View File

@ -158,6 +158,17 @@ public:
nsINode* GetCommonAncestor() const;
void Reset();
/**
* ResetTemporarily() is called when Selection starts to cache the instance
* to reuse later. This method clears mStart, mEnd and mIsPositioned but
* does not clear mRoot for reducing the cost to register this as a mutation
* observer again.
*/
void ResetTemporarily()
{
DoSetRange(RawRangeBoundary(), RawRangeBoundary(), mRoot);
}
/**
* SetStart() and SetEnd() sets start point or end point separately.
* However, this is expensive especially when it's a range of Selection.

View File

@ -6,7 +6,6 @@
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
/** This little class ensures that redirects maintain an https:// origin */
function RedirectHttpsOnly() {}

View File

@ -2331,6 +2331,11 @@ MediaStream::AddListenerImpl(already_AddRefed<MediaStreamListener> aListener)
// TrackUnionStream guarantees that each of its tracks has an input track.
// Other types do not implement GetInputStreamFor() and will return null.
inputStream = ps->GetInputStreamFor(it->GetID());
if (!inputStream && it->IsEnded()) {
// If this track has no input anymore we assume there's no data for the
// current iteration either and thus no need to expose it to a listener.
continue;
}
MOZ_ASSERT(inputStream);
inputTrackID = ps->GetInputTrackIDFor(it->GetID());
MOZ_ASSERT(IsTrackIDExplicit(inputTrackID));

View File

@ -5,8 +5,6 @@
var EXPORTED_SYMBOLS = ["PeerConnectionIdp"];
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.defineModuleGetter(this, "IdpSandbox",
"resource://gre/modules/media/IdpSandbox.jsm");
@ -344,4 +342,3 @@ PeerConnectionIdp.prototype = {
return this._win.Promise.race([ timeout, p ]);
}
};

View File

@ -1472,13 +1472,15 @@ XMLHttpRequestMainThread::Open(const nsACString& aMethod,
// Step 8
nsAutoCString host;
parsedURL->GetHost(host);
if (!host.IsEmpty()) {
if (!aUsername.IsVoid() || !aPassword.IsVoid()) {
Unused << NS_MutateURI(parsedURL)
.SetUsername(NS_ConvertUTF16toUTF8(aUsername))
.SetPassword(NS_ConvertUTF16toUTF8(aPassword))
.Finalize(parsedURL);
if (!host.IsEmpty() && (!aUsername.IsVoid() || !aPassword.IsVoid())) {
auto mutator = NS_MutateURI(parsedURL);
if (!aUsername.IsVoid()) {
mutator.SetUsername(NS_ConvertUTF16toUTF8(aUsername));
}
if (!aPassword.IsVoid()) {
mutator.SetPassword(NS_ConvertUTF16toUTF8(aPassword));
}
Unused << mutator.Finalize(parsedURL);
}
// Step 9

View File

@ -117,11 +117,45 @@ VRDisplayExternal::StartPresentation()
mBrowserState.layerState[0].type = VRLayerType::LayerType_Stereo_Immersive;
PushState();
#if defined(MOZ_WIDGET_ANDROID)
/**
* Android compositor is paused when presentation starts. That causes VRManager::NotifyVsync() not to be called.
* We post a VRTask to call VRManager::NotifyVsync() while the compositor is paused on Android.
* VRManager::NotifyVsync() should be called constinuosly while the compositor is paused because Gecko WebVR Architecture
* relies on that to act as a "watchdog" in order to avoid render loop stalls and recover from SubmitFrame call timeouts.
*/
PostVRTask();
#endif
// TODO - Implement telemetry:
// mTelemetry.mLastDroppedFrameCount = stats.m_nNumReprojectedFrames;
}
#if defined(MOZ_WIDGET_ANDROID)
void
VRDisplayExternal::PostVRTask() {
MessageLoop * vrLoop = VRListenerThreadHolder::Loop();
if (!vrLoop || !mBrowserState.presentationActive) {
return;
}
RefPtr<Runnable> task = NewRunnableMethod(
"VRDisplayExternal::RunVRTask",
this,
&VRDisplayExternal::RunVRTask);
VRListenerThreadHolder::Loop()->PostDelayedTask(task.forget(), 50);
}
void
VRDisplayExternal::RunVRTask() {
if (mBrowserState.presentationActive) {
VRManager *vm = VRManager::Get();
vm->NotifyVsync(TimeStamp::Now());
PostVRTask();
}
}
#endif // defined(MOZ_WIDGET_ANDROID)
void
VRDisplayExternal::StopPresentation()
{

View File

@ -60,6 +60,8 @@ private:
void PushState(bool aNotifyCond = false);
#if defined(MOZ_WIDGET_ANDROID)
bool PullState(const std::function<bool()>& aWaitCondition = nullptr);
void PostVRTask();
void RunVRTask();
#else
bool PullState();
#endif

View File

@ -24,6 +24,7 @@
#include "wasm/AsmJS.h"
#include "vm/EnvironmentObject-inl.h"
#include "vm/GeckoProfiler-inl.h"
#include "vm/JSObject-inl.h"
#include "vm/JSScript-inl.h"
@ -333,12 +334,16 @@ BytecodeCompiler::compileScript(HandleObject environment, SharedContext* sc)
for (;;) {
ParseNode* pn;
if (sc->isEvalContext())
pn = parser->evalBody(sc->asEvalContext());
else
pn = parser->globalBody(sc->asGlobalContext());
{
AutoGeckoProfilerEntry pseudoFrame(cx, "script parsing");
if (sc->isEvalContext())
pn = parser->evalBody(sc->asEvalContext());
else
pn = parser->globalBody(sc->asGlobalContext());
}
// Successfully parsed. Emit the script.
AutoGeckoProfilerEntry pseudoFrame(cx, "script emit");
if (pn) {
if (sc->isEvalContext() && sc->hasDebuggerStatement() && !cx->helperThread()) {
// If the eval'ed script contains any debugger statement, force construction

View File

@ -13,6 +13,8 @@ support-files =
printpreview_bug396024_helper.xul
printpreview_bug482976_helper.xul
printpreview_helper.xul
printpreview_font_api.html
printpreview_font_api_ref.html
file_bug1018265.xul
[test_bug396367-1.html]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -280,6 +280,32 @@ function runTest7() {
exitprintpreview();
ok(compareCanvases(), "Printing light DOM and shadow DOM should create same output");
requestAnimationFrame(function() { setTimeout(runTest8); } );
}
async function runTest8() {
// Test that fonts loaded with CSS and JS are printed the same.
const iframeElement = document.getElementsByTagName("iframe")[0];
// First, snapshot the page with font defined in CSS.
await new Promise((resolve) => {
iframeElement.addEventListener("load", resolve, { capture: true, once: true });
iframeElement.setAttribute("src", "printpreview_font_api_ref.html");
});
printpreview();
ctx1.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(255,255,255)");
exitprintpreview();
// Second, snapshot the page with font loaded in JS.
await new Promise((resolve) => {
iframeElement.addEventListener("message", resolve, { capture: true, once: true });
iframeElement.setAttribute("src", "printpreview_font_api.html");
});
printpreview();
ctx2.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(255,255,255)");
exitprintpreview();
ok(compareCanvases(), "Printing pages with fonts loaded from CSS and JS should be the same.");
finish();
}

View File

@ -1936,6 +1936,17 @@ FontFaceSet::RefreshStandardFontLoadPrincipal()
}
}
void
FontFaceSet::CopyNonRuleFacesTo(FontFaceSet* aFontFaceSet) const
{
for (const FontFaceRecord& rec : mNonRuleFaces) {
ErrorResult rv;
RefPtr<FontFace> f = rec.mFontFace;
aFontFaceSet->Add(*f, rv);
MOZ_ASSERT(!rv.Failed());
}
}
// -- FontFaceSet::UserFontSet ------------------------------------------------
/* virtual */ bool

View File

@ -177,6 +177,8 @@ public:
void RefreshStandardFontLoadPrincipal();
void CopyNonRuleFacesTo(FontFaceSet* aFontFaceSet) const;
nsIDocument* Document() const { return mDocument; }
// -- Web IDL --------------------------------------------------------------

View File

@ -933,7 +933,7 @@ def run_test_harness(parser, options):
# We have to validate options.app here for the case when the mach
# command is able to find it after argument parsing. This can happen
# when running from a tests.zip.
# when running from a tests archive.
if not options.app:
parser.error("could not find the application path, --appname must be specified")

View File

@ -36,6 +36,11 @@
<!-- Tab Queue -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
#ifdef MOZ_UPDATER
<!-- To be able to install Nightly app updates on API 26+ -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
#endif
#ifdef MOZ_ANDROID_BEAM
<!-- Android Beam support -->
<uses-permission android:name="android.permission.NFC"/>

View File

@ -2,8 +2,6 @@
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
ChromeUtils.import("resource://gre/modules/Task.jsm");
ChromeUtils.defineModuleGetter(this, "Sanitizer",
"resource://gre/modules/Sanitizer.jsm");
ChromeUtils.defineModuleGetter(this, "Services",

View File

@ -15,6 +15,8 @@ mk_add_options AUTOCLOBBER=
# Global options
ac_add_options --disable-tests
ac_add_options --disable-nodejs
unset NODEJS
ac_add_options --enable-updater
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}

View File

@ -15,6 +15,8 @@ mk_add_options AUTOCLOBBER=
# Global options
ac_add_options --disable-tests
ac_add_options --disable-nodejs
unset NODEJS
ac_add_options --enable-updater
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}

View File

@ -15,6 +15,8 @@ mk_add_options AUTOCLOBBER=
# Global options
ac_add_options --disable-tests
ac_add_options --disable-nodejs
unset NODEJS
ac_add_options --enable-updater
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}

View File

@ -4,8 +4,6 @@
"use strict";
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/Messaging.jsm");
var EXPORTED_SYMBOLS = ["BrowserActions"];

View File

@ -6,7 +6,6 @@ var EXPORTED_SYMBOLS = ["LightweightThemeConsumer"];
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/LightweightThemeManager.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.defineModuleGetter(this, "EventDispatcher",
"resource://gre/modules/Messaging.jsm");

View File

@ -4,7 +4,6 @@
"use strict";
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Messaging.jsm");
ChromeUtils.import("resource://gre/modules/UITelemetry.jsm");
@ -171,4 +170,3 @@ handlers.wifi = {
}
}
};

View File

@ -6,8 +6,6 @@
var EXPORTED_SYMBOLS = ["RuntimePermissions"];
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.defineModuleGetter(this, "EventDispatcher",
"resource://gre/modules/Messaging.jsm");

View File

@ -7,8 +7,6 @@
var EXPORTED_SYMBOLS = ["SharedPreferences"];
// For adding observers.
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/Messaging.jsm");
var Scope = Object.freeze({

View File

@ -6,8 +6,6 @@
var EXPORTED_SYMBOLS = ["Snackbars"];
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.defineModuleGetter(this, "EventDispatcher", "resource://gre/modules/Messaging.jsm");
const LENGTH_INDEFINITE = -2;

View File

@ -6,7 +6,6 @@
var EXPORTED_SYMBOLS = ["GeckoViewContentModule"];
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/GeckoViewUtils.jsm");
GeckoViewUtils.initLogging("GeckoView.Module.[C]", this);

View File

@ -6,7 +6,6 @@
var EXPORTED_SYMBOLS = ["GeckoViewModule"];
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/GeckoViewUtils.jsm");
GeckoViewUtils.initLogging("GeckoView.Module", this);

View File

@ -7,7 +7,6 @@
var EXPORTED_SYMBOLS = ["GeckoViewTab"];
ChromeUtils.import("resource://gre/modules/GeckoViewModule.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
// Stub BrowserApp implementation for WebExtensions support.
class GeckoViewTab extends GeckoViewModule {

View File

@ -7,7 +7,6 @@
var EXPORTED_SYMBOLS = ["GeckoViewTrackingProtection"];
ChromeUtils.import("resource://gre/modules/GeckoViewModule.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
class GeckoViewTrackingProtection extends GeckoViewModule {
onEnable() {

View File

@ -573,7 +573,7 @@ def find_files(archive):
if archive == 'common':
# Construct entries ensuring all our generated harness files are
# packaged in the common tests zip.
# packaged in the common tests archive.
packaged_paths = set()
for entry in OBJDIR_TEST_FILES.values():
pat = mozpath.join(entry['base'], entry['pattern'])

View File

@ -2,9 +2,8 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import sqlite3 as lite
import os
import time
import sqlite3 as lite
class Node(object):
@ -57,6 +56,7 @@ class Graph(object):
print ('\n Tup db does not have the necessary tables.')
raise Exception
self.node_dict = {}
self.results = None
def table_check(self):
tables = [x[0] for x in self.query_arg('SELECT name \
@ -114,3 +114,18 @@ class Graph(object):
\nTotal cost (mm:ss) = %d:%d\nNum Downstream Commands = %d"
% (f, m, s, node.num_cmds))
def populate(self):
# make nodes for files with downstream commands
files = self.query('SELECT id FROM node WHERE type=0 AND id in \
(SELECT DISTINCT from_id FROM normal_link)').fetchall()
res = []
for (i,) in files:
node = self.get_node(i)
res.append((node.path, node.cost))
self.results = res
def get_cost_dict(self):
if self.results is None:
self.populate()
return {k:v for k,v in self.results if v > 0}

View File

@ -144,7 +144,8 @@ class ArtifactJob(object):
# We can tell our input is a test archive by this suffix, which happens to
# be the same across platforms.
_test_archive_suffixes = ('.common.tests.zip', '.common.tests.tar.gz')
_test_zip_archive_suffix = '.common.tests.zip'
_test_tar_archive_suffix = '.common.tests.tar.gz'
def __init__(self, package_re, tests_re, log=None,
download_symbols=False,
@ -190,8 +191,10 @@ class ArtifactJob(object):
'found none!'.format(re=self._tests_re))
def process_artifact(self, filename, processed_filename):
if filename.endswith(ArtifactJob._test_archive_suffixes) and self._tests_re:
return self.process_tests_artifact(filename, processed_filename)
if filename.endswith(ArtifactJob._test_zip_archive_suffix) and self._tests_re:
return self.process_tests_zip_artifact(filename, processed_filename)
if filename.endswith(ArtifactJob._test_tar_archive_suffix) and self._tests_re:
return self.process_tests_tar_artifact(filename, processed_filename)
if self._symbols_archive_suffix and filename.endswith(self._symbols_archive_suffix):
return self.process_symbols_archive(filename, processed_filename)
if self._host_bins_re:
@ -206,7 +209,7 @@ class ArtifactJob(object):
def process_package_artifact(self, filename, processed_filename):
raise NotImplementedError("Subclasses must specialize process_package_artifact!")
def process_tests_artifact(self, filename, processed_filename):
def process_tests_zip_artifact(self, filename, processed_filename):
from mozbuild.action.test_archive import OBJDIR_TEST_FILES
added_entry = False
@ -242,6 +245,43 @@ class ArtifactJob(object):
'matched an archive path.'.format(
patterns=LinuxArtifactJob.test_artifact_patterns))
def process_tests_tar_artifact(self, filename, processed_filename):
from mozbuild.action.test_archive import OBJDIR_TEST_FILES
added_entry = False
with JarWriter(file=processed_filename, optimize=False, compress_level=5) as writer:
with tarfile.open(filename) as reader:
for filename, entry in TarFinder(filename, reader):
for pattern, (src_prefix, dest_prefix) in self.test_artifact_patterns:
if not mozpath.match(filename, pattern):
continue
destpath = mozpath.relpath(filename, src_prefix)
destpath = mozpath.join(dest_prefix, destpath)
self.log(logging.INFO, 'artifact',
{'destpath': destpath},
'Adding {destpath} to processed archive')
mode = entry.mode
writer.add(destpath.encode('utf-8'), entry.open(), mode=mode)
added_entry = True
break
for files_entry in OBJDIR_TEST_FILES.values():
origin_pattern = files_entry['pattern']
leaf_filename = filename
if 'dest' in files_entry:
dest = files_entry['dest']
origin_pattern = mozpath.join(dest, origin_pattern)
leaf_filename = filename[len(dest) + 1:]
if mozpath.match(filename, origin_pattern):
destpath = mozpath.join('..', files_entry['base'], leaf_filename)
mode = entry.mode
writer.add(destpath.encode('utf-8'), entry.open(), mode=mode)
if not added_entry:
raise ValueError('Archive format changed! No pattern from "{patterns}"'
'matched an archive path.'.format(
patterns=LinuxArtifactJob.test_artifact_patterns))
def process_symbols_archive(self, filename, processed_filename):
with JarWriter(file=processed_filename, optimize=False, compress_level=5) as writer:
reader = JarReader(filename)

View File

@ -5,6 +5,7 @@
from __future__ import absolute_import, unicode_literals
import os
import gzip
import itertools
import json
import sys
@ -12,6 +13,7 @@ import shutil
import mozpack.path as mozpath
from mozbuild import shellutil
from mozbuild.analyze.graph import Graph
from mozbuild.base import MozbuildObject
from mozbuild.backend.base import PartialBackend, HybridBackend
from mozbuild.backend.recursivemake import RecursiveMakeBackend
@ -303,12 +305,14 @@ class TupBackend(CommonBackend):
line_handler=output.on_line,
ensure_exit_code=False,
append_env=self._get_mozconfig_env(config))
# upload Tup db
if (not status and
self.environment.substs.get('MOZ_AUTOMATION') and self.environment.substs.get('UPLOAD_TUP_DB')):
if not status and self.environment.substs.get('MOZ_AUTOMATION'):
src = mozpath.join(self.environment.topsrcdir, '.tup')
dst = mozpath.join(os.environ['UPLOAD_PATH'], 'tup_db')
shutil.make_archive(dst, 'zip', src)
dst = os.environ['UPLOAD_PATH']
if self.environment.substs.get('UPLOAD_TUP_DB'):
shutil.make_archive(mozpath.join(dst, 'tup_db'), 'zip', src)
g = Graph(mozpath.join(src, 'db'))
with gzip.open(mozpath.join(dst, 'cost_dict.gz'), 'wt') as outfile:
json.dump(g.get_cost_dict(), outfile)
return status
def _get_backend_file(self, relobjdir):

View File

@ -0,0 +1,129 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "CredentialManagerSecret.h"
#include <wincred.h>
#include <windows.h>
#include "mozilla/Logging.h"
#include "mozilla/SyncRunnable.h"
// This is the implementation of CredentialManagerSecretSecret, an instantiation
// of OSKeyStore for Windows. It uses the system credential manager, hence the
// name.
using namespace mozilla;
LazyLogModule gCredentialManagerSecretLog("credentialmanagersecret");
struct ScopedDelete
{
void operator()(CREDENTIALA* cred) { CredFree(cred); }
};
template<class T>
struct ScopedMaybeDelete
{
void operator()(T* ptr)
{
if (ptr) {
ScopedDelete del;
del(ptr);
}
}
};
typedef std::unique_ptr<CREDENTIALA, ScopedMaybeDelete<CREDENTIALA>> ScopedCREDENTIALA;
CredentialManagerSecret::CredentialManagerSecret() {}
CredentialManagerSecret::~CredentialManagerSecret() {}
nsresult
CredentialManagerSecret::Lock()
{
// The Windows credential manager can't be locked.
return NS_OK;
}
nsresult
CredentialManagerSecret::Unlock()
{
// The Windows credential manager is always unlocked when the user is logged
// in.
return NS_OK;
}
nsresult
CredentialManagerSecret::StoreSecret(const nsACString& aSecret,
const nsACString& aLabel)
{
if (aSecret.Length() > CRED_MAX_CREDENTIAL_BLOB_SIZE) {
// Windows doesn't allow blobs larger than CRED_MAX_CREDENTIAL_BLOB_SIZE
// bytes.
MOZ_LOG(gCredentialManagerSecretLog,
LogLevel::Debug,
("StoreSecret secret must not be larger than 512 bytes (got %d)",
aSecret.Length()));
return NS_ERROR_FAILURE;
}
CREDENTIALA cred = { 0 };
cred.Type = CRED_TYPE_GENERIC;
const nsCString& label = PromiseFlatCString(aLabel);
cred.TargetName = const_cast<LPSTR>(label.get());
cred.CredentialBlobSize = aSecret.Length();
const nsCString& secret = PromiseFlatCString(aSecret);
cred.CredentialBlob = (LPBYTE)secret.get();
cred.Persist = CRED_PERSIST_LOCAL_MACHINE;
cred.UserName = "";
// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credwritea
BOOL ok = CredWriteA(&cred, 0);
if (!ok) {
MOZ_LOG(gCredentialManagerSecretLog,
LogLevel::Debug,
("CredWriteW failed %d", GetLastError()));
NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
CredentialManagerSecret::DeleteSecret(const nsACString& aLabel)
{
// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-creddeletea
const nsCString& label = PromiseFlatCString(aLabel);
BOOL ok = CredDeleteA(label.get(), CRED_TYPE_GENERIC, 0);
int error = GetLastError();
if (!ok && error != ERROR_NOT_FOUND) {
MOZ_LOG(gCredentialManagerSecretLog,
LogLevel::Debug,
("CredDeleteA failed %d", error));
NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
CredentialManagerSecret::RetrieveSecret(const nsACString& aLabel,
/* out */ nsACString& aSecret)
{
aSecret.Truncate();
PCREDENTIALA pcred_raw = nullptr;
const nsCString& label = PromiseFlatCString(aLabel);
// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credreada
BOOL ok = CredReadA(label.get(), CRED_TYPE_GENERIC, 0, &pcred_raw);
ScopedCREDENTIALA pcred(pcred_raw);
if (!ok) {
MOZ_LOG(gCredentialManagerSecretLog,
LogLevel::Debug,
("CredReadA failed %d", GetLastError()));
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(pcred);
aSecret.Assign(reinterpret_cast<const char*>(pcred->CredentialBlob),
pcred->CredentialBlobSize);
return NS_OK;
}

View File

@ -0,0 +1,29 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef CredentialManagerSecret_h
#define CredentialManagerSecret_h
#include "OSKeyStore.h"
#include "nsString.h"
class CredentialManagerSecret final : public AbstractOSKeyStore
{
public:
CredentialManagerSecret();
virtual nsresult RetrieveSecret(const nsACString& label,
/* out */ nsACString& secret) override;
virtual nsresult StoreSecret(const nsACString& secret,
const nsACString& label) override;
virtual nsresult DeleteSecret(const nsACString& label) override;
virtual nsresult Lock() override;
virtual nsresult Unlock() override;
virtual ~CredentialManagerSecret();
};
#endif // CredentialManagerSecret_h

View File

@ -15,6 +15,8 @@
#include "LibSecret.h"
#elif defined(XP_MACOSX)
#include "KeychainSecret.h"
#elif defined(XP_WIN)
#include "CredentialManagerSecret.h"
#else
#include "NSSKeyStore.h"
#endif
@ -33,6 +35,8 @@ OSKeyStore::OSKeyStore()
mKs.reset(new LibSecret());
#elif defined(XP_MACOSX)
mKs.reset(new KeychainSecret());
#elif defined(XP_WIN)
mKs.reset(new CredentialManagerSecret());
#else
mKs.reset(new NSSKeyStore());
#endif

View File

@ -155,6 +155,11 @@ if CONFIG['OS_ARCH'] == 'Darwin':
'-framework Security'
]
if CONFIG['OS_ARCH'] == 'WINNT':
UNIFIED_SOURCES += [
'CredentialManagerSecret.cpp',
]
IPDL_SOURCES += [
'PPSMContentDownloader.ipdl',
]

View File

@ -15,8 +15,7 @@ const LABELS = ["mylabel1",
async function delete_all_secrets() {
let keystore = Cc["@mozilla.org/security/oskeystore;1"]
.getService(Ci.nsIOSKeyStore);
for (let i in LABELS) {
let label = LABELS[i];
for (let label of LABELS) {
if (await keystore.asyncSecretAvailable(label)) {
await keystore.asyncDeleteSecret(label);
ok(!await keystore.asyncSecretAvailable(label), label + " should be deleted now.");
@ -114,8 +113,8 @@ add_task(async function() {
await encrypt_decrypt_test();
await delete_all_secrets();
if (AppConstants.platform == "macosx") {
ok(!keystore.isNSSKeyStore, "OS X should use the non-NSS implementation");
if (AppConstants.platform == "macosx" || AppConstants.platform == "win") {
ok(!keystore.isNSSKeyStore, "OS X and Windows should use the non-NSS implementation");
}
if (keystore.isNSSKeyStore) {

View File

@ -787,25 +787,29 @@ add_task(async function test_onPageAnnoChanged() {
await tracker.stop();
_("Insert a bookmark without an annotation");
let pageURI = CommonUtils.makeURI("http://getfirefox.com");
PlacesUtils.bookmarks.insertBookmark(
PlacesUtils.bookmarks.bookmarksMenuFolder,
pageURI,
PlacesUtils.bookmarks.DEFAULT_INDEX,
"Get Firefox!");
let pageURI = "http://getfirefox.com";
await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.menuGuid,
url: pageURI,
title: "Get Firefox!",
});
await startTracking();
_("Add a page annotation");
PlacesUtils.annotations.setPageAnnotation(pageURI, "URIProperties/characterSet",
"UTF-8", 0, PlacesUtils.annotations.EXPIRE_NEVER);
await PlacesUtils.history.update({
url: pageURI,
annotations: new Map([[PlacesUtils.CHARSET_ANNO, "UTF-16"]]),
});
await verifyTrackedItems([]);
Assert.equal(tracker.score, 0);
await resetTracker();
_("Remove the page annotation");
PlacesUtils.annotations.removePageAnnotation(pageURI,
"URIProperties/characterSet");
await PlacesUtils.history.update({
url: pageURI,
annotations: new Map([[PlacesUtils.CHARSET_ANNO, null]]),
});
await verifyTrackedItems([]);
Assert.equal(tracker.score, 0);
} finally {

View File

@ -42,3 +42,5 @@ jobs:
tooltool-downloads: public
need-xvfb: true
keep-artifacts: false
toolchains:
- linux64-node

View File

@ -37,6 +37,7 @@ android-test/opt:
toolchains:
- android-gradle-dependencies
- android-sdk-linux
- linux64-node
optimization:
skip-unless-changed:
- "mobile/android/base/**"
@ -79,6 +80,7 @@ android-test-ccov/opt:
toolchains:
- android-gradle-dependencies
- android-sdk-linux
- linux64-node
fetches:
fetch:
- grcov-linux-x86_64
@ -125,6 +127,7 @@ android-lint/opt:
toolchains:
- android-gradle-dependencies
- android-sdk-linux
- linux64-node
optimization:
skip-unless-changed:
- "mobile/android/**/*.java"
@ -178,6 +181,7 @@ android-checkstyle/opt:
toolchains:
- android-gradle-dependencies
- android-sdk-linux
- linux64-node
optimization:
skip-unless-changed:
- "mobile/android/**/checkstyle.xml"
@ -227,6 +231,7 @@ android-findbugs/opt:
toolchains:
- android-gradle-dependencies
- android-sdk-linux
- linux64-node
optimization:
skip-unless-changed:
- "mobile/android/**/*.java"
@ -271,6 +276,7 @@ android-geckoview-docs/opt:
toolchains:
- android-gradle-dependencies
- android-sdk-linux
- linux64-node
optimization:
skip-unless-changed:
- "mobile/android/**/*.java"

View File

@ -46,6 +46,7 @@ android-api-16/debug:
- linux64-rust-android
- linux64-rust-size
- linux64-sccache
- linux64-node
android-x86/opt:
description: "Android 4.2 x86 Opt"
@ -95,6 +96,7 @@ android-x86/opt:
- linux64-rust-android
- linux64-rust-size
- linux64-sccache
- linux64-node
android-x86-nightly/opt:
description: "Android 4.2 x86 Nightly"
@ -150,6 +152,7 @@ android-x86-nightly/opt:
- linux64-rust-android
- linux64-rust-size
- linux64-sccache
- linux64-node
android-api-16/opt:
description: "Android 4.0 api-16+ Opt"
@ -199,6 +202,7 @@ android-api-16/opt:
- linux64-rust-android
- linux64-rust-size
- linux64-sccache
- linux64-node
android-api-16-without-google-play-services/opt:
description: "Android 4.0 api-16+ (without Google Play Services) Opt"
@ -247,6 +251,7 @@ android-api-16-without-google-play-services/opt:
- linux64-rust-android
- linux64-rust-size
- linux64-sccache
- linux64-node
android-api-16-nightly/opt:
description: "Android 4.0 api-16+ Nightly"
@ -302,6 +307,7 @@ android-api-16-nightly/opt:
- linux64-rust-android
- linux64-rust-size
- linux64-sccache
- linux64-node
android-aarch64/opt:
description: "Android 5.0 AArch64 Opt"
@ -351,6 +357,7 @@ android-aarch64/opt:
- linux64-rust-android
- linux64-rust-size
- linux64-sccache
- linux64-node
android-aarch64-nightly/opt:
description: "Android 5.0 AArch64 Nightly"
@ -406,3 +413,4 @@ android-aarch64-nightly/opt:
- linux64-rust-android
- linux64-rust-size
- linux64-sccache
- linux64-node

View File

@ -27,6 +27,7 @@ linux64/opt:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux64-plain/opt:
description: "Linux64 Opt Plain"
@ -55,6 +56,7 @@ linux64-plain/opt:
- linux64-clang
- linux64-gcc
- linux64-rust
- linux64-node
linux64-dmd/opt:
description: "Linux64 DMD Opt"
@ -87,6 +89,7 @@ linux64-dmd/opt:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux64/pgo:
description: "Linux64 PGO"
@ -118,6 +121,7 @@ linux64/pgo:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux64-fuzzing/debug:
description: "Linux64 Fuzzing Debug"
@ -149,6 +153,7 @@ linux64-fuzzing/debug:
- linux64-sccache
- linux64-rust
- linux64-rust-size
- linux64-node
linux64/debug:
description: "Linux64 Debug"
@ -180,6 +185,7 @@ linux64/debug:
- linux64-sccache
- linux64-rust
- linux64-rust-size
- linux64-node
linux64-plain/debug:
description: "Linux64 Debug Plain"
@ -208,6 +214,7 @@ linux64-plain/debug:
- linux64-clang
- linux64-gcc
- linux64-rust
- linux64-node
linux64-devedition-nightly/opt:
description: "Linux64 devedition Nightly"
@ -245,6 +252,7 @@ linux64-devedition-nightly/opt:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux64-base-toolchains/opt:
description: "Linux64 base toolchains Opt"
@ -274,6 +282,7 @@ linux64-base-toolchains/opt:
- linux64-gcc-6
- linux64-rust-1.27
- linux64-sccache
- linux64-node
linux64-base-toolchains/debug:
description: "Linux64 base toolchains Debug"
@ -304,6 +313,7 @@ linux64-base-toolchains/debug:
- linux64-gcc-6
- linux64-rust-1.27
- linux64-sccache
- linux64-node
linux/opt:
description: "Linux32 Opt"
@ -335,6 +345,7 @@ linux/opt:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux/debug:
description: "Linux32 Debug"
@ -367,6 +378,7 @@ linux/debug:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux/pgo:
description: "Linux32 PGO"
@ -399,6 +411,7 @@ linux/pgo:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux-rusttests/opt:
description: "Linux32 Rust tests Opt"
@ -433,6 +446,7 @@ linux-rusttests/opt:
- linux64-gcc
- linux64-rust
- linux64-sccache
- linux64-node
linux-rusttests/debug:
description: "Linux32 Rust tests Debug"
@ -467,6 +481,7 @@ linux-rusttests/debug:
- linux64-gcc
- linux64-rust
- linux64-sccache
- linux64-node
linux-devedition-nightly/opt:
description: "Linux32 devedition Nightly"
@ -505,6 +520,7 @@ linux-devedition-nightly/opt:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux-nightly/opt:
description: "Linux32 Nightly"
@ -541,6 +557,7 @@ linux-nightly/opt:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux64-asan/opt:
description: "Linux64 Opt ASAN"
@ -572,6 +589,7 @@ linux64-asan/opt:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux64-asan-fuzzing/opt:
description: "Linux64 Fuzzing Opt ASAN"
@ -603,6 +621,7 @@ linux64-asan-fuzzing/opt:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux64-asan-fuzzing-ccov/opt:
description: "Linux64 Fuzzing Opt ASAN w/ Coverage"
@ -635,6 +654,7 @@ linux64-asan-fuzzing-ccov/opt:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux64-asan-reporter-nightly/opt:
description: "Linux64 Opt ASAN Reporter Nightly"
@ -670,6 +690,7 @@ linux64-asan-reporter-nightly/opt:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux64-asan/debug:
description: "Linux64 Debug ASAN"
@ -701,6 +722,7 @@ linux64-asan/debug:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux64-lto/opt:
description: "Linux64 Opt LTO"
@ -733,6 +755,7 @@ linux64-lto/opt:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux64-lto/debug:
description: "Linux64 Debug LTO"
@ -765,6 +788,7 @@ linux64-lto/debug:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux64-nightly/opt:
description: "Linux64 Nightly"
@ -800,6 +824,7 @@ linux64-nightly/opt:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux64-noopt/debug:
description: "Linux64 No-optimize Debug"
@ -832,6 +857,7 @@ linux64-noopt/debug:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node
linux64-rusttests/opt:
description: "Linux64 Rust tests Opt"
@ -865,6 +891,7 @@ linux64-rusttests/opt:
- linux64-gcc
- linux64-rust
- linux64-sccache
- linux64-node
linux64-rusttests/debug:
description: "Linux64 Rust tests Debug"
@ -898,6 +925,7 @@ linux64-rusttests/debug:
- linux64-gcc
- linux64-rust
- linux64-sccache
- linux64-node
linux64-tup/opt:
description: "Linux64 Tup"
@ -930,6 +958,7 @@ linux64-tup/opt:
- linux64-rust-nightly
- linux64-sccache
- linux64-tup
- linux64-node
linux64-jsdcov/opt:
description: "Linux64-JSDCov Opt"
@ -959,6 +988,7 @@ linux64-jsdcov/opt:
- linux64-gcc
- linux64-rust
- linux64-sccache
- linux64-node
linux64-ccov/debug:
description: "Linux64-CCov Debug"
@ -989,6 +1019,7 @@ linux64-ccov/debug:
- linux64-rust-nightly
- linux64-gcc
- linux64-sccache
- linux64-node
linux64-ccov/opt:
description: "Linux64-CCov Opt"
@ -1019,6 +1050,7 @@ linux64-ccov/opt:
- linux64-rust
- linux64-gcc
- linux64-sccache
- linux64-node
linux64-add-on-devel/opt:
description: "Linux64 add-on-devel"
@ -1050,3 +1082,4 @@ linux64-add-on-devel/opt:
- linux64-rust
- linux64-rust-size
- linux64-sccache
- linux64-node

View File

@ -33,6 +33,7 @@ macosx64/debug:
- linux64-rust-macos
- linux64-rust-size
- linux64-sccache
- linux64-node
macosx64/opt:
description: "MacOS X x64 Cross-compile"
@ -68,6 +69,7 @@ macosx64/opt:
- linux64-rust-macos
- linux64-rust-size
- linux64-sccache
- linux64-node
macosx64-asan-fuzzing/opt:
description: "MacOS X x64 Cross-compile Fuzzing ASAN"
@ -102,6 +104,7 @@ macosx64-asan-fuzzing/opt:
- linux64-rust-macos
- linux64-rust-size
- linux64-sccache
- linux64-node
macosx64-dmd/opt:
description: "MacOS X x64 DMD Cross-compile"
@ -138,6 +141,7 @@ macosx64-dmd/opt:
- linux64-rust-macos
- linux64-rust-size
- linux64-sccache
- linux64-node
macosx64-devedition-nightly/opt:
description: "MacOS X Dev Edition x64 Nightly"
@ -180,6 +184,7 @@ macosx64-devedition-nightly/opt:
- linux64-rust-macos
- linux64-rust-size
- linux64-sccache
- linux64-node
macosx64-noopt/debug:
description: "MacOS X x64 No-optimize Debug"
@ -216,6 +221,7 @@ macosx64-noopt/debug:
- linux64-rust-macos
- linux64-rust-size
- linux64-sccache
- linux64-node
macosx64-add-on-devel/opt:
description: "MacOS X x64 add-on-devel"
@ -251,6 +257,7 @@ macosx64-add-on-devel/opt:
- linux64-rust-macos
- linux64-rust-size
- linux64-sccache
- linux64-node
macosx64-nightly/opt:
description: "MacOS X x64 Cross-compile Nightly"
@ -326,3 +333,4 @@ macosx64-ccov/debug:
- linux64-rust-macos
- linux64-rust-size
- linux64-sccache
- linux64-node

View File

@ -28,6 +28,7 @@ win32/debug:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win32/opt:
description: "Win32 Opt"
@ -65,6 +66,7 @@ win32/opt:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win32-dmd/opt:
description: "Win32 DMD Opt"
@ -97,6 +99,7 @@ win32-dmd/opt:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win32/pgo:
description: "Win32 Opt PGO"
@ -128,6 +131,7 @@ win32/pgo:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win64/debug:
description: "Win64 Debug"
@ -159,6 +163,7 @@ win64/debug:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win64-plain/debug:
description: "Win64 Debug Plain"
@ -188,6 +193,7 @@ win64-plain/debug:
toolchains:
- win64-clang-cl
- win64-rust
- win64-node
win64/opt:
description: "Win64 Opt"
@ -219,6 +225,7 @@ win64/opt:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win64-plain/opt:
description: "Win64 Opt Plain"
@ -248,6 +255,7 @@ win64-plain/opt:
toolchains:
- win64-clang-cl
- win64-rust
- win64-node
win64-dmd/opt:
description: "Win64 DMD Opt"
@ -280,6 +288,7 @@ win64-dmd/opt:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win32-nightly/opt:
description: "Win32 Nightly"
@ -324,6 +333,7 @@ win32-nightly/opt:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win64-nightly/opt:
description: "Win64 Nightly"
@ -361,6 +371,7 @@ win64-nightly/opt:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win64/pgo:
description: "Win64 Opt PGO"
@ -392,6 +403,7 @@ win64/pgo:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win32-add-on-devel/opt:
description: "Windows32 add-on-devel"
@ -422,6 +434,7 @@ win32-add-on-devel/opt:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win64-add-on-devel/opt:
description: "Windows64 add-on-devel"
@ -452,6 +465,7 @@ win64-add-on-devel/opt:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win64-noopt/debug:
description: "Win64 No-optimize Debug"
@ -482,6 +496,7 @@ win64-noopt/debug:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win32-noopt/debug:
description: "Win32 No-optimize Debug"
@ -512,6 +527,7 @@ win32-noopt/debug:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win32-rusttests/opt:
description: "Win32 Opt Rust tests"
@ -542,6 +558,7 @@ win32-rusttests/opt:
- win64-clang-cl
- win64-rust
- win64-sccache
- win64-node
win64-rusttests/opt:
description: "Win64 Opt Rust tests"
@ -572,6 +589,7 @@ win64-rusttests/opt:
- win64-clang-cl
- win64-rust
- win64-sccache
- win64-node
win64-ccov/debug:
description: "Win64 Debug Code Coverage"
@ -602,6 +620,7 @@ win64-ccov/debug:
- win64-rust-nightly
- win64-rust-size
- win64-sccache
- win64-node
win64-asan/debug:
description: "Win64 Debug ASAN"
@ -633,6 +652,7 @@ win64-asan/debug:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win64-asan/opt:
description: "Win64 Opt ASAN"
@ -664,6 +684,7 @@ win64-asan/opt:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win64-asan-reporter-nightly/opt:
description: "Win64 Opt ASAN Reporter Nightly"
@ -743,6 +764,7 @@ win32-devedition-nightly/opt:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win64-devedition-nightly/opt:
description: "Win64 Dev Edition Nightly"
@ -781,6 +803,7 @@ win64-devedition-nightly/opt:
- win64-rust
- win64-rust-size
- win64-sccache
- win64-node
win32-mingw32/opt:
description: "Win32 MinGW Opt"
@ -814,6 +837,7 @@ win32-mingw32/opt:
- linux64-mingw32-gcc
- linux64-mingw32-nsis
- linux64-mingw32-fxc2
- linux64-node
win32-msvc/debug:
description: "Win32 MSVC Debug"
@ -846,6 +870,7 @@ win32-msvc/debug:
- win64-clang-cl
- win64-rust
- win64-sccache
- win64-node
win32-msvc/opt:
description: "Win32 MSVC PGO"
@ -884,6 +909,7 @@ win32-msvc/opt:
- win64-clang-cl
- win64-rust
- win64-sccache
- win64-node
win64-msvc/debug:
description: "Win64 MSVC Debug"
@ -916,6 +942,7 @@ win64-msvc/debug:
- win64-clang-cl
- win64-rust
- win64-sccache
- win64-node
win64-msvc/opt:
description: "Win64 MSVC PGO"
@ -948,6 +975,7 @@ win64-msvc/opt:
- win64-clang-cl
- win64-rust
- win64-sccache
- win64-node
win32-mingw32/debug:
description: "Win32 MinGW Debug"
@ -982,3 +1010,4 @@ win32-mingw32/debug:
- linux64-mingw32-gcc
- linux64-mingw32-nsis
- linux64-mingw32-fxc2
- linux64-node

View File

@ -46,6 +46,7 @@ jobs:
- linux64-gcc-6
- linux64-gcc-sixgill
- linux64-rust
- linux64-node
linux64-haz/debug:
description: "Browser Hazard Analysis Linux"
@ -66,3 +67,4 @@ jobs:
- linux64-gcc-6
- linux64-gcc-sixgill
- linux64-rust
- linux64-node

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