Merge mozilla-central to autoland

This commit is contained in:
Daniel Varga 2018-09-04 01:03:27 +03:00
commit e32b3d5290
90 changed files with 1670 additions and 915 deletions

View File

@ -14,28 +14,27 @@ function caretMoveChecker(target, caretOffset) {
}
async function checkURLBarCaretEvents() {
let url = "about:mozilla";
const kURL = "about:mozilla";
let newWin = await BrowserTestUtils.openNewBrowserWindow();
newWin.gBrowser.selectedBrowser.loadURI(kURL);
let onDocLoad = waitForEvent(
await waitForEvent(
EVENT_DOCUMENT_LOAD_COMPLETE,
event => {
try {
return event.accessible.QueryInterface(nsIAccessibleDocument).URL == url;
return event.accessible.QueryInterface(nsIAccessibleDocument).URL == kURL;
} catch (e) {
return false;
}
}
);
let [ newWin ] = await Promise.all([
BrowserTestUtils.openNewBrowserWindow({ url }),
onDocLoad
]);
info("Loaded " + kURL);
let urlbarInputEl = newWin.document.getElementById("urlbar").inputField;
let urlbarInput = getAccessible(urlbarInputEl, [ nsIAccessibleText ]);
let onCaretMove = waitForEvents([
[ EVENT_TEXT_CARET_MOVED, caretMoveChecker(urlbarInput, url.length) ],
[ EVENT_TEXT_CARET_MOVED, caretMoveChecker(urlbarInput, kURL.length) ],
[ EVENT_FOCUS, urlbarInput ]
]);

View File

@ -124,7 +124,7 @@ class NetErrorChild extends ActorChild {
msg1 = "";
msg1 += gPipNSSBundle.formatStringFromName("certErrorTrust_UnknownIssuer4", [hostString], 1);
msg1 += "\n\n";
msg1 += gPipNSSBundle.formatStringFromName("certErrorTrust_UnknownIssuer5", [brandName, hostString], 2);
msg1 += gPipNSSBundle.formatStringFromName("certErrorTrust_UnknownIssuer6", [brandName, hostString], 2);
msg1 += "\n\n";
} else {
msg1 += gPipNSSBundle.GetStringFromName("certErrorTrust_UnknownIssuer") + "\n";
@ -168,7 +168,7 @@ class NetErrorChild extends ActorChild {
if (newErrorPagesEnabled) {
technicalInfo.textContent = "";
let brandName = gBrandBundle.GetStringFromName("brandShortName");
msgPrefix = gPipNSSBundle.formatStringFromName("certErrorMismatchSinglePrefix1", [brandName, hostString], 2) + " ";
msgPrefix = gPipNSSBundle.formatStringFromName("certErrorMismatchSinglePrefix2", [brandName, hostString], 2) + " ";
msgPrefix += gPipNSSBundle.GetStringFromName("certErrorMismatchSinglePrefix");
} else {
msgPrefix = gPipNSSBundle.GetStringFromName("certErrorMismatchSinglePrefix");
@ -242,7 +242,7 @@ class NetErrorChild extends ActorChild {
if (newErrorPagesEnabled) {
technicalInfo.textContent = "";
let brandName = gBrandBundle.GetStringFromName("brandShortName");
msg = gPipNSSBundle.formatStringFromName("certErrorMismatchMultiple1", [brandName, hostString], 2) + " ";
msg = gPipNSSBundle.formatStringFromName("certErrorMismatchMultiple2", [brandName, hostString], 2) + " ";
} else {
msg = gPipNSSBundle.GetStringFromName("certErrorMismatchMultiple") + "\n";
}
@ -259,7 +259,7 @@ class NetErrorChild extends ActorChild {
if (newErrorPagesEnabled) {
technicalInfo.textContent = "";
let brandName = gBrandBundle.GetStringFromName("brandShortName");
msg = gPipNSSBundle.formatStringFromName("certErrorMismatch1", [brandName, hostString], 2) + " ";
msg = gPipNSSBundle.formatStringFromName("certErrorMismatch2", [brandName, hostString], 2) + " ";
} else {
msg = gPipNSSBundle.formatStringFromName("certErrorMismatch",
[hostString], 1);
@ -277,7 +277,7 @@ class NetErrorChild extends ActorChild {
if (nowTime > input.data.validity.notAfter) {
if (newErrorPagesEnabled) {
technicalInfo.textContent = "";
msg += gPipNSSBundle.formatStringFromName("certErrorExpiredNow1",
msg += gPipNSSBundle.formatStringFromName("certErrorExpiredNow2",
[hostString], 1);
msg += "\n";
} else {
@ -289,7 +289,7 @@ class NetErrorChild extends ActorChild {
// eslint-disable-next-line no-lonely-if
if (newErrorPagesEnabled) {
technicalInfo.textContent = "";
msg += gPipNSSBundle.formatStringFromName("certErrorNotYetValidNow1",
msg += gPipNSSBundle.formatStringFromName("certErrorNotYetValidNow2",
[hostString], 1);
msg += "\n";
} else {
@ -303,7 +303,7 @@ class NetErrorChild extends ActorChild {
// eslint-disable-next-line no-lonely-if
if (newErrorPagesEnabled) {
technicalInfo.textContent = "";
msg += gPipNSSBundle.formatStringFromName("certErrorExpiredNow1",
msg += gPipNSSBundle.formatStringFromName("certErrorExpiredNow2",
[hostString], 1);
msg += "\n";
} else {

View File

@ -1464,8 +1464,8 @@ pref("browser.translation.detectLanguage", false);
pref("browser.translation.neverForLanguages", "");
// Show the translation UI bits, like the info bar, notification icon and preferences.
pref("browser.translation.ui.show", false);
// Allows to define the translation engine. Bing is default, Yandex may optionally switched on.
pref("browser.translation.engine", "bing");
// Allows to define the translation engine. Google is default, Bing or Yandex are other options.
pref("browser.translation.engine", "Google");
// Telemetry settings.
// Determines if Telemetry pings can be archived locally.

View File

@ -113,6 +113,12 @@ var CaptivePortalWatcher = {
}
let win = BrowserWindowTracker.getTopWindow();
// Used by tests: ignore the main test window in order to enable testing of
// the case where we have no open windows.
if (win && win.document.documentElement.getAttribute("ignorecaptiveportal")) {
win = null;
}
// If no browser window has focus, open and show the tab when we regain focus.
// This is so that if a different application was focused, when the user
// (re-)focuses a browser window, we open the tab immediately in that window
@ -136,6 +142,12 @@ var CaptivePortalWatcher = {
}
let win = BrowserWindowTracker.getTopWindow();
// Used by tests: ignore the main test window in order to enable testing of
// the case where we have no open windows.
if (win && win.document.documentElement.getAttribute("ignorecaptiveportal")) {
win = null;
}
if (win != Services.ww.activeWindow) {
// The window that got focused was not a browser window.
return;

View File

@ -4292,6 +4292,19 @@ function toOpenWindowByType(inType, uri, features) {
window.open(uri, "_blank", "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar");
}
/**
* Open a new browser window.
*
* @param {Object} options
* {
* private: A boolean indicating if the window should be
* private
* remote: A boolean indicating if the window should run
* remote browser tabs or not. If omitted, the window
* will choose the profile default state.
* }
* @return a reference to the new window.
*/
function OpenBrowserWindow(options) {
var telemetryObj = {};
TelemetryStopwatch.start("FX_NEW_WINDOW_MS", telemetryObj);

View File

@ -20,22 +20,13 @@ async function setupPrefsAndRecentWindowBehavior() {
// We need to test behavior when a portal is detected when there is no browser
// window, but we can't close the default window opened by the test harness.
// Instead, we deactivate CaptivePortalWatcher in the default window and
// exclude it from BrowserWindowTracker.getTopWindow in an attempt to
// mask its presence.
// exclude it using an attribute to mask its presence.
window.CaptivePortalWatcher.uninit();
let getTopWindowCopy = BrowserWindowTracker.getTopWindow;
let defaultWindow = window;
BrowserWindowTracker.getTopWindow = () => {
let win = getTopWindowCopy();
if (win == defaultWindow) {
return null;
}
return win;
};
window.document.documentElement.setAttribute("ignorecaptiveportal", "true");
registerCleanupFunction(function cleanUp() {
BrowserWindowTracker.getTopWindow = getTopWindowCopy;
window.CaptivePortalWatcher.init();
window.document.documentElement.removeAttribute("ignorecaptiveportal");
});
}

View File

@ -590,18 +590,24 @@ add_task(async function test_large_popup() {
// This test checks the same as the previous test but in a new smaller window.
add_task(async function test_large_popup_in_small_window() {
let newwin = await BrowserTestUtils.openNewBrowserWindow({ width: 400, height: 400 });
let newWin = await BrowserTestUtils.openNewBrowserWindow();
let resizePromise = BrowserTestUtils.waitForEvent(newWin, "resize", false, e => {
return newWin.innerHeight <= 400 && newWin.innerWidth <= 400;
});
newWin.resizeTo(400, 400);
await resizePromise;
const pageUrl = "data:text/html," + escape(PAGECONTENT_SMALL);
let browserLoadedPromise = BrowserTestUtils.browserLoaded(newwin.gBrowser.selectedBrowser);
await BrowserTestUtils.loadURI(newwin.gBrowser.selectedBrowser, pageUrl);
let browserLoadedPromise = BrowserTestUtils.browserLoaded(newWin.gBrowser.selectedBrowser);
await BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, pageUrl);
await browserLoadedPromise;
newwin.gBrowser.selectedBrowser.focus();
newWin.gBrowser.selectedBrowser.focus();
await performLargePopupTests(newwin);
await performLargePopupTests(newWin);
await BrowserTestUtils.closeWindow(newwin);
await BrowserTestUtils.closeWindow(newWin);
});
async function performSelectSearchTests(win) {

View File

@ -26,7 +26,8 @@ let createPrivateWindow = async function createPrivateWindow(url) {
gPrivateBrowser = gPrivateWindow.getBrowser().selectedBrowser;
BrowserTestUtils.loadURI(gPrivateBrowser, url);
await BrowserTestUtils.browserLoaded(gPrivateBrowser);
await BrowserTestUtils.browserLoaded(gPrivateBrowser, false, url);
info("loaded " + url);
};
add_task(async function test() {

View File

@ -19,11 +19,11 @@ add_task(async function testAdoptedTwoWindows() {
// being adopted from the main window which doesn't have a shown sidebar. See Bug 1407737.
info("Ensure that sidebar state is adopted only from the opener");
let win1 = await BrowserTestUtils.openNewBrowserWindow({opener: window});
let win1 = await BrowserTestUtils.openNewBrowserWindow();
await win1.SidebarUI.show("viewBookmarksSidebar");
await BrowserTestUtils.closeWindow(win1);
let win2 = await BrowserTestUtils.openNewBrowserWindow({opener: window});
let win2 = await BrowserTestUtils.openNewBrowserWindow();
ok(!win2.document.getElementById("sidebar-button").hasAttribute("checked"), "Sidebar button isn't checked");
ok(!win2.SidebarUI.isOpen, "Sidebar is closed");
await BrowserTestUtils.closeWindow(win2);
@ -46,7 +46,7 @@ add_task(async function testEventReceivedInNewWindow() {
info("Opening a new window and expecting the SidebarFocused event to not fire");
let promiseNewWindow = BrowserTestUtils.waitForNewWindow();
BrowserTestUtils.openNewBrowserWindow({opener: window});
BrowserTestUtils.openNewBrowserWindow();
let win = await promiseNewWindow;
let adoptedShown = BrowserTestUtils.waitForEvent(win, "SidebarShown");

View File

@ -118,6 +118,11 @@ var whitelist = [
// browser/extensions/pdfjs/content/web/viewer.js#7450
{file: "resource://pdf.js/web/debugger.js"},
// resource://app/modules/translation/TranslationContentHandler.jsm
{file: "resource://app/modules/translation/BingTranslator.jsm"},
{file: "resource://app/modules/translation/GoogleTranslator.jsm"},
{file: "resource://app/modules/translation/YandexTranslator.jsm"},
// Starting from here, files in the whitelist are bugs that need fixing.
// Bug 1339424 (wontfix?)
{file: "chrome://browser/locale/taskbar.properties",

View File

@ -202,6 +202,11 @@ add_task(async function test_initial_state() {
let testWindow = await BrowserTestUtils.openNewBrowserWindow();
await SimpleTest.promiseFocus(testWindow);
// For focusing the URL bar to have an effect, we need to ensure the URL bar isn't
// initially focused:
testWindow.gBrowser.selectedTab.focus();
await TestUtils.waitForCondition(() => !testWindow.gURLBar.focused);
let overridePromise = expectCommandUpdate(isMac, testWindow);
testWindow.gURLBar.focus();

View File

@ -42,7 +42,7 @@ add_task(async function() {
is(SidebarUI.currentID, "viewHistorySidebar", "Selected sidebar remembered");
await hideSidebar();
let otherWin = await BrowserTestUtils.openNewBrowserWindow({opener: window});
let otherWin = await BrowserTestUtils.openNewBrowserWindow();
await showSidebar(otherWin);
is(otherWin.SidebarUI.currentID, "viewHistorySidebar", "Selected sidebar remembered across windows");
await hideSidebar(otherWin);

View File

@ -48,7 +48,7 @@ add_task(async function sidebar_windows() {
// SidebarUI relies on window.opener being set, which is normal behavior when
// using menu or key commands to open a new browser window.
let win = await BrowserTestUtils.openNewBrowserWindow({opener: window});
let win = await BrowserTestUtils.openNewBrowserWindow();
await secondSidebar;
ok(!win.document.getElementById("sidebar-box").hidden, "sidebar box is visible in second window");

View File

@ -428,7 +428,7 @@ var gMainPane = {
row.removeAttribute("hidden");
// Showing attribution only for Bing Translator.
ChromeUtils.import("resource:///modules/translation/Translation.jsm");
if (Translation.translationEngine == "bing") {
if (Translation.translationEngine == "Bing") {
document.getElementById("bingAttribution").removeAttribute("hidden");
}
}

View File

@ -204,12 +204,13 @@ var gPrivacyPane = {
if (contentBlockingUiEnabled) {
let tpCheckbox =
document.getElementById("contentBlockingTrackingProtectionCheckbox");
if (!tpCheckbox.checked) {
disabled = true;
}
// Only enable the TP menu if content blocking is enabled.
// Only enable the TP menu if content blocking and Detect All Trackers
// are enabled.
document.getElementById("trackingProtectionMenu").disabled = disabled ||
!tpCheckbox.checked ||
!contentBlockingEnabled;
// Only enable the TP category checkbox if content blocking is enabled.
tpCheckbox.disabled = disabled || !contentBlockingEnabled;
} else {
document.querySelectorAll("#trackingProtectionRadioGroup > radio")
.forEach((element) => {
@ -529,10 +530,15 @@ var gPrivacyPane = {
let siteDataGroup = document.getElementById("siteDataGroup");
let browserPrivacyCategory = document.getElementById("browserPrivacyCategory");
browserPrivacyCategory.parentNode.insertBefore(siteDataGroup,
browserPrivacyCategory.nextSibling);
browserPrivacyCategory.parentNode.insertBefore(trackingGroup,
browserPrivacyCategory.nextSibling);
// If we do this without a timeout, trackingProtectionReadPrefs will set the checked
// attribute on our checkbox element before the XBL binding has had a chance to have
// been re-applied to it.
setTimeout(() => {
browserPrivacyCategory.parentNode.insertBefore(siteDataGroup,
browserPrivacyCategory.nextSibling);
browserPrivacyCategory.parentNode.insertBefore(trackingGroup,
browserPrivacyCategory.nextSibling);
}, 0);
},
/**

View File

@ -379,7 +379,10 @@
data-l10n-id="content-blocking-tracking-protection-option-always"
flex="1" />
</radiogroup>
<label id="changeBlockListLink" data-l10n-id="content-blocking-tracking-protection-change-block-list" class="text-link"/>
<label id="changeBlockListLink"
data-l10n-id="content-blocking-tracking-protection-change-block-list"
class="text-link"
search-l10n-ids="blocklist-window.title, blocklist-desc, blocklist-button-cancel.label, blocklist-button-ok.label"/>
</vbox>
</hbox>
</vbox>

View File

@ -56,6 +56,67 @@ add_task(async function testContentBlockingToggle() {
gBrowser.removeCurrentTab();
});
// Tests that the content blocking main category checkboxes have the correct default state.
add_task(async function testContentBlockingMainCategory() {
SpecialPowers.pushPrefEnv({set: [
[CB_UI_PREF, true],
[CB_PREF, true],
[FB_PREF, true],
[TP_PREF, false],
[TP_PBM_PREF, true],
[NCB_PREF, Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER],
]});
let checkboxes = [
"#contentBlockingFastBlockCheckbox",
"#contentBlockingTrackingProtectionCheckbox",
"#contentBlockingBlockCookiesCheckbox",
];
await openPreferencesViaOpenPreferencesAPI("privacy", {leaveOpen: true});
let doc = gBrowser.contentDocument;
for (let selector of checkboxes) {
let element = doc.querySelector(selector);
ok(element, "checkbox " + selector + " exists");
is(element.getAttribute("checked"), "true",
"checkbox " + selector + " is checked");
}
// Ensure the dependent controls of the tracking protection subsection behave properly.
let tpCheckbox = doc.querySelector(checkboxes[1]);
let dependentControls = [
"#trackingProtectionMenu",
];
let alwaysEnabledControls = [
"#trackingProtectionMenuDesc",
".content-blocking-category-name",
"#changeBlockListLink",
];
tpCheckbox.checked = true;
// The first time, privacy-pane-tp-ui-updated won't be dispatched since the
// assignment above is a no-op.
// Ensure the dependent controls are enabled
checkControlStateWorker(doc, dependentControls, true);
checkControlStateWorker(doc, alwaysEnabledControls, true);
let promise = TestUtils.topicObserved("privacy-pane-tp-ui-updated");
EventUtils.synthesizeMouseAtCenter(tpCheckbox, {}, doc.defaultView);
await promise;
ok(!tpCheckbox.checked, "The checkbox should now be unchecked");
// Ensure the dependent controls are disabled
checkControlStateWorker(doc, dependentControls, false);
checkControlStateWorker(doc, alwaysEnabledControls, true);
gBrowser.removeCurrentTab();
});
// Tests that the content blocking "Restore Defaults" button does what it's supposed to.
add_task(async function testContentBlockingRestoreDefaults() {
SpecialPowers.pushPrefEnv({set: [
@ -140,6 +201,24 @@ add_task(async function testContentBlockingRestoreDefaultsSkipExtensionControlle
await TestUtils.waitForCondition(() => Services.prefs.prefHasUserValue(TP_PREF));
let dependentControls = [
"#content-blocking-categories-label",
".fast-block-ui .content-blocking-checkbox",
".reject-trackers-ui .content-blocking-checkbox",
".content-blocking-icon",
".content-blocking-category-name",
"#changeBlockListLink",
"#contentBlockingChangeCookieSettings",
"#blockCookiesCB, #blockCookiesCB > radio",
];
let alwaysDisabledControls = [
".tracking-protection-ui .content-blocking-checkbox",
"#trackingProtectionMenu",
"[control=trackingProtectionMenu]",
];
await doDependentControlChecks(dependentControls, alwaysDisabledControls);
await openPreferencesViaOpenPreferencesAPI("privacy", {leaveOpen: true});
let doc = gBrowser.contentDocument;
@ -281,16 +360,13 @@ add_task(async function testContentBlockingDependentTPControls() {
let dependentControls = [
"#content-blocking-categories-label",
".content-blocking-checkbox",
".content-blocking-icon",
".content-blocking-category-name",
"[control=trackingProtectionMenu]",
"#changeBlockListLink",
"#contentBlockingChangeCookieSettings",
"#blockCookiesCB, #blockCookiesCB > radio",
];
let alwaysDisabledControls = [
"#trackingProtectionMenu",
"[control=trackingProtectionMenu]",
];
await doDependentControlChecks(dependentControls, alwaysDisabledControls);

View File

@ -13,9 +13,21 @@ add_task(async function() {
* Test for searching for the "Block Lists" subdialog.
*/
add_task(async function() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
await evaluateSearchResults("block Web elements", "trackingGroup");
BrowserTestUtils.removeTab(gBrowser.selectedTab);
async function doTest() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
await evaluateSearchResults("block Web elements", "trackingGroup");
BrowserTestUtils.removeTab(gBrowser.selectedTab);
}
await SpecialPowers.pushPrefEnv({"set": [
["browser.contentblocking.ui.enabled", true],
]});
info("Run the test with Content Blocking UI enabled");
await doTest();
await SpecialPowers.pushPrefEnv({"set": [
["browser.contentblocking.ui.enabled", false],
]});
info("Run the test with Content Blocking UI disabled");
await doTest();
});
/**

View File

@ -7,6 +7,11 @@ add_task(async function() {
await SpecialPowers.pushPrefEnv({"set": [["browser.preferences.search", true]]});
});
// First, run the tests without the Content Blocking UI.
add_task(async function() {
await SpecialPowers.pushPrefEnv({"set": [["browser.contentblocking.ui.enabled", false]]});
});
/**
* Test for searching for the "Settings - Site Data" subdialog.
*/
@ -33,3 +38,35 @@ add_task(async function() {
await evaluateSearchResults("third-party", "siteDataGroup");
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
// Now, run the tests with the Content Blocking UI.
add_task(async function() {
await SpecialPowers.pushPrefEnv({"set": [["browser.contentblocking.ui.enabled", true]]});
});
/**
* Test for searching for the "Settings - Site Data" subdialog.
*/
add_task(async function() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
await evaluateSearchResults("cookies", ["siteDataGroup", "trackingGroup"]);
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
add_task(async function() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
await evaluateSearchResults("site data", ["siteDataGroup"]);
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
add_task(async function() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
await evaluateSearchResults("cache", ["siteDataGroup"]);
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
add_task(async function() {
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
await evaluateSearchResults("third-party", ["siteDataGroup", "trackingGroup"]);
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});

View File

@ -10,10 +10,11 @@ const CB_UI_ENABLED_PREF = "browser.contentblocking.ui.enabled";
* Opens a new private window and loads "about:privatebrowsing" there.
*/
async function openAboutPrivateBrowsing() {
let win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
let win = await BrowserTestUtils.openNewBrowserWindow({
private: true,
waitForTabURL: "about:privatebrowsing",
});
let tab = win.gBrowser.selectedBrowser;
tab.loadURI("about:privatebrowsing");
await BrowserTestUtils.browserLoaded(tab);
return { win, tab };
}

View File

@ -17,8 +17,7 @@ function promiseTestOpenCloseWindow(aIsPrivate, aTest) {
return (async function() {
let win = await BrowserTestUtils.openNewBrowserWindow({ "private": aIsPrivate });
win.gBrowser.selectedBrowser.loadURI(aTest.url);
await promiseBrowserLoaded(win.gBrowser.selectedBrowser);
await Promise.resolve();
await promiseBrowserLoaded(win.gBrowser.selectedBrowser, true, aTest.url);
// Mark the window with some unique data to be restored later on.
ss.setWindowValue(win, aTest.key, aTest.value);
await TabStateFlusher.flushWindow(win);

View File

@ -0,0 +1,297 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var EXPORTED_SYMBOLS = [ "GoogleTranslator" ];
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm");
ChromeUtils.import("resource://gre/modules/Http.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyGlobalGetters(this, ["DOMParser"]);
// The maximum amount of net data allowed per request on Google's API.
const MAX_REQUEST_DATA = 5000; // XXX This is the Bing value
// The maximum number of chunks allowed to be translated in a single
// request.
const MAX_REQUEST_CHUNKS = 128; // Undocumented, but the de facto upper limit.
// Self-imposed limit of 15 requests. This means that a page that would need
// to be broken in more than 15 requests won't be fully translated.
// The maximum amount of data that we will translate for a single page
// is MAX_REQUESTS * MAX_REQUEST_DATA.
const MAX_REQUESTS = 15;
const URL = "https://translation.googleapis.com/language/translate/v2";
/**
* Translates a webpage using Google's Translation API.
*
* @param translationDocument The TranslationDocument object that represents
* the webpage to be translated
* @param sourceLanguage The source language of the document
* @param targetLanguage The target language for the translation
*
* @returns {Promise} A promise that will resolve when the translation
* task is finished.
*/
var GoogleTranslator = function(translationDocument, sourceLanguage, targetLanguage) {
this.translationDocument = translationDocument;
this.sourceLanguage = sourceLanguage;
this.targetLanguage = targetLanguage;
this._pendingRequests = 0;
this._partialSuccess = false;
this._translatedCharacterCount = 0;
};
this.GoogleTranslator.prototype = {
/**
* Performs the translation, splitting the document into several chunks
* respecting the data limits of the API.
*
* @returns {Promise} A promise that will resolve when the translation
* task is finished.
*/
async translate() {
let currentIndex = 0;
this._onFinishedDeferred = PromiseUtils.defer();
// Let's split the document into various requests to be sent to
// Google's Translation API.
for (let requestCount = 0; requestCount < MAX_REQUESTS; requestCount++) {
// Generating the text for each request can be expensive, so
// let's take the opportunity of the chunkification process to
// allow for the event loop to attend other pending events
// before we continue.
await new Promise(resolve => Services.tm.dispatchToMainThread(resolve));
// Determine the data for the next request.
let request = this._generateNextTranslationRequest(currentIndex);
// Create a real request to the server, and put it on the
// pending requests list.
let googleRequest = new GoogleRequest(request.data,
this.sourceLanguage,
this.targetLanguage);
this._pendingRequests++;
googleRequest.fireRequest().then(this._chunkCompleted.bind(this),
this._chunkFailed.bind(this));
currentIndex = request.lastIndex;
if (request.finished) {
break;
}
}
return this._onFinishedDeferred.promise;
},
/**
* Function called when a request sent to the server completed successfully.
* This function handles calling the function to parse the result and the
* function to resolve the promise returned by the public `translate()`
* method when there's no pending request left.
*
* @param request The GoogleRequest sent to the server.
*/
_chunkCompleted(googleRequest) {
if (this._parseChunkResult(googleRequest)) {
this._partialSuccess = true;
// Count the number of characters successfully translated.
this._translatedCharacterCount += googleRequest.characterCount;
}
this._checkIfFinished();
},
/**
* Function called when a request sent to the server has failed.
* This function handles deciding if the error is transient or means the
* service is unavailable (zero balance on the key or request credentials are
* not in an active state) and calling the function to resolve the promise
* returned by the public `translate()` method when there's no pending.
* request left.
*
* @param aError [optional] The XHR object of the request that failed.
*/
_chunkFailed(aError) {
this._checkIfFinished();
},
/**
* Function called when a request sent to the server has completed.
* This function handles resolving the promise
* returned by the public `translate()` method when all chunks are completed.
*/
_checkIfFinished() {
// Check if all pending requests have been
// completed and then resolves the promise.
// If at least one chunk was successful, the
// promise will be resolved positively which will
// display the "Success" state for the infobar. Otherwise,
// the "Error" state will appear.
if (--this._pendingRequests == 0) {
if (this._partialSuccess) {
this._onFinishedDeferred.resolve({
characterCount: this._translatedCharacterCount,
});
} else {
this._onFinishedDeferred.reject("failure");
}
}
},
/**
* This function parses the result returned by Bing's Http.svc API,
* which is a XML file that contains a number of elements. To our
* particular interest, the only part of the response that matters
* are the <TranslatedText> nodes, which contains the resulting
* items that were sent to be translated.
*
* @param request The request sent to the server.
* @returns boolean True if parsing of this chunk was successful.
*/
_parseChunkResult(googleRequest) {
let results;
try {
let response = googleRequest.networkRequest.response;
results = JSON.parse(response).data.translations;
} catch (e) {
return false;
}
let len = results.length;
if (len != googleRequest.translationData.length) {
// This should never happen, but if the service returns a different number
// of items (from the number of items submitted), we can't use this chunk
// because all items would be paired incorrectly.
return false;
}
let error = false;
for (let i = 0; i < len; i++) {
try {
let result = results[i].translatedText;
let root = googleRequest.translationData[i][0];
if (root.isSimpleRoot && result.includes("&")) {
// If the result contains HTML entities, we need to convert them as
// simple roots expect a plain text result.
let doc = (new DOMParser()).parseFromString(result, "text/html");
result = doc.body.firstChild.nodeValue;
}
root.parseResult(result);
} catch (e) { error = true; }
}
return !error;
},
/**
* This function will determine what is the data to be used for
* the Nth request we are generating, based on the input params.
*
* @param startIndex What is the index, in the roots list, that the
* chunk should start.
*/
_generateNextTranslationRequest(startIndex) {
let currentDataSize = 0;
let currentChunks = 0;
let output = [];
let rootsList = this.translationDocument.roots;
for (let i = startIndex; i < rootsList.length; i++) {
let root = rootsList[i];
let text = this.translationDocument.generateTextForItem(root);
if (!text) {
continue;
}
let newCurSize = currentDataSize + text.length;
let newChunks = currentChunks + 1;
if (newCurSize > MAX_REQUEST_DATA ||
newChunks > MAX_REQUEST_CHUNKS) {
// If we've reached the API limits, let's stop accumulating data
// for this request and return. We return information useful for
// the caller to pass back on the next call, so that the function
// can keep working from where it stopped.
return {
data: output,
finished: false,
lastIndex: i,
};
}
currentDataSize = newCurSize;
currentChunks = newChunks;
output.push([root, text]);
}
return {
data: output,
finished: true,
lastIndex: 0,
};
},
};
/**
* Represents a request (for 1 chunk) sent off to Google's service.
*
* @params translationData The data to be used for this translation,
* generated by the generateNextTranslationRequest...
* function.
* @param sourceLanguage The source language of the document.
* @param targetLanguage The target language for the translation.
*
*/
function GoogleRequest(translationData, sourceLanguage, targetLanguage) {
this.translationData = translationData;
this.sourceLanguage = sourceLanguage;
this.targetLanguage = targetLanguage;
this.characterCount = 0;
}
GoogleRequest.prototype = {
/**
* Initiates the request
*/
fireRequest() {
let key = Services.cpmm.sharedData.get("translationKey") ||
Services.prefs.getStringPref("browser.translation.google.apiKey", "");
if (!key) {
return Promise.reject("no API key");
}
// Prepare the request body.
let postData = [
["key", key],
["source", this.sourceLanguage],
["target", this.targetLanguage],
];
for (let [, text] of this.translationData) {
postData.push(["q", text]);
this.characterCount += text.length;
}
// Set up request options.
return new Promise((resolve, reject) => {
let options = {
onLoad: (responseText, xhr) => {
resolve(this);
},
onError(e, responseText, xhr) {
reject(xhr);
},
postData,
};
// Fire the request.
this.networkRequest = httpRequest(URL, options);
});
},
};

View File

@ -82,16 +82,16 @@ var Translation = {
* The list of translation engines and their attributions.
*/
supportedEngines: {
"bing": "http://aka.ms/MicrosoftTranslatorAttribution",
"yandex": "http://translate.yandex.com/",
"Google": "",
"Bing": "http://aka.ms/MicrosoftTranslatorAttribution",
"Yandex": "http://translate.yandex.com/",
},
/**
* Fallback engine (currently Bing Translator) if the preferences seem
* confusing.
* Fallback engine (currently Google) if the preferences seem confusing.
*/
get defaultEngine() {
return this.supportedEngines.keys[0];
return Object.keys(this.supportedEngines)[0];
},
/**

View File

@ -64,9 +64,14 @@ TranslationContentHandler.prototype = {
!this.global.content)
return;
let url = aRequest.name;
if (!url.startsWith("http://") && !url.startsWith("https://"))
try {
let url = aRequest.name;
if (!url.startsWith("http://") && !url.startsWith("https://"))
return;
} catch (e) {
// nsIRequest.name throws NS_ERROR_NOT_IMPLEMENTED for view-source: tabs.
return;
}
let content = this.global.content;
if (content.detectedLanguage)
@ -120,19 +125,12 @@ TranslationContentHandler.prototype = {
let translationDocument = this.global.content.translationDocument ||
new TranslationDocument(this.global.content.document);
let preferredEngine = Services.prefs.getCharPref("browser.translation.engine");
let translator = null;
if (preferredEngine == "yandex") {
ChromeUtils.import("resource:///modules/translation/YandexTranslator.jsm");
translator = new YandexTranslator(translationDocument,
msg.data.from,
msg.data.to);
} else {
ChromeUtils.import("resource:///modules/translation/BingTranslator.jsm");
translator = new BingTranslator(translationDocument,
msg.data.from,
msg.data.to);
}
let engine = Services.prefs.getCharPref("browser.translation.engine");
let importScope =
ChromeUtils.import(`resource:///modules/translation/${engine}Translator.jsm`, {});
let translator = new importScope[engine + "Translator"](translationDocument,
msg.data.from,
msg.data.to);
this.global.content.translationDocument = translationDocument;
translationDocument.translatedFrom = msg.data.from;

View File

@ -9,6 +9,7 @@ EXTRA_JS_MODULES.translation = [
'BingTranslator.jsm',
'cld2/cld-worker.js',
'cld2/cld-worker.js.mem',
'GoogleTranslator.jsm',
'LanguageDetector.jsm',
'Translation.jsm',
'TranslationContentHandler.jsm',

View File

@ -21,7 +21,7 @@ const kShowUIPref = "browser.translation.ui.show";
const {Translation} = ChromeUtils.import("resource:///modules/translation/Translation.jsm", {});
add_task(async function setup() {
Services.prefs.setCharPref(kEnginePref, "yandex");
Services.prefs.setCharPref(kEnginePref, "Yandex");
Services.prefs.setCharPref(kApiKeyPref, "yandexValidKey");
Services.prefs.setBoolPref(kShowUIPref, true);

View File

@ -217,8 +217,22 @@
// Show attribution for the preferred translator.
let engineIndex = Object.keys(Translation.supportedEngines)
.indexOf(Translation.translationEngine);
// We currently only have attribution for the Bing and Yandex engines.
if (engineIndex >= 0) {
--engineIndex;
}
let attributionNode = this._getAnonElt("translationEngine");
if (engineIndex != -1) {
this._getAnonElt("translationEngine").selectedIndex = engineIndex;
attributionNode.selectedIndex = engineIndex;
} else {
// Hide the attribution menuitem
let footer = attributionNode.parentNode;
footer.hidden = true;
// Make the 'Translation preferences' item the new footer.
footer = footer.previousSibling;
footer.setAttribute("class", "subviewbutton panel-subview-footer");
// And hide the menuseparator.
footer.previousSibling.hidden = true;
}
const kWelcomePref = "browser.translation.ui.welcomeMessageShown";

View File

@ -11,6 +11,7 @@ module.exports = {
"synthesizeKeyFromKeyTag": true,
"TargetFactory": true,
"waitForTick": true,
"waitUntilState": true,
},
"parserOptions": {

View File

@ -6,10 +6,11 @@
"use strict";
const promise = require("promise");
const flags = require("devtools/shared/flags");
const ToolDefinitions = require("devtools/client/definitions").Tools;
const CssLogic = require("devtools/shared/inspector/css-logic");
const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
const promise = require("promise");
const OutputParser = require("devtools/client/shared/output-parser");
const {PrefObserver} = require("devtools/client/shared/prefs");
const {createChild} = require("devtools/client/inspector/shared/utils");
@ -183,14 +184,20 @@ function CssComputedView(inspector, document, pageStyle) {
this.styleDocument.addEventListener("mousedown", this.focusWindow);
this.element.addEventListener("click", this._onClick);
this.element.addEventListener("contextmenu", this._onContextMenu);
this.element.addEventListener("mousemove", () => {
this.addHighlightersToView();
}, { once: true });
this.searchField.addEventListener("input", this._onFilterStyles);
this.searchClearButton.addEventListener("click", this._onClearSearch);
this.includeBrowserStylesCheckbox.addEventListener("input",
this._onIncludeBrowserStyles);
if (flags.testing) {
// In tests, we start listening immediately to avoid having to simulate a mousemove.
this.highlighters.addToView(this);
} else {
this.element.addEventListener("mousemove", () => {
this.highlighters.addToView(this);
}, { once: true });
}
this.searchClearButton.hidden = true;
// No results text.
@ -732,14 +739,6 @@ CssComputedView.prototype = {
}
},
/**
* Adds the highlighters overlay to the computed view. This is called by the "mousemove"
* event handler and in shared-head.js when opening and selecting the computed view.
*/
addHighlightersToView() {
this.highlighters.addToView(this);
},
/**
* Destructor for CssComputedView.
*/

View File

@ -5,6 +5,7 @@
"use strict";
const { throttle } = require("devtools/client/inspector/shared/utils");
const flags = require("devtools/shared/flags");
const {
clearFlexbox,
@ -62,10 +63,16 @@ class FlexboxInspector {
return;
}
this.document.addEventListener("mousemove", () => {
if (flags.testing) {
// In tests, we start listening immediately to avoid having to simulate a mousemove.
this.highlighters.on("flexbox-highlighter-hidden", this.onHighlighterHidden);
this.highlighters.on("flexbox-highlighter-shown", this.onHighlighterShown);
}, { once: true });
} else {
this.document.addEventListener("mousemove", () => {
this.highlighters.on("flexbox-highlighter-hidden", this.onHighlighterHidden);
this.highlighters.on("flexbox-highlighter-shown", this.onHighlighterShown);
}, { once: true });
}
this.inspector.sidebar.on("select", this.onSidebarSelect);
@ -304,99 +311,77 @@ class FlexboxInspector {
async update(flexboxFront) {
// Stop refreshing if the inspector or store is already destroyed or no node is
// selected.
if (!this.inspector || !this.store || !this.inspector.selection.nodeFront) {
if (!this.inspector ||
!this.store ||
!this.inspector.selection.nodeFront ||
!this.hasGetCurrentFlexbox) {
return;
}
// Fetch the current flexbox if no flexbox front was passed into this update.
if (!flexboxFront) {
try {
if (!this.hasGetCurrentFlexbox) {
return;
}
try {
// Fetch the current flexbox if no flexbox front was passed into this update.
if (!flexboxFront) {
flexboxFront = await this.layoutInspector.getCurrentFlexbox(
this.inspector.selection.nodeFront);
} catch (e) {
// This call might fail if called asynchrously after the toolbox is finished
// closing.
}
// Clear the flexbox panel if there is no flex container for the current node
// selection.
if (!flexboxFront) {
this.store.dispatch(clearFlexbox());
return;
}
}
// Clear the flexbox panel if there is no flex container for the current node
// selection.
if (!flexboxFront) {
try {
this.store.dispatch(clearFlexbox());
} catch (e) {
// This call might fail if called asynchrously after the toolbox is finished
// closing.
}
return;
}
let containerNodeFront = flexboxFront.containerNodeFront;
// If the FlexboxFront doesn't yet have access to the NodeFront for its container,
// then get it from the walker. This happens when the walker hasn't seen this
// particular DOM Node in the tree yet or when we are connected to an older server.
if (!containerNodeFront) {
try {
// If the FlexboxFront doesn't yet have access to the NodeFront for its container,
// then get it from the walker. This happens when the walker hasn't seen this
// particular DOM Node in the tree yet or when we are connected to an older server.
let containerNodeFront = flexboxFront.containerNodeFront;
if (!containerNodeFront) {
containerNodeFront = await this.walker.getNodeFromActor(flexboxFront.actorID,
["containerEl"]);
} catch (e) {
// This call might fail if called asynchrously after the toolbox is finished
// closing.
return;
}
}
const highlighted = this._highlighters &&
containerNodeFront == this.highlighters.flexboxHighlighterShown;
// Fetch the flex items for the given flex container and the flex item NodeFronts.
const flexItems = [];
const flexItemFronts = await flexboxFront.getFlexItems();
// Fetch the flex items for the given flex container and the flex item NodeFronts.
const flexItems = [];
const flexItemFronts = await flexboxFront.getFlexItems();
for (const flexItemFront of flexItemFronts) {
let itemNodeFront = flexItemFront.nodeFront;
if (!itemNodeFront) {
try {
for (const flexItemFront of flexItemFronts) {
let itemNodeFront = flexItemFront.nodeFront;
if (!itemNodeFront) {
itemNodeFront = await this.walker.getNodeFromActor(flexItemFront.actorID,
["element"]);
} catch (e) {
// This call might fail if called asynchrously after the toolbox is finished
// closing.
return;
}
flexItems.push({
actorID: flexItemFront.actorID,
shown: false,
flexItemSizing: flexItemFront.flexItemSizing,
nodeFront: itemNodeFront,
properties: flexItemFront.properties,
});
}
flexItems.push({
actorID: flexItemFront.actorID,
shown: false,
flexItemSizing: flexItemFront.flexItemSizing,
nodeFront: itemNodeFront,
properties: flexItemFront.properties,
});
const highlighted = this._highlighters &&
containerNodeFront == this.highlighters.flexboxHighlighterShown;
const currentUrl = this.inspector.target.url;
// Get the hostname, if there is no hostname, fall back on protocol
// ex: `data:` uri, and `about:` pages
const hostname = parseURL(currentUrl).hostname || parseURL(currentUrl).protocol;
const customColors = await this.getCustomFlexboxColors();
const color = customColors[hostname] ? customColors[hostname] : FLEXBOX_COLOR;
this.store.dispatch(updateFlexbox({
actorID: flexboxFront.actorID,
color,
flexItems,
highlighted,
nodeFront: containerNodeFront,
properties: flexboxFront.properties,
}));
} catch (e) {
// This call might fail if called asynchrously after the toolbox is finished
// closing.
}
const currentUrl = this.inspector.target.url;
// Get the hostname, if there is no hostname, fall back on protocol
// ex: `data:` uri, and `about:` pages
const hostname = parseURL(currentUrl).hostname || parseURL(currentUrl).protocol;
const customColors = await this.getCustomFlexboxColors();
const color = customColors[hostname] ? customColors[hostname] : FLEXBOX_COLOR;
this.store.dispatch(updateFlexbox({
actorID: flexboxFront.actorID,
color,
flexItems,
highlighted,
nodeFront: containerNodeFront,
properties: flexboxFront.properties,
}));
}
}

View File

@ -6,6 +6,7 @@
const Services = require("Services");
const { throttle } = require("devtools/client/inspector/shared/utils");
const flags = require("devtools/shared/flags");
const {
updateGridColor,
@ -97,10 +98,16 @@ class GridInspector {
return;
}
this.document.addEventListener("mousemove", () => {
if (flags.testing) {
// In tests, we start listening immediately to avoid having to simulate a mousemove.
this.highlighters.on("grid-highlighter-hidden", this.onHighlighterHidden);
this.highlighters.on("grid-highlighter-shown", this.onHighlighterShown);
}, { once: true });
} else {
this.document.addEventListener("mousemove", () => {
this.highlighters.on("grid-highlighter-hidden", this.onHighlighterHidden);
this.highlighters.on("grid-highlighter-shown", this.onHighlighterShown);
}, { once: true });
}
this.inspector.sidebar.on("select", this.onSidebarSelect);
this.inspector.on("new-root", this.onNavigate);

View File

@ -3,7 +3,4 @@
module.exports = {
// Extend from the shared list of defined globals for mochitests.
"extends": "../../../../.eslintrc.mochitests.js",
"globals": {
"waitUntilState": true
}
};

View File

@ -2,5 +2,5 @@
module.exports = {
// Extend from the shared list of defined globals for mochitests.
"extends": "../../../../.eslintrc.mochitests.js"
"extends": "../../../../.eslintrc.mochitests.js",
};

View File

@ -73,6 +73,7 @@ support-files =
!/devtools/client/inspector/test/head.js
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/shared-redux-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
!/devtools/client/shared/test/test-actor.js
!/devtools/client/shared/test/test-actor-registry.js
@ -130,6 +131,8 @@ skip-if = true # Bug 1177550
[browser_markup_events_react_production_16.2.0_jsx.js]
[browser_markup_events_source_map.js]
[browser_markup_events-windowed-host.js]
[browser_markup_flex_display_badge.js]
[browser_markup_grid_display_badge.js]
[browser_markup_links_01.js]
[browser_markup_links_02.js]
[browser_markup_links_03.js]

View File

@ -0,0 +1,56 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that the flex display badge toggles on the flexbox highlighter.
const TEST_URI = `
<style type="text/css">
#flex {
display: flex;
}
</style>
<div id="flex"></div>
`;
const HIGHLIGHTER_TYPE = "FlexboxHighlighter";
add_task(async function() {
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
const { inspector } = await openLayoutView();
const { highlighters, store } = inspector;
info("Check the flex display badge is shown and not active.");
await selectNode("#flex", inspector);
const flexContainer = await getContainerForSelector("#flex", inspector);
const flexDisplayBadge = flexContainer.elt.querySelector(".markup-badge[data-display]");
ok(!flexDisplayBadge.classList.contains("active"), "flex display badge is not active.");
info("Check the initial state of the flex highlighter.");
ok(!highlighters.highlighters[HIGHLIGHTER_TYPE],
"No flexbox highlighter exists in the highlighters overlay.");
ok(!highlighters.flexboxHighlighterShown, "No flexbox highlighter is shown.");
info("Toggling ON the flexbox highlighter from the flex display badge.");
const onHighlighterShown = highlighters.once("flexbox-highlighter-shown");
let onCheckboxChange = waitUntilState(store, state => state.flexbox.highlighted);
flexDisplayBadge.click();
await onHighlighterShown;
await onCheckboxChange;
info("Check the flexbox highlighter is created and flex display badge state.");
ok(highlighters.highlighters[HIGHLIGHTER_TYPE],
"Flexbox highlighter is created in the highlighters overlay.");
ok(highlighters.flexboxHighlighterShown, "Flexbox highlighter is shown.");
ok(flexDisplayBadge.classList.contains("active"), "flex display badge is active.");
info("Toggling OFF the flexbox highlighter from the flex display badge.");
const onHighlighterHidden = highlighters.once("flexbox-highlighter-hidden");
onCheckboxChange = waitUntilState(store, state => !state.flexbox.highlighted);
flexDisplayBadge.click();
await onHighlighterHidden;
await onCheckboxChange;
ok(!flexDisplayBadge.classList.contains("active"), "flex display badge is not active.");
});

View File

@ -0,0 +1,60 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that the grid display badge toggles on the grid highlighter.
const TEST_URI = `
<style type="text/css">
#grid {
display: grid;
}
</style>
<div id="grid"></div>
`;
const HIGHLIGHTER_TYPE = "CssGridHighlighter";
add_task(async function() {
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
const { inspector } = await openLayoutView();
const { highlighters, store } = inspector;
info("Check the grid display badge is shown and not active.");
await selectNode("#grid", inspector);
const gridContainer = await getContainerForSelector("#grid", inspector);
const gridDisplayBadge = gridContainer.elt.querySelector(".markup-badge[data-display]");
ok(!gridDisplayBadge.classList.contains("active"), "grid display badge is not active.");
info("Check the initial state of the grid highlighter.");
ok(!highlighters.highlighters[HIGHLIGHTER_TYPE],
"No CSS grid highlighter exists in the highlighters overlay.");
ok(!highlighters.gridHighlighterShown, "No CSS grid highlighter is shown.");
info("Toggling ON the CSS grid highlighter from the grid display badge.");
const onHighlighterShown = highlighters.once("grid-highlighter-shown");
let onCheckboxChange = waitUntilState(store, state =>
state.grids.length === 1 &&
state.grids[0].highlighted);
gridDisplayBadge.click();
await onHighlighterShown;
await onCheckboxChange;
info("Check the CSS grid highlighter is created and grid display badge state.");
ok(highlighters.highlighters[HIGHLIGHTER_TYPE],
"CSS grid highlighter is created in the highlighters overlay.");
ok(highlighters.gridHighlighterShown, "CSS grid highlighter is shown.");
ok(gridDisplayBadge.classList.contains("active"), "grid display badge is active.");
info("Toggling OFF the CSS grid highlighter from the grid display badge.");
const onHighlighterHidden = highlighters.once("grid-highlighter-hidden");
onCheckboxChange = waitUntilState(store, state =>
state.grids.length == 1 &&
!state.grids[0].highlighted);
gridDisplayBadge.click();
await onHighlighterHidden;
await onCheckboxChange;
ok(!gridDisplayBadge.classList.contains("active"), "grid display badge is not active.");
});

View File

@ -1,4 +1,3 @@
/* 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/. */
@ -11,6 +10,11 @@ Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/inspector/test/head.js",
this);
// Load the shared Redux helpers into this compartment.
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/shared/test/shared-redux-head.js",
this);
var {getInplaceEditorForSpan: inplaceEditor} = require("devtools/client/shared/inplace-editor");
var clipboard = require("devtools/shared/platform/clipboard");

View File

@ -8,6 +8,7 @@
const promise = require("promise");
const Services = require("Services");
const flags = require("devtools/shared/flags");
const {l10n} = require("devtools/shared/inspector/css-logic");
const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
const OutputParser = require("devtools/client/shared/output-parser");
@ -151,9 +152,6 @@ function CssRuleView(inspector, document, store, pageStyle) {
this.shortcuts.on("CmdOrCtrl+F", event => this._onShortcut("CmdOrCtrl+F", event));
this.element.addEventListener("copy", this._onCopy);
this.element.addEventListener("contextmenu", this._onContextMenu);
this.element.addEventListener("mousemove", () => {
this.addHighlightersToView();
}, { once: true });
this.addRuleButton.addEventListener("click", this._onAddRule);
this.searchField.addEventListener("input", this._onFilterStyles);
this.searchClearButton.addEventListener("click", this._onClearSearch);
@ -163,6 +161,15 @@ function CssRuleView(inspector, document, store, pageStyle) {
this.activeCheckbox.addEventListener("click", this._onTogglePseudoClass);
this.focusCheckbox.addEventListener("click", this._onTogglePseudoClass);
if (flags.testing) {
// In tests, we start listening immediately to avoid having to simulate a mousemove.
this.highlighters.addToView(this);
} else {
this.element.addEventListener("mousemove", () => {
this.highlighters.addToView(this);
}, { once: true });
}
this._handlePrefChange = this._handlePrefChange.bind(this);
this._handleUAStylePrefChange = this._handleUAStylePrefChange.bind(this);
this._handleDefaultColorUnitPrefChange =
@ -1637,14 +1644,6 @@ CssRuleView.prototype = {
event.stopPropagation();
}
},
/**
* Adds the highlighters overlay to the rule view. This is called by the "mousemove"
* event handler and in shared-head.js when opening and selecting the rule view.
*/
addHighlightersToView() {
this.highlighters.addToView(this);
},
};
/**

View File

@ -91,9 +91,6 @@ function openRuleView() {
// through an additional ".flush()" property.
view.debounce = manualDebounce();
// Adds the highlighters overlay in the rule view.
view.addHighlightersToView();
return {
toolbox: data.toolbox,
inspector: data.inspector,
@ -113,8 +110,6 @@ function openRuleView() {
function openComputedView() {
return openInspectorSidebarTab("computedview").then(data => {
const view = data.inspector.getPanel("computedview").computedView;
// Adds the highlighters overlay in the computed view.
view.addHighlightersToView();
return {
toolbox: data.toolbox,
@ -165,9 +160,7 @@ function openLayoutView() {
* @return {CssRuleView} the rule view
*/
function selectRuleView(inspector) {
const view = inspector.getPanel("ruleview").view;
view.addHighlightersToView();
return view;
return inspector.getPanel("ruleview").view;
}
/**
@ -179,9 +172,7 @@ function selectRuleView(inspector) {
*/
function selectComputedView(inspector) {
inspector.sidebar.select("computedview");
const view = inspector.getPanel("computedview").computedView;
view.addHighlightersToView();
return view;
return inspector.getPanel("computedview").computedView;
}
/**

View File

@ -8,7 +8,6 @@ module.exports = {
"run_next_test": true,
"equal": true,
"do_print": true,
"waitUntilState": true
},
"rules": {
// Stop giving errors for run_test

View File

@ -43,12 +43,16 @@ async function waitContentVisibilityChange(aIsHidden, aBrowser) {
*/
add_task(async function() {
info("creating test window");
let winTest = await BrowserTestUtils.openNewBrowserWindow();
// Specify the width, height, left and top, so that the new window can be
// fully covered by "window".
let winTest = await BrowserTestUtils.openNewBrowserWindow({ width: 500,
height: 500,
left: 200,
top: 200 });
let resizePromise = BrowserTestUtils.waitForEvent(winTest, "resize", false, e => {
return winTest.innerHeight <= 500 && winTest.innerWidth <= 500;
});
winTest.moveTo(200, 200);
winTest.resizeTo(500, 500);
await resizePromise;
let browserTest = winTest.gBrowser;
info(`loading test page: ${testPageURL}`);

View File

@ -146,6 +146,8 @@ SourceSurfaceD2D1::DrawTargetWillChange()
DrawTargetD2D1::mVRAMUsageSS += mSize.width * mSize.height * BytesPerPixel(mFormat);
// Ensure the object stays alive for the duration of MarkIndependent.
RefPtr<SourceSurfaceD2D1> deathGrip = this;
// We now no longer depend on the source surface content remaining the same.
MarkIndependent();
}

View File

@ -24,10 +24,10 @@ Firefox, these simply need to be added to the /components directory of your XPI.
Other applications may require use of regxpcom or other techniques; consult the
applicable documentation for further details.
Finally, create an instance of the server using the following command:
Finally, load httpd.js into the current file, and create an instance of the
server using the following command:
var server = Components.classes["@mozilla.org/server/jshttp;1"]
.createInstance(Components.interfaces.nsIHttpServer);
var server = new nsHttpServer();
At this point you'll want to initialize the server, since by default it doesn't
serve many useful paths. For more information on this, see the IDL docs for the

View File

@ -38,8 +38,6 @@ var EXPORTED_SYMBOLS = [
"HttpServer",
];
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
const CC = Components.Constructor;
const PR_UINT32_MAX = Math.pow(2, 32) - 1;
@ -390,8 +388,6 @@ function nsHttpServer()
}
nsHttpServer.prototype =
{
classID: Components.ID("{54ef6f81-30af-4b1d-ac55-8ba811293e41}"),
// NSISERVERSOCKETLISTENER
/**
@ -5329,11 +5325,6 @@ Request.prototype =
}
};
// XPCOM trappings
var NSGetFactory = XPCOMUtils.generateNSGetFactory([nsHttpServer]);
/**
* Creates a new HTTP server listening for loopback traffic on the given port,
* starts it, and runs the server until the server processes a shutdown request,

View File

@ -1,3 +1 @@
component {54ef6f81-30af-4b1d-ac55-8ba811293e41} httpd.js
contract @mozilla.org/server/jshttp;1 {54ef6f81-30af-4b1d-ac55-8ba811293e41}
interfaces test_necko.xpt

View File

@ -11,6 +11,7 @@ load(_HTTPD_JS_PATH.path);
// if these tests fail, we'll want the debug output
DEBUG = true;
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
/**

View File

@ -279,8 +279,8 @@ certErrorTrust_UnknownIssuer=The certificate is not trusted because the issuer c
certErrorTrust_UnknownIssuer2=The server might not be sending the appropriate intermediate certificates.
certErrorTrust_UnknownIssuer3=An additional root certificate may need to be imported.
certErrorTrust_UnknownIssuer4=Someone could be trying to impersonate the site and you should not continue.
# LOCALIZATION NOTE (certErrorTrust_UnknownIssuer5): %1$S is replaced by the brand name, %2$S is replaced by host name.
certErrorTrust_UnknownIssuer5=Websites prove their identity via security certificates. %1$S does not trust %2$S because its security certificate issuer is unknown, the certificate is self-signed, or the server is not sending the correct intermediate certificates.
# LOCALIZATION NOTE (certErrorTrust_UnknownIssuer6): %1$S is replaced by the brand name, %2$S is replaced by host name.
certErrorTrust_UnknownIssuer6=Websites prove their identity via certificates. %1$S does not trust %2$S because its security certificate issuer is unknown, the certificate is self-signed, or the server is not sending the correct intermediate certificates.
certErrorTrust_CaInvalid=The certificate is not trusted because it was issued by an invalid CA certificate.
certErrorTrust_Issuer=The certificate is not trusted because the issuer certificate is not trusted.
certErrorTrust_SignatureAlgorithmDisabled=The certificate is not trusted because it was signed using a signature algorithm that was disabled because that algorithm is not secure.
@ -291,22 +291,22 @@ certErrorTrust_MitM=Your connection is being intercepted by a TLS proxy. Uninsta
certErrorTrust_Symantec=The security certificate for %S is not trustworthy because the issuing organization failed to follow security practices. Certificates issued by Symantec, including the Thawte, GeoTrust, and RapidSSL brands, are not considered safe.
certErrorMismatch=The certificate is not valid for the name %S.
# LOCALIZATION NOTE (certErrorMismatch1, certErrorMismatchSinglePrefix1, certErrorMismatchMultiple1): %1$S is replaced by the brand name, %2$S is replaced by host name.
certErrorMismatch1=Websites prove their identity via security certificates. %1$S does not trust %2$S because it uses a security certificate that is not valid for %2$S.
# LOCALIZATION NOTE (certErrorMismatch2, certErrorMismatchSinglePrefix2, certErrorMismatchMultiple2): %1$S is replaced by the brand name, %2$S is replaced by host name.
certErrorMismatch2=Websites prove their identity via certificates. %1$S does not trust %2$S because it uses a security certificate that is not valid for %2$S.
# LOCALIZATION NOTE (certErrorMismatchSinglePrefix): %S is replaced by the domain for which the certificate is valid
certErrorMismatchSinglePrefix=The certificate is only valid for %S.
# LOCALIZATION NOTE (certErrorMismatchSinglePrefix1): %3$S is replaced by the domain for which the certificate is valid
certErrorMismatchSinglePrefix1=Websites prove their identity via security certificates. %1$S does not trust %2$S because it uses a security certificate that is not valid for %2$S.
# LOCALIZATION NOTE (certErrorMismatchSinglePrefix2): %3$S is replaced by the domain for which the certificate is valid
certErrorMismatchSinglePrefix2=Websites prove their identity via certificates. %1$S does not trust %2$S because it uses a security certificate that is not valid for %2$S.
certErrorMismatchMultiple=The certificate is only valid for the following names:
certErrorMismatchMultiple1=Websites prove their identity via security certificates. %1$S does not trust %2$S because it uses a security certificate that is not valid for %2$S. The certificate is only valid for the following names:
certErrorMismatchMultiple2=Websites prove their identity via certificates. %1$S does not trust %2$S because it uses a security certificate that is not valid for %2$S. The certificate is only valid for the following names:
# LOCALIZATION NOTE (certErrorExpiredNow): Do not translate %1$S (date+time of expired certificate) or %2$S (current date+time)
certErrorExpiredNow=The certificate expired on %1$S. The current time is %2$S.
certErrorExpiredNow1=Websites prove their identity via security certificates, which are valid for a set time period. The security certificate for %S appears to be expired.
certErrorExpiredNow2=Websites prove their identity via certificates, which are valid for a set time period. The security certificate for %S appears to be expired.
# LOCALIZATION NOTE (certErrorNotYetValidNow): Do not translate %1$S (date+time certificate will become valid) or %2$S (current date+time)
certErrorNotYetValidNow=The certificate will not be valid until %1$S. The current time is %2$S.
certErrorNotYetValidNow1=Websites prove their identity via security certificates, which are valid for a set time period. The security certificate for %S appears to be not yet valid.
certErrorNotYetValidNow2=Websites prove their identity via certificates, which are valid for a set time period. The security certificate for %S appears to be not yet valid.
# LOCALIZATION NOTE (certErrorSymantecDistrustDescription): %S will be replaced by the domain for which the certificate is valid.
certErrorSymantecDistrustDescription=Websites prove their identity via certificates, which are issued by certificate authorities. Most browsers will no longer trust Symantec, the certificate authority for %S.

View File

@ -143,6 +143,10 @@ web-platform-tests-wdspec:
linux64-asan/opt: 2
linux64-qr/.*: 2 # can't be tier-1 if it's not running on integration branches
default: default
chunks:
by-test-platform:
linux64-ccov/.*: 2
default: 1
web-platform-tests-wdspec-headless:
description: "Web platform webdriver-spec headless run"

View File

@ -25,6 +25,9 @@ ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://testing-common/TestUtils.jsm");
ChromeUtils.import("resource://testing-common/ContentTask.jsm");
ChromeUtils.defineModuleGetter(this, "BrowserWindowTracker",
"resource:///modules/BrowserWindowTracker.jsm");
Services
.mm
.loadFrameScript(
@ -701,61 +704,25 @@ var BrowserTestUtils = {
},
/**
* @param {Object} options
* {
* private: A boolean indicating if the window should be
* private
* remote: A boolean indicating if the window should run
* remote browser tabs or not. If omitted, the window
* will choose the profile default state.
* width: Desired width of window
* height: Desired height of window
* }
* Open a new browser window from an existing one.
* This relies on OpenBrowserWindow in browser.js, and waits for the window
* to be completely loaded before resolving.
*
* @param {Object}
* Options to pass to OpenBrowserWindow. Additionally, supports:
* - waitForTabURL
* Forces the initial browserLoaded check to wait for the tab to
* load the given URL (instead of about:blank)
*
* @return {Promise}
* Resolves with the new window once it is loaded.
*/
async openNewBrowserWindow(options = {}) {
let argString = Cc["@mozilla.org/supports-string;1"].
createInstance(Ci.nsISupportsString);
argString.data = "";
let features = "chrome,dialog=no,all";
let opener = null;
if (options.opener) {
opener = options.opener;
let currentWin = BrowserWindowTracker.getTopWindow({private: false});
if (!currentWin) {
throw new Error("Can't open a new browser window from this helper if no non-private window is open.");
}
if (options.private) {
features += ",private";
}
if (options.width) {
features += ",width=" + options.width;
}
if (options.height) {
features += ",height=" + options.height;
}
if (options.left) {
features += ",left=" + options.left;
}
if (options.top) {
features += ",top=" + options.top;
}
if (options.hasOwnProperty("remote")) {
let remoteState = options.remote ? "remote" : "non-remote";
features += `,${remoteState}`;
}
if (options.url) {
argString.data = options.url;
}
let win = Services.ww.openWindow(
opener, AppConstants.BROWSER_CHROME_URL, "_blank",
features, argString);
let win = currentWin.OpenBrowserWindow(options);
// Wait for browser-delayed-startup-finished notification, it indicates
// that the window has loaded completely and is ready to be used for
@ -764,7 +731,9 @@ var BrowserTestUtils = {
TestUtils.topicObserved("browser-delayed-startup-finished",
subject => subject == win).then(() => win);
let loadPromise = this.firstBrowserLoaded(win);
let loadPromise = this.firstBrowserLoaded(win, !options.waitForTabURL, browser => {
return !options.waitForTabURL || options.waitForTabURL == browser.currentURI.spec;
});
await startupPromise;
await loadPromise;

View File

@ -63,7 +63,7 @@ user_pref("browser.tabs.remote.autostart", false);
// Make sure Translation won't hit the network.
user_pref("browser.translation.bing.authURL", "http://{server}/browser/browser/components/translation/test/bing.sjs");
user_pref("browser.translation.bing.translateArrayURL", "http://{server}/browser/browser/components/translation/test/bing.sjs");
user_pref("browser.translation.engine", "bing");
user_pref("browser.translation.engine", "Bing");
user_pref("browser.translation.yandex.translateURLOverride", "http://{server}/browser/browser/components/translation/test/yandex.sjs");
user_pref("browser.ui.layout.tablet", 0); // force tablet UI off
// Ensure UITour won't hit the network

View File

@ -185107,6 +185107,18 @@
{}
]
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering.html": [
[
"/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering.html",
[
[
"/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering-ref.html",
"=="
]
],
{}
]
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float.html": [
[
"/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float.html",
@ -285839,6 +285851,11 @@
{}
]
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering-ref.html": [
[
{}
]
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-dynamic-update.html": [
[
{}
@ -356684,6 +356701,12 @@
{}
]
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none.html": [
[
"/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none.html",
{}
]
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display.html": [
[
"/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display.html",
@ -365856,6 +365879,12 @@
{}
]
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/quirks.window.js": [
[
"/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/quirks.window.html",
{}
]
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/reload.window.js": [
[
"/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/reload.window.html",
@ -394108,9 +394137,21 @@
{}
]
],
"trusted-types/TrustedTypePolicyFactory-createPolicy.tentative.html": [
"trusted-types/TrustedTypePolicyFactory-createPolicy-createXYZTests.tentative.html": [
[
"/trusted-types/TrustedTypePolicyFactory-createPolicy.tentative.html",
"/trusted-types/TrustedTypePolicyFactory-createPolicy-createXYZTests.tentative.html",
{}
]
],
"trusted-types/TrustedTypePolicyFactory-createPolicy-nameTests.tentative.html": [
[
"/trusted-types/TrustedTypePolicyFactory-createPolicy-nameTests.tentative.html",
{}
]
],
"trusted-types/Window-TrustedTypes.tentative.html": [
[
"/trusted-types/Window-TrustedTypes.tentative.html",
{}
]
],
@ -394120,12 +394161,6 @@
{}
]
],
"trusted-types/Window-trustedTypes.tentative.html": [
[
"/trusted-types/Window-trustedTypes.tentative.html",
{}
]
],
"trusted-types/block-string-assignment-to-DOMParser-parseFromString.tentative.html": [
[
"/trusted-types/block-string-assignment-to-DOMParser-parseFromString.tentative.html",
@ -599453,6 +599488,18 @@
"4e9539179739a3690aab276f2ba98c25bd4dfe9b",
"testharness"
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering-ref.html": [
"e6eff47e53c7a40e973b7f9dc298af2343f59941",
"support"
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering.html": [
"abf3c45df71ee6617ddb8b6d402a103f54624820",
"reftest"
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none.html": [
"689454ac493a05b28658edf549d71c6aa1c7be0e",
"testharness"
],
"html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display.html": [
"914547fc6cdde3e464b28eb7cc9737d17305f9af",
"testharness"
@ -608321,6 +608368,10 @@
"5e5ca80781809cc509a8eade7ea91e74de92f9a8",
"testharness"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/quirks.window.js": [
"0ff0bb99443677b8f8844c8ecedef22c408f2bac",
"testharness"
],
"html/webappapis/dynamic-markup-insertion/opening-the-input-stream/reload.window.js": [
"d6ff9dc7a45425cb688ed4b6c9ea2ab5c1c3ae5c",
"testharness"
@ -620542,11 +620593,11 @@
"testharness"
],
"payment-request/allowpaymentrequest/common.sub.js": [
"85a08461fcb0197ed2259d77035e696c1c69d6d8",
"a94bac064c9432980d437a98b72d4843f1b40bbe",
"support"
],
"payment-request/allowpaymentrequest/echo-PaymentRequest.html": [
"f18b16ee31bf7e3eb868d073ab5e0fb0061bbd88",
"5211c7e5ce78c0621036578fef79aeb2c98f2a27",
"support"
],
"payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https.html": [
@ -646978,35 +647029,35 @@
"testharness"
],
"trusted-types/DOMParser-parseFromString.tentative.html": [
"2fe9b31b787e1fb458a3ed8996b2d79f7e14aa35",
"2dfc37686bca15431c216a50d29f9f9eed2782e0",
"testharness"
],
"trusted-types/Document-write.tentative.html": [
"3a63e923543b999b05d1fab926ad33d7d2719dfa",
"79247fb4d68e6724b98c62d3b62a0e6b20784f4d",
"testharness"
],
"trusted-types/Element-insertAdjacentHTML.tentative.html": [
"599ade44ec117ecb429659a9f969a2767bd95cbb",
"d5db7936b1f98012ee3750f6d3056f4a5b172615",
"testharness"
],
"trusted-types/Element-outerHTML.tentative.html": [
"a0bb6c1a5e3fef47e4351353befbfc8eb105652f",
"c8daddfe9955196bf0b69410263cb7c01e473e5e",
"testharness"
],
"trusted-types/HTMLElement-generic.tentative.html": [
"cea32a5a2df1d9b255f5aaf85ac5a694fdb3a618",
"08d165a75d4185a61374128be8046384cc701b4e",
"testharness"
],
"trusted-types/Location-assign.tentative.html": [
"13cca5679488d0b3e12631d5f70408565ea1b065",
"62f98e96d7febe6c744b882f8d196d1686fe9166",
"testharness"
],
"trusted-types/Location-href.tentative.html": [
"d759d28593e67f25d8bc28d36cf0ff4912460dc0",
"bacadf6a91b1c0bc5c76293aab38f9d503cfa2b7",
"testharness"
],
"trusted-types/Location-replace.tentative.html": [
"7d84905d19878d57634a8497b81ef86d8114b72e",
"4fb53d0260973ed5d714540a448909488b6e2465",
"testharness"
],
"trusted-types/META.yml": [
@ -647014,63 +647065,67 @@
"support"
],
"trusted-types/Range-createContextualFragment.tentative.html": [
"3d45b33486d3971c0c58180fa4034dbfae18f135",
"3a880a53778acb165fd5d957eeaca22685baf2b5",
"testharness"
],
"trusted-types/TrustedTypePolicyFactory-createPolicy.tentative.html": [
"76e6d130b05dfba00911ad42eb7a162cd29b222e",
"trusted-types/TrustedTypePolicyFactory-createPolicy-createXYZTests.tentative.html": [
"b20fcf2436eac17f9f558cab0c80d1eced6bb1be",
"testharness"
],
"trusted-types/TrustedTypePolicyFactory-createPolicy-nameTests.tentative.html": [
"6d43e0bafc61f34c17d7d7b751bf69f12d035adf",
"testharness"
],
"trusted-types/Window-TrustedTypes.tentative.html": [
"8e20e492e6a8484e386d1a08f854bd9b162bd6be",
"testharness"
],
"trusted-types/Window-open.tentative.html": [
"c005fbba143f66a9540deebba7988fdea9661558",
"testharness"
],
"trusted-types/Window-trustedTypes.tentative.html": [
"ef4487749dd0c12a00bd3ab42c1353467a6eeb8f",
"172d566e57fc635b551b5d355661db690869b220",
"testharness"
],
"trusted-types/block-string-assignment-to-DOMParser-parseFromString.tentative.html": [
"cc575dc0085bce3aa1370fb528e28003ad3c1c2b",
"e5959a425a2feafc95deb4f6b8b1372ad5ad1497",
"testharness"
],
"trusted-types/block-string-assignment-to-Document-write.tentative.html": [
"28813d72e0e1833e25658e2210abb9b0a30b2137",
"06532c3b47948c22c5debfae511c5fbd414c64de",
"testharness"
],
"trusted-types/block-string-assignment-to-Element-insertAdjacentHTML.tentative.html": [
"ad94b44e8fb7621ba4693ad65377872281f3e9a6",
"1fb3bbd994a4a6904cfc4609430f9188692eda40",
"testharness"
],
"trusted-types/block-string-assignment-to-Element-outerHTML.tentative.html": [
"47f1165b1a69366848dd5dd21a2ad2199b9c2e81",
"abb595222ba5e609cff02adc27a8a7239d44103e",
"testharness"
],
"trusted-types/block-string-assignment-to-HTMLElement-generic.tentative.html": [
"eae52626190746ad0a8b436f74981009e400232b",
"7b1a5795d7c04448cd204391ba75030a87131150",
"testharness"
],
"trusted-types/block-string-assignment-to-Location-assign.tentative.html": [
"8079335bc5861fa723691a0f884cf249e6f63e24",
"cd375b9d016365f01d8e6f95b50d928520c82afa",
"testharness"
],
"trusted-types/block-string-assignment-to-Location-href.tentative.html": [
"4e393f92506e00276a4440e1023ac23e7a6138e8",
"14fbcb2fb3cdc6f51e957bbb047ba8900f0d0865",
"testharness"
],
"trusted-types/block-string-assignment-to-Location-replace.tentative.html": [
"872f14e144830ed87b51e352f93c32ce85438bfe",
"9d00fcdeb35d36b05adeb7b67f3816169f3ad036",
"testharness"
],
"trusted-types/block-string-assignment-to-Range-createContextualFragment.tentative.html": [
"2afa2572c350071b791ee280bce0a1e5135dc2aa",
"ff9be06251dc7965ad1d765d49e45b4ef9f8d728",
"testharness"
],
"trusted-types/block-string-assignment-to-Window-open.tentative.html": [
"f5712295d30d7b1d680ad6753dd401d21c0409f9",
"ae4b038dc0c67ab828c3531b3ac01e819114f1ed",
"testharness"
],
"trusted-types/support/helper.sub.js": [
"b5435917bec607c97eaa5d75ee7fa2752999cb0a",
"617e02aa6badddd36f01f88241ac8ce7d5670597",
"support"
],
"uievents/META.yml": [
@ -659870,7 +659925,7 @@
"testharness"
],
"xhr/timeout-multiple-fetches.html": [
"30d6b736c56d5576483c12a7413dd809d27d89e8",
"4f4998c4285222bf4bdf41c3e0c1c27e913d2149",
"testharness"
],
"xhr/timeout-sync.htm": [

View File

@ -0,0 +1,13 @@
[quirks.window.html]
[document.open() sets document to no-quirks mode (write no doctype)]
expected: FAIL
[document.open() sets document to no-quirks mode (write old doctype)]
expected: FAIL
[document.open() sets document to no-quirks mode (write new doctype)]
expected: FAIL
[document.open() sets document to no-quirks mode, not limited-quirks mode]
expected: FAIL

View File

@ -1,2 +1,2 @@
local: a3acca752946dcc6b1196f588815e8d89dd2a047
upstream: 3d172bc612e03a896b5611d9e9652f860995feef
local: c6fdb0456dcc9f12ac413c063f48f36493401dbd
upstream: 128c48e50cea769df396af8c90c38bc49b620939

View File

@ -1,8 +1,5 @@
[TrustedTypePolicyFactory-createPolicy.tentative.html]
[policy.name = name]
expected: FAIL
[TrustedTypePolicyFactory-createPolicy]
[TrustedTypePolicyFactory-createPolicy-createXYZTests.tentative.html]
[script = identity function]
expected: FAIL
[html = callback that throws]
@ -11,15 +8,18 @@
[script_url - calling undefined callback]
expected: FAIL
[html - calling undefined callback]
expected: FAIL
[script_url = identity function]
expected: FAIL
[script = identity function, global string changed]
expected: FAIL
[url = this without bind]
expected: FAIL
[script = this without bind]
expected: FAIL
[html = this bound to an object]
expected: FAIL
@ -29,25 +29,37 @@
[url = this bound to an object]
expected: FAIL
[url = identity function]
expected: FAIL
[script_url = identity function, global string changed]
expected: FAIL
[script_url = this bound to an object]
expected: FAIL
[script_url = this without bind]
expected: FAIL
[html = identity function, global string changed]
expected: FAIL
[url = callback that throws]
expected: FAIL
[url = identity function]
[html = string + global string]
expected: FAIL
[script = this bound to an object]
expected: FAIL
[html = identity function]
expected: FAIL
[script_url = this without bind]
[script = callback that throws]
expected: FAIL
[html - calling undefined callback]
expected: FAIL
[url - calling undefined callback]
@ -56,13 +68,16 @@
[script_url = callback that throws]
expected: FAIL
[script - calling undefined callback]
expected: FAIL
[html = this without bind]
expected: FAIL
[html = string + global string]
[script_url = string + global string]
expected: FAIL
[script_url = string + global string]
[script = null]
expected: FAIL
[script_url = null]
@ -71,33 +86,39 @@
[html = null]
expected: FAIL
[script = string + global string]
expected: FAIL
[url = string + global string]
expected: FAIL
[url = null]
expected: FAIL
[script = identity function]
[script_url - calling undefined callback throws]
expected: FAIL
[script = identity function, global string changed]
[url - calling undefined callback throws]
expected: FAIL
[script = this without bind]
[script - calling undefined callback throws]
expected: FAIL
[script = this bound to an object]
[policy has createScript, throws when called with createHTML]
expected: FAIL
[script = callback that throws]
[html - calling undefined callback throws]
expected: FAIL
[script - calling undefined callback]
[createScript defined - calling undefined callbacks throws]
expected: FAIL
[script = null]
[createScriptURL defined - calling undefined callbacks throws]
expected: FAIL
[script = string + global string]
[createHTML defined - calling undefined callbacks throws]
expected: FAIL
[createURL defined - calling undefined callbacks throws]
expected: FAIL

View File

@ -0,0 +1,7 @@
[TrustedTypePolicyFactory-createPolicy-nameTests.tentative.html]
[Retrieving policy names]
expected: FAIL
[policy.name = name]
expected: FAIL

View File

@ -0,0 +1,4 @@
[Window-TrustedTypes.tentative.html]
[factory = window.TrustedTypes]
expected: FAIL

View File

@ -1,7 +0,0 @@
[Window-trustedTypes.tentative.html]
[factory = window.trustedTypes]
expected: FAIL
[Window-trustedTypes]
expected: FAIL

View File

@ -0,0 +1,7 @@
<!doctype html>
<title>Reference for Rendering of display: none legend</title>
<style>
div { border: 2em solid lime; width: 0; }
</style>
<p>There should be a green box below.</p>
<div></div>

View File

@ -0,0 +1,11 @@
<!doctype html>
<title>Rendering of display: none legend</title>
<link rel=match href=legend-display-none-rendering-ref.html>
<style>
fieldset { border: 2em solid lime; width: 0; margin: 0; padding: 0; }
legend { display: none; background: red; }
</style>
<p>There should be a green box below.</p>
<fieldset>
<legend>FAIL</legend>
</fieldset>

View File

@ -0,0 +1,16 @@
<!doctype html>
<title>legend display: none</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<style>
legend { display: none; }
</style>
<fieldset>
<legend>Foo</legend>
</fieldset>
<script>
test(() => {
const display = getComputedStyle(document.querySelector('legend')).display;
assert_equals(display, 'none');
});
</script>

View File

@ -0,0 +1,74 @@
test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.contentDocument.close());
assert_equals(frame.contentDocument.compatMode, "BackCompat");
frame.contentDocument.open();
assert_equals(frame.contentDocument.compatMode, "CSS1Compat");
frame.contentDocument.close();
assert_equals(frame.contentDocument.compatMode, "BackCompat");
}, "document.open() sets document to no-quirks mode (write no doctype)");
test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.contentDocument.close());
assert_equals(frame.contentDocument.compatMode, "BackCompat");
frame.contentDocument.open();
assert_equals(frame.contentDocument.compatMode, "CSS1Compat");
frame.contentDocument.write("<!doctype html public");
assert_equals(frame.contentDocument.compatMode, "CSS1Compat");
frame.contentDocument.write(" \"-//IETF//DTD HTML 3//\"");
assert_equals(frame.contentDocument.compatMode, "CSS1Compat");
frame.contentDocument.write(">");
assert_equals(frame.contentDocument.compatMode, "BackCompat");
frame.contentDocument.close();
assert_equals(frame.contentDocument.compatMode, "BackCompat");
}, "document.open() sets document to no-quirks mode (write old doctype)");
test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.contentDocument.close());
assert_equals(frame.contentDocument.compatMode, "BackCompat");
frame.contentDocument.open();
assert_equals(frame.contentDocument.compatMode, "CSS1Compat");
frame.contentDocument.write("<!doctype html");
assert_equals(frame.contentDocument.compatMode, "CSS1Compat");
frame.contentDocument.write(">");
assert_equals(frame.contentDocument.compatMode, "CSS1Compat");
frame.contentDocument.close();
assert_equals(frame.contentDocument.compatMode, "CSS1Compat");
}, "document.open() sets document to no-quirks mode (write new doctype)");
// This tests the document.open() call in fact sets the document to no-quirks
// mode, not limited-quirks mode. It is derived from
// quirks/blocks-ignore-line-height.html in WPT, as there is no direct way to
// distinguish between a no-quirks document and a limited-quirks document. It
// assumes that the user agent passes the linked test, which at the time of
// writing is all major web browsers.
test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.contentDocument.close());
assert_equals(frame.contentDocument.compatMode, "BackCompat");
frame.contentDocument.open();
assert_equals(frame.contentDocument.compatMode, "CSS1Compat");
// Create the DOM tree manually rather than going through document.write() to
// bypass the parser, which resets the document mode.
const html = frame.contentDocument.appendChild(frame.contentDocument.createElement("html"));
const body = html.appendChild(frame.contentDocument.createElement("body"));
assert_equals(frame.contentDocument.body, body);
body.innerHTML = `
<style>#ref { display:block }</style>
<div id=test><font size=1>x</font></div>
<font id=ref size=1>x</font>
<div id=s_ref>x</div>
`;
assert_equals(frame.contentDocument.compatMode, "CSS1Compat");
const idTest = frame.contentDocument.getElementById("test");
const idRef = frame.contentDocument.getElementById("ref");
const idSRef = frame.contentDocument.getElementById("s_ref");
assert_equals(frame.contentWindow.getComputedStyle(idTest).height,
frame.contentWindow.getComputedStyle(idSRef).height);
assert_not_equals(frame.contentWindow.getComputedStyle(idTest).height,
frame.contentWindow.getComputedStyle(idRef).height);
}, "document.open() sets document to no-quirks mode, not limited-quirks mode");

View File

@ -5,41 +5,57 @@
const tests = {};
window.onmessage = (e) => {
window.onmessage = e => {
const result = e.data;
const tagName = result.urlQuery;
const t = tests[tagName];
t.step(() => {
if (expectSuccess[tagName]) {
assert_equals(result.message, 'Success');
assert_equals(result.message, "Success");
if (result.message === "Exception") {
const [, code, name, stack] = result.details;
assert_unreached(`Unexpected exception "${name}" (${code}) ${stack}`);
}
} else {
assert_equals(result.message, 'Exception');
assert_array_equals(result.details, [true /*ex instanceof DOMException*/,
DOMException.SECURITY_ERR /*ex.code*/,
'SecurityError' /*ex.name*/]);
assert_equals(result.message, "Exception");
const detailsArray = result.details.slice(0,3);
assert_array_equals(detailsArray, [
true /*ex instanceof DOMException*/,
DOMException.SECURITY_ERR /*ex.code*/,
"SecurityError" /*ex.name*/,
]);
}
t.done();
});
};
['iframe', 'frame', 'object', 'embed'].forEach((tagName, i) => {
tests[tagName] = async_test((t) => {
["iframe", "frame", "object", "embed"].forEach((tagName, i) => {
tests[tagName] = async_test(t => {
const elm = document.createElement(tagName);
if (setAllowPaymentRequest) {
elm.setAttribute('allowpaymentrequest', '');
elm.setAttribute("allowpaymentrequest", "");
}
const path = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1);
const url = (testCrossOrigin ? "https://{{domains[www1]}}:{{ports[https][0]}}" : "") +
path + "echo-PaymentRequest.html?" + tagName;
if (tagName === 'object') {
const path = location.pathname.substring(
0,
location.pathname.lastIndexOf("/") + 1
);
const url =
(testCrossOrigin ? "https://{{domains[www1]}}:{{ports[https][0]}}" : "") +
path +
"echo-PaymentRequest.html?" +
tagName;
if (tagName === "object") {
elm.data = url;
} else {
elm.src = url;
}
elm.onload = t.step_func(() => {
window[i].postMessage('What is the result of new PaymentRequest(...)?', '*');
window[i].postMessage(
"What is the result of new PaymentRequest(...)?",
"*"
);
});
elm.onerror = t.unreached_func('elm.onerror');
elm.onerror = t.unreached_func("elm.onerror");
document.body.appendChild(elm);
}, tagName);
});

View File

@ -11,7 +11,9 @@ window.onmessage = (e) => {
e.source.postMessage(result, '*');
} catch(ex) {
result.message = 'Exception';
result.details = [ex instanceof DOMException, ex.code, ex.name];
const isDomException = ex instanceof DOMException;
const stack = "stack" in ex ? ex.stack : "";
result.details = [ isDomException, ex.code, ex.name, stack ];
e.source.postMessage(result, '*');
}
} else {

View File

@ -4,14 +4,12 @@
<script src="support/helper.sub.js"></script>
<body>
<script>
async_test(t => {
createHTML_policy(window)
.then(t.step_func_done(p => {
let html = p.createHTML(INPUTS.HTML);
let parser = new DOMParser();
let doc = parser.parseFromString(html, "text/html");
assert_equals(doc.body.innerText, RESULTS.HTML);
}));
test(t => {
let p = createHTML_policy(window, 1);
let html = p.createHTML(INPUTS.HTML);
let parser = new DOMParser();
let doc = parser.parseFromString(html, "text/html");
assert_equals(doc.body.innerText, RESULTS.HTML);
}, "document.innerText assigned via policy (successful HTML transformation).");
test(t => {

View File

@ -4,12 +4,10 @@
<script src="support/helper.sub.js"></script>
<body>
<script>
async_test(t => {
createHTML_policy(window)
.then(t.step_func_done(p => {
let html = p.createHTML(INPUTS.HTML);
document.write(html);
assert_equals(document.body.innerText, RESULTS.HTML);
}));
test(t => {
let p = createHTML_policy(window, 1);
let html = p.createHTML(INPUTS.HTML);
document.write(html);
assert_equals(document.body.innerText, RESULTS.HTML);
}, "document.write with html assigned via policy (successful URL transformation).");
</script>

View File

@ -7,32 +7,30 @@
<script>
var container = document.querySelector('#container');
async_test(t => {
createHTML_policy(window)
.then(t.step_func_done(p => {
let html = p.createHTML(INPUTS.HTML);
test(t => {
let p = createHTML_policy(window, 1);
let html = p.createHTML(INPUTS.HTML);
var d = document.createElement('div');
container.appendChild(d);
var d = document.createElement('div');
container.appendChild(d);
d.insertAdjacentHTML('beforebegin', html);
assert_equals(d.previousSibling.nodeType, Node.TEXT_NODE);
assert_equals(d.previousSibling.data, RESULTS.HTML);
d.insertAdjacentHTML('beforebegin', html);
assert_equals(d.previousSibling.nodeType, Node.TEXT_NODE);
assert_equals(d.previousSibling.data, RESULTS.HTML);
d.insertAdjacentHTML('afterbegin', html);
assert_equals(d.firstChild.nodeType, Node.TEXT_NODE);
assert_equals(d.firstChild.data, RESULTS.HTML);
d.insertAdjacentHTML('afterbegin', html);
assert_equals(d.firstChild.nodeType, Node.TEXT_NODE);
assert_equals(d.firstChild.data, RESULTS.HTML);
d.insertAdjacentHTML('beforeend', html);
assert_equals(d.lastChild.nodeType, Node.TEXT_NODE);
assert_equals(d.lastChild.data, RESULTS.HTML);
d.insertAdjacentHTML('beforeend', html);
assert_equals(d.lastChild.nodeType, Node.TEXT_NODE);
assert_equals(d.lastChild.data, RESULTS.HTML);
d.insertAdjacentHTML('afterend', html);
assert_equals(d.nextSibling.nodeType, Node.TEXT_NODE);
assert_equals(d.nextSibling.data, RESULTS.HTML);
d.insertAdjacentHTML('afterend', html);
assert_equals(d.nextSibling.nodeType, Node.TEXT_NODE);
assert_equals(d.nextSibling.data, RESULTS.HTML);
while (container.firstChild)
container.firstChild.remove();
}));
while (container.firstChild)
container.firstChild.remove();
}, "insertAdjacentHTML with html assigned via policy (successful HTML transformation).");
</script>

View File

@ -5,20 +5,18 @@
<body>
<div id="container"></div>
<script>
var container = document.querySelector('#container')
var container = document.querySelector('#container');
async_test(t => {
createHTML_policy(window)
.then(t.step_func_done(p => {
let html = p.createHTML(INPUTS.HTML);
test(t => {
let p = createHTML_policy(window, 1);
let html = p.createHTML(INPUTS.HTML);
var d = document.createElement('div');
document.querySelector('#container').appendChild(d);
d.outerHTML = html;
assert_equals(container.innerText, RESULTS.HTML);
var d = document.createElement('div');
document.querySelector('#container').appendChild(d);
d.outerHTML = html;
assert_equals(container.innerText, RESULTS.HTML);
while (container.firstChild)
container.firstChild.remove();
}));
while (container.firstChild)
container.firstChild.remove();
}, "outerHTML with html assigned via policy (successful HTML transformation).");
</script>

View File

@ -24,8 +24,8 @@
];
testCases.forEach(c => {
async_test(t => {
assert_element_accepts_trusted_url(window, t, c[0], c[1], RESULTS.URL);
test(t => {
assert_element_accepts_trusted_url(window, c, t, c[0], c[1], RESULTS.URL);
}, c[0] + "." + c[1] + " assigned via policy (successful URL transformation)");
});
@ -36,8 +36,8 @@
];
scriptTestCases.forEach(c => {
async_test(t => {
assert_element_accepts_trusted_script_url(window, t, c[0], c[1], RESULTS.SCRIPTURL);
test(t => {
assert_element_accepts_trusted_script_url(window, c, t, c[0], c[1], RESULTS.SCRIPTURL);
}, c[0] + "." + c[1] + " assigned via policy (successful ScriptURL transformation)");
});
@ -48,8 +48,8 @@
];
HTMLTestCases.forEach(c => {
async_test(t => {
assert_element_accepts_trusted_html(window, t, c[0], c[1], RESULTS.HTML);
test(t => {
assert_element_accepts_trusted_html(window, c, t, c[0], c[1], RESULTS.HTML);
}, c[0] + "." + c[1] + " assigned via policy (successful HTML transformation)");
});
</script>

View File

@ -4,12 +4,10 @@
<script src="support/helper.sub.js"></script>
<body>
<script>
async_test(t => {
createURL_policy(window)
.then(t.step_func_done(p => {
let url = p.createURL(location.href + "#xxx");
location.assign(url);
assert_equals("" + url, location.href, "location href");
}));
test(t => {
let p = createURL_policy(window, 1);
let url = p.createURL(location.href + "#xxx");
location.assign(url);
assert_equals("" + url, location.href, "location href");
}, "location.assign via policy (successful URL transformation).");
</script>

View File

@ -4,12 +4,10 @@
<script src="support/helper.sub.js"></script>
<body>
<script>
async_test(t => {
createURL_policy(window)
.then(t.step_func_done(p => {
let url = p.createURL(location.href + "#xxx");
location.href = url;
assert_equals("" + url, location.href, "location href");
}));
test(t => {
let p = createURL_policy(window, 1);
let url = p.createURL(location.href + "#xxx");
location.href = url;
assert_equals("" + url, location.href, "location href");
}, "location.href assigned via policy (successful URL transformation).");
</script>

View File

@ -4,12 +4,10 @@
<script src="support/helper.sub.js"></script>
<body>
<script>
async_test(t => {
createURL_policy(window)
.then(t.step_func_done(p => {
let url = p.createURL(location.href + "#xxx");
location.replace(url);
assert_equals("" + url, location.href, "location href");
}));
test(t => {
let p = createURL_policy(window, 1);
let url = p.createURL(location.href + "#xxx");
location.replace(url);
assert_equals("" + url, location.href, "location href");
}, "location.replace via policy (successful URL transformation).");
</script>

View File

@ -4,14 +4,12 @@
<script src="support/helper.sub.js"></script>
<body>
<script>
async_test(t => {
createHTML_policy(window)
.then(t.step_func_done(p => {
let html = p.createHTML(INPUTS.HTML);
var range = document.createRange();
range.selectNodeContents(document.documentElement);
var result = range.createContextualFragment(html);
assert_equals(result.textContent, RESULTS.HTML);
}));
test(t => {
let p = createHTML_policy(window, 1);
let html = p.createHTML(INPUTS.HTML);
var range = document.createRange();
range.selectNodeContents(document.documentElement);
var result = range.createContextualFragment(html);
assert_equals(result.textContent, RESULTS.HTML);
}, "range.createContextualFragment assigned via policy (successful HTML transformation).");
</script>

View File

@ -0,0 +1,294 @@
<!DOCTYPE html>
<script src="/resources/testharness.js" ></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/helper.sub.js"></script>
<body>
<script>
//HTML tests
function createHTMLTest(policyName, policy, expectedHTML, t) {
let p = window.TrustedTypes.createPolicy(policyName, policy);
assert_true(p.createHTML('whatever') instanceof TrustedHTML);
assert_equals(p.createHTML('whatever') + "", expectedHTML);
}
test(t => {
createHTMLTest('TestPolicyHTML1', { createHTML: s => s }, 'whatever', t);
}, "html = identity function");
test(t => {
createHTMLTest('TestPolicyHTML2', { createHTML: s => null }, "null", t);
}, "html = null");
var HTMLstr = 'well, ';
test(t => {
createHTMLTest('TestPolicyHTML3', { createHTML: s => HTMLstr + s }, HTMLstr + 'whatever', t);
}, "html = string + global string");
var HTMLx = 'global';
test(t => {
createHTMLTest('TestPolicyHTML4', { createHTML: s => { HTMLx = s; return s; } }, 'whatever', t);
assert_equals(HTMLx, 'whatever');
}, "html = identity function, global string changed");
test(t => {
let p = window.TrustedTypes.createPolicy('TestPolicyHTML5', { createHTML: s => { throw new Error(); }});
assert_throws(new Error(), _ => {
p.createHTML('whatever');
});
}, "html = callback that throws");
var obj = {
"foo": "well,"
}
function getHTML(s) {
return this.foo + " " + s;
}
test(t => {
createHTMLTest('TestPolicyHTML6', { createHTML: getHTML.bind(obj) }, 'well, whatever', t);
}, "html = this bound to an object");
var foo = "well,";
test(t => {
createHTMLTest('TestPolicyHTML7', { createHTML: s => getHTML(s) }, 'well, whatever', t);
}, "html = this without bind");
test(t => {
let p = window.TrustedTypes.createPolicy('TestPolicyHTML8', null);
assert_throws(new TypeError(), _ => {
p.createHTML('whatever');
});
}, "html - calling undefined callback throws");
test(t => {
let p = window.TrustedTypes.createPolicy('TestPolicyHTML9', { createHTML: createHTMLJS });
assert_throws(new TypeError(), _ => {
p.createScript(INPUTS.SCRIPT);
});
assert_throws(new TypeError(), _ => {
p.createScriptURL(INPUTS.SCRIPTURL);
});
assert_throws(new TypeError(), _ => {
p.createURL(INPUTS.URL);
});
}, "createHTML defined - calling undefined callbacks throws");
//Script tests
function createScriptTest(policyName, policy, expectedScript, t) {
let p = window.TrustedTypes.createPolicy(policyName, policy);
assert_true(p.createScript('whatever') instanceof TrustedScript);
assert_equals(p.createScript('whatever') + "", expectedScript);
}
test(t => {
createScriptTest('TestPolicyScript1', { createScript: s => s }, 'whatever', t);
}, "script = identity function");
test(t => {
createScriptTest('TestPolicyScript2', { createScript: s => null }, "null", t);
}, "script = null");
var Scriptstr = 'well, ';
test(t => {
createScriptTest('TestPolicyScript3', { createScript: s => Scriptstr + s }, Scriptstr + 'whatever', t);
}, "script = string + global string");
var Scriptx = 'global';
test(t => {
createScriptTest('TestPolicyScript4', { createScript: s => { Scriptx = s; return s; } }, 'whatever', t);
assert_equals(Scriptx, 'whatever');
}, "script = identity function, global string changed");
test(t => {
let p = window.TrustedTypes.createPolicy('TestPolicyScript5', {
createScript: s => { throw new Error(); }
});
assert_throws(new Error(), _ => {
p.createScript('whatever');
});
}, "script = callback that throws");
var obj = {
"foo": "well,"
}
function getScript(s) {
return this.foo + " " + s;
}
test(t => {
createScriptTest('TestPolicyScript6', { createScript: getScript.bind(obj) }, 'well, whatever', t);
}, "script = this bound to an object");
var foo = "well,";
test(t => {
createScriptTest('TestPolicyScript7', { createScript: s => getScript(s) }, 'well, whatever', t);
}, "script = this without bind");
test(t => {
let p = window.TrustedTypes.createPolicy('TestPolicyScript8', null);
assert_throws(new TypeError(), _ => {
p.createScript('whatever');
});
}, "script - calling undefined callback throws");
test(t => {
let p = window.TrustedTypes.createPolicy('TestPolicyScript9', { createScript: createScriptJS });
assert_throws(new TypeError(), _ => {
p.createHTML(INPUTS.HTML);
});
assert_throws(new TypeError(), _ => {
p.createScriptURL(INPUTS.SCRIPTURL);
});
assert_throws(new TypeError(), _ => {
p.createURL(INPUTS.URL);
});
}, "createScript defined - calling undefined callbacks throws");
//ScriptURL tests
function createScriptURLTest(policyName, policy, expectedScriptURL, t) {
let p = window.TrustedTypes.createPolicy(policyName, policy);
assert_true(p.createScriptURL(INPUTS.SCRIPTURL) instanceof TrustedScriptURL);
assert_equals(p.createScriptURL(INPUTS.SCRIPTURL) + "", expectedScriptURL);
}
test(t => {
createScriptURLTest('TestPolicyScriptURL1', { createScriptURL: s => s }, INPUTS.SCRIPTURL, t);
}, "script_url = identity function");
test(t => {
createScriptURLTest('TestPolicyScriptURL2', { createScriptURL: s => null }, "", t);
}, "script_url = null");
var scriptURLstr = '#duck';
test(t => {
createScriptURLTest('TestPolicyScriptURL3', { createScriptURL: s => s + scriptURLstr }, INPUTS.SCRIPTURL + scriptURLstr, t);
}, "script_url = string + global string");
var scriptURLx = 'global';
test(t => {
createScriptURLTest('TestPolicyScriptURL4', { createScriptURL: s => { ScriptURLx = s; return s; } }, INPUTS.SCRIPTURL, t);
assert_equals(ScriptURLx, INPUTS.SCRIPTURL);
}, "script_url = identity function, global string changed");
test(t => {
let p = window.TrustedTypes.createPolicy('TestPolicyScriptURL5', {
createScriptURL: s => { throw new Error(); }
});
assert_throws(new Error(), _ => {
p.createScriptURL(INPUTS.SCRIPTURL);
});
}, "script_url = callback that throws");
function getScriptURL(s) {
return s + this.baz;
}
var obj = {
"baz": "#duck"
}
test(t => {
createScriptURLTest('TestPolicyScriptURL6', { createScriptURL: getScriptURL.bind(obj) }, INPUTS.SCRIPTURL + "#duck", t);
}, "script_url = this bound to an object");
var baz = "#duck";
test(t => {
createScriptURLTest('TestPolicyScriptURL7', { createScriptURL: s => getScriptURL(s) }, INPUTS.SCRIPTURL + baz, t);
}, "script_url = this without bind");
test(t => {
let p = window.TrustedTypes.createPolicy('TestPolicyScriptURL8', null);
assert_throws(new TypeError(), _ => {
p.createScriptURL(INPUTS.SCRIPTURL);
});
}, "script_url - calling undefined callback throws");
test(t => {
let p = window.TrustedTypes.createPolicy('TestPolicyScriptURL9', { createScriptURL: createScriptURLJS });
assert_throws(new TypeError(), _ => {
p.createHTML(INPUTS.HTML);
});
assert_throws(new TypeError(), _ => {
p.createScript(INPUTS.SCRIPT);
});
assert_throws(new TypeError(), _ => {
p.createURL(INPUTS.URL);
});
}, "createScriptURL defined - calling undefined callbacks throws");
//URL tests
function createURLTest(policyName, policy, expectedURL, t) {
let p = window.TrustedTypes.createPolicy(policyName, policy);
assert_true(p.createURL(INPUTS.URL) instanceof TrustedURL);
assert_equals(p.createURL(INPUTS.URL) + "", expectedURL);
}
test(t => {
createURLTest('TestPolicyURL1', { createURL: s => s }, INPUTS.URL, t);
}, "url = identity function");
test(t => {
createURLTest('TestPolicyURL2', { createURL: s => null }, "", t);
}, "url = null");
var URLstr = '#x';
test(t => {
createURLTest('TestPolicyURL3', { createURL: s => s + URLstr }, INPUTS.URL + URLstr, t);
}, "url = string + global string");
var URLx = 'global';
test(t => {
createURLTest('TestPolicyURL4', { createURL: s => { URLx = s; return s; } }, INPUTS.URL, t);
assert_equals(URLx, INPUTS.URL);
}, "url = identity function, global string changed");
test(t => {
let p = window.TrustedTypes.createPolicy('TestPolicyURL5', {
createURL: s => { throw new Error(); }
});
assert_throws(new Error(), _ => {
p.createURL(INPUTS.URL);
});
}, "url = callback that throws");
function getURL(s) {
return s + this.bar;
}
var obj = {
"bar": "#x"
}
test(t => {
createURLTest('TestPolicyURL6', { createURL: getURL.bind(obj) }, INPUTS.URL + "#x", t);
}, "url = this bound to an object");
var bar = "#x";
test(t => {
createURLTest('TestPolicyURL7', { createURL: s => getURL(s) }, INPUTS.URL + bar, t);
}, "url = this without bind");
test(t => {
let p = window.TrustedTypes.createPolicy('TestPolicyURL8', null);
assert_throws(new TypeError(), _ => {
p.createURL(INPUTS.URL);
});
}, "url - calling undefined callback throws");
test(t => {
let p = window.TrustedTypes.createPolicy('TestPolicyURL9', { createURL: createURLJS });
assert_throws(new TypeError(), _ => {
p.createHTML(INPUTS.HTML);
});
assert_throws(new TypeError(), _ => {
p.createScript(INPUTS.SCRIPT);
});
assert_throws(new TypeError(), _ => {
p.createScriptURL(INPUTS.SCRIPTURL);
});
}, "createURL defined - calling undefined callbacks throws");
</script>

View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<script src="/resources/testharness.js" ></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/helper.sub.js"></script>
<body>
<script>
//Policy name test
test(t => {
let policy = window.TrustedTypes.createPolicy('SomeName', { createHTML: s => s } );
assert_true(policy instanceof TrustedTypePolicy);
assert_equals(policy.name, 'SomeName');
}, "policy.name = name");
//Duplicate names test
test(t => {
assert_throws(new TypeError(), _ => {
window.TrustedTypes.createPolicy('SomeName', { createURL: s => s } );
});
}, "duplicate policy name attempt throws");
//Retrieve policy names tests
test(t => {
let policy = window.TrustedTypes.createPolicy('SomeOtherName', { createURL: s => s } );
let names = window.TrustedTypes.getPolicyNames();
assert_true(names.includes('SomeName'));
assert_true(names.includes('SomeOtherName'));
}, "Retrieving policy names");
</script>

View File

@ -1,299 +0,0 @@
<!DOCTYPE html>
<script src="/resources/testharness.js" ></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/helper.sub.js"></script>
<body>
<script>
//Policy name test
async_test(t => {
window.trustedTypes.createPolicy('SomeName', { createHTML: s => s } )
.then(t.step_func_done(policy => {
assert_true(policy instanceof TrustedTypePolicy);
assert_equals(policy.name, 'SomeName');
}));
}, "policy.name = name");
//HTML tests
function createHTMLTest(policy, expectedHTML, t) {
window.trustedTypes.createPolicy('SomeName', policy)
.then(t.step_func_done(p => {
assert_true(p.createHTML('whatever') instanceof TrustedHTML);
assert_equals(p.createHTML('whatever') + "", expectedHTML);
}));
}
async_test(t => {
createHTMLTest( { createHTML: s => s }, 'whatever', t);
}, "html = identity function");
async_test(t => {
createHTMLTest( { createHTML: s => null }, "null", t);
}, "html = null");
var HTMLstr = 'well, ';
async_test(t => {
createHTMLTest( { createHTML: s => HTMLstr + s }, HTMLstr + 'whatever', t);
}, "html = string + global string");
var HTMLx = 'global';
async_test(t => {
window.trustedTypes.createPolicy('SomeName', {
createHTML: s => { HTMLx = s; return s; }
})
.then(t.step_func_done(p => {
assert_true(p.createHTML('whatever') instanceof TrustedHTML);
assert_equals(p.createHTML('whatever') + "", 'whatever');
assert_equals(HTMLx, 'whatever');
}));
}, "html = identity function, global string changed");
async_test(t => {
window.trustedTypes.createPolicy('SomeName', {
createHTML: s => { throw new Error(); }
})
.then(t.step_func_done(p => {
assert_throws(new Error(), _ => {
p.createHTML('whatever');
});
}));
}, "html = callback that throws");
var obj = {
"foo": "well,"
}
function getHTML(s) {
return this.foo + " " + s;
}
async_test(t => {
createHTMLTest( {
createHTML: getHTML.bind(obj)},
'well, whatever', t);
}, "html = this bound to an object");
var foo = "well,";
async_test(t => {
createHTMLTest( { createHTML: s => getHTML(s) }, 'well, whatever', t);
}, "html = this without bind");
async_test(t => {
window.trustedTypes.createPolicy('SomeName', null)
.then(t.step_func_done(p => {
assert_equals(p.createHTML('whatever'), null);
}));
}, "html - calling undefined callback");
//Script tests
function createScriptTest(policy, expectedScript, t) {
let p = window.trustedTypes.createPolicy('SomeName', policy)
.then(t.step_func_done(p => {
assert_true(p.createScript('whatever') instanceof TrustedScript);
assert_equals(p.createScript('whatever') + "", expectedScript);
}));
}
async_test(t => {
createScriptTest( { createScript: s => s }, 'whatever', t);
}, "script = identity function");
async_test(t => {
createScriptTest( { createScript: s => null }, "null", t);
}, "script = null");
var Scriptstr = 'well, ';
async_test(t => {
createScriptTest( { createScript: s => Scriptstr + s }, Scriptstr + 'whatever', t);
}, "script = string + global string");
var Scriptx = 'global';
async_test(t => {
let p = window.trustedTypes.createPolicy('SomeName', {
createScript: s => { Scriptx = s; return s; }
})
.then(t.step_func_done(p => {
assert_true(p.createScript('whatever') instanceof TrustedScript);
assert_equals(p.createScript('whatever') + "", 'whatever');
assert_equals(Scriptx, 'whatever');
}));
}, "script = identity function, global string changed");
async_test(t => {
let p = window.trustedTypes.createPolicy('SomeName', {
createScript: s => { throw new Error(); }
})
.then(t.step_func_done(p => {
assert_throws(new Error(), _ => {
p.createScript('whatever');
});
}));
}, "script = callback that throws");
var obj = {
"foo": "well,"
}
function getScript(s) {
return this.foo + " " + s;
}
async_test(t => {
createScriptTest( {
createScript: getScript.bind(obj)},
'well, whatever', t);
}, "script = this bound to an object");
var foo = "well,";
async_test(t => {
createScriptTest( { createScript: s => getScript(s) }, 'well, whatever', t);
}, "script = this without bind");
async_test(t => {
let p = window.trustedTypes.createPolicy('SomeName', null)
.then(t.step_func_done(p => {
assert_equals(p.createScript('whatever'), null);
}));
}, "script - calling undefined callback");
//ScriptURL tests
function createScriptURLTest(policy, expectedScriptURL, t) {
window.trustedTypes.createPolicy('SomeName', policy)
.then(t.step_func_done(p => {
assert_true(p.createScriptURL(INPUTS.SCRIPTURL) instanceof TrustedScriptURL);
assert_equals(p.createScriptURL(INPUTS.SCRIPTURL) + "", expectedScriptURL);
}));
}
async_test(t => {
createScriptURLTest( { createScriptURL: s => s }, INPUTS.SCRIPTURL, t);
}, "script_url = identity function");
async_test(t => {
createScriptURLTest( { createScriptURL: s => null }, "", t);
}, "script_url = null");
var scriptURLstr = '#duck';
async_test(t => {
createScriptURLTest( { createScriptURL: s => s + scriptURLstr }, INPUTS.SCRIPTURL + scriptURLstr, t);
}, "script_url = string + global string");
var scriptURLx = 'global';
async_test(t => {
window.trustedTypes.createPolicy('SomeName', {
createScriptURL: s => { ScriptURLx = s; return s; }
})
.then(t.step_func_done(p => {
assert_true(p.createScriptURL(INPUTS.SCRIPTURL) instanceof TrustedScriptURL);
assert_equals(p.createScriptURL(INPUTS.SCRIPTURL) + "", INPUTS.SCRIPTURL);
assert_equals(ScriptURLx, INPUTS.SCRIPTURL);
}));
}, "script_url = identity function, global string changed");
async_test(t => {
window.trustedTypes.createPolicy('SomeName', {
createScriptURL: s => { throw new Error(); }
})
.then(t.step_func_done(p => {
assert_throws(new Error(), _ => {
p.createScriptURL(INPUTS.SCRIPTURL);
});
}));
}, "script_url = callback that throws");
function getScriptURL(s) {
return s + this.baz;
}
var obj = {
"baz": "#duck"
}
async_test(t => {
createScriptURLTest( {
createScriptURL: getScriptURL.bind(obj)},
INPUTS.SCRIPTURL + "#duck", t);
}, "script_url = this bound to an object");
var baz = "#duck";
async_test(t => {
createScriptURLTest( { createScriptURL: s => getScriptURL(s) }, INPUTS.SCRIPTURL + baz, t);
}, "script_url = this without bind");
async_test(t => {
window.trustedTypes.createPolicy('SomeName', null)
.then(t.step_func_done(p => {
assert_equals(p.createScriptURL(INPUTS.SCRIPTURL), null);
}));
}, "script_url - calling undefined callback");
//URL tests
function createURLTest(policy, expectedURL, t) {
window.trustedTypes.createPolicy('SomeName', policy)
.then(t.step_func_done(p => {
assert_true(p.createURL(INPUTS.URL) instanceof TrustedURL);
assert_equals(p.createURL(INPUTS.URL) + "", expectedURL);
}));
}
async_test(t => {
createURLTest( { createURL: s => s }, INPUTS.URL, t);
}, "url = identity function");
async_test(t => {
createURLTest( { createURL: s => null }, "", t);
}, "url = null");
var URLstr = '#x';
async_test(t => {
createURLTest( { createURL: s => s + URLstr }, INPUTS.URL + URLstr, t);
}, "url = string + global string");
var URLx = 'global';
async_test(t => {
window.trustedTypes.createPolicy('SomeName', {
createURL: s => { URLx = s; return s; }
})
.then(t.step_func_done(p => {
assert_true(p.createURL(INPUTS.URL) instanceof TrustedURL);
assert_equals(p.createURL(INPUTS.URL) + "", INPUTS.URL);
assert_equals(URLx, INPUTS.URL);
}));
}, "url = identity function, global string changed");
async_test(t => {
window.trustedTypes.createPolicy('SomeName', {
createURL: s => { throw new Error(); }
})
.then(t.step_func_done(p => {
assert_throws(new Error(), _ => {
p.createURL(INPUTS.URL);
});
}));
}, "url = callback that throws");
function getURL(s) {
return s + this.bar;
}
var obj = {
"bar": "#x"
}
async_test(t => {
createURLTest( {
createURL: getURL.bind(obj)},
INPUTS.URL + "#x", t);
}, "url = this bound to an object");
var bar = "#x";
async_test(t => {
createURLTest( { createURL: s => getURL(s) }, INPUTS.URL + bar, t);
}, "url = this without bind");
async_test(t => {
window.trustedTypes.createPolicy('SomeName', null)
.then(t.step_func_done(p => {
assert_equals(p.createURL(INPUTS.URL), null);
}));
}, "url - calling undefined callback");
</script>

View File

@ -5,7 +5,7 @@
<body>
<script>
test(t => {
let factory = window.trustedTypes;
let factory = window.TrustedTypes;
assert_true(factory instanceof TrustedTypePolicyFactory);
}, "factory = window.trustedTypes");
}, "factory = window.TrustedTypes");
</script>

View File

@ -5,23 +5,21 @@
<body>
<script>
// helper functions for the tests
function testWindowOpen(t, win) {
createURL_policy(window)
.then(t.step_func_done(p => {
let url = p.createURL(INPUTS.URL);
let child_window = win.open(url, "", "");
child_window.onload = t.step_func_done(_ => {
assert_equals(child_window.location.href, "" + url);
child_window.close();
});
}));
function testWindowOpen(t, win, testNumber) {
let p = createURL_policy(window, testNumber);
let url = p.createURL(INPUTS.URL);
let child_window = win.open(url, "", "");
child_window.onload = t.step_func_done(_ => {
assert_equals(child_window.location.href, "" + url);
child_window.close();
});
}
async_test(t => {
testWindowOpen(t, window);
test(t => {
testWindowOpen(t, window, 1);
}, "window.open via policy (successful URL transformation).");
async_test(t => {
testWindowOpen(t, document);
test(t => {
testWindowOpen(t, document, 2);
}, "document.open via policy (successful URL transformation).");
</script>

View File

@ -7,14 +7,12 @@
<body>
<script>
// Trusted HTML assignments do not throw.
async_test(t => {
createHTML_policy(window)
.then(t.step_func_done(p => {
let html = p.createHTML(INPUTS.HTML);
let parser = new DOMParser();
let doc = parser.parseFromString(html, "text/html");
assert_equals(doc.body.innerText, RESULTS.HTML);
}));
test(t => {
let p = createHTML_policy(window, 1);
let html = p.createHTML(INPUTS.HTML);
let parser = new DOMParser();
let doc = parser.parseFromString(html, "text/html");
assert_equals(doc.body.innerText, RESULTS.HTML);
}, "document.innerText assigned via policy (successful HTML transformation).");
// String assignments throw.

View File

@ -10,13 +10,11 @@
<body>
<script>
// TrustedURL assignments do not throw.
async_test(t => {
createHTML_policy(window)
.then(t.step_func_done(p => {
let html = p.createHTML(INPUTS.HTML);
document.write(html);
assert_equals(document.body.innerText, RESULTS.HTML);
}));
test(t => {
let p = createHTML_policy(window, 1);
let html = p.createHTML(INPUTS.HTML);
document.write(html);
assert_equals(document.body.innerText, RESULTS.HTML);
}, "document.write with html assigned via policy (successful URL transformation).");
// String assignments throw.

View File

@ -13,33 +13,31 @@
var container = document.querySelector('#container');
// Trusted HTML assignments do not throw.
async_test(t => {
createHTML_policy(window)
.then(t.step_func_done(p => {
let html = p.createHTML(INPUTS.HTML);
test(t => {
let p = createHTML_policy(window, 1);
let html = p.createHTML(INPUTS.HTML);
var d = document.createElement('div');
container.appendChild(d);
var d = document.createElement('div');
container.appendChild(d);
d.insertAdjacentHTML('beforebegin', html);
assert_equals(d.previousSibling.nodeType, Node.TEXT_NODE);
assert_equals(d.previousSibling.data, RESULTS.HTML);
d.insertAdjacentHTML('beforebegin', html);
assert_equals(d.previousSibling.nodeType, Node.TEXT_NODE);
assert_equals(d.previousSibling.data, RESULTS.HTML);
d.insertAdjacentHTML('afterbegin', html);
assert_equals(d.firstChild.nodeType, Node.TEXT_NODE);
assert_equals(d.firstChild.data, RESULTS.HTML);
d.insertAdjacentHTML('afterbegin', html);
assert_equals(d.firstChild.nodeType, Node.TEXT_NODE);
assert_equals(d.firstChild.data, RESULTS.HTML);
d.insertAdjacentHTML('beforeend', html);
assert_equals(d.lastChild.nodeType, Node.TEXT_NODE);
assert_equals(d.lastChild.data, RESULTS.HTML);
d.insertAdjacentHTML('beforeend', html);
assert_equals(d.lastChild.nodeType, Node.TEXT_NODE);
assert_equals(d.lastChild.data, RESULTS.HTML);
d.insertAdjacentHTML('afterend', html);
assert_equals(d.nextSibling.nodeType, Node.TEXT_NODE);
assert_equals(d.nextSibling.data, RESULTS.HTML);
d.insertAdjacentHTML('afterend', html);
assert_equals(d.nextSibling.nodeType, Node.TEXT_NODE);
assert_equals(d.nextSibling.data, RESULTS.HTML);
while (container.firstChild)
container.firstChild.remove();
}));
while (container.firstChild)
container.firstChild.remove();
}, "insertAdjacentHTML with html assigned via policy (successful HTML transformation).");
// String assignments throw.

View File

@ -13,19 +13,17 @@
var container = document.querySelector('#container')
// TrustedHTML assignments do not throw.
async_test(t => {
createHTML_policy(window)
.then(t.step_func_done(p => {
let html = p.createHTML(INPUTS.HTML);
test(t => {
let p = createHTML_policy(window, 1);
let html = p.createHTML(INPUTS.HTML);
var d = document.createElement('div');
document.querySelector('#container').appendChild(d);
d.outerHTML = html;
assert_equals(container.innerText, RESULTS.HTML);
var d = document.createElement('div');
document.querySelector('#container').appendChild(d);
d.outerHTML = html;
assert_equals(container.innerText, RESULTS.HTML);
while (container.firstChild)
container.firstChild.remove();
}));
while (container.firstChild)
container.firstChild.remove();
}, "outerHTML with html assigned via policy (successful HTML transformation).");
// String assignments throw.

View File

@ -27,8 +27,8 @@
];
testCases.forEach(c => {
async_test(t => {
assert_element_accepts_trusted_url(window, t, c[0], c[1], RESULTS.URL);
test(t => {
assert_element_accepts_trusted_url(window, c, t, c[0], c[1], RESULTS.URL);
assert_throws_no_trusted_type(c[0], c[1], 'A string');
assert_throws_no_trusted_type(c[0], c[1], null);
}, c[0] + "." + c[1] + " accepts only TrustedURL");
@ -41,8 +41,8 @@
];
scriptTestCases.forEach(c => {
async_test(t => {
assert_element_accepts_trusted_script_url(window, t, c[0], c[1], RESULTS.SCRIPTURL);
test(t => {
assert_element_accepts_trusted_script_url(window, c, t, c[0], c[1], RESULTS.SCRIPTURL);
assert_throws_no_trusted_type(c[0], c[1], 'A string');
assert_throws_no_trusted_type(c[0], c[1], null);
}, c[0] + "." + c[1] + " accepts only TrustedScriptURL");
@ -55,8 +55,8 @@
];
HTMLTestCases.forEach(c => {
async_test(t => {
assert_element_accepts_trusted_html(window, t, c[0], c[1], RESULTS.HTML);
test(t => {
assert_element_accepts_trusted_html(window, c, t, c[0], c[1], RESULTS.HTML);
assert_throws_no_trusted_type(c[0], c[1], 'A string');
assert_throws_no_trusted_type(c[0], c[1], null);
}, c[0] + "." + c[1] + " accepts only TrustedHTML");

View File

@ -10,13 +10,11 @@
<body>
<script>
// TrustedURL assignments do not throw.
async_test(t => {
createURL_policy(window)
.then(t.step_func_done(p => {
let url = p.createURL(location.href + "#xxx");
location.assign(url);
assert_equals("" + url, location.href, "location href");
}));
test(t => {
let p = createURL_policy(window, 1);
let url = p.createURL(location.href + "#xxx");
location.assign(url);
assert_equals("" + url, location.href, "location href");
}, "location.assign via policy (successful URL transformation).");
// String assignments throw.

View File

@ -10,13 +10,11 @@
<body>
<script>
// TrustedURL assignments do not throw.
async_test(t => {
createURL_policy(window)
.then(t.step_func_done(p => {
let url = p.createURL(location.href + "#xxx");
location.href = url;
assert_equals("" + url, location.href, "location href");
}));
test(t => {
let p = createURL_policy(window, 1);
let url = p.createURL(location.href + "#xxx");
location.href = url;
assert_equals("" + url, location.href, "location href");
}, "location.href assigned via policy (successful URL transformation).");
// String assignments throw.

View File

@ -10,13 +10,11 @@
<body>
<script>
// TrustedURL replacements do not throw.
async_test(t => {
createURL_policy(window)
.then(t.step_func_done(p => {
let url = p.createURL(location.href + "#xxx");
location.replace(url);
assert_equals("" + url, location.href, "location href");
}));
test(t => {
let p = createURL_policy(window, 1);
let url = p.createURL(location.href + "#xxx");
location.replace(url);
assert_equals("" + url, location.href, "location href");
}, "location.replace via policy (successful URL transformation).");
// String replacements throw.

View File

@ -7,15 +7,13 @@
<body>
<script>
// TrustedHTML assignments do not throw.
async_test(t => {
createHTML_policy(window)
.then(t.step_func_done(p => {
let html = p.createHTML(INPUTS.HTML);
var range = document.createRange();
range.selectNodeContents(document.documentElement);
var result = range.createContextualFragment(html);
assert_equals(result.textContent, RESULTS.HTML);
}));
test(t => {
let p = createHTML_policy(window, 1);
let html = p.createHTML(INPUTS.HTML);
var range = document.createRange();
range.selectNodeContents(document.documentElement);
var result = range.createContextualFragment(html);
assert_equals(result.textContent, RESULTS.HTML);
}, "range.createContextualFragment assigned via policy (successful HTML transformation).");
// String assignments throw.

View File

@ -9,54 +9,51 @@
</head>
<body>
<script>
var testnb = 0;
// helper functions for the tests
function testWindowOpen(t, win) {
createURL_policy(window)
.then(t.step_func_done(p => {
let url = p.createURL(INPUTS.URL);
let child_window = win.open(url, "", "");
child_window.onload = t.step_func_done(_ => {
assert_equals(child_window.location.href, "" + url);
child_window.close();
});
}));
function testWindowOpen(t, win, nb) {
let p = createURL_policy(window, nb);
let url = p.createURL(INPUTS.URL);
let child_window = win.open(url, "", "");
child_window.onload = t.step_func_done(_ => {
assert_equals(child_window.location.href, "" + url);
child_window.close();
});
}
function testWindowThrows(t, url, win) {
createURL_policy(window)
.then(t.step_func_done(p => {
assert_throws(new TypeError(), _ => {
let child_window = win.open(url, "", "");
child_window.close();
});
}));
function testWindowThrows(t, url, win, nb) {
let p = createURL_policy(window, nb);
assert_throws(new TypeError(), _ => {
let child_window = win.open(url, "", "");
child_window.close();
});
}
// TrustedURL assignments do not throw.
async_test(t => {
testWindowOpen(t, window);
test(t => {
testWindowOpen(t, window, ++testnb);
}, "window.open via policy (successful URL transformation).");
async_test(t => {
testWindowOpen(t, document);
test(t => {
testWindowOpen(t, document, ++testnb);
}, "document.open via policy (successful URL transformation).");
// String assignments throw.
async_test(t => {
testWindowThrows(t, 'A string', window);
test(t => {
testWindowThrows(t, 'A string', window, ++testnb);
}, "`window.open(string)` throws.");
async_test(t => {
testWindowThrows(t, 'A string', document);
test(t => {
testWindowThrows(t, 'A string', document, ++testnb);
}, "`document.open(string)` throws.");
// Null assignment throws.
async_test(t => {
testWindowThrows(t, null, window);
test(t => {
testWindowThrows(t, null, window, ++testnb);
}, "`window.open(null)` throws.");
async_test(t => {
testWindowThrows(t, null, document);
test(t => {
testWindowThrows(t, null, document, ++testnb);
}, "`document.open(null)` throws.");
</script>
</body>

View File

@ -31,52 +31,44 @@ function createURLJS(url) {
.replace("an.url", "successfully.transformed");
}
function createHTML_policy(win) {
return win.trustedTypes.createPolicy('SomeName', { createHTML: createHTMLJS });
function createHTML_policy(win, c) {
return win.TrustedTypes.createPolicy('SomeHTMLPolicyName' + c, { createHTML: createHTMLJS });
}
function createScript_policy(win) {
return win.trustedTypes.createPolicy('SomeName', { createScript: createScriptJS });
function createScript_policy(win, c) {
return win.TrustedTypes.createPolicy('SomeScriptPolicyName' + c, { createScript: createScriptJS });
}
function createScriptURL_policy(win) {
return win.trustedTypes.createPolicy('SomeName', { createScriptURL: createScriptURLJS });
function createScriptURL_policy(win, c) {
return win.TrustedTypes.createPolicy('SomeScriptURLPolicyName' + c, { createScriptURL: createScriptURLJS });
}
function createURL_policy(win) {
return win.trustedTypes.createPolicy('SomeName', { createURL: createURLJS });
function createURL_policy(win, c) {
return win.TrustedTypes.createPolicy('SomeURLPolicyName' + c, { createURL: createURLJS });
}
function assert_element_accepts_trusted_html(win, t, tag, attribute, expected) {
createHTML_policy(win)
.then(t.step_func_done(p => {
let html = p.createHTML(INPUTS.HTML);
assert_element_accepts_trusted_type(tag, attribute, html, expected);
}));
function assert_element_accepts_trusted_html(win, c, t, tag, attribute, expected) {
let p = createHTML_policy(win, c);
let html = p.createHTML(INPUTS.HTML);
assert_element_accepts_trusted_type(tag, attribute, html, expected);
}
function assert_element_accepts_trusted_script(win, t, tag, attribute, expected) {
createScript_policy(win)
.then(t.step_func_done(p => {
let script = p.createScript(INPUTS.SCRIPT);
assert_element_accepts_trusted_type(tag, attribute, script, expected);
}));
function assert_element_accepts_trusted_script(win, c, t, tag, attribute, expected) {
let p = createScript_policy(win, c);
let script = p.createScript(INPUTS.SCRIPT);
assert_element_accepts_trusted_type(tag, attribute, script, expected);
}
function assert_element_accepts_trusted_script_url(win, t, tag, attribute, expected) {
createScriptURL_policy(win)
.then(t.step_func_done(p => {
let scripturl = p.createScriptURL(INPUTS.SCRIPTURL);
assert_element_accepts_trusted_type(tag, attribute, scripturl, expected);
}));
function assert_element_accepts_trusted_script_url(win, c, t, tag, attribute, expected) {
let p = createScriptURL_policy(win, c);
let scripturl = p.createScriptURL(INPUTS.SCRIPTURL);
assert_element_accepts_trusted_type(tag, attribute, scripturl, expected);
}
function assert_element_accepts_trusted_url(win, t, tag, attribute, expected) {
createURL_policy(win)
.then(t.step_func_done(p => {
let url = p.createURL(INPUTS.URL);
assert_element_accepts_trusted_type(tag, attribute, url, expected);
}));
function assert_element_accepts_trusted_url(win, c, t, tag, attribute, expected) {
let p = createURL_policy(win, c);
let url = p.createURL(INPUTS.URL);
assert_element_accepts_trusted_type(tag, attribute, url, expected);
}
function assert_element_accepts_trusted_type(tag, attribute, value, expected) {

View File

@ -3,12 +3,13 @@
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/common/get-host-info.sub.js></script>
<script src=/common/utils.js></script>
<div id=log></div>
<script>
async_test(t => {
const client = new XMLHttpRequest
client.open("GET", "resources/redirect.py?delay=500&location=delay.py") // 500 + 500 = 1000
client.timeout = 1000
client.timeout = 750
client.send()
client.ontimeout = t.step_func_done(() => {
assert_equals(client.readyState, 4)
@ -17,9 +18,11 @@ async_test(t => {
}, "Redirects should not reset the timer")
async_test(t => {
// Use a unique ID to prevent caching of the preflight making the test flaky.
const uuid = token();
const client = new XMLHttpRequest
client.open("YO", get_host_info().HTTP_REMOTE_ORIGIN + "/xhr/resources/delay.py")
client.timeout = 1000
client.open("YO", get_host_info().HTTP_REMOTE_ORIGIN + "/xhr/resources/delay.py?uuid=" + uuid)
client.timeout = 750
client.send()
client.ontimeout = t.step_func_done(() => {
assert_equals(client.readyState, 4)

View File

@ -63,13 +63,13 @@ skip-if = os == "android" # checking for telemetry needs to be updated: 1384923
skip-if = (os == "win" && !debug) #Bug 1419183 disable on Windows
[test_ext_management_uninstall_self.js]
[test_ext_messaging_startup.js]
skip-if = appname == "thunderbird"
skip-if = appname == "thunderbird" || (os == "android" && debug)
[test_ext_onmessage_removelistener.js]
skip-if = true # This test no longer tests what it is meant to test.
[test_ext_permission_xhr.js]
[test_ext_persistent_events.js]
[test_ext_privacy.js]
skip-if = appname == "thunderbird"
skip-if = appname == "thunderbird" || (os == "android" && debug)
[test_ext_privacy_disable.js]
skip-if = appname == "thunderbird"
[test_ext_privacy_update.js]
@ -83,6 +83,7 @@ skip-if = appname == "thunderbird" || os == "android" # proxy settings are not s
[test_ext_proxy_speculative.js]
[test_ext_proxy_startup.js]
[test_ext_redirects.js]
skip-if = os == "android" && debug
[test_ext_runtime_connect_no_receiver.js]
[test_ext_runtime_getBrowserInfo.js]
[test_ext_runtime_getPlatformInfo.js]
@ -103,8 +104,11 @@ skip-if = true # bug 1315829
skip-if = os == "android"
[test_ext_startup_perf.js]
[test_ext_storage.js]
skip-if = os == "android" && debug
[test_ext_storage_idb_data_migration.js]
skip-if = os == "android" && debug
[test_ext_storage_content.js]
skip-if = os == "android" && debug
[test_ext_storage_managed.js]
skip-if = os == "android"
[test_ext_storage_sync.js]
@ -124,12 +128,17 @@ skip-if = os == "android"
[test_ext_unload_frame.js]
skip-if = true # Too frequent intermittent failures
[test_ext_webRequest_auth.js]
skip-if = os == "android" && debug
[test_ext_webRequest_filterResponseData.js]
skip-if = os == "android" && debug
[test_ext_webRequest_permission.js]
skip-if = os == "android" && debug
[test_ext_webRequest_responseBody.js]
skip-if = os == "android" && debug
[test_ext_webRequest_set_cookie.js]
skip-if = appname == "thunderbird"
skip-if = appname == "thunderbird" || (os == "android" && debug)
[test_ext_webRequest_startup.js]
skip-if = os == "android" && debug
[test_ext_webRequest_suspend.js]
[test_ext_webRequest_webSocket.js]
skip-if = appname == "thunderbird"