This commit is contained in:
Wes Kocher 2017-03-29 15:47:46 -07:00
Родитель 11961c7776 8e0bc97954
Коммит 3c0c112ff9
488 изменённых файлов: 5802 добавлений и 27044 удалений

Просмотреть файл

@ -24,9 +24,9 @@
"size": 12072532
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 110077036,
"digest": "8b99d058cc081f6ca2a3cc88c3ca9c15232961d2539774dacee35e2258955ad8fc4cb0af3b903a3e3f8a264ddecb3baae9256502ffc178a2823779284ace2bd8",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 112075416,
"digest": "134538dda3512363c8b103fc59128aba830bd994053612f8ad8721e1a0033ad9836cd11595ed8056d885aec7dc78b7f4c4169c0a12bd0f9c31549f2d81939054",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

Просмотреть файл

@ -16,9 +16,9 @@
"unpack": true
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 110077036,
"digest": "8b99d058cc081f6ca2a3cc88c3ca9c15232961d2539774dacee35e2258955ad8fc4cb0af3b903a3e3f8a264ddecb3baae9256502ffc178a2823779284ace2bd8",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 112075416,
"digest": "134538dda3512363c8b103fc59128aba830bd994053612f8ad8721e1a0033ad9836cd11595ed8056d885aec7dc78b7f4c4169c0a12bd0f9c31549f2d81939054",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

Просмотреть файл

@ -1179,8 +1179,14 @@ var gBrowserInit = {
// have been initialized.
Services.obs.notifyObservers(window, "browser-window-before-show", "");
let isResistFingerprintingEnabled = gPrefService.getBoolPref("privacy.resistFingerprinting");
// Set a sane starting width/height for all resolutions on new profiles.
if (!document.documentElement.hasAttribute("width")) {
if (isResistFingerprintingEnabled) {
// When the fingerprinting resistance is enabled, making sure that we don't
// have a maximum window to interfere with generating rounded window dimensions.
document.documentElement.setAttribute("sizemode", "normal");
} else if (!document.documentElement.hasAttribute("width")) {
const TARGET_WIDTH = 1280;
const TARGET_HEIGHT = 1040;
let width = Math.min(screen.availWidth * .9, TARGET_WIDTH);
@ -3182,7 +3188,7 @@ var BrowserOnClick = {
let title;
if (reason === "malware") {
let reportUrl = gSafeBrowsing.getReportURL("MalwareMistake", blockedInfo);
title = gNavigatorBundle.getString("safebrowsing.reportedAttackSite");
// There's no button if we can not get report url, for example if the provider
// of blockedInfo is not Google
if (reportUrl) {
@ -3196,7 +3202,7 @@ var BrowserOnClick = {
}
} else if (reason === "phishing") {
let reportUrl = gSafeBrowsing.getReportURL("PhishMistake", blockedInfo);
title = gNavigatorBundle.getString("safebrowsing.deceptiveSite");
// There's no button if we can not get report url, for example if the provider
// of blockedInfo is not Google
if (reportUrl) {

Просмотреть файл

@ -18,6 +18,7 @@ DIRS += [
'places',
'preferences',
'privatebrowsing',
'resistfingerprinting',
'search',
'sessionstore',
'shell',

Просмотреть файл

@ -26,7 +26,7 @@ add_task(function* test_private_popup_window_opens_private_tabs() {
// Sanity check - this browser better be private.
ok(PrivateBrowsingUtils.isWindowPrivate(privWin),
"Could not open a private browsing window.");
"Opened a private browsing window.");
// First, open a private browsing window, and load our
// testing page.
@ -36,17 +36,17 @@ add_task(function* test_private_popup_window_opens_private_tabs() {
// Next, click on the link in the testing page, and ensure
// that a private popup window is opened.
let openedPromise = BrowserTestUtils.waitForNewWindow();
let openedPromise = BrowserTestUtils.waitForNewWindow(true, POPUP_LINK);
yield BrowserTestUtils.synthesizeMouseAtCenter("#first", {}, privBrowser);
let popupWin = yield openedPromise;
ok(PrivateBrowsingUtils.isWindowPrivate(popupWin),
"Popup window was not private.");
"Popup window was private.");
// Now click on the link in the popup, and ensure that a new
// tab is opened in the original private browsing window.
let newTabPromise = BrowserTestUtils.waitForNewTab(privWin.gBrowser);
let popupBrowser = popupWin.gBrowser.selectedBrowser;
yield BrowserTestUtils.browserLoaded(popupBrowser);
yield BrowserTestUtils.synthesizeMouseAtCenter("#second", {}, popupBrowser);
let newPrivTab = yield newTabPromise;

Просмотреть файл

@ -0,0 +1,9 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
BROWSER_CHROME_MANIFESTS += [
'test/browser/browser.ini',
]

Просмотреть файл

@ -0,0 +1,11 @@
"use strict";
module.exports = {
"extends": [
"plugin:mozilla/browser-test"
],
"rules": {
"no-undef": "error"
}
};

Просмотреть файл

@ -0,0 +1,13 @@
[DEFAULT]
tags = resistfingerprinting
support-files =
file_dummy.html
head.js
[browser_roundedWindow_newWindow.js]
[browser_roundedWindow_open_max.js]
[browser_roundedWindow_open_mid.js]
[browser_roundedWindow_open_min.js]
[browser_roundedWindow_windowSetting_max.js]
[browser_roundedWindow_windowSetting_mid.js]
[browser_roundedWindow_windowSetting_min.js]

Просмотреть файл

@ -0,0 +1,49 @@
/*
* Bug 1330882 - A test case for opening new windows as rounded size when
* fingerprinting resistance is enabled.
*/
const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
const TEST_DOMAIN = "http://example.net/";
const TEST_PATH = TEST_DOMAIN + "browser/browser/components/resistFingerprinting/test/browser/";
let gMaxAvailWidth;
let gMaxAvailHeight;
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({"set":
[["privacy.resistFingerprinting", true]]
});
// Calculate the maximum available size.
let maxAvailSize = yield calcMaximumAvailSize();
gMaxAvailWidth = maxAvailSize.maxAvailWidth;
gMaxAvailHeight = maxAvailSize.maxAvailHeight;
});
add_task(function* test_new_window() {
// Open a new window.
let win = yield BrowserTestUtils.openNewBrowserWindow();
// Load a page and verify its window size.
let tab = yield BrowserTestUtils.openNewForegroundTab(
win.gBrowser, TEST_PATH + "file_dummy.html");
yield ContentTask.spawn(tab.linkedBrowser, {gMaxAvailWidth, gMaxAvailHeight},
function* (input) {
is(content.screen.width, input.gMaxAvailWidth,
"The screen.width has a correct rounded value");
is(content.screen.height, input.gMaxAvailHeight,
"The screen.height has a correct rounded value");
is(content.innerWidth, input.gMaxAvailWidth,
"The window.innerWidth has a correct rounded value");
is(content.innerHeight, input.gMaxAvailHeight,
"The window.innerHeight has a correct rounded value");
}
);
yield BrowserTestUtils.removeTab(tab);
yield BrowserTestUtils.closeWindow(win);
});

Просмотреть файл

@ -0,0 +1,62 @@
/*
* Bug 1330882 - A test case for opening new windows through window.open() as
* rounded size when fingerprinting resistance is enabled. This test is for
* maximum values.
*/
const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
const TEST_DOMAIN = "http://example.net/";
const TEST_PATH = TEST_DOMAIN + "browser/browser/components/resistFingerprinting/test/browser/";
let gMaxAvailWidth;
let gMaxAvailHeight;
// We need the chrome UI size of popup windows for testing outerWidth/Height.
let gPopupChromeUIWidth;
let gPopupChromeUIHeight;
const TESTCASES = [
{ settingWidth: 1025, settingHeight: 1050, targetWidth: 1000, targetHeight: 1000 },
{ settingWidth: 9999, settingHeight: 9999, targetWidth: 1000, targetHeight: 1000 },
{ settingWidth: 999, settingHeight: 999, targetWidth: 1000, targetHeight: 1000 },
];
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({"set":
[["privacy.resistFingerprinting", true]]
});
// Calculate the popup window's chrome UI size for tests of outerWidth/Height.
let popUpChromeUISize = yield calcPopUpWindowChromeUISize();
gPopupChromeUIWidth = popUpChromeUISize.chromeWidth;
gPopupChromeUIHeight = popUpChromeUISize.chromeHeight;
// Calculate the maximum available size.
let maxAvailSize = yield calcMaximumAvailSize(gPopupChromeUIWidth,
gPopupChromeUIHeight);
gMaxAvailWidth = maxAvailSize.maxAvailWidth;
gMaxAvailHeight = maxAvailSize.maxAvailHeight;
});
add_task(function* test_window_open() {
// Open a tab to test window.open().
let tab = yield BrowserTestUtils.openNewForegroundTab(
gBrowser, TEST_PATH + "file_dummy.html");
for (let test of TESTCASES) {
// Test 'width' and 'height' of window features.
yield testWindowOpen(tab.linkedBrowser, test.settingWidth, test.settingHeight,
test.targetWidth, test.targetHeight, false, gMaxAvailWidth,
gMaxAvailHeight, gPopupChromeUIWidth, gPopupChromeUIHeight);
// test 'outerWidth' and 'outerHeight' of window features.
yield testWindowOpen(tab.linkedBrowser, test.settingWidth, test.settingHeight,
test.targetWidth, test.targetHeight, true, gMaxAvailWidth,
gMaxAvailHeight, gPopupChromeUIWidth, gPopupChromeUIHeight);
}
yield BrowserTestUtils.removeTab(tab);
});

Просмотреть файл

@ -0,0 +1,62 @@
/*
* Bug 1330882 - A test case for opening new windows through window.open() as
* rounded size when fingerprinting resistance is enabled. This test is for
* middle values.
*/
const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
const TEST_DOMAIN = "http://example.net/";
const TEST_PATH = TEST_DOMAIN + "browser/browser/components/resistFingerprinting/test/browser/";
let gMaxAvailWidth;
let gMaxAvailHeight;
// We need the chrome UI size of popup windows for testing outerWidth/Height.
let gPopupChromeUIWidth;
let gPopupChromeUIHeight;
const TESTCASES = [
{ settingWidth: 600, settingHeight: 600, targetWidth: 600, targetHeight: 600 },
{ settingWidth: 599, settingHeight: 599, targetWidth: 600, targetHeight: 600 },
{ settingWidth: 401, settingHeight: 501, targetWidth: 600, targetHeight: 600 },
];
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({"set":
[["privacy.resistFingerprinting", true]]
});
// Calculate the popup window's chrome UI size for tests of outerWidth/Height.
let popUpChromeUISize = yield calcPopUpWindowChromeUISize();
gPopupChromeUIWidth = popUpChromeUISize.chromeWidth;
gPopupChromeUIHeight = popUpChromeUISize.chromeHeight;
// Calculate the maximum available size.
let maxAvailSize = yield calcMaximumAvailSize(gPopupChromeUIWidth,
gPopupChromeUIHeight);
gMaxAvailWidth = maxAvailSize.maxAvailWidth;
gMaxAvailHeight = maxAvailSize.maxAvailHeight;
});
add_task(function* test_window_open() {
// Open a tab to test window.open().
let tab = yield BrowserTestUtils.openNewForegroundTab(
gBrowser, TEST_PATH + "file_dummy.html");
for (let test of TESTCASES) {
// Test 'width' and 'height' of window features.
yield testWindowOpen(tab.linkedBrowser, test.settingWidth, test.settingHeight,
test.targetWidth, test.targetHeight, false, gMaxAvailWidth,
gMaxAvailHeight, gPopupChromeUIWidth, gPopupChromeUIHeight);
// test 'outerWidth' and 'outerHeight' of window features.
yield testWindowOpen(tab.linkedBrowser, test.settingWidth, test.settingHeight,
test.targetWidth, test.targetHeight, true, gMaxAvailWidth,
gMaxAvailHeight, gPopupChromeUIWidth, gPopupChromeUIHeight);
}
yield BrowserTestUtils.removeTab(tab);
});

Просмотреть файл

@ -0,0 +1,61 @@
/*
* Bug 1330882 - A test case for opening new windows through window.open() as
* rounded size when fingerprinting resistance is enabled. This test is for
* minimum values.
*/
const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
const TEST_DOMAIN = "http://example.net/";
const TEST_PATH = TEST_DOMAIN + "browser/browser/components/resistFingerprinting/test/browser/";
let gMaxAvailWidth;
let gMaxAvailHeight;
// We need the chrome UI size of popup windows for testing outerWidth/Height.
let gPopupChromeUIWidth;
let gPopupChromeUIHeight;
const TESTCASES = [
{ settingWidth: 199, settingHeight: 99, targetWidth: 200, targetHeight: 100 },
{ settingWidth: 10, settingHeight: 10, targetWidth: 200, targetHeight: 100 },
];
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({"set":
[["privacy.resistFingerprinting", true]]
});
// Calculate the popup window's chrome UI size for tests of outerWidth/Height.
let popUpChromeUISize = yield calcPopUpWindowChromeUISize();
gPopupChromeUIWidth = popUpChromeUISize.chromeWidth;
gPopupChromeUIHeight = popUpChromeUISize.chromeHeight;
// Calculate the maximum available size.
let maxAvailSize = yield calcMaximumAvailSize(gPopupChromeUIWidth,
gPopupChromeUIHeight);
gMaxAvailWidth = maxAvailSize.maxAvailWidth;
gMaxAvailHeight = maxAvailSize.maxAvailHeight;
});
add_task(function* test_window_open() {
// Open a tab to test window.open().
let tab = yield BrowserTestUtils.openNewForegroundTab(
gBrowser, TEST_PATH + "file_dummy.html");
for (let test of TESTCASES) {
// Test 'width' and 'height' of window features.
yield testWindowOpen(tab.linkedBrowser, test.settingWidth, test.settingHeight,
test.targetWidth, test.targetHeight, false, gMaxAvailWidth,
gMaxAvailHeight, gPopupChromeUIWidth, gPopupChromeUIHeight);
// test 'outerWidth' and 'outerHeight' of window features.
yield testWindowOpen(tab.linkedBrowser, test.settingWidth, test.settingHeight,
test.targetWidth, test.targetHeight, true, gMaxAvailWidth,
gMaxAvailHeight, gPopupChromeUIWidth, gPopupChromeUIHeight);
}
yield BrowserTestUtils.removeTab(tab);
});

Просмотреть файл

@ -0,0 +1,67 @@
/*
* Bug 1330882 - A test case for setting window size through window.innerWidth/Height
* and window.outerWidth/Height when fingerprinting resistance is enabled. This
* test is for maximum values.
*/
const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
const TEST_DOMAIN = "http://example.net/";
const TEST_PATH = TEST_DOMAIN + "browser/browser/components/resistFingerprinting/test/browser/";
let gMaxAvailWidth;
let gMaxAvailHeight;
// We need the chrome UI size of popup windows for testing outerWidth/Height.
let gPopupChromeUIWidth;
let gPopupChromeUIHeight;
const TESTCASES = [
{ settingWidth: 1025, settingHeight: 1050, targetWidth: 1000, targetHeight: 1000,
initWidth: 200, initHeight: 100 },
{ settingWidth: 9999, settingHeight: 9999, targetWidth: 1000, targetHeight: 1000,
initWidth: 200, initHeight: 100 },
{ settingWidth: 999, settingHeight: 999, targetWidth: 1000, targetHeight: 1000,
initWidth: 200, initHeight: 100 },
];
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({"set":
[["privacy.resistFingerprinting", true]]
});
// Calculate the popup window's chrome UI size for tests of outerWidth/Height.
let popUpChromeUISize = yield calcPopUpWindowChromeUISize();
gPopupChromeUIWidth = popUpChromeUISize.chromeWidth;
gPopupChromeUIHeight = popUpChromeUISize.chromeHeight;
// Calculate the maximum available size.
let maxAvailSize = yield calcMaximumAvailSize(gPopupChromeUIWidth,
gPopupChromeUIHeight);
gMaxAvailWidth = maxAvailSize.maxAvailWidth;
gMaxAvailHeight = maxAvailSize.maxAvailHeight;
});
add_task(function* test_window_size_setting() {
// Open a tab to test.
let tab = yield BrowserTestUtils.openNewForegroundTab(
gBrowser, TEST_PATH + "file_dummy.html");
for (let test of TESTCASES) {
// Test window.innerWidth and window.innerHeight.
yield testWindowSizeSetting(tab.linkedBrowser, test.settingWidth, test.settingHeight,
test.targetWidth, test.targetHeight, test.initWidth,
test.initHeight, false, gMaxAvailWidth, gMaxAvailHeight,
gPopupChromeUIWidth, gPopupChromeUIHeight);
// test window.outerWidth and window.outerHeight.
yield testWindowSizeSetting(tab.linkedBrowser, test.settingWidth, test.settingHeight,
test.targetWidth, test.targetHeight, test.initWidth,
test.initHeight, true, gMaxAvailWidth, gMaxAvailHeight,
gPopupChromeUIWidth, gPopupChromeUIHeight);
}
yield BrowserTestUtils.removeTab(tab);
});

Просмотреть файл

@ -0,0 +1,67 @@
/*
* Bug 1330882 - A test case for setting window size through window.innerWidth/Height
* and window.outerWidth/Height when fingerprinting resistance is enabled. This
* test is for middle values.
*/
const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
const TEST_DOMAIN = "http://example.net/";
const TEST_PATH = TEST_DOMAIN + "browser/browser/components/resistFingerprinting/test/browser/";
let gMaxAvailWidth;
let gMaxAvailHeight;
// We need the chrome UI size of popup windows for testing outerWidth/Height.
let gPopupChromeUIWidth;
let gPopupChromeUIHeight;
const TESTCASES = [
{ settingWidth: 600, settingHeight: 600, targetWidth: 600, targetHeight: 600,
initWidth: 200, initHeight: 100 },
{ settingWidth: 599, settingHeight: 599, targetWidth: 600, targetHeight: 600,
initWidth: 200, initHeight: 100 },
{ settingWidth: 401, settingHeight: 501, targetWidth: 600, targetHeight: 600,
initWidth: 200, initHeight: 100 },
];
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({"set":
[["privacy.resistFingerprinting", true]]
});
// Calculate the popup window's chrome UI size for tests of outerWidth/Height.
let popUpChromeUISize = yield calcPopUpWindowChromeUISize();
gPopupChromeUIWidth = popUpChromeUISize.chromeWidth;
gPopupChromeUIHeight = popUpChromeUISize.chromeHeight;
// Calculate the maximum available size.
let maxAvailSize = yield calcMaximumAvailSize(gPopupChromeUIWidth,
gPopupChromeUIHeight);
gMaxAvailWidth = maxAvailSize.maxAvailWidth;
gMaxAvailHeight = maxAvailSize.maxAvailHeight;
});
add_task(function* test_window_size_setting() {
// Open a tab to test.
let tab = yield BrowserTestUtils.openNewForegroundTab(
gBrowser, TEST_PATH + "file_dummy.html");
for (let test of TESTCASES) {
// Test window.innerWidth and window.innerHeight.
yield testWindowSizeSetting(tab.linkedBrowser, test.settingWidth, test.settingHeight,
test.targetWidth, test.targetHeight, test.initWidth,
test.initHeight, false, gMaxAvailWidth, gMaxAvailHeight,
gPopupChromeUIWidth, gPopupChromeUIHeight);
// test window.outerWidth and window.outerHeight.
yield testWindowSizeSetting(tab.linkedBrowser, test.settingWidth, test.settingHeight,
test.targetWidth, test.targetHeight, test.initWidth,
test.initHeight, true, gMaxAvailWidth, gMaxAvailHeight,
gPopupChromeUIWidth, gPopupChromeUIHeight);
}
yield BrowserTestUtils.removeTab(tab);
});

Просмотреть файл

@ -0,0 +1,65 @@
/*
* Bug 1330882 - A test case for setting window size through window.innerWidth/Height
* and window.outerWidth/Height when fingerprinting resistance is enabled. This
* test is for minimum values.
*/
const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
const TEST_DOMAIN = "http://example.net/";
const TEST_PATH = TEST_DOMAIN + "browser/browser/components/resistFingerprinting/test/browser/";
let gMaxAvailWidth;
let gMaxAvailHeight;
// We need the chrome UI size of popup windows for testing outerWidth/Height.
let gPopupChromeUIWidth;
let gPopupChromeUIHeight;
const TESTCASES = [
{ settingWidth: 199, settingHeight: 99, targetWidth: 200, targetHeight: 100,
initWidth: 1000, initHeight: 1000 },
{ settingWidth: 10, settingHeight: 10, targetWidth: 200, targetHeight: 100,
initWidth: 1000, initHeight: 1000 },
];
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({"set":
[["privacy.resistFingerprinting", true]]
});
// Calculate the popup window's chrome UI size for tests of outerWidth/Height.
let popUpChromeUISize = yield calcPopUpWindowChromeUISize();
gPopupChromeUIWidth = popUpChromeUISize.chromeWidth;
gPopupChromeUIHeight = popUpChromeUISize.chromeHeight;
// Calculate the maximum available size.
let maxAvailSize = yield calcMaximumAvailSize(gPopupChromeUIWidth,
gPopupChromeUIHeight);
gMaxAvailWidth = maxAvailSize.maxAvailWidth;
gMaxAvailHeight = maxAvailSize.maxAvailHeight;
});
add_task(function* test_window_size_setting() {
// Open a tab to test.
let tab = yield BrowserTestUtils.openNewForegroundTab(
gBrowser, TEST_PATH + "file_dummy.html");
for (let test of TESTCASES) {
// Test window.innerWidth and window.innerHeight.
yield testWindowSizeSetting(tab.linkedBrowser, test.settingWidth, test.settingHeight,
test.targetWidth, test.targetHeight, test.initWidth,
test.initHeight, false, gMaxAvailWidth, gMaxAvailHeight,
gPopupChromeUIWidth, gPopupChromeUIHeight);
// test window.outerWidth and window.outerHeight.
yield testWindowSizeSetting(tab.linkedBrowser, test.settingWidth, test.settingHeight,
test.targetWidth, test.targetHeight, test.initWidth,
test.initHeight, true, gMaxAvailWidth, gMaxAvailHeight,
gPopupChromeUIWidth, gPopupChromeUIHeight);
}
yield BrowserTestUtils.removeTab(tab);
});

Просмотреть файл

@ -0,0 +1,9 @@
<html>
<head>
<title>Dummy test page</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
</head>
<body>
<p>Dummy test page</p>
</body>
</html>

Просмотреть файл

@ -0,0 +1,227 @@
/* 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";
// This function calculates the maximum available window dimensions and returns
// them as an object.
function* calcMaximumAvailSize(aChromeWidth, aChromeHeight) {
let chromeUIWidth;
let chromeUIHeight;
let testPath = "http://example.net/browser/browser/" +
"components/resistFingerprinting/test/browser/"
// If the chrome UI dimensions is not given, we will calculate it.
if (!aChromeWidth || !aChromeHeight) {
let tab = yield BrowserTestUtils.openNewForegroundTab(
gBrowser, testPath + "file_dummy.html");
let contentSize = yield ContentTask.spawn(tab.linkedBrowser, null, function* () {
let result = {
width: content.innerWidth,
height: content.innerHeight
};
return result;
});
// Calculate the maximum available window size which is depending on the
// available screen space.
chromeUIWidth = window.outerWidth - contentSize.width;
chromeUIHeight = window.outerHeight - contentSize.height;
yield BrowserTestUtils.removeTab(tab);
} else {
chromeUIWidth = aChromeWidth;
chromeUIHeight = aChromeHeight;
}
let availWidth = window.screen.availWidth;
let availHeight = window.screen.availHeight;
// Ideally, we would round the window size as 1000x1000. But the available
// screen space might not suffice. So, we decide the size according to the
// available screen size.
let availContentWidth = Math.min(1000, availWidth - chromeUIWidth);
let availContentHeight;
// If it is GTK window, we would consider the system decorations when we
// calculating avail content height since the system decorations won't be
// reported when we get available screen dimensions.
if (AppConstants.MOZ_WIDGET_GTK) {
availContentHeight = Math.min(1000, -40 + availHeight - chromeUIHeight);
} else {
availContentHeight = Math.min(1000, availHeight - chromeUIHeight);
}
// Rounded the desire size to the nearest 200x100.
let maxAvailWidth = availContentWidth - (availContentWidth % 200);
let maxAvailHeight = availContentHeight - (availContentHeight % 100);
return {maxAvailWidth, maxAvailHeight};
}
function* calcPopUpWindowChromeUISize() {
let testPath = "http://example.net/browser/browser/" +
"components/resistFingerprinting/test/browser/"
// open a popup window to acquire the chrome UI size of it.
let tab = yield BrowserTestUtils.openNewForegroundTab(
gBrowser, testPath + "file_dummy.html");
let result = yield ContentTask.spawn(tab.linkedBrowser, null, function* () {
let win;
yield new Promise(resolve => {
win = content.open("about:blank", "", "width=1000,height=1000");
win.onload = () => resolve();
});
let res = {
chromeWidth: win.outerWidth - win.innerWidth,
chromeHeight: win.outerHeight - win.innerHeight
};
win.close();
return res;
});
yield BrowserTestUtils.removeTab(tab);
return result;
}
function* testWindowOpen(aBrowser, aSettingWidth, aSettingHeight,
aTargetWidth, aTargetHeight, aTestOuter,
aMaxAvailWidth, aMaxAvailHeight, aPopupChromeUIWidth,
aPopupChromeUIHeight) {
// If the target size is greater than the maximum available content size,
// we set the target size to it.
if (aTargetWidth > aMaxAvailWidth) {
aTargetWidth = aMaxAvailWidth;
}
if (aTargetHeight > aMaxAvailHeight) {
aTargetHeight = aMaxAvailHeight;
}
// Create the testing window features.
let winFeatures;
if (aTestOuter) {
winFeatures = "outerWidth=" + (aSettingWidth + aPopupChromeUIWidth) +
",outerHeight=" + (aSettingHeight + aPopupChromeUIHeight);
} else {
winFeatures = "width=" + aSettingWidth + ",height=" + aSettingHeight;
}
let testParams = {
winFeatures,
targetWidth: aTargetWidth,
targetHeight: aTargetHeight,
};
yield ContentTask.spawn(aBrowser, testParams,
function* (input) {
// Call window.open() with window features.
yield new Promise(resolve => {
let win = content.open("http://example.net/", "", input.winFeatures);
win.onload = () => {
is(win.screen.width, input.targetWidth,
"The screen.width has a correct rounded value");
is(win.screen.height, input.targetHeight,
"The screen.height has a correct rounded value");
is(win.innerWidth, input.targetWidth,
"The window.innerWidth has a correct rounded value");
is(win.innerHeight, input.targetHeight,
"The window.innerHeight has a correct rounded value");
win.close()
resolve();
};
});
}
);
}
function* testWindowSizeSetting(aBrowser, aSettingWidth, aSettingHeight,
aTargetWidth, aTargetHeight, aInitWidth,
aInitHeight, aTestOuter, aMaxAvailWidth,
aMaxAvailHeight, aPopupChromeUIWidth,
aPopupChromeUIHeight) {
// If the target size is greater than the maximum available content size,
// we set the target size to it.
if (aTargetWidth > aMaxAvailWidth) {
aTargetWidth = aMaxAvailWidth;
}
if (aTargetHeight > aMaxAvailHeight) {
aTargetHeight = aMaxAvailHeight;
}
let testParams = {
initWidth: aInitWidth,
initHeight: aInitHeight,
settingWidth: aSettingWidth + (aTestOuter ? aPopupChromeUIWidth : 0),
settingHeight: aSettingHeight + (aTestOuter ? aPopupChromeUIHeight : 0),
targetWidth: aTargetWidth,
targetHeight: aTargetHeight,
testOuter: aTestOuter
};
yield ContentTask.spawn(aBrowser, testParams,
function* (input) {
let win;
// Open a new window and wait until it loads.
yield new Promise(resolve => {
// Given a initial window size which should be different from target
// size. We need this to trigger 'onresize' event.
let initWinFeatures = "width=" + input.initWidth + ",height=" + input.initHeight;
win = content.open("http://example.net/", "", initWinFeatures);
win.onload = () => resolve();
});
// Test inner/outerWidth.
yield new Promise(resolve => {
win.onresize = () => {
is(win.screen.width, input.targetWidth,
"The screen.width has a correct rounded value");
is(win.innerWidth, input.targetWidth,
"The window.innerWidth has a correct rounded value");
resolve();
};
if (input.testOuter) {
win.outerWidth = input.settingWidth;
} else {
win.innerWidth = input.settingWidth;
}
});
// Test inner/outerHeight.
yield new Promise(resolve => {
win.onresize = () => {
is(win.screen.height, input.targetHeight,
"The screen.height has a correct rounded value");
is(win.innerHeight, input.targetHeight,
"The window.innerHeight has a correct rounded value");
resolve();
};
if (input.testOuter) {
win.outerHeight = input.settingHeight;
} else {
win.innerHeight = input.settingHeight;
}
});
win.close();
}
);
}

Просмотреть файл

@ -221,6 +221,14 @@ function debug(aMsg) {
}
}
/**
* A global value to tell that fingerprinting resistance is enabled or not.
* If it's enabled, the session restore won't restore the window's size and
* size mode.
* This value is controlled by preference privacy.resistFingerprinting.
*/
var gResistFingerprintingEnabled = false;
this.SessionStore = {
get promiseInitialized() {
return SessionStoreInternal.promiseInitialized;
@ -701,6 +709,10 @@ var SessionStoreInternal = {
this._max_windows_undo = this._prefBranch.getIntPref("sessionstore.max_windows_undo");
this._prefBranch.addObserver("sessionstore.max_windows_undo", this, true);
gResistFingerprintingEnabled = Services.prefs.getBoolPref("privacy.resistFingerprinting");
Services.prefs.addObserver("privacy.resistFingerprinting", this, false);
},
/**
@ -1822,6 +1834,9 @@ var SessionStoreInternal = {
this._max_windows_undo = this._prefBranch.getIntPref("sessionstore.max_windows_undo");
this._capClosedWindows();
break;
case "privacy.resistFingerprinting":
gResistFingerprintingEnabled = Services.prefs.getBoolPref("privacy.resistFingerprinting");
break;
}
},
@ -3888,14 +3903,14 @@ var SessionStoreInternal = {
if (!isNaN(aLeft) && !isNaN(aTop) && (aLeft != win_("screenX") || aTop != win_("screenY"))) {
aWindow.moveTo(aLeft, aTop);
}
if (aWidth && aHeight && (aWidth != win_("width") || aHeight != win_("height"))) {
if (aWidth && aHeight && (aWidth != win_("width") || aHeight != win_("height")) && !gResistFingerprintingEnabled) {
// Don't resize the window if it's currently maximized and we would
// maximize it again shortly after.
if (aSizeMode != "maximized" || win_("sizemode") != "maximized") {
aWindow.resizeTo(aWidth, aHeight);
}
}
if (aSizeMode && win_("sizemode") != aSizeMode) {
if (aSizeMode && win_("sizemode") != aSizeMode && !gResistFingerprintingEnabled) {
switch (aSizeMode) {
case "maximized":
aWindow.maximize();

Просмотреть файл

@ -16,9 +16,9 @@
"unpack": true
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 110077036,
"digest": "8b99d058cc081f6ca2a3cc88c3ca9c15232961d2539774dacee35e2258955ad8fc4cb0af3b903a3e3f8a264ddecb3baae9256502ffc178a2823779284ace2bd8",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 112075416,
"digest": "134538dda3512363c8b103fc59128aba830bd994053612f8ad8721e1a0033ad9836cd11595ed8056d885aec7dc78b7f4c4169c0a12bd0f9c31549f2d81939054",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

Просмотреть файл

@ -16,9 +16,9 @@
"unpack": true
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 110077036,
"digest": "8b99d058cc081f6ca2a3cc88c3ca9c15232961d2539774dacee35e2258955ad8fc4cb0af3b903a3e3f8a264ddecb3baae9256502ffc178a2823779284ace2bd8",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 112075416,
"digest": "134538dda3512363c8b103fc59128aba830bd994053612f8ad8721e1a0033ad9836cd11595ed8056d885aec7dc78b7f4c4169c0a12bd0f9c31549f2d81939054",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

Просмотреть файл

@ -16,9 +16,9 @@
"unpack": true
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 110077036,
"digest": "8b99d058cc081f6ca2a3cc88c3ca9c15232961d2539774dacee35e2258955ad8fc4cb0af3b903a3e3f8a264ddecb3baae9256502ffc178a2823779284ace2bd8",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 112075416,
"digest": "134538dda3512363c8b103fc59128aba830bd994053612f8ad8721e1a0033ad9836cd11595ed8056d885aec7dc78b7f4c4169c0a12bd0f9c31549f2d81939054",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

Просмотреть файл

@ -16,9 +16,9 @@
"unpack": true
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 110077036,
"digest": "8b99d058cc081f6ca2a3cc88c3ca9c15232961d2539774dacee35e2258955ad8fc4cb0af3b903a3e3f8a264ddecb3baae9256502ffc178a2823779284ace2bd8",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 112075416,
"digest": "134538dda3512363c8b103fc59128aba830bd994053612f8ad8721e1a0033ad9836cd11595ed8056d885aec7dc78b7f4c4169c0a12bd0f9c31549f2d81939054",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

Просмотреть файл

@ -24,9 +24,9 @@
"size": 12072532
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 110077036,
"digest": "8b99d058cc081f6ca2a3cc88c3ca9c15232961d2539774dacee35e2258955ad8fc4cb0af3b903a3e3f8a264ddecb3baae9256502ffc178a2823779284ace2bd8",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 112075416,
"digest": "134538dda3512363c8b103fc59128aba830bd994053612f8ad8721e1a0033ad9836cd11595ed8056d885aec7dc78b7f4c4169c0a12bd0f9c31549f2d81939054",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

Просмотреть файл

@ -16,9 +16,9 @@
"unpack": true
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 110077036,
"digest": "8b99d058cc081f6ca2a3cc88c3ca9c15232961d2539774dacee35e2258955ad8fc4cb0af3b903a3e3f8a264ddecb3baae9256502ffc178a2823779284ace2bd8",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 112075416,
"digest": "134538dda3512363c8b103fc59128aba830bd994053612f8ad8721e1a0033ad9836cd11595ed8056d885aec7dc78b7f4c4169c0a12bd0f9c31549f2d81939054",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

Просмотреть файл

@ -16,9 +16,9 @@
"unpack": true
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 110077036,
"digest": "8b99d058cc081f6ca2a3cc88c3ca9c15232961d2539774dacee35e2258955ad8fc4cb0af3b903a3e3f8a264ddecb3baae9256502ffc178a2823779284ace2bd8",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 112075416,
"digest": "134538dda3512363c8b103fc59128aba830bd994053612f8ad8721e1a0033ad9836cd11595ed8056d885aec7dc78b7f4c4169c0a12bd0f9c31549f2d81939054",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

Просмотреть файл

@ -8,9 +8,9 @@
"unpack": true
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 122706608,
"digest": "b9ae830cfe24430907490cd58f8215447667fb8f1f052d6e78c8ecd7aadfbc92f75a404774d4cc7b30a46b756275209c2fe2723473704b3bce7ffee908e353a8",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 124444249,
"digest": "11239565e6dde851a5229a0380da129b129c560c3fa765eb4998549e688385be314523074456afec9ebe4ddb6af71e44c64d7c669e7e904ed253f6e7b0f6317b",
"algorithm": "sha512",
"filename": "rustc.tar.bz2",
"unpack": true

Просмотреть файл

@ -42,9 +42,9 @@
"filename": "dmg.tar.xz"
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 140284816,
"digest": "c97503ed2448af059a450792aac76f9b91ce8bc6daf683cdbc2d3fb49a6bd205a4ba854838281b1e3888ae15b5df585cc8fa56365fb1ec5acafc9e1b8871f3e3",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 142669732,
"digest": "ab74516718ac2b848f0d28df314c0588559dd77b203e8e0a20510a44e7d8b9b757b35c5eebd72524d9ce29bfa10a6e72e44fa54cb9cfe808bb42b5fc603b14bc",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

Просмотреть файл

@ -8,9 +8,9 @@
"unpack": true
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 122706608,
"digest": "b9ae830cfe24430907490cd58f8215447667fb8f1f052d6e78c8ecd7aadfbc92f75a404774d4cc7b30a46b756275209c2fe2723473704b3bce7ffee908e353a8",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 124444249,
"digest": "11239565e6dde851a5229a0380da129b129c560c3fa765eb4998549e688385be314523074456afec9ebe4ddb6af71e44c64d7c669e7e904ed253f6e7b0f6317b",
"algorithm": "sha512",
"filename": "rustc.tar.bz2",
"unpack": true

Просмотреть файл

@ -6,9 +6,9 @@
"filename": "mozmake.exe"
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 67227255,
"digest": "95164dc1abb2ab90ea18cf4f322d5c8390e0212e79a52b12578720d568eb6df62e55a9938c8d2a364cd3a6bd0f99608c2139d141a88ec43484b8d0651398532a",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 68287611,
"digest": "702b162f53970de096d1c7777f37eddd22251a910d523df4edcbead399d40bfb85b059b5745ec8d6e835149a8c7e7888aed36f7ca77ddfd57466a72505c2e86f",
"algorithm": "sha512",
"filename": "rustc.tar.bz2",
"unpack": true

Просмотреть файл

@ -6,9 +6,9 @@
"filename": "mozmake.exe"
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 67227255,
"digest": "95164dc1abb2ab90ea18cf4f322d5c8390e0212e79a52b12578720d568eb6df62e55a9938c8d2a364cd3a6bd0f99608c2139d141a88ec43484b8d0651398532a",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 68287611,
"digest": "702b162f53970de096d1c7777f37eddd22251a910d523df4edcbead399d40bfb85b059b5745ec8d6e835149a8c7e7888aed36f7ca77ddfd57466a72505c2e86f",
"algorithm": "sha512",
"filename": "rustc.tar.bz2",
"unpack": true

Просмотреть файл

@ -6,9 +6,9 @@
"filename": "mozmake.exe"
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 67227255,
"digest": "95164dc1abb2ab90ea18cf4f322d5c8390e0212e79a52b12578720d568eb6df62e55a9938c8d2a364cd3a6bd0f99608c2139d141a88ec43484b8d0651398532a",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 68287611,
"digest": "702b162f53970de096d1c7777f37eddd22251a910d523df4edcbead399d40bfb85b059b5745ec8d6e835149a8c7e7888aed36f7ca77ddfd57466a72505c2e86f",
"algorithm": "sha512",
"filename": "rustc.tar.bz2",
"unpack": true

Просмотреть файл

@ -6,9 +6,9 @@
"filename": "mozmake.exe"
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 72782416,
"digest": "bf9fb1a21de834d7b6992fe9d95dfe2ff19e3cbff5b00117889eef0e6c9d85442cd75640e3051f0c1788b1f629e79ffae5cc8a4106b0cad520c1f954ae2be6b0",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 73762095,
"digest": "9241134ee89a0beca228d9867b7526621faf05560fe802bb6471cc19d5c42135933883e1abd934c8d6657a06c975e167a3712e80e01bf9aa443db6ebb03a8096",
"algorithm": "sha512",
"visibility": "public",
"filename": "rustc.tar.bz2",

Просмотреть файл

@ -6,9 +6,9 @@
"filename": "mozmake.exe"
},
{
"version": "rustc 1.15.1 (021bd294c 2017-02-08) repack",
"size": 72782416,
"digest": "bf9fb1a21de834d7b6992fe9d95dfe2ff19e3cbff5b00117889eef0e6c9d85442cd75640e3051f0c1788b1f629e79ffae5cc8a4106b0cad520c1f954ae2be6b0",
"version": "rustc 1.16.0 (30cf806ef 2017-03-10) repack",
"size": 73762095,
"digest": "9241134ee89a0beca228d9867b7526621faf05560fe802bb6471cc19d5c42135933883e1abd934c8d6657a06c975e167a3712e80e01bf9aa443db6ebb03a8096",
"algorithm": "sha512",
"visibility": "public",
"filename": "rustc.tar.bz2",

Просмотреть файл

@ -883,7 +883,7 @@ return /******/ (function(modules) { // webpackBootstrap
displayName: "Number",
propTypes: {
object: React.PropTypes.oneOfType([React.PropTypes.object, React.PropTypes.number]).isRequired
object: React.PropTypes.oneOfType([React.PropTypes.object, React.PropTypes.number, React.PropTypes.bool]).isRequired
},
stringify: function (object) {
@ -973,9 +973,8 @@ return /******/ (function(modules) { // webpackBootstrap
}
if (array.length > max) {
let objectLink = this.props.objectLink || DOM.span;
items.push(Caption({
object: objectLink({
object: this.safeObjectLink({
object: this.props.object
}, array.length - max + " more…")
}));
@ -1028,6 +1027,20 @@ return /******/ (function(modules) { // webpackBootstrap
onClickBracket: function (event) {},
safeObjectLink: function (config, ...children) {
if (this.props.objectLink) {
return this.props.objectLink(Object.assign({
object: this.props.object
}, config), ...children);
}
if (Object.keys(config).length === 0 && children.length === 1) {
return children[0];
}
return DOM.span(config, ...children);
},
render: wrapRender(function () {
let {
object,
@ -1050,13 +1063,11 @@ return /******/ (function(modules) { // webpackBootstrap
brackets = needSpace(items.length > 0);
}
let objectLink = this.props.objectLink || DOM.span;
return DOM.span({
className: "objectBox objectBox-array" }, objectLink({
className: "objectBox objectBox-array" }, this.safeObjectLink({
className: "arrayLeftBracket",
object: object
}, brackets.left), ...items, objectLink({
}, brackets.left), ...items, this.safeObjectLink({
className: "arrayRightBracket",
object: object
}, brackets.right), DOM.span({
@ -1115,7 +1126,7 @@ return /******/ (function(modules) { // webpackBootstrap
displayName: "Caption",
propTypes: {
object: React.PropTypes.object
object: React.PropTypes.oneOfType([React.PropTypes.number, React.PropTypes.string]).isRequired
},
render: wrapRender(function () {
@ -1157,12 +1168,7 @@ return /******/ (function(modules) { // webpackBootstrap
getTitle: function (object) {
let title = this.props.title || object.class || "Object";
if (this.props.objectLink) {
return this.props.objectLink({
object: object
}, title);
}
return title;
return this.safeObjectLink({ className: "objectTitle" }, title);
},
safePropIterator: function (object, max) {
@ -1258,21 +1264,32 @@ return /******/ (function(modules) { // webpackBootstrap
return propsArray;
},
safeObjectLink: function (config, ...children) {
if (this.props.objectLink) {
return this.props.objectLink(Object.assign({
object: this.props.object
}, config), ...children);
}
if (Object.keys(config).length === 0 && children.length === 1) {
return children[0];
}
return span(config, ...children);
},
render: wrapRender(function () {
let object = this.props.object;
let propsArray = this.safePropIterator(object);
let objectLink = this.props.objectLink || span;
if (this.props.mode === MODE.TINY || !propsArray.length) {
return span({ className: "objectBox objectBox-object" }, objectLink({ className: "objectTitle" }, this.getTitle(object)));
return span({ className: "objectBox objectBox-object" }, this.getTitle(object));
}
return span({ className: "objectBox objectBox-object" }, this.getTitle(object), objectLink({
className: "objectLeftBrace",
object: object
}, " { "), ...propsArray, objectLink({
className: "objectRightBrace",
object: object
return span({ className: "objectBox objectBox-object" }, this.getTitle(object), this.safeObjectLink({
className: "objectLeftBrace"
}, " { "), ...propsArray, this.safeObjectLink({
className: "objectRightBrace"
}, " }"));
})
});
@ -1408,12 +1425,7 @@ return /******/ (function(modules) { // webpackBootstrap
getTitle: function (object) {
let title = this.props.title || object.class || "Object";
if (this.props.objectLink) {
return this.props.objectLink({
object: object
}, title);
}
return title;
return this.safeObjectLink({}, title);
},
safePropIterator: function (object, max) {
@ -1467,12 +1479,8 @@ return /******/ (function(modules) { // webpackBootstrap
let propsArray = this.getProps(properties, indexes, truncate, suppressQuotes);
if (truncate) {
// There are some undisplayed props. Then display "more...".
let objectLink = this.props.objectLink || span;
propsArray.push(Caption({
object: objectLink({
object: object
}, `${propertiesLength - max} more…`)
object: this.safeObjectLink({}, `${propertiesLength - max} more…`)
}));
}
@ -1501,7 +1509,7 @@ return /******/ (function(modules) { // webpackBootstrap
let name = Object.keys(properties)[i];
let value = this.getPropValue(properties[name]);
propsArray.push(PropRep(Object.assign({}, this.props, {
let propRepProps = Object.assign({}, this.props, {
mode: MODE.TINY,
name: name,
object: value,
@ -1511,7 +1519,9 @@ return /******/ (function(modules) { // webpackBootstrap
// Do not propagate title to properties reps
title: undefined,
suppressQuotes
})));
});
delete propRepProps.objectLink;
propsArray.push(PropRep(propRepProps));
});
return propsArray;
@ -1571,24 +1581,32 @@ return /******/ (function(modules) { // webpackBootstrap
return value;
},
safeObjectLink: function (config, ...children) {
if (this.props.objectLink) {
return this.props.objectLink(Object.assign({
object: this.props.object
}, config), ...children);
}
if (Object.keys(config).length === 0 && children.length === 1) {
return children[0];
}
return span(config, ...children);
},
render: wrapRender(function () {
let object = this.props.object;
let propsArray = this.safePropIterator(object, this.props.mode === MODE.LONG ? 10 : 3);
let objectLink = this.props.objectLink || span;
if (this.props.mode === MODE.TINY) {
return span({ className: "objectBox objectBox-object" }, this.getTitle(object), objectLink({
className: "objectLeftBrace",
object: object
}, ""));
return span({ className: "objectBox objectBox-object" }, this.getTitle(object));
}
return span({ className: "objectBox objectBox-object" }, this.getTitle(object), objectLink({
className: "objectLeftBrace",
object: object
}, " { "), ...propsArray, objectLink({
className: "objectRightBrace",
object: object
return span({ className: "objectBox objectBox-object" }, this.getTitle(object), this.safeObjectLink({
className: "objectLeftBrace"
}, " { "), ...propsArray, this.safeObjectLink({
className: "objectRightBrace"
}, " }"));
})
});
@ -1757,9 +1775,14 @@ return /******/ (function(modules) { // webpackBootstrap
render: wrapRender(function () {
let object = this.props.object;
let value = object.preview.value;
let objectLink = this.props.objectLink || span;
let objectLink = (config, ...children) => {
if (this.props.objectLink) {
return this.props.objectLink(Object.assign({ object }, config), ...children);
}
return span(config, ...children);
};
return objectLink({ className: "objectLink-Attr", object }, span({}, span({ className: "attrTitle" }, this.getTitle(object)), span({ className: "attrEqual" }, "="), StringRepFactory({ object: value })));
return objectLink({ className: "objectLink-Attr" }, span({ className: "attrTitle" }, this.getTitle(object)), span({ className: "attrEqual" }, "="), StringRepFactory({ object: value }));
})
});
@ -2136,12 +2159,7 @@ return /******/ (function(modules) { // webpackBootstrap
getTitle: function (object) {
const title = object.class;
if (this.props.objectLink) {
return this.props.objectLink({
object: object
}, title);
}
return title;
return this.safeObjectLink({}, title);
},
getProps: function (promiseState) {
@ -2163,30 +2181,39 @@ return /******/ (function(modules) { // webpackBootstrap
});
},
safeObjectLink: function (config, ...children) {
if (this.props.objectLink) {
return this.props.objectLink(Object.assign({
object: this.props.object
}, config), ...children);
}
if (Object.keys(config).length === 0 && children.length === 1) {
return children[0];
}
return span(config, ...children);
},
render: wrapRender(function () {
const object = this.props.object;
const { promiseState } = object;
let objectLink = this.props.objectLink || span;
if (this.props.mode === MODE.TINY) {
let { Rep } = createFactories(__webpack_require__(2));
return span({ className: "objectBox objectBox-object" }, this.getTitle(object), objectLink({
className: "objectLeftBrace",
object: object
}, " { "), Rep({ object: promiseState.state }), objectLink({
className: "objectRightBrace",
object: object
return span({ className: "objectBox objectBox-object" }, this.getTitle(object), this.safeObjectLink({
className: "objectLeftBrace"
}, " { "), Rep({ object: promiseState.state }), this.safeObjectLink({
className: "objectRightBrace"
}, " }"));
}
const propsArray = this.getProps(promiseState);
return span({ className: "objectBox objectBox-object" }, this.getTitle(object), objectLink({
className: "objectLeftBrace",
object: object
}, " { "), ...propsArray, objectLink({
className: "objectRightBrace",
object: object
return span({ className: "objectBox objectBox-object" }, this.getTitle(object), this.safeObjectLink({
className: "objectLeftBrace"
}, " { "), ...propsArray, this.safeObjectLink({
className: "objectRightBrace"
}, " }"));
})
});
@ -2237,13 +2264,17 @@ return /******/ (function(modules) { // webpackBootstrap
},
render: wrapRender(function () {
let grip = this.props.object;
let objectLink = this.props.objectLink || span;
let { object } = this.props;
let objectLink = (config, ...children) => {
if (this.props.objectLink) {
return this.props.objectLink(Object.assign({ object }, config), ...children);
}
return span(config, ...children);
};
return span({ className: "objectBox objectBox-regexp" }, objectLink({
object: grip,
className: "regexpSource"
}, this.getSource(grip)));
return objectLink({
className: "objectBox objectBox-regexp regexpSource"
}, this.getSource(object));
})
});
@ -2475,7 +2506,12 @@ return /******/ (function(modules) { // webpackBootstrap
onInspectIconClick
} = this.props;
let elements = this.getElements(object, mode);
let objectLink = this.props.objectLink || span;
let objectLink = (config, ...children) => {
if (this.props.objectLink) {
return this.props.objectLink(Object.assign({ object }, config), ...children);
}
return span(config, ...children);
};
let isInTree = attachedActorIds ? attachedActorIds.includes(object.actor) : true;
@ -2505,7 +2541,7 @@ return /******/ (function(modules) { // webpackBootstrap
}
}
return span(baseConfig, objectLink({ object }, ...elements), inspectIcon);
return span(baseConfig, objectLink({}, ...elements), inspectIcon);
})
});
@ -2864,8 +2900,14 @@ return /******/ (function(modules) { // webpackBootstrap
content = `${content}\nStack trace:\n${preview.stack}`;
}
let objectLink = this.props.objectLink || span;
return objectLink({ object, className: "objectBox-stackTrace" }, span({}, content));
let objectLink = (config, ...children) => {
if (this.props.objectLink) {
return this.props.objectLink(Object.assign({ object }, config), ...children);
}
return span(config, ...children);
};
return objectLink({ className: "objectBox-stackTrace" }, content);
})
});
@ -3137,14 +3179,12 @@ return /******/ (function(modules) { // webpackBootstrap
},
getTitle: function (object, context) {
let objectLink = this.props.objectLink || span;
if (this.props.mode !== MODE.TINY) {
let title = this.props.title || object.class || "Array";
return objectLink({
object: object
}, title, " ");
if (this.props.mode === MODE.TINY) {
return "";
}
return "";
let title = this.props.title || object.class || "Array";
return this.safeObjectLink({}, title + " ");
},
getPreviewItems: function (grip) {
@ -3197,18 +3237,29 @@ return /******/ (function(modules) { // webpackBootstrap
}
}
if (previewItems.length > max || gripLength > previewItems.length) {
let objectLink = this.props.objectLink || span;
let leftItemNum = gripLength - max > 0 ? gripLength - max : gripLength - previewItems.length;
items.push(Caption({
object: objectLink({
object: this.props.object
}, leftItemNum + " more…")
object: this.safeObjectLink({}, leftItemNum + " more…")
}));
}
return items;
},
safeObjectLink: function (config, ...children) {
if (this.props.objectLink) {
return this.props.objectLink(Object.assign({
object: this.props.object
}, config), ...children);
}
if (Object.keys(config).length === 0 && children.length === 1) {
return children[0];
}
return span(config, ...children);
},
render: wrapRender(function () {
let {
object,
@ -3232,16 +3283,13 @@ return /******/ (function(modules) { // webpackBootstrap
brackets = needSpace(items.length > 0);
}
let objectLink = this.props.objectLink || span;
let title = this.getTitle(object);
return span({
className: "objectBox objectBox-array" }, title, objectLink({
className: "arrayLeftBracket",
object: object
}, brackets.left), ...items, objectLink({
className: "arrayRightBracket",
object: object
className: "objectBox objectBox-array" }, title, this.safeObjectLink({
className: "arrayLeftBracket"
}, brackets.left), ...items, this.safeObjectLink({
className: "arrayRightBracket"
}, brackets.right), span({
className: "arrayProperties",
role: "group" }));
@ -3257,7 +3305,7 @@ return /******/ (function(modules) { // webpackBootstrap
propTypes: {
delim: React.PropTypes.string,
object: React.PropTypes.object.isRequired,
object: React.PropTypes.oneOfType([React.PropTypes.object, React.PropTypes.number, React.PropTypes.string]).isRequired,
objectLink: React.PropTypes.func,
// @TODO Change this to Object.values once it's supported in Node's version of V8
mode: React.PropTypes.oneOf(Object.keys(MODE).map(key => MODE[key])),
@ -3328,12 +3376,7 @@ return /******/ (function(modules) { // webpackBootstrap
getTitle: function (object) {
let title = this.props.title || (object && object.class ? object.class : "Map");
if (this.props.objectLink) {
return this.props.objectLink({
object: object
}, title);
}
return title;
return this.safeObjectLink({}, title);
},
safeEntriesIterator: function (object, max) {
@ -3365,13 +3408,9 @@ return /******/ (function(modules) { // webpackBootstrap
let entries = this.getEntries(mapEntries, indexes);
if (entries.length < mapEntries.length) {
// There are some undisplayed entries. Then display "more…".
let objectLink = this.props.objectLink || span;
entries.push(Caption({
key: "more",
object: objectLink({
object: object
}, `${mapEntries.length - max} more…`)
object: this.safeObjectLink({}, `${mapEntries.length - max} more…`)
}));
}
@ -3446,24 +3485,32 @@ return /******/ (function(modules) { // webpackBootstrap
}, []);
},
safeObjectLink: function (config, ...children) {
if (this.props.objectLink) {
return this.props.objectLink(Object.assign({
object: this.props.object
}, config), ...children);
}
if (Object.keys(config).length === 0 && children.length === 1) {
return children[0];
}
return span(config, ...children);
},
render: wrapRender(function () {
let object = this.props.object;
let propsArray = this.safeEntriesIterator(object, this.props.mode === MODE.LONG ? 10 : 3);
let objectLink = this.props.objectLink || span;
if (this.props.mode === MODE.TINY) {
return span({ className: "objectBox objectBox-object" }, this.getTitle(object), objectLink({
className: "objectLeftBrace",
object: object
}, ""));
return span({ className: "objectBox objectBox-object" }, this.getTitle(object));
}
return span({ className: "objectBox objectBox-object" }, this.getTitle(object), objectLink({
className: "objectLeftBrace",
object: object
}, " { "), propsArray, objectLink({
className: "objectRightBrace",
object: object
return span({ className: "objectBox objectBox-object" }, this.getTitle(object), this.safeObjectLink({
className: "objectLeftBrace"
}, " { "), propsArray, this.safeObjectLink({
className: "objectRightBrace"
}, " }"));
})
});

Просмотреть файл

@ -14,8 +14,8 @@ Test ArrayRep rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
"use strict";
/* import-globals-from head.js */
@ -42,6 +42,7 @@ window.onload = Task.async(function* () {
yield testNested();
yield testArray();
yield testObjectLink();
} catch (e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
@ -248,6 +249,42 @@ window.onload = Task.async(function* () {
testRepRenderModes(modeTests, "testNested", componentUnderTest, stub);
}
function testObjectLink() {
let stub = ["a", "b", "c"];
const defaultOutput = `*[ *"a", "b", "c"* ]*`;
const modeTests = [
{
mode: undefined,
expectedOutput: defaultOutput,
},
{
mode: MODE.TINY,
expectedOutput: `*[*3*]*`,
},
{
mode: MODE.SHORT,
expectedOutput: defaultOutput,
},
{
mode: MODE.LONG,
expectedOutput: defaultOutput,
}
];
testRepRenderModes(
modeTests,
"testObjectLink",
componentUnderTest,
stub,
{
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
}
);
}
});
</script>
</pre>

Просмотреть файл

@ -14,14 +14,43 @@ Test Attribute rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
try {
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
let { Rep, Attribute } = REPS;
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
let { Rep, Attribute } = REPS;
let gripStub = {
try {
testBasic();
testObjectLink();
} catch (e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
SimpleTest.finish();
}
function testBasic() {
// Test that correct rep is chosen
const renderedRep = shallowRenderComponent(Rep, { object: getStub() });
is(renderedRep.type, Attribute.rep, `Rep correctly selects ${Attribute.rep.displayName}`);
// Test rendering
const renderedComponent = renderComponent(Attribute.rep, { object: getStub() });
is(renderedComponent.textContent, "class=\"autocomplete-suggestions\"", "Attribute rep has expected text content");
}
function testObjectLink() {
const renderedComponent = renderComponent(Attribute.rep, {
object: getStub(),
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
});
is(renderedComponent.textContent, "*class=\"autocomplete-suggestions\"*",
"Attribute rep has expected text content when an objectLink is passed as a prop");
}
function getStub() {
return {
"type": "object",
"class": "Attr",
"actor": "server1.conn19.obj65",
@ -36,18 +65,6 @@ window.onload = Task.async(function* () {
"value": "autocomplete-suggestions"
}
};
// Test that correct rep is chosen
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
is(renderedRep.type, Attribute.rep, `Rep correctly selects ${Attribute.rep.displayName}`);
// Test rendering
const renderedComponent = renderComponent(Attribute.rep, { object: gripStub });
is(renderedComponent.textContent, "class=\"autocomplete-suggestions\"", "Attribute rep has expected text content");
} catch(e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
SimpleTest.finish();
}
});
</script>

Просмотреть файл

@ -14,8 +14,8 @@ Test comment-node rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
"use strict";
window.onload = Task.async(function* () {

Просмотреть файл

@ -14,8 +14,8 @@ Test DateTime rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
let { Rep, DateTime } = REPS;
@ -23,6 +23,7 @@ window.onload = Task.async(function* () {
try {
testValid();
testInvalid();
testObjectLink();
} catch(e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
@ -72,6 +73,30 @@ window.onload = Task.async(function* () {
const renderedComponent = renderComponent(DateTime.rep, { object: gripStub });
is(renderedComponent.textContent, "Invalid Date", "DateTime rep has expected text content for invalid date");
}
function testObjectLink() {
let gripStub = {
"type": "object",
"class": "Date",
"actor": "server1.conn0.child1/obj32",
"extensible": true,
"frozen": false,
"sealed": false,
"ownPropertyLength": 0,
"preview": {
"timestamp": 1459372644859
}
};
// Test rendering
const renderedComponent = renderComponent(DateTime.rep, {
object: gripStub,
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
});
is(renderedComponent.textContent, "*Date *2016-03-30T21:17:24.859Z",
"DateTime rep has expected text content when an objectLink is passed as a prop");
}
});
</script>
</pre>

Просмотреть файл

@ -14,14 +14,45 @@ Test Document rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
let { Rep, Document } = REPS;
try {
let gripStub = {
testBasic();
testObjectLink();
} catch (e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
SimpleTest.finish();
}
function testBasic() {
// Test that correct rep is chosen
const renderedRep = shallowRenderComponent(Rep, { object: getStub() });
is(renderedRep.type, Document.rep, `Rep correctly selects ${Document.rep.displayName}`);
// Test rendering
const renderedComponent = renderComponent(Document.rep, { object: getStub() });
is(renderedComponent.textContent, "https://www.mozilla.org/en-US/firefox/new/",
"Document rep has expected text content");
}
function testObjectLink() {
// Test rendering
const renderedComponent = renderComponent(Document.rep, {
object: getStub(),
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
});
is(renderedComponent.textContent, "*HTMLDocument *https://www.mozilla.org/en-US/firefox/new/",
"Document rep has expected text content when an objectLink is passed as a prop");
}
function getStub() {
return {
"type": "object",
"class": "HTMLDocument",
"actor": "server1.conn17.obj115",
@ -36,18 +67,6 @@ window.onload = Task.async(function* () {
"location": "https://www.mozilla.org/en-US/firefox/new/"
}
};
// Test that correct rep is chosen
const renderedRep = shallowRenderComponent(Rep, { object: gripStub });
is(renderedRep.type, Document.rep, `Rep correctly selects ${Document.rep.displayName}`);
// Test rendering
const renderedComponent = renderComponent(Document.rep, { object: gripStub });
is(renderedComponent.textContent, "https://www.mozilla.org/en-US/firefox/new/", "Document rep has expected text content");
} catch(e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
SimpleTest.finish();
}
});
</script>

Просмотреть файл

@ -14,8 +14,8 @@ Test Element node rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
"use strict";
window.onload = Task.async(function* () {
@ -39,6 +39,7 @@ window.onload = Task.async(function* () {
yield testOnMouseOver();
yield testOnMouseOut();
yield testOnInspectIconClick();
yield testObjectLink();
} catch (e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
@ -272,6 +273,29 @@ window.onload = Task.async(function* () {
"onInspectIconClick forwarded the original event to the callback");
}
function testObjectLink() {
const stub = getGripStub("testBodyNode");
const renderedComponent = renderComponent(ElementNode.rep, {
object: stub,
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
});
is(renderedComponent.textContent, `*<body id="body-id" class="body-class">*`,
"Element node rep has expected text content for body node when an objectLink is " +
"passed as a prop");
const tinyRenderedComponent = renderComponent(ElementNode.rep, {
object: stub, mode: MODE.TINY,
objectLink: (props, ...children) => React.DOM.span({
className: "object-link"
}, "*", ...children, "*"),
});
is(tinyRenderedComponent.textContent, `*body#body-id.body-class*`,
"Element node rep has expected text content for body node in tiny mode when an " +
"objectLink is passed as a prop");
}
function getGripStub(name) {
switch (name) {
case "testBodyNode":

Просмотреть файл

@ -14,8 +14,8 @@ Test Error rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
"use strict";
window.onload = Task.async(function* () {
@ -36,6 +36,8 @@ window.onload = Task.async(function* () {
yield testSyntaxError();
yield testTypeError();
yield testURIError();
yield testObjectLink();
} catch (e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
@ -260,6 +262,34 @@ window.onload = Task.async(function* () {
"Error Rep has expected text content for URIError in tiny mode");
}
function testObjectLink() {
// Test object = `new Error("Error message")`
const stub = getGripStub("testSimpleError");
const renderedComponent = renderComponent(ErrorRep.rep, {
object: stub,
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
});
is(renderedComponent.textContent,
"*Error: Error message\n" +
"Stack trace:\n" +
"@debugger eval code:1:13\n*",
"Error Rep has expected text content when an objectLink is passed as a prop");
const tinyRenderedComponent = renderComponent(
ErrorRep.rep, {
object: stub,
mode: MODE.TINY,
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
});
is(tinyRenderedComponent.textContent,
"*Error*",
"Error Rep has expected text content in tiny mode when an objectLink is passed " +
"as a prop");
}
function getGripStub(name) {
switch (name) {
case "testSimpleError":

Просмотреть файл

@ -14,8 +14,8 @@ Test Event rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
const {
REPS,
@ -38,6 +38,8 @@ window.onload = Task.async(function* () {
yield testOnDomNodeMouseOver();
yield testOnDomNodeMouseOut();
yield testOnDomNodeInspectIconClick();
yield testObjectLink();
} catch (e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
@ -210,6 +212,29 @@ window.onload = Task.async(function* () {
"when the inspect icon is clicked");
}
function testObjectLink() {
const renderedComponent = renderComponent(Event.rep, {
object: getGripStub("testMouseEvent"),
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
});
is(renderedComponent.textContent,
"*click** { *target: div#test, clientX: 62, clientY: 18, *3 more…** }*",
"Event rep has expected text content when an objectLink is passed as a prop");
const longRenderedComponent = renderComponent(Event.rep, {
object: getGripStub("testMouseEvent"),
mode: MODE.LONG,
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
});
is(longRenderedComponent.textContent,
"*click** { *target: div#test, buttons: 0, clientX: 62, clientY: 18, layerX: 0, " +
"layerY: 0* }*",
"Event rep has expected text content in long mode when an objectLink is passed " +
"as a prop");
}
function getGripStub(name) {
switch (name) {
case "testEvent":

Просмотреть файл

@ -14,8 +14,8 @@ Test fallback for rep rendering when a rep fails to render.
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
try {
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");

Просмотреть файл

@ -14,8 +14,8 @@ Test Func rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
const { REPS, MODE } = browserRequire("devtools/client/shared/components/reps/reps");
let { Rep, Func } = REPS;
@ -36,6 +36,7 @@ window.onload = Task.async(function* () {
yield testAnonAsyncFunction();
yield testGeneratorFunction();
yield testAnonGeneratorFunction();
yield testObjectLink();
} catch(e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
@ -226,6 +227,27 @@ window.onload = Task.async(function* () {
testRepRenderModes(modeTests, testName, componentUnderTest, getGripStub(testName));
}
function testObjectLink() {
// Test declaration: `function testName() { let innerVar = "foo" }`
const modeTests = [
{
mode: undefined,
expectedOutput: "*function *testName()",
}
];
testRepRenderModes(
modeTests,
"testObjectLink",
componentUnderTest,
getGripStub("testNamed"),
{
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
}
);
}
function getGripStub(functionName) {
switch (functionName) {
case "testNamed":

Просмотреть файл

@ -14,8 +14,8 @@ Test GripArray rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
const {
REPS,
@ -46,6 +46,8 @@ window.onload = Task.async(function* () {
yield testOnDomNodeMouseOver();
yield testOnDomNodeMouseOut();
yield testOnDomNodeInspectIconClick();
yield testObjectLink();
} catch (e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
@ -414,6 +416,41 @@ window.onload = Task.async(function* () {
});
}
function testObjectLink() {
// Test array = `["test string"…] //4 items`
const defaultOutput = `*Array **[ *${Array(maxLength.short).fill("\"test string\"").join(", ")}, *1 more…** ]*`;
const modeTests = [
{
mode: undefined,
expectedOutput: defaultOutput,
},
{
mode: MODE.TINY,
expectedOutput: `*[*${maxLength.short + 1}*]*`,
},
{
mode: MODE.SHORT,
expectedOutput: defaultOutput,
},
{
mode: MODE.LONG,
expectedOutput: `*Array **[ *${Array(maxLength.short + 1).fill("\"test string\"").join(", ")}* ]*`,
}
];
testRepRenderModes(
modeTests,
"testObjectLink",
componentUnderTest,
getGripStub("testMoreThanShortMaxProps"),
{
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
}
);
}
function getGripStub(functionName) {
switch (functionName) {
case "testBasic":

Просмотреть файл

@ -14,8 +14,8 @@ Test GripMap rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
"use strict";
window.onload = Task.async(function* () {
@ -41,6 +41,8 @@ window.onload = Task.async(function* () {
yield testOnDomNodeMouseOver();
yield testOnDomNodeMouseOut();
yield testOnDomNodeInspectIconClick();
yield testObjectLink();
} catch (e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
@ -400,6 +402,45 @@ window.onload = Task.async(function* () {
});
}
function testObjectLink() {
// Test object:
// `new Map([["key-a",null], ["key-b",undefined], ["key-c","value-c"], ["key-d",4]])`
const defaultOutput =
`*Map** { *"key-a": null, "key-c": "value-c", "key-d": 4, *1 more…** }*`;
const longOutput =
`*Map** { *"key-a": null, "key-b": undefined, "key-c": "value-c", "key-d": 4* }*`;
const modeTests = [
{
mode: undefined,
expectedOutput: defaultOutput,
},
{
mode: MODE.TINY,
expectedOutput: `*Map*`,
},
{
mode: MODE.SHORT,
expectedOutput: defaultOutput,
},
{
mode: MODE.LONG,
expectedOutput: longOutput,
}
];
testRepRenderModes(
modeTests,
"testObjectLink",
componentUnderTest,
getGripStub("testUninterestingEntries"),
{
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
}
);
}
function getGripStub(functionName) {
switch (functionName) {
case "testEmptyMap":

Просмотреть файл

@ -14,8 +14,8 @@ Test grip rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
const {
REPS,
@ -52,6 +52,8 @@ window.onload = Task.async(function* () {
yield testOnDomNodeMouseOver();
yield testOnDomNodeMouseOut();
yield testOnDomNodeInspectIconClick();
yield testObjectLink();
} catch(e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
@ -628,6 +630,42 @@ window.onload = Task.async(function* () {
});
}
function testObjectLink() {
// Test object: `{a: undefined, b: 1, more: 2, d: 3}`;
const defaultOutput = `*Object** { *b: 1, more: 2, d: 3, *1 more…** }*`;
const longOutput = `*Object** { *a: undefined, b: 1, more: 2, d: 3* }*`;
const modeTests = [
{
mode: undefined,
expectedOutput: defaultOutput,
},
{
mode: MODE.TINY,
expectedOutput: `*Object*`,
},
{
mode: MODE.SHORT,
expectedOutput: defaultOutput,
},
{
mode: MODE.LONG,
expectedOutput: longOutput,
}
];
testRepRenderModes(
modeTests,
"testObjectLink",
componentUnderTest,
getGripStub("testMoreProp"),
{
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
}
);
}
function getGripStub(functionName) {
switch (functionName) {
case "testBasic":

Просмотреть файл

@ -14,8 +14,8 @@ Test Infinity rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
"use strict";
window.onload = Task.async(function* () {

Просмотреть файл

@ -14,8 +14,8 @@ Test LongString rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
let { Rep, LongStringRep } = REPS;

Просмотреть файл

@ -14,8 +14,8 @@ Test NaN rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
"use strict";
window.onload = Task.async(function* () {

Просмотреть файл

@ -14,8 +14,8 @@ Test Null rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
try {
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");

Просмотреть файл

@ -14,8 +14,8 @@ Test Number rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
let { Rep, Number } = REPS;

Просмотреть файл

@ -14,8 +14,8 @@ Test ObjectWithText rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
try {
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
@ -42,6 +42,17 @@ window.onload = Task.async(function* () {
// Test rendering
const renderedComponent = renderComponent(ObjectWithText.rep, { object: gripStub });
is(renderedComponent.textContent, "\".Shadow\"", "ObjectWithText rep has expected text content");
// Test rendering with objectLink
const objectLinkRenderedComponent = renderComponent(ObjectWithText.rep, {
object: gripStub,
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
});
is(objectLinkRenderedComponent.textContent,
"*CSSStyleRule *\".Shadow\"",
"ObjectWithText rep has expected text content when an objectLink is passed as a prop"
);
} catch(e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {

Просмотреть файл

@ -14,8 +14,8 @@ Test ObjectWithURL rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
try {
let ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
@ -48,6 +48,17 @@ window.onload = Task.async(function* () {
const innerNode = renderedComponent.querySelector(".objectPropValue");
is(innerNode.textContent, "https://www.mozilla.org/en-US/", "ObjectWithURL rep has expected inner HTML structure and text content");
// Test rendering with objectLink
const objectLinkRenderedComponent = renderComponent(ObjectWithURL.rep, {
object: gripStub,
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
});
is(objectLinkRenderedComponent.textContent,
"*Location *https://www.mozilla.org/en-US/",
"ObjectWithURL rep has expected text content when an objectLink is passed as a prop"
);
// @TODO test link once Bug 1245303 has been implemented.
} catch(e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));

Просмотреть файл

@ -14,8 +14,8 @@ Test Obj rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
const { REPS, MODE } = browserRequire("devtools/client/shared/components/reps/reps");
let { Rep, Obj } = REPS;
@ -41,6 +41,9 @@ window.onload = Task.async(function* () {
// Test that you can pass a custom title to the Rep
yield testCustomTitle();
// Test that you can pass an objectLink to the Rep
yield testCustomTitle();
} catch(e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
@ -285,6 +288,46 @@ window.onload = Task.async(function* () {
}
);
}
function testObjectLink() {
const stub = {
a: undefined,
b: 1,
"more": 2,
d: 3
};
const defaultOutput = `*Object **{ *b: 1, more: 2, d: 3, *1 more…** }*`;
const modeTests = [
{
mode: undefined,
expectedOutput: defaultOutput,
},
{
mode: MODE.TINY,
expectedOutput: `*Object*`,
},
{
mode: MODE.SHORT,
expectedOutput: defaultOutput,
},
{
mode: MODE.LONG,
expectedOutput: defaultOutput,
}
];
testRepRenderModes(
modeTests,
"testObjectLink",
componentUnderTest,
stub,
{
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
}
);
}
});
</script>
</pre>

Просмотреть файл

@ -14,8 +14,8 @@ Test Promise rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
"use strict";
window.onload = Task.async(function* () {
@ -38,6 +38,8 @@ window.onload = Task.async(function* () {
yield testOnDomNodeMouseOver();
yield testOnDomNodeMouseOut();
yield testOnDomNodeInspectIconClick();
yield testObjectLink();
} catch (e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
@ -300,6 +302,44 @@ window.onload = Task.async(function* () {
"when the inspect icon is clicked");
}
function testObjectLink() {
// Test object = `new Promise((resolve, reject) => true)`
const stub = getGripStub("testPending");
// Test rendering
const defaultOutput = `*Promise** { *<state>: "pending"* }*`;
const modeTests = [
{
mode: undefined,
expectedOutput: defaultOutput,
},
{
mode: MODE.TINY,
expectedOutput: `*Promise** { *"pending"* }*`,
},
{
mode: MODE.SHORT,
expectedOutput: defaultOutput,
},
{
mode: MODE.LONG,
expectedOutput: defaultOutput,
}
];
testRepRenderModes(
modeTests,
"testObjectLink",
componentUnderTest,
stub,
{
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
}
);
}
function getGripStub(name) {
switch (name) {
case "testPending":

Просмотреть файл

@ -14,8 +14,8 @@ Test RegExp rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
try {
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
@ -39,6 +39,18 @@ window.onload = Task.async(function* () {
// Test rendering
const renderedComponent = renderComponent(RegExp.rep, { object: gripStub });
is(renderedComponent.textContent, "/ab+c/i", "RegExp rep has expected text content");
// Test rendering with objectLink
const objectLinkRenderedComponent = renderComponent(RegExp.rep, {
object: gripStub,
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
});
is(
objectLinkRenderedComponent.textContent,
"*/ab+c/i*",
"RegExp rep has expected text content when an objectLink is passed as a prop"
);
} catch(e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {

Просмотреть файл

@ -14,8 +14,8 @@ Test String rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
let { Rep, StringRep } = REPS;

Просмотреть файл

@ -14,8 +14,8 @@ Test Stylesheet rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
try {
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
@ -42,6 +42,18 @@ window.onload = Task.async(function* () {
// Test rendering
const renderedComponent = renderComponent(StyleSheet.rep, { object: gripStub });
is(renderedComponent.textContent, "StyleSheet https://example.com/styles.css", "StyleSheet rep has expected text content");
// Test rendering with objectLink
const objectLinkRenderedComponent = renderComponent(StyleSheet.rep, {
object: gripStub,
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
});
is(
objectLinkRenderedComponent.textContent,
"*StyleSheet *https://example.com/styles.css",
"StyleSheet rep has expected text content when an objectLink is passed as a prop"
);
} catch(e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {

Просмотреть файл

@ -14,8 +14,8 @@ Test Symbol rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
"use strict";
/* import-globals-from head.js */

Просмотреть файл

@ -14,8 +14,8 @@ Test text-node rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
"use strict";
window.onload = Task.async(function* () {
@ -63,6 +63,8 @@ window.onload = Task.async(function* () {
yield testOnMouseOver();
yield testOnMouseOut();
yield testOnInspectIconClick();
yield testObjectLink();
} catch (e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
@ -202,6 +204,41 @@ window.onload = Task.async(function* () {
ok(inspectIconClickedEvent !== null && inspectIconClickedEvent.type === "click",
"onInspectIconClick forwarded the original event to the callback");
}
function testObjectLink() {
const stub = gripStubs.get("testRendering");
const defaultOutput = `*#text* "hello world"`;
const modeTests = [
{
mode: undefined,
expectedOutput: defaultOutput,
},
{
mode: MODE.TINY,
expectedOutput: "*#text*",
},
{
mode: MODE.SHORT,
expectedOutput: defaultOutput,
},
{
mode: MODE.LONG,
expectedOutput: defaultOutput,
}
];
testRepRenderModes(
modeTests,
"testObjectLink",
TextNode,
stub,
{
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
}
);
}
});
</script>
</pre>

Просмотреть файл

@ -14,8 +14,8 @@ Test undefined rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
try {
let ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");

Просмотреть файл

@ -14,8 +14,8 @@ Test window rep
</head>
<body>
<pre id="test">
<script src="head.js" type="application/javascript;version=1.8"></script>
<script type="application/javascript;version=1.8">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
window.onload = Task.async(function* () {
try {
let ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
@ -77,7 +77,31 @@ window.onload = Task.async(function* () {
});
is(displayClassLongRenderedComponent.textContent, "Custom about:newtab",
"Window rep has expected text content in LONG mode with Custom display class");
} catch(e) {
const objectLinkTinyRenderedComponent = renderComponent(Window.rep, {
object: gripStub,
mode: MODE.TINY,
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
});
is(
objectLinkTinyRenderedComponent.textContent,
"*Window*",
"Window rep has expected text content in TINY mode when an objectLink is passed as a prop"
);
const objectLinkLongRenderedComponent = renderComponent(Window.rep, {
object: gripStub,
mode: MODE.LONG,
objectLink: (props, ...children) => React.DOM.span({},
"*", ...children, "*"),
});
is(
objectLinkLongRenderedComponent.textContent,
"*Window* about:newtab",
"Window rep has expected text content in LONG mode when an objectLink is passed as a prop"
);
} catch (e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
SimpleTest.finish();

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -54,236 +54,22 @@ return /******/ (function(modules) { // webpackBootstrap
/* 0 */
/***/ function(module, exports, __webpack_require__) {
let _resolveAndFetch = (() => {
var _ref = _asyncToGenerator(function* (generatedSource) {
// Fetch the sourcemap over the network and create it.
const sourceMapURL = _resolveSourceMapURL(generatedSource);
const fetched = yield networkRequest(sourceMapURL, { loadFromCache: false });
// Create the source map and fix it up.
const map = new SourceMapConsumer(fetched.content);
_setSourceMapRoot(map, sourceMapURL, generatedSource);
return map;
});
return function _resolveAndFetch(_x) {
return _ref.apply(this, arguments);
};
})();
let getOriginalURLs = (() => {
var _ref2 = _asyncToGenerator(function* (generatedSource) {
const map = yield _fetchSourceMap(generatedSource);
return map && map.sources;
});
return function getOriginalURLs(_x2) {
return _ref2.apply(this, arguments);
};
})();
let getGeneratedLocation = (() => {
var _ref3 = _asyncToGenerator(function* (location, originalSource) {
if (!isOriginalId(location.sourceId)) {
return location;
}
const generatedSourceId = originalToGeneratedId(location.sourceId);
const map = yield _getSourceMap(generatedSourceId);
if (!map) {
return location;
}
const { line, column } = map.generatedPositionFor({
source: originalSource.url,
line: location.line,
column: location.column == null ? 0 : location.column,
bias: SourceMapConsumer.LEAST_UPPER_BOUND
});
return {
sourceId: generatedSourceId,
line: line,
// Treat 0 as no column so that line breakpoints work correctly.
column: column === 0 ? undefined : column
};
});
return function getGeneratedLocation(_x3, _x4) {
return _ref3.apply(this, arguments);
};
})();
let getOriginalLocation = (() => {
var _ref4 = _asyncToGenerator(function* (location) {
if (!isGeneratedId(location.sourceId)) {
return location;
}
const map = yield _getSourceMap(location.sourceId);
if (!map) {
return location;
}
const { source: url, line, column } = map.originalPositionFor({
line: location.line,
column: location.column == null ? Infinity : location.column
});
if (url == null) {
// No url means the location didn't map.
return location;
}
return {
sourceId: generatedToOriginalId(location.sourceId, url),
line,
column
};
});
return function getOriginalLocation(_x5) {
return _ref4.apply(this, arguments);
};
})();
let getOriginalSourceText = (() => {
var _ref5 = _asyncToGenerator(function* (originalSource) {
assert(isOriginalId(originalSource.id), "Source is not an original source");
const generatedSourceId = originalToGeneratedId(originalSource.id);
const map = yield _getSourceMap(generatedSourceId);
if (!map) {
return null;
}
let text = map.sourceContentFor(originalSource.url);
if (!text) {
text = (yield networkRequest(originalSource.url, { loadFromCache: false })).content;
}
return {
text,
contentType: getContentType(originalSource.url || "")
};
});
return function getOriginalSourceText(_x6) {
return _ref5.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
/**
* Source Map Worker
* @module utils/source-map-worker
*/
const networkRequest = __webpack_require__(70);
const { parse } = __webpack_require__(71);
const path = __webpack_require__(78);
const { SourceMapConsumer, SourceMapGenerator } = __webpack_require__(79);
const assert = __webpack_require__(90);
const {
originalToGeneratedId,
generatedToOriginalId,
isGeneratedId,
isOriginalId,
getContentType
} = __webpack_require__(65);
let sourceMapRequests = new Map();
let sourceMapsEnabled = false;
function clearSourceMaps() {
sourceMapRequests.clear();
}
function enableSourceMaps() {
sourceMapsEnabled = true;
}
function _resolveSourceMapURL(source) {
const { url = "", sourceMapURL = "" } = source;
if (path.isURL(sourceMapURL) || url == "") {
// If it's already a full URL or the source doesn't have a URL,
// don't resolve anything.
return sourceMapURL;
} else if (path.isAbsolute(sourceMapURL)) {
// If it's an absolute path, it should be resolved relative to the
// host of the source.
const { protocol = "", host = "" } = parse(url);
return `${protocol}//${host}${sourceMapURL}`;
}
// Otherwise, it's a relative path and should be resolved relative
// to the source.
return `${path.dirname(url)}/${sourceMapURL}`;
}
/**
* Sets the source map's sourceRoot to be relative to the source map url.
* @memberof utils/source-map-worker
* @static
*/
function _setSourceMapRoot(sourceMap, absSourceMapURL, source) {
// No need to do this fiddling if we won't be fetching any sources over the
// wire.
if (sourceMap.hasContentsOfAllSources()) {
return;
}
const base = path.dirname(absSourceMapURL.indexOf("data:") === 0 && source.url ? source.url : absSourceMapURL);
if (sourceMap.sourceRoot) {
sourceMap.sourceRoot = path.join(base, sourceMap.sourceRoot);
} else {
sourceMap.sourceRoot = base;
}
return sourceMap;
}
function _getSourceMap(generatedSourceId) {
return sourceMapRequests.get(generatedSourceId);
}
function _fetchSourceMap(generatedSource) {
const existingRequest = sourceMapRequests.get(generatedSource.id);
if (existingRequest) {
// If it has already been requested, return the request. Make sure
// to do this even if sourcemapping is turned off, because
// pretty-printing uses sourcemaps.
//
// An important behavior here is that if it's in the middle of
// requesting it, all subsequent calls will block on the initial
// request.
return existingRequest;
} else if (!generatedSource.sourceMapURL || !sourceMapsEnabled) {
return Promise.resolve(null);
}
// Fire off the request, set it in the cache, and return it.
const req = _resolveAndFetch(generatedSource).catch(e => console.error(e));
sourceMapRequests.set(generatedSource.id, req);
return req;
}
function applySourceMap(generatedId, url, code, mappings) {
const generator = new SourceMapGenerator({ file: url });
mappings.forEach(mapping => generator.addMapping(mapping));
generator.setSourceContent(url, code);
const map = SourceMapConsumer(generator.toJSON());
sourceMapRequests.set(generatedId, Promise.resolve(map));
}
getOriginalURLs,
getGeneratedLocation,
getOriginalLocation,
getOriginalSourceText,
applySourceMap,
clearSourceMaps
} = __webpack_require__(84);
// The interface is implemented in source-map to be
// easier to unit test.
const publicInterface = {
getOriginalURLs,
getGeneratedLocation,
getOriginalLocation,
getOriginalSourceText,
enableSourceMaps,
applySourceMap,
clearSourceMaps
};
@ -299,74 +85,10 @@ return /******/ (function(modules) { // webpackBootstrap
};
/***/ },
/* 1 */,
/* 2 */,
/* 3 */,
/* 4 */,
/* 5 */,
/* 6 */,
/* 7 */,
/* 8 */,
/* 9 */,
/* 10 */,
/* 11 */,
/* 12 */,
/* 13 */,
/* 14 */,
/* 15 */,
/* 16 */,
/* 17 */,
/* 18 */,
/* 19 */,
/* 20 */,
/* 21 */,
/* 22 */,
/* 23 */,
/* 24 */,
/* 25 */,
/* 26 */,
/* 27 */,
/* 28 */,
/* 29 */,
/* 30 */,
/* 31 */,
/* 32 */,
/* 33 */,
/* 34 */,
/* 35 */,
/* 36 */,
/* 37 */,
/* 38 */,
/* 39 */,
/* 40 */,
/* 41 */,
/* 42 */,
/* 43 */,
/* 44 */,
/* 45 */,
/* 46 */,
/* 47 */,
/* 48 */,
/* 49 */,
/* 50 */,
/* 51 */,
/* 52 */,
/* 53 */,
/* 54 */,
/* 55 */,
/* 56 */,
/* 57 */,
/* 58 */,
/* 59 */,
/* 60 */,
/* 61 */,
/* 62 */,
/* 63 */,
/* 64 */,
/* 65 */
/* 1 */
/***/ function(module, exports, __webpack_require__) {
const md5 = __webpack_require__(66);
const md5 = __webpack_require__(2);
function originalToGeneratedId(originalId) {
const match = originalId.match(/(.*)\/originalSource/);
@ -441,49 +163,23 @@ return /******/ (function(modules) { // webpackBootstrap
return "text/plain";
}
let msgId = 1;
function workerTask(worker, method) {
return function (...args) {
return new Promise((resolve, reject) => {
const id = msgId++;
worker.postMessage({ id, method, args });
const listener = ({ data: result }) => {
if (result.id !== id) {
return;
}
worker.removeEventListener("message", listener);
if (result.error) {
reject(result.error);
} else {
resolve(result.response);
}
};
worker.addEventListener("message", listener);
});
};
}
module.exports = {
originalToGeneratedId,
generatedToOriginalId,
isOriginalId,
isGeneratedId,
getContentType,
workerTask
getContentType
};
/***/ },
/* 66 */
/* 2 */
/***/ function(module, exports, __webpack_require__) {
(function(){
var crypt = __webpack_require__(67),
utf8 = __webpack_require__(68).utf8,
isBuffer = __webpack_require__(69),
bin = __webpack_require__(68).bin,
var crypt = __webpack_require__(3),
utf8 = __webpack_require__(4).utf8,
isBuffer = __webpack_require__(5),
bin = __webpack_require__(4).bin,
// The core
md5 = function (message, options) {
@ -642,7 +338,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 67 */
/* 3 */
/***/ function(module, exports) {
(function() {
@ -744,7 +440,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 68 */
/* 4 */
/***/ function(module, exports) {
var charenc = {
@ -783,7 +479,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 69 */
/* 5 */
/***/ function(module, exports) {
/*!
@ -810,7 +506,318 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 70 */
/* 6 */,
/* 7 */,
/* 8 */,
/* 9 */,
/* 10 */,
/* 11 */,
/* 12 */,
/* 13 */,
/* 14 */,
/* 15 */,
/* 16 */,
/* 17 */,
/* 18 */,
/* 19 */,
/* 20 */,
/* 21 */,
/* 22 */,
/* 23 */,
/* 24 */,
/* 25 */,
/* 26 */,
/* 27 */,
/* 28 */,
/* 29 */,
/* 30 */,
/* 31 */,
/* 32 */,
/* 33 */,
/* 34 */,
/* 35 */,
/* 36 */,
/* 37 */,
/* 38 */,
/* 39 */,
/* 40 */,
/* 41 */,
/* 42 */,
/* 43 */,
/* 44 */,
/* 45 */,
/* 46 */,
/* 47 */,
/* 48 */,
/* 49 */,
/* 50 */,
/* 51 */,
/* 52 */,
/* 53 */,
/* 54 */,
/* 55 */,
/* 56 */,
/* 57 */,
/* 58 */,
/* 59 */,
/* 60 */,
/* 61 */,
/* 62 */,
/* 63 */,
/* 64 */,
/* 65 */,
/* 66 */,
/* 67 */,
/* 68 */,
/* 69 */,
/* 70 */,
/* 71 */,
/* 72 */,
/* 73 */,
/* 74 */,
/* 75 */,
/* 76 */,
/* 77 */,
/* 78 */,
/* 79 */,
/* 80 */,
/* 81 */,
/* 82 */,
/* 83 */,
/* 84 */
/***/ function(module, exports, __webpack_require__) {
let _resolveAndFetch = (() => {
var _ref = _asyncToGenerator(function* (generatedSource) {
// Fetch the sourcemap over the network and create it.
const sourceMapURL = _resolveSourceMapURL(generatedSource);
const fetched = yield networkRequest(sourceMapURL, { loadFromCache: false });
// Create the source map and fix it up.
const map = new SourceMapConsumer(fetched.content);
_setSourceMapRoot(map, sourceMapURL, generatedSource);
return map;
});
return function _resolveAndFetch(_x) {
return _ref.apply(this, arguments);
};
})();
let getOriginalURLs = (() => {
var _ref2 = _asyncToGenerator(function* (generatedSource) {
const map = yield _fetchSourceMap(generatedSource);
return map && map.sources;
});
return function getOriginalURLs(_x2) {
return _ref2.apply(this, arguments);
};
})();
let getGeneratedLocation = (() => {
var _ref3 = _asyncToGenerator(function* (location, originalSource) {
if (!isOriginalId(location.sourceId)) {
return location;
}
const generatedSourceId = originalToGeneratedId(location.sourceId);
const map = yield _getSourceMap(generatedSourceId);
if (!map) {
return location;
}
const { line, column } = map.generatedPositionFor({
source: originalSource.url,
line: location.line,
column: location.column == null ? 0 : location.column,
bias: SourceMapConsumer.LEAST_UPPER_BOUND
});
return {
sourceId: generatedSourceId,
line: line,
// Treat 0 as no column so that line breakpoints work correctly.
column: column === 0 ? undefined : column
};
});
return function getGeneratedLocation(_x3, _x4) {
return _ref3.apply(this, arguments);
};
})();
let getOriginalLocation = (() => {
var _ref4 = _asyncToGenerator(function* (location) {
if (!isGeneratedId(location.sourceId)) {
return location;
}
const map = yield _getSourceMap(location.sourceId);
if (!map) {
return location;
}
const { source: url, line, column } = map.originalPositionFor({
line: location.line,
column: location.column == null ? Infinity : location.column
});
if (url == null) {
// No url means the location didn't map.
return location;
}
return {
sourceId: generatedToOriginalId(location.sourceId, url),
line,
column
};
});
return function getOriginalLocation(_x5) {
return _ref4.apply(this, arguments);
};
})();
let getOriginalSourceText = (() => {
var _ref5 = _asyncToGenerator(function* (originalSource) {
assert(isOriginalId(originalSource.id), "Source is not an original source");
const generatedSourceId = originalToGeneratedId(originalSource.id);
const map = yield _getSourceMap(generatedSourceId);
if (!map) {
return null;
}
let text = map.sourceContentFor(originalSource.url);
if (!text) {
text = (yield networkRequest(originalSource.url, { loadFromCache: false })).content;
}
return {
text,
contentType: getContentType(originalSource.url || "")
};
});
return function getOriginalSourceText(_x6) {
return _ref5.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
/**
* Source Map Worker
* @module utils/source-map-worker
*/
const networkRequest = __webpack_require__(85);
const { parse } = __webpack_require__(86);
const path = __webpack_require__(93);
const { SourceMapConsumer, SourceMapGenerator } = __webpack_require__(94);
const assert = __webpack_require__(105);
const {
originalToGeneratedId,
generatedToOriginalId,
isGeneratedId,
isOriginalId,
getContentType
} = __webpack_require__(1);
let sourceMapRequests = new Map();
function clearSourceMaps() {
sourceMapRequests.clear();
}
function _resolveSourceMapURL(source) {
const { url = "", sourceMapURL = "" } = source;
if (path.isURL(sourceMapURL) || url == "") {
// If it's already a full URL or the source doesn't have a URL,
// don't resolve anything.
return sourceMapURL;
} else if (path.isAbsolute(sourceMapURL)) {
// If it's an absolute path, it should be resolved relative to the
// host of the source.
const { protocol = "", host = "" } = parse(url);
return `${protocol}//${host}${sourceMapURL}`;
}
// Otherwise, it's a relative path and should be resolved relative
// to the source.
return `${path.dirname(url)}/${sourceMapURL}`;
}
/**
* Sets the source map's sourceRoot to be relative to the source map url.
* @memberof utils/source-map-worker
* @static
*/
function _setSourceMapRoot(sourceMap, absSourceMapURL, source) {
// No need to do this fiddling if we won't be fetching any sources over the
// wire.
if (sourceMap.hasContentsOfAllSources()) {
return;
}
const base = path.dirname(absSourceMapURL.indexOf("data:") === 0 && source.url ? source.url : absSourceMapURL);
if (sourceMap.sourceRoot) {
sourceMap.sourceRoot = path.join(base, sourceMap.sourceRoot);
} else {
sourceMap.sourceRoot = base;
}
return sourceMap;
}
function _getSourceMap(generatedSourceId) {
return sourceMapRequests.get(generatedSourceId);
}
function _fetchSourceMap(generatedSource) {
const existingRequest = sourceMapRequests.get(generatedSource.id);
if (existingRequest) {
// If it has already been requested, return the request. Make sure
// to do this even if sourcemapping is turned off, because
// pretty-printing uses sourcemaps.
//
// An important behavior here is that if it's in the middle of
// requesting it, all subsequent calls will block on the initial
// request.
return existingRequest;
} else if (!generatedSource.sourceMapURL) {
return Promise.resolve(null);
}
// Fire off the request, set it in the cache, and return it.
const req = _resolveAndFetch(generatedSource).catch(e => console.error(e));
sourceMapRequests.set(generatedSource.id, req);
return req;
}
function applySourceMap(generatedId, url, code, mappings) {
const generator = new SourceMapGenerator({ file: url });
mappings.forEach(mapping => generator.addMapping(mapping));
generator.setSourceContent(url, code);
const map = SourceMapConsumer(generator.toJSON());
sourceMapRequests.set(generatedId, Promise.resolve(map));
}
module.exports = {
getOriginalURLs,
getGeneratedLocation,
getOriginalLocation,
getOriginalSourceText,
applySourceMap,
clearSourceMaps
};
/***/ },
/* 85 */
/***/ function(module, exports) {
function networkRequest(url, opts) {
@ -843,9 +850,8 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = networkRequest;
/***/ },
/* 71 */
/* 86 */
/***/ function(module, exports, __webpack_require__) {
// Copyright Joyent, Inc. and other Node contributors.
@ -871,8 +877,8 @@ return /******/ (function(modules) { // webpackBootstrap
'use strict';
var punycode = __webpack_require__(72);
var util = __webpack_require__(74);
var punycode = __webpack_require__(87);
var util = __webpack_require__(89);
exports.parse = urlParse;
exports.resolve = urlResolve;
@ -947,7 +953,7 @@ return /******/ (function(modules) { // webpackBootstrap
'gopher:': true,
'file:': true
},
querystring = __webpack_require__(75);
querystring = __webpack_require__(90);
function urlParse(url, parseQueryString, slashesDenoteHost) {
if (url && util.isObject(url) && url instanceof Url) return url;
@ -1583,7 +1589,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 72 */
/* 87 */
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/*! https://mths.be/punycode v1.3.2 by @mathias */
@ -2115,10 +2121,10 @@ return /******/ (function(modules) { // webpackBootstrap
}(this));
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(73)(module), (function() { return this; }())))
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(88)(module), (function() { return this; }())))
/***/ },
/* 73 */
/* 88 */
/***/ function(module, exports) {
module.exports = function(module) {
@ -2134,7 +2140,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 74 */
/* 89 */
/***/ function(module, exports) {
'use strict';
@ -2156,17 +2162,17 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 75 */
/* 90 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.decode = exports.parse = __webpack_require__(76);
exports.encode = exports.stringify = __webpack_require__(77);
exports.decode = exports.parse = __webpack_require__(91);
exports.encode = exports.stringify = __webpack_require__(92);
/***/ },
/* 76 */
/* 91 */
/***/ function(module, exports) {
// Copyright Joyent, Inc. and other Node contributors.
@ -2252,7 +2258,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 77 */
/* 92 */
/***/ function(module, exports) {
// Copyright Joyent, Inc. and other Node contributors.
@ -2322,7 +2328,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 78 */
/* 93 */
/***/ function(module, exports) {
function basename(path) {
@ -2351,7 +2357,7 @@ return /******/ (function(modules) { // webpackBootstrap
};
/***/ },
/* 79 */
/* 94 */
/***/ function(module, exports, __webpack_require__) {
/*
@ -2359,13 +2365,13 @@ return /******/ (function(modules) { // webpackBootstrap
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
exports.SourceMapGenerator = __webpack_require__(80).SourceMapGenerator;
exports.SourceMapConsumer = __webpack_require__(86).SourceMapConsumer;
exports.SourceNode = __webpack_require__(89).SourceNode;
exports.SourceMapGenerator = __webpack_require__(95).SourceMapGenerator;
exports.SourceMapConsumer = __webpack_require__(101).SourceMapConsumer;
exports.SourceNode = __webpack_require__(104).SourceNode;
/***/ },
/* 80 */
/* 95 */
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -2375,10 +2381,10 @@ return /******/ (function(modules) { // webpackBootstrap
* http://opensource.org/licenses/BSD-3-Clause
*/
var base64VLQ = __webpack_require__(81);
var util = __webpack_require__(83);
var ArraySet = __webpack_require__(84).ArraySet;
var MappingList = __webpack_require__(85).MappingList;
var base64VLQ = __webpack_require__(96);
var util = __webpack_require__(98);
var ArraySet = __webpack_require__(99).ArraySet;
var MappingList = __webpack_require__(100).MappingList;
/**
* An instance of the SourceMapGenerator represents a source map which is
@ -2775,7 +2781,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 81 */
/* 96 */
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -2815,7 +2821,7 @@ return /******/ (function(modules) { // webpackBootstrap
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var base64 = __webpack_require__(82);
var base64 = __webpack_require__(97);
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
@ -2921,7 +2927,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 82 */
/* 97 */
/***/ function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -2994,7 +3000,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 83 */
/* 98 */
/***/ function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -3417,7 +3423,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 84 */
/* 99 */
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -3427,7 +3433,7 @@ return /******/ (function(modules) { // webpackBootstrap
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = __webpack_require__(83);
var util = __webpack_require__(98);
var has = Object.prototype.hasOwnProperty;
/**
@ -3527,7 +3533,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 85 */
/* 100 */
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -3537,7 +3543,7 @@ return /******/ (function(modules) { // webpackBootstrap
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = __webpack_require__(83);
var util = __webpack_require__(98);
/**
* Determine whether mappingB is after mappingA with respect to generated
@ -3612,7 +3618,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 86 */
/* 101 */
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -3622,11 +3628,11 @@ return /******/ (function(modules) { // webpackBootstrap
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = __webpack_require__(83);
var binarySearch = __webpack_require__(87);
var ArraySet = __webpack_require__(84).ArraySet;
var base64VLQ = __webpack_require__(81);
var quickSort = __webpack_require__(88).quickSort;
var util = __webpack_require__(98);
var binarySearch = __webpack_require__(102);
var ArraySet = __webpack_require__(99).ArraySet;
var base64VLQ = __webpack_require__(96);
var quickSort = __webpack_require__(103).quickSort;
function SourceMapConsumer(aSourceMap) {
var sourceMap = aSourceMap;
@ -4700,7 +4706,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 87 */
/* 102 */
/***/ function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4817,7 +4823,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 88 */
/* 103 */
/***/ function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4937,7 +4943,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 89 */
/* 104 */
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
@ -4947,8 +4953,8 @@ return /******/ (function(modules) { // webpackBootstrap
* http://opensource.org/licenses/BSD-3-Clause
*/
var SourceMapGenerator = __webpack_require__(80).SourceMapGenerator;
var util = __webpack_require__(83);
var SourceMapGenerator = __webpack_require__(95).SourceMapGenerator;
var util = __webpack_require__(98);
// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
// operating systems these days (capturing the result).
@ -5350,7 +5356,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ },
/* 90 */
/* 105 */
/***/ function(module, exports) {
function assert(condition, message) {

Просмотреть файл

@ -6,8 +6,8 @@ pref(dom.animations-api.core.enabled,true) load 1216842-3.html
pref(dom.animations-api.core.enabled,true) load 1216842-4.html
pref(dom.animations-api.core.enabled,true) load 1216842-5.html # bug 1334036
pref(dom.animations-api.core.enabled,true) load 1216842-6.html # bug 1334036
skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1272475-1.html # bug 1324693 and bug 1332657 and bug 1336769
skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1272475-2.html # bug 1324693 and bug 1332657 and bug 1336769
pref(dom.animations-api.core.enabled,true) load 1272475-1.html
pref(dom.animations-api.core.enabled,true) load 1272475-2.html
pref(dom.animations-api.core.enabled,true) load 1278485-1.html
pref(dom.animations-api.core.enabled,true) load 1277272-1.html
pref(dom.animations-api.core.enabled,true) load 1290535-1.html

Просмотреть файл

@ -293,6 +293,9 @@ bool nsContentUtils::sPrivacyResistFingerprinting = false;
bool nsContentUtils::sSendPerformanceTimingNotifications = false;
bool nsContentUtils::sUseActivityCursor = false;
int32_t nsContentUtils::sPrivacyMaxInnerWidth = 1000;
int32_t nsContentUtils::sPrivacyMaxInnerHeight = 1000;
uint32_t nsContentUtils::sHandlingInputTimeout = 1000;
uint32_t nsContentUtils::sCookiesLifetimePolicy = nsICookieService::ACCEPT_NORMALLY;
@ -591,6 +594,14 @@ nsContentUtils::Init()
Preferences::AddBoolVarCache(&sPrivacyResistFingerprinting,
"privacy.resistFingerprinting", false);
Preferences::AddIntVarCache(&sPrivacyMaxInnerWidth,
"privacy.window.maxInnerWidth",
1000);
Preferences::AddIntVarCache(&sPrivacyMaxInnerHeight,
"privacy.window.maxInnerHeight",
1000);
Preferences::AddUintVarCache(&sHandlingInputTimeout,
"dom.event.handling-user-input-time-limit",
1000);
@ -2137,6 +2148,13 @@ nsContentUtils::IsCallerChrome()
return xpc::IsUniversalXPConnectEnabled(GetCurrentJSContext());
}
/* static */
bool
nsContentUtils::ShouldResistFingerprinting()
{
return sPrivacyResistFingerprinting;
}
bool
nsContentUtils::ShouldResistFingerprinting(nsIDocShell* aDocShell)
{
@ -2147,6 +2165,77 @@ nsContentUtils::ShouldResistFingerprinting(nsIDocShell* aDocShell)
return !isChrome && sPrivacyResistFingerprinting;
}
/* static */
void
nsContentUtils::CalcRoundedWindowSizeForResistingFingerprinting(int32_t aChromeWidth,
int32_t aChromeHeight,
int32_t aScreenWidth,
int32_t aScreenHeight,
int32_t aInputWidth,
int32_t aInputHeight,
bool aSetOuterWidth,
bool aSetOuterHeight,
int32_t* aOutputWidth,
int32_t* aOutputHeight)
{
MOZ_ASSERT(aOutputWidth);
MOZ_ASSERT(aOutputHeight);
int32_t availContentWidth = 0;
int32_t availContentHeight = 0;
availContentWidth = std::min(sPrivacyMaxInnerWidth,
aScreenWidth - aChromeWidth);
#ifdef MOZ_WIDGET_GTK
// In the GTK window, it will not report outside system decorations
// when we get available window size, see Bug 581863. So, we leave a
// 40 pixels space for them when calculating the available content
// height. It is not necessary for the width since the content width
// is usually pretty much the same as the chrome width.
availContentHeight = std::min(sPrivacyMaxInnerHeight,
(-40 + aScreenHeight) - aChromeHeight);
#else
availContentHeight = std::min(sPrivacyMaxInnerHeight,
aScreenHeight - aChromeHeight);
#endif
// Ideally, we'd like to round window size to 1000x1000, but the
// screen space could be too small to accommodate this size in some
// cases. If it happens, we would round the window size to the nearest
// 200x100.
availContentWidth = availContentWidth - (availContentWidth % 200);
availContentHeight = availContentHeight - (availContentHeight % 100);
// If aIsOuter is true, we are setting the outer window. So we
// have to consider the chrome UI.
int32_t chromeOffsetWidth = aSetOuterWidth ? aChromeWidth : 0;
int32_t chromeOffsetHeight = aSetOuterHeight ? aChromeHeight : 0;
int32_t resultWidth = 0, resultHeight = 0;
// if the original size is greater than the maximum available size, we set
// it to the maximum size. And if the original value is less than the
// minimum rounded size, we set it to the minimum 200x100.
if (aInputWidth > (availContentWidth + chromeOffsetWidth)) {
resultWidth = availContentWidth + chromeOffsetWidth;
} else if (aInputWidth < (200 + chromeOffsetWidth)) {
resultWidth = 200 + chromeOffsetWidth;
} else {
// Otherwise, we round the window to the nearest upper rounded 200x100.
resultWidth = NSToIntCeil((aInputWidth - chromeOffsetWidth) / 200.0) * 200 + chromeOffsetWidth;
}
if (aInputHeight > (availContentHeight + chromeOffsetHeight)) {
resultHeight = availContentHeight + chromeOffsetHeight;
} else if (aInputHeight < (100 + chromeOffsetHeight)) {
resultHeight = 100 + chromeOffsetHeight;
} else {
resultHeight = NSToIntCeil((aInputHeight - chromeOffsetHeight) / 100.0) * 100 + chromeOffsetHeight;
}
*aOutputWidth = resultWidth;
*aOutputHeight = resultHeight;
}
bool
nsContentUtils::ThreadsafeIsCallerChrome()
{

Просмотреть файл

@ -265,8 +265,25 @@ public:
JS::MutableHandle<JS::PropertyDescriptor> aDesc);
// Check whether we should avoid leaking distinguishing information to JS/CSS.
static bool ShouldResistFingerprinting();
static bool ShouldResistFingerprinting(nsIDocShell* aDocShell);
// A helper function to calculate the rounded window size for fingerprinting
// resistance. The rounded size is based on the chrome UI size and available
// screen size. If the inputWidth/Height is greater than the available content
// size, this will report the available content size. Otherwise, it will
// round the size to the nearest upper 200x100.
static void CalcRoundedWindowSizeForResistingFingerprinting(int32_t aChromeWidth,
int32_t aChromeHeight,
int32_t aScreenWidth,
int32_t aScreenHeight,
int32_t aInputWidth,
int32_t aInputHeight,
bool aSetOuterWidth,
bool aSetOuterHeight,
int32_t* aOutputWidth,
int32_t* aOutputHeight);
/**
* Returns the parent node of aChild crossing document boundaries.
* Uses the parent node in the composed document.
@ -2933,6 +2950,9 @@ private:
static uint32_t sCookiesLifetimePolicy;
static uint32_t sCookiesBehavior;
static int32_t sPrivacyMaxInnerWidth;
static int32_t sPrivacyMaxInnerHeight;
static nsHtml5StringParser* sHTMLFragmentParser;
static nsIParser* sXMLFragmentParser;
static nsIFragmentContentSink* sXMLFragmentSink;

Просмотреть файл

@ -14797,6 +14797,101 @@ nsGlobalWindow::SetReplaceableWindowCoord(JSContext* aCx,
return;
}
if (nsContentUtils::ShouldResistFingerprinting(GetDocShell())) {
bool innerWidthSpecified = false;
bool innerHeightSpecified = false;
bool outerWidthSpecified = false;
bool outerHeightSpecified = false;
if (strcmp(aPropName, "innerWidth") == 0) {
innerWidthSpecified = true;
} else if (strcmp(aPropName, "innerHeight") == 0) {
innerHeightSpecified = true;
} else if (strcmp(aPropName, "outerWidth") == 0) {
outerWidthSpecified = true;
} else if (strcmp(aPropName, "outerHeight") == 0) {
outerHeightSpecified = true;
}
if (innerWidthSpecified || innerHeightSpecified ||
outerWidthSpecified || outerHeightSpecified)
{
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = outer->GetTreeOwnerWindow();
nsCOMPtr<nsIScreen> screen;
nsCOMPtr<nsIScreenManager> screenMgr(
do_GetService("@mozilla.org/gfx/screenmanager;1"));
int32_t winLeft = 0;
int32_t winTop = 0;
int32_t winWidth = 0;
int32_t winHeight = 0;
double scale = 1.0;
if (treeOwnerAsWin && screenMgr) {
// Acquire current window size.
treeOwnerAsWin->GetUnscaledDevicePixelsPerCSSPixel(&scale);
treeOwnerAsWin->GetPositionAndSize(&winLeft, &winTop, &winWidth, &winHeight);
winLeft = NSToIntRound(winHeight / scale);
winTop = NSToIntRound(winWidth / scale);
winWidth = NSToIntRound(winWidth / scale);
winHeight = NSToIntRound(winHeight / scale);
// Acquire content window size.
CSSIntSize contentSize;
outer->GetInnerSize(contentSize);
screenMgr->ScreenForRect(winLeft, winTop, winWidth, winHeight,
getter_AddRefs(screen));
if (screen) {
int32_t* targetContentWidth = nullptr;
int32_t* targetContentHeight = nullptr;
int32_t screenWidth = 0;
int32_t screenHeight = 0;
int32_t chromeWidth = 0;
int32_t chromeHeight = 0;
int32_t inputWidth = 0;
int32_t inputHeight = 0;
int32_t unused = 0;
// Get screen dimensions (in device pixels)
screen->GetAvailRect(&unused, &unused, &screenWidth,
&screenHeight);
// Convert them to CSS pixels
screenWidth = NSToIntRound(screenWidth / scale);
screenHeight = NSToIntRound(screenHeight / scale);
// Calculate the chrome UI size.
chromeWidth = winWidth - contentSize.width;
chromeHeight = winHeight - contentSize.height;
if (innerWidthSpecified || outerWidthSpecified) {
inputWidth = value;
targetContentWidth = &value;
targetContentHeight = &unused;
} else if (innerHeightSpecified || outerHeightSpecified) {
inputHeight = value;
targetContentWidth = &unused;
targetContentHeight = &value;
}
nsContentUtils::CalcRoundedWindowSizeForResistingFingerprinting(
chromeWidth,
chromeHeight,
screenWidth,
screenHeight,
inputWidth,
inputHeight,
outerWidthSpecified,
outerHeightSpecified,
targetContentWidth,
targetContentHeight
);
}
}
}
}
(this->*aSetter)(value, aCallerType, aError);
}

Просмотреть файл

@ -12,8 +12,6 @@
namespace mozilla {
#define NS_EVENT_STATE_HIGHEST_SERVO_BIT 21
/**
* EventStates is the class used to represent the event states of nsIContent
* instances. These states are calculated by IntrinsicState() and
@ -163,7 +161,7 @@ public:
*/
ServoType ServoValue() const
{
return mStates & ((1 << (NS_EVENT_STATE_HIGHEST_SERVO_BIT + 1)) - 1);
return mStates;
}
private:
@ -223,87 +221,73 @@ private:
#define NS_EVENT_STATE_INVALID NS_DEFINE_EVENT_STATE_MACRO(11)
// UI friendly version of :valid pseudo-class.
#define NS_EVENT_STATE_MOZ_UI_VALID NS_DEFINE_EVENT_STATE_MACRO(12)
// UI friendly version of :invalid pseudo-class.
#define NS_EVENT_STATE_MOZ_UI_INVALID NS_DEFINE_EVENT_STATE_MACRO(13)
// Content could not be rendered (image/object/etc).
#define NS_EVENT_STATE_BROKEN NS_DEFINE_EVENT_STATE_MACRO(13)
#define NS_EVENT_STATE_BROKEN NS_DEFINE_EVENT_STATE_MACRO(14)
// Content disabled by the user (images turned off, say).
#define NS_EVENT_STATE_USERDISABLED NS_DEFINE_EVENT_STATE_MACRO(14)
#define NS_EVENT_STATE_USERDISABLED NS_DEFINE_EVENT_STATE_MACRO(15)
// Content suppressed by the user (ad blocking, etc).
#define NS_EVENT_STATE_SUPPRESSED NS_DEFINE_EVENT_STATE_MACRO(15)
#define NS_EVENT_STATE_SUPPRESSED NS_DEFINE_EVENT_STATE_MACRO(16)
// Content is still loading such that there is nothing to show the
// user (eg an image which hasn't started coming in yet).
#define NS_EVENT_STATE_LOADING NS_DEFINE_EVENT_STATE_MACRO(16)
#define NS_EVENT_STATE_LOADING NS_DEFINE_EVENT_STATE_MACRO(17)
// Handler for the content has been blocked.
#define NS_EVENT_STATE_HANDLER_BLOCKED NS_DEFINE_EVENT_STATE_MACRO(17)
#define NS_EVENT_STATE_HANDLER_BLOCKED NS_DEFINE_EVENT_STATE_MACRO(18)
// Handler for the content has been disabled.
#define NS_EVENT_STATE_HANDLER_DISABLED NS_DEFINE_EVENT_STATE_MACRO(18)
#define NS_EVENT_STATE_HANDLER_DISABLED NS_DEFINE_EVENT_STATE_MACRO(19)
// Handler for the content has crashed
#define NS_EVENT_STATE_HANDLER_CRASHED NS_DEFINE_EVENT_STATE_MACRO(19)
#define NS_EVENT_STATE_HANDLER_CRASHED NS_DEFINE_EVENT_STATE_MACRO(20)
// Content is required.
#define NS_EVENT_STATE_REQUIRED NS_DEFINE_EVENT_STATE_MACRO(20)
#define NS_EVENT_STATE_REQUIRED NS_DEFINE_EVENT_STATE_MACRO(21)
// Content is optional (and can be required).
#define NS_EVENT_STATE_OPTIONAL NS_DEFINE_EVENT_STATE_MACRO(21)
/*
* Bits below here do not have Servo-related ordering constraints.
*
* Remember to change NS_EVENT_STATE_HIGHEST_SERVO_BIT at the top of the file if
* this changes!
*/
// Drag is hovering over content.
#define NS_EVENT_STATE_DRAGOVER NS_DEFINE_EVENT_STATE_MACRO(22)
#define NS_EVENT_STATE_OPTIONAL NS_DEFINE_EVENT_STATE_MACRO(22)
// Element is an unresolved custom element candidate
#define NS_EVENT_STATE_UNRESOLVED NS_DEFINE_EVENT_STATE_MACRO(23)
// Link has been visited.
#define NS_EVENT_STATE_VISITED NS_DEFINE_EVENT_STATE_MACRO(23)
#define NS_EVENT_STATE_VISITED NS_DEFINE_EVENT_STATE_MACRO(24)
// Link hasn't been visited.
#define NS_EVENT_STATE_UNVISITED NS_DEFINE_EVENT_STATE_MACRO(24)
#define NS_EVENT_STATE_UNVISITED NS_DEFINE_EVENT_STATE_MACRO(25)
// Drag is hovering over content.
#define NS_EVENT_STATE_DRAGOVER NS_DEFINE_EVENT_STATE_MACRO(26)
// Content value is in-range (and can be out-of-range).
#define NS_EVENT_STATE_INRANGE NS_DEFINE_EVENT_STATE_MACRO(25)
#define NS_EVENT_STATE_INRANGE NS_DEFINE_EVENT_STATE_MACRO(27)
// Content value is out-of-range.
#define NS_EVENT_STATE_OUTOFRANGE NS_DEFINE_EVENT_STATE_MACRO(26)
#define NS_EVENT_STATE_OUTOFRANGE NS_DEFINE_EVENT_STATE_MACRO(28)
// These two are temporary (see bug 302188)
// Content is read-only.
#define NS_EVENT_STATE_MOZ_READONLY NS_DEFINE_EVENT_STATE_MACRO(27)
#define NS_EVENT_STATE_MOZ_READONLY NS_DEFINE_EVENT_STATE_MACRO(29)
// Content is editable.
#define NS_EVENT_STATE_MOZ_READWRITE NS_DEFINE_EVENT_STATE_MACRO(28)
#define NS_EVENT_STATE_MOZ_READWRITE NS_DEFINE_EVENT_STATE_MACRO(30)
// Content is the default one (meaning depends of the context).
#define NS_EVENT_STATE_DEFAULT NS_DEFINE_EVENT_STATE_MACRO(29)
#define NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL NS_DEFINE_EVENT_STATE_MACRO(30)
// Content has focus and should show a ring.
#define NS_EVENT_STATE_FOCUSRING NS_DEFINE_EVENT_STATE_MACRO(31)
#define NS_EVENT_STATE_DEFAULT NS_DEFINE_EVENT_STATE_MACRO(31)
// Content is a submit control and the form isn't valid.
#define NS_EVENT_STATE_MOZ_SUBMITINVALID NS_DEFINE_EVENT_STATE_MACRO(32)
// UI friendly version of :invalid pseudo-class.
#define NS_EVENT_STATE_MOZ_UI_INVALID NS_DEFINE_EVENT_STATE_MACRO(33)
// This bit is currently free.
// #define NS_EVENT_STATE_?????????? NS_DEFINE_EVENT_STATE_MACRO(34)
// Handler for click to play plugin
#define NS_EVENT_STATE_TYPE_CLICK_TO_PLAY NS_DEFINE_EVENT_STATE_MACRO(35)
// Content is in the optimum region.
#define NS_EVENT_STATE_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(36)
#define NS_EVENT_STATE_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(33)
// Content is in the suboptimal region.
#define NS_EVENT_STATE_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(37)
#define NS_EVENT_STATE_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(34)
// Content is in the sub-suboptimal region.
#define NS_EVENT_STATE_SUB_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(38)
// Handler for click to play plugin (vulnerable w/update)
#define NS_EVENT_STATE_VULNERABLE_UPDATABLE NS_DEFINE_EVENT_STATE_MACRO(39)
// Handler for click to play plugin (vulnerable w/no update)
#define NS_EVENT_STATE_VULNERABLE_NO_UPDATE NS_DEFINE_EVENT_STATE_MACRO(40)
// Element is ltr (for :dir pseudo-class)
#define NS_EVENT_STATE_LTR NS_DEFINE_EVENT_STATE_MACRO(42)
// Element is rtl (for :dir pseudo-class)
#define NS_EVENT_STATE_RTL NS_DEFINE_EVENT_STATE_MACRO(43)
// This bit is currently free.
// #define NS_EVENT_STATE_?????????? NS_DEFINE_EVENT_STATE_MACRO(44)
#define NS_EVENT_STATE_SUB_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(35)
// Element is highlighted (devtools inspector)
#define NS_EVENT_STATE_DEVTOOLS_HIGHLIGHTED NS_DEFINE_EVENT_STATE_MACRO(45)
// Element is an unresolved custom element candidate
#define NS_EVENT_STATE_UNRESOLVED NS_DEFINE_EVENT_STATE_MACRO(46)
#define NS_EVENT_STATE_DEVTOOLS_HIGHLIGHTED NS_DEFINE_EVENT_STATE_MACRO(36)
// Element is transitioning for rules changed by style editor
#define NS_EVENT_STATE_STYLEEDITOR_TRANSITIONING NS_DEFINE_EVENT_STATE_MACRO(47)
// This bit is currently free.
// #define NS_EVENT_STATE_?????????? NS_DEFINE_EVENT_STATE_MACRO(48)
#define NS_EVENT_STATE_STYLEEDITOR_TRANSITIONING NS_DEFINE_EVENT_STATE_MACRO(37)
#define NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL NS_DEFINE_EVENT_STATE_MACRO(38)
// Content has focus and should show a ring.
#define NS_EVENT_STATE_FOCUSRING NS_DEFINE_EVENT_STATE_MACRO(39)
// Handler for click to play plugin
#define NS_EVENT_STATE_TYPE_CLICK_TO_PLAY NS_DEFINE_EVENT_STATE_MACRO(40)
// Handler for click to play plugin (vulnerable w/update)
#define NS_EVENT_STATE_VULNERABLE_UPDATABLE NS_DEFINE_EVENT_STATE_MACRO(41)
// Handler for click to play plugin (vulnerable w/no update)
#define NS_EVENT_STATE_VULNERABLE_NO_UPDATE NS_DEFINE_EVENT_STATE_MACRO(42)
// Element has focus-within.
#define NS_EVENT_STATE_FOCUS_WITHIN NS_DEFINE_EVENT_STATE_MACRO(49)
#define NS_EVENT_STATE_FOCUS_WITHIN NS_DEFINE_EVENT_STATE_MACRO(43)
// Element is ltr (for :dir pseudo-class)
#define NS_EVENT_STATE_LTR NS_DEFINE_EVENT_STATE_MACRO(44)
// Element is rtl (for :dir pseudo-class)
#define NS_EVENT_STATE_RTL NS_DEFINE_EVENT_STATE_MACRO(45)
// Event state that is used for values that need to be parsed but do nothing.
#define NS_EVENT_STATE_IGNORE NS_DEFINE_EVENT_STATE_MACRO(63)

Просмотреть файл

@ -113,8 +113,8 @@ GamepadManager::StopMonitoring()
mGamepads.Clear();
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
mVRChannelChild = gfx::VRManagerChild::Get();
mVRChannelChild->SendControllerListenerRemoved();
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
vm->SendControllerListenerRemoved();
#endif
}
@ -681,10 +681,11 @@ GamepadManager::VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
if (aControllerIdx >= VR_GAMEPAD_IDX_OFFSET) {
uint32_t index = aControllerIdx - VR_GAMEPAD_IDX_OFFSET;
mVRChannelChild->AddPromise(mPromiseID, promise);
mVRChannelChild->SendVibrateHaptic(index, aHapticIndex,
aIntensity, aDuration,
mPromiseID);
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
vm->AddPromise(mPromiseID, promise);
vm->SendVibrateHaptic(index, aHapticIndex,
aIntensity, aDuration,
mPromiseID);
} else {
for (const auto& channelChild: mChannelChildren) {
channelChild->AddPromise(mPromiseID, promise);
@ -705,7 +706,8 @@ GamepadManager::StopHaptics()
const uint32_t gamepadIndex = iter.UserData()->HashKey();
if (gamepadIndex >= VR_GAMEPAD_IDX_OFFSET) {
const uint32_t index = gamepadIndex - VR_GAMEPAD_IDX_OFFSET;
mVRChannelChild->SendStopVibrateHaptic(index);
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
vm->SendStopVibrateHaptic(index);
} else {
for (auto& channelChild : mChannelChildren) {
channelChild->SendStopVibrateHaptic(gamepadIndex);
@ -733,8 +735,8 @@ GamepadManager::ActorCreated(PBackgroundChild *aActor)
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
// Construct VRManagerChannel and ask adding the connected
// VR controllers to GamepadManager
mVRChannelChild = gfx::VRManagerChild::Get();
mVRChannelChild->SendControllerListenerAdded();
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
vm->SendControllerListenerAdded();
#endif
}

Просмотреть файл

@ -131,7 +131,6 @@ class GamepadManager final : public nsIObserver,
// will be destroyed during the IPDL shutdown chain, so we
// don't need to refcount it here.
nsTArray<GamepadEventChannelChild *> mChannelChildren;
gfx::VRManagerChild* mVRChannelChild;
private:

Просмотреть файл

@ -50,7 +50,7 @@ fails == bug917595-exif-rotated.jpg bug917595-exif-rotated.jpg
== bug1106522-1.html bug1106522-1.html
== bug1106522-2.html bug1106522-2.html
fails == href-attr-change-restyles.html href-attr-change-restyles.html
== href-attr-change-restyles.html href-attr-change-restyles.html
== figure.html figure.html
== pre-1.html pre-1.html
== table-border-1.html table-border-1.html

Просмотреть файл

@ -16,7 +16,7 @@ fails == passwd-3.html passwd-3.html
fails needs-focus == passwd-4.html passwd-4.html
fails == emptypasswd-1.html emptypasswd-1.html
fails == emptypasswd-2.html emptypasswd-2.html
fails == caret_on_positioned.html caret_on_positioned.html
== caret_on_positioned.html caret_on_positioned.html
fails == spellcheck-input-disabled.html spellcheck-input-disabled.html
fails == spellcheck-input-attr-before.html spellcheck-input-attr-before.html
fails == spellcheck-input-attr-before.html spellcheck-input-attr-before.html
@ -57,7 +57,7 @@ fails == spellcheck-textarea-attr-dynamic-override.html spellcheck-textarea-attr
fails == spellcheck-textarea-attr-dynamic-override-inherit.html spellcheck-textarea-attr-dynamic-override-inherit.html
fails == spellcheck-textarea-property-dynamic-override.html spellcheck-textarea-property-dynamic-override.html
fails == spellcheck-textarea-property-dynamic-override-inherit.html spellcheck-textarea-property-dynamic-override-inherit.html
fails needs-focus == caret_on_focus.html caret_on_focus.html
needs-focus == caret_on_focus.html caret_on_focus.html
fails needs-focus == caret_on_textarea_lastline.html caret_on_textarea_lastline.html
fails needs-focus == input-text-onfocus-reframe.html input-text-onfocus-reframe.html
fails needs-focus == input-text-notheme-onfocus-reframe.html input-text-notheme-onfocus-reframe.html
@ -89,18 +89,18 @@ fails == selection_visibility_after_reframe-2.html selection_visibility_after_re
fails == selection_visibility_after_reframe-3.html selection_visibility_after_reframe-3.html
== 672709.html 672709.html
fails == 338427-1.html 338427-1.html
fails == 674212-spellcheck.html 674212-spellcheck.html
fails == 338427-2.html 338427-2.html
== 674212-spellcheck.html 674212-spellcheck.html
== 338427-2.html 338427-2.html
fails == 338427-3.html 338427-3.html
fails == 462758-grabbers-resizers.html 462758-grabbers-resizers.html
== 462758-grabbers-resizers.html 462758-grabbers-resizers.html
fails == readwrite-non-editable.html readwrite-non-editable.html
fails == readwrite-editable.html readwrite-editable.html
fails == readonly-non-editable.html readonly-non-editable.html
fails == readonly-editable.html readonly-editable.html
fails == dynamic-overflow-change.html dynamic-overflow-change.html
fails == 694880-1.html 694880-1.html
fails == 694880-2.html 694880-2.html
fails == 694880-3.html 694880-3.html
== 694880-1.html 694880-1.html
== 694880-2.html 694880-2.html
== 694880-3.html 694880-3.html
== 388980-1.html 388980-1.html
fails needs-focus == spellcheck-superscript-1.html spellcheck-superscript-1.html
fails == spellcheck-superscript-2.html spellcheck-superscript-2.html
@ -132,6 +132,6 @@ needs-focus == spellcheck-contenteditable-focused-reframe.html spellcheck-conten
== spellcheck-contenteditable-property-dynamic-override.html spellcheck-contenteditable-property-dynamic-override.html
== spellcheck-contenteditable-property-dynamic-override-inherit.html spellcheck-contenteditable-property-dynamic-override-inherit.html
== 911201.html 911201.html
fails needs-focus == 969773.html 969773.html
needs-focus == 969773.html 969773.html
fails == 997805.html 997805.html
fails == 1088158.html 1088158.html

Просмотреть файл

@ -35,6 +35,9 @@ class gfxVarReceiver;
_(PDMWMFDisableD3D9Dlls, nsCString, nsCString()) \
_(DXInterop2Blocked, bool, false) \
_(UseWebRender, bool, false) \
_(UseWebRenderANGLE, bool, false) \
_(ScreenDepth, int32_t, 0) \
_(GREDirectory, nsCString, nsCString()) \
/* Add new entries above this line. */

Просмотреть файл

@ -79,4 +79,4 @@ to make sure that mozjs_sys also has its Cargo.lock file updated if needed, henc
the need to run the cargo update command in js/src as well. Hopefully this will
be resolved soon.
Latest Commit: 0794911f97cae92496fca992d7430da696fa24eb
Latest Commit: dafe3579e8dc886e6584116dc52a9362b543c169

Просмотреть файл

@ -11,6 +11,9 @@
#elif defined(MOZ_WIDGET_ANDROID)
#define GET_NATIVE_WINDOW_FROM_REAL_WIDGET(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_JAVA_SURFACE))
#define GET_NATIVE_WINDOW_FROM_COMPOSITOR_WIDGET(aWidget) (aWidget->AsAndroid()->GetEGLNativeWindow())
#elif defined(XP_WIN)
#define GET_NATIVE_WINDOW_FROM_REAL_WIDGET(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
#define GET_NATIVE_WINDOW_FROM_COMPOSITOR_WIDGET(aWidget) ((EGLNativeWindowType)aWidget->AsWindows()->GetHwnd())
#else
#define GET_NATIVE_WINDOW_FROM_REAL_WIDGET(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
#define GET_NATIVE_WINDOW_FROM_COMPOSITOR_WIDGET(aWidget) ((EGLNativeWindowType)aWidget->RealWidget()->GetNativeData(NS_NATIVE_WINDOW))
@ -27,6 +30,7 @@
#define GLES2_LIB2 "libGLESv2.so.2"
#elif defined(XP_WIN)
#include "mozilla/widget/WinCompositorWidget.h"
#include "nsIFile.h"
#define GLES2_LIB "libGLESv2.dll"
@ -51,6 +55,7 @@
#include "GLLibraryEGL.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/Preferences.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/layers/CompositorOptions.h"
#include "mozilla/widget/CompositorWidget.h"
#include "nsDebug.h"
@ -693,7 +698,7 @@ CreateConfig(EGLConfig* aConfig, int32_t depth)
static bool
CreateConfig(EGLConfig* aConfig)
{
int32_t depth = gfxPlatform::GetPlatform()->GetScreenDepth();
int32_t depth = gfxVars::ScreenDepth();
if (!CreateConfig(aConfig, depth)) {
#ifdef MOZ_WIDGET_ANDROID
// Bug 736005

Просмотреть файл

@ -24,6 +24,7 @@
#endif
#include "OGLShaderProgram.h"
#include "prenv.h"
#include "prsystem.h"
#include "GLContext.h"
#include "GLContextProvider.h"
#include "gfxPrefs.h"
@ -101,20 +102,14 @@ static PRLibrary* LoadApitraceLibrary()
static PRLibrary*
LoadLibraryForEGLOnWindows(const nsAString& filename)
{
nsCOMPtr<nsIFile> file;
nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(file));
if (NS_FAILED(rv))
return nullptr;
nsAutoCString path(gfx::gfxVars::GREDirectory());
path.Append(PR_GetDirectorySeparator());
path.Append(ToNewUTF8String(filename));
file->Append(filename);
PRLibrary* lib = nullptr;
rv = file->Load(&lib);
if (NS_FAILED(rv)) {
nsPrintfCString msg("Failed to load %s - Expect EGL initialization to fail",
NS_LossyConvertUTF16toASCII(filename).get());
NS_WARNING(msg.get());
}
return lib;
PRLibSpec lspec;
lspec.type = PR_LibSpec_Pathname;
lspec.value.pathname = path.get();
return PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_LOCAL);
}
#endif // XP_WIN
@ -241,6 +236,10 @@ GetAndInitDisplayForAccelANGLE(GLLibraryEGL& egl, nsACString* const out_failureI
{
EGLDisplay ret = 0;
if (wr::RenderThread::IsInRenderThread()) {
return GetAndInitDisplay(egl, LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE);
}
FeatureState& d3d11ANGLE = gfxConfig::GetFeature(Feature::D3D11_HW_ANGLE);
if (!gfxPrefs::WebGLANGLETryD3D11())

Просмотреть файл

@ -73,6 +73,7 @@ union GfxVarValue
gfxImageFormat;
IntSize;
nsCString;
int32_t;
};
struct GfxVarUpdate

Просмотреть файл

@ -2444,6 +2444,22 @@ LayerManager::DumpPacket(layerscope::LayersPacket* aPacket)
layer->set_parentptr(0);
}
void
LayerManager::TrackDisplayItemLayer(RefPtr<DisplayItemLayer> aLayer)
{
mDisplayItemLayers.AppendElement(aLayer);
}
void
LayerManager::ClearDisplayItemLayers()
{
for (uint32_t i = 0; i < mDisplayItemLayers.Length(); i++) {
mDisplayItemLayers[i]->EndTransaction();
}
mDisplayItemLayers.Clear();
}
/*static*/ bool
LayerManager::IsLogEnabled()
{

Просмотреть файл

@ -462,6 +462,15 @@ public:
static already_AddRefed<ImageContainer> CreateImageContainer(ImageContainer::Mode flag
= ImageContainer::SYNCHRONOUS);
/**
* Since the lifetimes of display items and display item layers are different,
* calling this tells the layer manager that the display item layer is valid for
* only one transaction. Users should call ClearDisplayItemLayers() to remove
* references to the dead display item at the end of a transaction.
*/
virtual void TrackDisplayItemLayer(RefPtr<DisplayItemLayer> aLayer);
virtual void ClearDisplayItemLayers();
/**
* Type of layer manager his is. This is to be used sparsely in order to
* avoid a lot of Layers backend specific code. It should be used only when
@ -775,6 +784,14 @@ public:
void ClearPendingScrollInfoUpdate();
private:
std::map<FrameMetrics::ViewID,ScrollUpdateInfo> mPendingScrollUpdates;
// Display items are only valid during this transaction.
// At the end of the transaction, we have to go and clear out
// DisplayItemLayer's and null their display item. See comment
// above DisplayItemLayer declaration.
// Since layers are ref counted, we also have to stop holding
// a reference to the display item layer as well.
nsTArray<RefPtr<DisplayItemLayer>> mDisplayItemLayers;
};
/**

Просмотреть файл

@ -76,7 +76,6 @@ BasicLayerManager::CreateDisplayItemLayer()
{
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
RefPtr<DisplayItemLayer> layer = new BasicDisplayItemLayer(this);
mDisplayItemLayers.AppendElement(layer);
return layer.forget();
}

Просмотреть файл

@ -546,18 +546,6 @@ BasicLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
mInTransaction = false;
EndTransactionInternal(aCallback, aCallbackData, aFlags);
ClearDisplayItemLayers();
}
void
BasicLayerManager::ClearDisplayItemLayers()
{
for (uint32_t i = 0; i < mDisplayItemLayers.Length(); i++) {
mDisplayItemLayers[i]->EndTransaction();
}
mDisplayItemLayers.Clear();
}
void
@ -672,6 +660,8 @@ BasicLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
NS_ASSERTION(!aCallback || !mTransactionIncomplete,
"If callback is not null, transaction must be complete");
ClearDisplayItemLayers();
// XXX - We should probably assert here that for an incomplete transaction
// out target is the default target.

Просмотреть файл

@ -213,14 +213,6 @@ protected:
bool mUsingDefaultTarget;
bool mTransactionIncomplete;
bool mCompositorMightResample;
private:
// Display items are only valid during this transaction.
// At the end of the transaction, we have to go and clear out
// DisplayItemLayer's and null their display item. See comment
// above DisplayItemLayer declaration.
void ClearDisplayItemLayers();
nsTArray<RefPtr<DisplayItemLayer>> mDisplayItemLayers;
};
} // namespace layers

Просмотреть файл

@ -314,6 +314,8 @@ WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
MakeSnapshotIfRequired(size);
ClearDisplayItemLayers();
// this may result in Layers being deleted, which results in
// PLayer::Send__delete__() and DeallocShmem()
mKeepAlive.Clear();

Просмотреть файл

@ -621,6 +621,16 @@ gfxPlatform::Init()
gfxVars::SetPDMWMFDisableD3D11Dlls(Preferences::GetCString("media.wmf.disable-d3d11-for-dlls"));
gfxVars::SetPDMWMFDisableD3D9Dlls(Preferences::GetCString("media.wmf.disable-d3d9-for-dlls"));
}
nsCOMPtr<nsIFile> file;
nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(file));
if (NS_FAILED(rv)) {
gfxVars::SetGREDirectory(nsCString());
} else {
nsAutoCString nativePath;
file->GetNativePath(nativePath);
gfxVars::SetGREDirectory(nsCString(nativePath));
}
}
// Drop a note in the crash report if we end up forcing an option that could
@ -1254,6 +1264,9 @@ gfxPlatform::PopulateScreenInfo()
}
screen->GetColorDepth(&mScreenDepth);
if (XRE_IsParentProcess()) {
gfxVars::SetScreenDepth(mScreenDepth);
}
int left, top;
screen->GetRect(&left, &top, &mScreenSize.width, &mScreenSize.height);
@ -2328,6 +2341,19 @@ gfxPlatform::InitWebRenderConfig()
NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_WEBRENDER"));
#endif
#ifdef XP_WIN
if (Preferences::GetBool("gfx.webrender.force-angle", false)) {
if (!gfxConfig::IsEnabled(Feature::D3D11_HW_ANGLE)) {
featureWebRender.ForceDisable(
FeatureStatus::Unavailable,
"ANGLE is disabled",
NS_LITERAL_CSTRING("FEATURE_FAILURE_ANGLE_DISABLED"));
} else {
gfxVars::SetUseWebRenderANGLE(gfxConfig::IsEnabled(Feature::WEBRENDER));
}
}
#endif
// gfxFeature is not usable in the GPU process, so we use gfxVars to transmit this feature
if (gfxConfig::IsEnabled(Feature::WEBRENDER)) {
gfxVars::SetUseWebRender(true);

Просмотреть файл

@ -485,6 +485,7 @@ private:
DECL_GFX_PREF(Live, "layers.acceleration.draw-fps.print-histogram", FPSPrintHistogram, bool, false);
DECL_GFX_PREF(Live, "layers.acceleration.draw-fps.write-to-file", WriteFPSToFile, bool, false);
DECL_GFX_PREF(Once, "layers.acceleration.force-enabled", LayersAccelerationForceEnabledDoNotUseDirectly, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.background-color", LayersAllowBackgroundColorLayers, bool, false);
DECL_OVERRIDE_PREF(Live, "layers.advanced.background-image", LayersAllowBackgroundImage, false);
DECL_OVERRIDE_PREF(Live, "layers.advanced.border-layers", LayersAllowBorderLayers, false);
DECL_OVERRIDE_PREF(Live, "layers.advanced.boxshadow-inset-layers", LayersAllowInsetBoxShadow, gfxPrefs::OverrideBase_WebRender());

Просмотреть файл

@ -29,6 +29,7 @@
#include "gfxVROculus.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/dom/GamepadEventTypes.h"
#include "mozilla/dom/GamepadBinding.h"
@ -145,7 +146,7 @@ enum class OculusRightControllerButtonType : uint16_t {
static const uint32_t kNumOculusButton = static_cast<uint32_t>
(OculusLeftControllerButtonType::
NumButtonType);
static const uint32_t kNumOculusHaptcs = 0; // TODO: Bug 1305892
static const uint32_t kNumOculusHaptcs = 1;
static bool
@ -886,6 +887,8 @@ VRControllerOculus::VRControllerOculus(dom::GamepadHand aHand)
: VRControllerHost(VRDeviceType::Oculus)
, mIndexTrigger(0.0f)
, mHandTrigger(0.0f)
, mVibrateThread(nullptr)
, mIsVibrateStopped(false)
{
MOZ_COUNT_CTOR_INHERITED(VRControllerOculus, VRControllerHost);
@ -957,6 +960,144 @@ VRControllerOculus::~VRControllerOculus()
MOZ_COUNT_DTOR_INHERITED(VRControllerOculus, VRControllerHost);
}
void
VRControllerOculus::UpdateVibrateHaptic(ovrSession aSession,
uint32_t aHapticIndex,
double aIntensity,
double aDuration,
uint64_t aVibrateIndex,
uint32_t aPromiseID)
{
// UpdateVibrateHaptic() only can be called by mVibrateThread
MOZ_ASSERT(mVibrateThread == NS_GetCurrentThread());
// It has been interrupted by loss focus.
if (mIsVibrateStopped) {
VibrateHapticComplete(aSession, aPromiseID, true);
return;
}
// Avoid the previous vibrate event to override the new one.
if (mVibrateIndex != aVibrateIndex) {
VibrateHapticComplete(aSession, aPromiseID, false);
return;
}
const double duration = (aIntensity == 0) ? 0 : aDuration;
// Vibration amplitude in the [0.0, 1.0] range.
const float amplitude = aIntensity > 1.0 ? 1.0 : aIntensity;
// Vibration is enabled by specifying the frequency.
// Specifying 0.0f will disable the vibration, 0.5f will vibrate at 160Hz,
// and 1.0f will vibrate at 320Hz.
const float frequency = (duration > 0) ? 1.0f : 0.0f;
ovrControllerType hand;
switch (GetHand()) {
case GamepadHand::Left:
hand = ovrControllerType::ovrControllerType_LTouch;
break;
case GamepadHand::Right:
hand = ovrControllerType::ovrControllerType_RTouch;
break;
default:
MOZ_ASSERT(false);
break;
}
// Oculus Touch only can get the response from ovr_SetControllerVibration()
// at the presenting mode.
ovrResult result = ovr_SetControllerVibration(aSession, hand, frequency,
(frequency == 0.0f) ? 0.0f : amplitude);
if (result != ovrSuccess) {
printf_stderr("%s hand ovr_SetControllerVibration skipped.\n",
GamepadHandValues::strings[uint32_t(GetHand())].value);
}
// In Oculus dev doc, it mentions vibration lasts for a maximum of 2.5 seconds
// at ovr_SetControllerVibration(), but we found 2.450 sec is more close to the
// real looping use case.
const double kVibrateRate = 2450.0;
const double remainingTime = (duration > kVibrateRate)
? (duration - kVibrateRate) : duration;
if (remainingTime) {
MOZ_ASSERT(mVibrateThread);
RefPtr<Runnable> runnable =
NewRunnableMethod<ovrSession, uint32_t, double, double, uint64_t, uint32_t>
(this, &VRControllerOculus::UpdateVibrateHaptic, aSession,
aHapticIndex, aIntensity, (duration > kVibrateRate) ? remainingTime : 0, aVibrateIndex, aPromiseID);
NS_DelayedDispatchToCurrentThread(runnable.forget(),
(duration > kVibrateRate) ? kVibrateRate : remainingTime);
} else {
VibrateHapticComplete(aSession, aPromiseID, true);
}
}
void
VRControllerOculus::VibrateHapticComplete(ovrSession aSession, uint32_t aPromiseID,
bool aStop)
{
if (aStop) {
ovrControllerType hand;
switch (GetHand()) {
case GamepadHand::Left:
hand = ovrControllerType::ovrControllerType_LTouch;
break;
case GamepadHand::Right:
hand = ovrControllerType::ovrControllerType_RTouch;
break;
default:
MOZ_ASSERT(false);
break;
}
ovrResult result = ovr_SetControllerVibration(aSession, hand, 0.0f, 0.0f);
if (result != ovrSuccess) {
printf_stderr("%s Haptics skipped.\n",
GamepadHandValues::strings[uint32_t(GetHand())].value);
}
}
VRManager *vm = VRManager::Get();
MOZ_ASSERT(vm);
CompositorThreadHolder::Loop()->PostTask(NewRunnableMethod<uint32_t>
(vm, &VRManager::NotifyVibrateHapticCompleted, aPromiseID));
}
void
VRControllerOculus::VibrateHaptic(ovrSession aSession,
uint32_t aHapticIndex,
double aIntensity,
double aDuration,
uint32_t aPromiseID)
{
// Spinning up the haptics thread at the first haptics call.
if (!mVibrateThread) {
nsresult rv = NS_NewThread(getter_AddRefs(mVibrateThread));
MOZ_ASSERT(mVibrateThread);
if (NS_FAILED(rv)) {
MOZ_ASSERT(false, "Failed to create async thread.");
}
}
++mVibrateIndex;
mIsVibrateStopped = false;
RefPtr<Runnable> runnable =
NewRunnableMethod<ovrSession, uint32_t, double, double, uint64_t, uint32_t>
(this, &VRControllerOculus::UpdateVibrateHaptic, aSession,
aHapticIndex, aIntensity, aDuration, mVibrateIndex, aPromiseID);
mVibrateThread->Dispatch(runnable.forget(), NS_DISPATCH_NORMAL);
}
void
VRControllerOculus::StopVibrateHaptic()
{
mIsVibrateStopped = true;
}
/*static*/ already_AddRefed<VRSystemManagerOculus>
VRSystemManagerOculus::Create()
{
@ -1262,12 +1403,31 @@ VRSystemManagerOculus::VibrateHaptic(uint32_t aControllerIdx,
double aDuration,
uint32_t aPromiseID)
{
// TODO: Bug 1305892
// mSession is available after VRDisplay is created
// at GetHMDs().
if (!mSession) {
return;
}
RefPtr<impl::VRControllerOculus> controller = mOculusController[aControllerIdx];
MOZ_ASSERT(controller);
controller->VibrateHaptic(mSession, aHapticIndex, aIntensity, aDuration, aPromiseID);
}
void
VRSystemManagerOculus::StopVibrateHaptic(uint32_t aControllerIdx)
{
// mSession is available after VRDisplay is created
// at GetHMDs().
if (!mSession) {
return;
}
RefPtr<impl::VRControllerOculus> controller = mOculusController[aControllerIdx];
MOZ_ASSERT(controller);
controller->StopVibrateHaptic();
}
void

Просмотреть файл

@ -103,15 +103,31 @@ public:
void SetIndexTrigger(float aValue);
float GetHandTrigger();
void SetHandTrigger(float aValue);
void VibrateHaptic(ovrSession aSession,
uint32_t aHapticIndex,
double aIntensity,
double aDuration,
uint32_t aPromiseID);
void StopVibrateHaptic();
protected:
virtual ~VRControllerOculus();
private:
void UpdateVibrateHaptic(ovrSession aSession,
uint32_t aHapticIndex,
double aIntensity,
double aDuration,
uint64_t aVibrateIndex,
uint32_t aPromiseID);
void VibrateHapticComplete(ovrSession aSession, uint32_t aPromiseID, bool aStop);
float mAxisMove[static_cast<uint32_t>(
OculusControllerAxisType::NumVRControllerAxisType)];
float mIndexTrigger;
float mHandTrigger;
nsCOMPtr<nsIThread> mVibrateThread;
Atomic<bool> mIsVibrateStopped;
};
} // namespace impl

Просмотреть файл

@ -462,11 +462,11 @@ VRControllerOpenVR::UpdateVibrateHaptic(vr::IVRSystem* aVRSystem,
return;
}
double duration = (aIntensity == 0) ? 0 : aDuration;
const double duration = (aIntensity == 0) ? 0 : aDuration;
// We expect OpenVR to vibrate for 5 ms, but we found it only response the
// commend ~ 3.9 ms. For duration time longer than 3.9 ms, we separate them
// to a loop of 3.9 ms for make users feel that is a continuous events.
uint32_t microSec = (duration < 3.9 ? duration : 3.9) * 1000 * aIntensity;
const uint32_t microSec = (duration < 3.9 ? duration : 3.9) * 1000 * aIntensity;
aVRSystem->TriggerHapticPulse(GetTrackedIndex(),
aHapticIndex, microSec);

Просмотреть файл

@ -1,15 +1,16 @@
[package]
name = "webrender"
version = "0.25.0"
version = "0.26.0"
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
license = "MPL-2.0"
repository = "https://github.com/servo/webrender"
build = "build.rs"
[features]
default = ["freetype-lib"]
default = ["freetype-lib", "webgl"]
freetype-lib = ["freetype/servo-freetype-sys"]
profiler = ["thread_profiler/thread_profiler"]
webgl = ["offscreen_gl_context", "webrender_traits/webgl"]
[dependencies]
app_units = "0.4"
@ -22,7 +23,7 @@ gleam = "0.4.1"
lazy_static = "0.2"
log = "0.3"
num-traits = "0.1.32"
offscreen_gl_context = {version = "0.8.0", features = ["serde", "osmesa"]}
offscreen_gl_context = {version = "0.8.0", features = ["serde", "osmesa"], optional = true}
time = "0.1"
threadpool = "1.3.2"
webrender_traits = {path = "../webrender_traits"}

Просмотреть файл

@ -15,17 +15,17 @@ float gauss(float x, float sigma) {
}
void main(void) {
vec4 cache_sample = texture(sCache, vUv);
vec4 cache_sample = texture(sCacheRGBA8, vUv);
vec4 color = vec4(cache_sample.rgb, 1.0) * (cache_sample.a * gauss(0.0, vSigma));
for (int i=1 ; i < vBlurRadius ; ++i) {
vec2 offset = vec2(float(i)) * vOffsetScale;
vec2 st0 = clamp(vUv.xy + offset, vUvRect.xy, vUvRect.zw);
vec4 color0 = texture(sCache, vec3(st0, vUv.z));
vec4 color0 = texture(sCacheRGBA8, vec3(st0, vUv.z));
vec2 st1 = clamp(vUv.xy - offset, vUvRect.xy, vUvRect.zw);
vec4 color1 = texture(sCache, vec3(st1, vUv.z));
vec4 color1 = texture(sCacheRGBA8, vec3(st1, vUv.z));
// Alpha must be premultiplied in order to properly blur the alpha channel.
float weight = gauss(float(i), vSigma);
@ -36,5 +36,5 @@ void main(void) {
// Unpremultiply the alpha.
color.rgb /= color.a;
oFragColor = color;
oFragColor = dither(color);
}

Просмотреть файл

@ -40,7 +40,7 @@ void main(void) {
local_rect.xy + local_rect.zw,
aPosition.xy);
vec2 texture_size = vec2(textureSize(sCache, 0).xy);
vec2 texture_size = vec2(textureSize(sCacheRGBA8, 0).xy);
vUv.z = src_task.data1.x;
vBlurRadius = int(task.data1.y);
vSigma = task.data1.y * 0.5;

Просмотреть файл

@ -144,5 +144,5 @@ void main(void) {
float value = color(pos, p0Rect, p1Rect, radii, sigma);
value = max(value, 0.0);
oFragColor = vec4(1.0, 1.0, 1.0, vInverted == 1.0 ? 1.0 - value : value);
oFragColor = dither(vec4(1.0, 1.0, 1.0, vInverted == 1.0 ? 1.0 - value : value));
}

Просмотреть файл

@ -33,7 +33,8 @@
#define EXTEND_MODE_CLAMP 0
#define EXTEND_MODE_REPEAT 1
uniform sampler2DArray sCache;
uniform sampler2DArray sCacheA8;
uniform sampler2DArray sCacheRGBA8;
flat varying vec4 vClipMaskUvBounds;
varying vec3 vClipMaskUv;
@ -707,7 +708,7 @@ BoxShadow fetch_boxshadow(int index) {
}
void write_clip(vec2 global_pos, ClipArea area) {
vec2 texture_size = vec2(textureSize(sCache, 0).xy);
vec2 texture_size = vec2(textureSize(sCacheA8, 0).xy);
vec2 uv = global_pos + area.task_bounds.xy - area.screen_origin_target_index.xy;
vClipMaskUvBounds = area.task_bounds / texture_size.xyxy;
vClipMaskUv = vec3(uv / texture_size, area.screen_origin_target_index.z);
@ -755,6 +756,15 @@ float do_clip() {
vec4(vClipMaskUv.xy, vClipMaskUvBounds.zw));
// check for the dummy bounds, which are given to the opaque objects
return vClipMaskUvBounds.xy == vClipMaskUvBounds.zw ? 1.0:
all(inside) ? textureLod(sCache, vClipMaskUv, 0.0).r : 0.0;
all(inside) ? textureLod(sCacheA8, vClipMaskUv, 0.0).r : 0.0;
}
vec4 dither(vec4 color) {
const int matrix_mask = 7;
ivec2 pos = ivec2(gl_FragCoord.xy) & ivec2(matrix_mask);
float noise_factor = 4.0 / 255.0;
float noise = texelFetch(sDither, pos, 0).r * noise_factor;
return color + vec4(noise, noise, noise, 0);
}
#endif //WR_FRAGMENT_SHADER

Просмотреть файл

@ -11,11 +11,10 @@ void main(void) {
// gradient color entries (texture width / 2).
float x = mix(clamp(vOffset, 0.0, 1.0), fract(vOffset), vGradientRepeat) * 0.5 * texture_size.x;
// Start at the center of first color in the nearest 2-color entry, then offset with the
// fractional remainder to interpolate between the colors. Rely on texture clamping when
// outside of valid range.
x = 2.0 * floor(x) + 0.5 + fract(x);
// Normalize the texture coordates so we can use texture() for bilinear filtering.
oFragColor = texture(sGradients, vec2(x, vGradientIndex) / texture_size);
// Use linear filtering to mix in the low bits (vGradientIndex + 1) with the high
// bits (vGradientIndex)
float y = vGradientIndex * 2.0 + 0.5 + 1.0 / 256.0;
oFragColor = dither(texture(sGradients, vec2(x, y) / texture_size));
}

Просмотреть файл

@ -27,7 +27,7 @@ void main(void) {
vOffset = dot(vi.local_pos - start_point, dir) / dot(dir, dir);
// V coordinate of gradient row in lookup texture.
vGradientIndex = float(prim.sub_index) + 0.5;
vGradientIndex = float(prim.sub_index);
// Whether to repeat the gradient instead of clamping.
vGradientRepeat = float(int(gradient.extend_mode.x) == EXTEND_MODE_REPEAT);

Просмотреть файл

@ -99,7 +99,7 @@ vec4 Opacity(vec4 Cs, float amount) {
}
void main(void) {
vec4 Cs = texture(sCache, vUv);
vec4 Cs = texture(sCacheRGBA8, vUv);
if (Cs.a == 0.0) {
discard;

Просмотреть файл

@ -16,7 +16,7 @@ void main(void) {
dest_origin + src_task.size,
aPosition.xy);
vec2 texture_size = vec2(textureSize(sCache, 0));
vec2 texture_size = vec2(textureSize(sCacheRGBA8, 0));
vec2 st0 = src_task.render_target_origin / texture_size;
vec2 st1 = (src_task.render_target_origin + src_task.size) / texture_size;
vUv = vec3(mix(st0, st1, aPosition.xy), src_task.render_target_layer_index);

Просмотреть файл

@ -366,10 +366,24 @@ void draw_mixed_border(float distanceFromMixLine, float distanceFromMiddle, vec2
float pixelsPerFragment = length(fwidth(localPos.xy));
vec4 color = get_fragment_color(distanceFromMixLine, pixelsPerFragment);
float distance = distance(vRefPoint, localPos) - vRadii.z;
float length = vRadii.x - vRadii.z;
if (distanceFromMiddle < 0.0) {
distance = length - distance;
if (vRadii.x > 0.0) {
float distance = distance(vRefPoint, localPos) - vRadii.z;
float length = vRadii.x - vRadii.z;
if (distanceFromMiddle < 0.0) {
distance = length - distance;
}
oFragColor = 0.0 <= distance && distance <= length ?
draw_mixed_edge(distance, length, color, brightness_mod) : vec4(0.0, 0.0, 0.0, 0.0);
break;
}
bool is_vertical = (vBorderPart == PST_TOP_LEFT) ? distanceFromMixLine < 0.0 :
distanceFromMixLine >= 0.0;
float distance = is_vertical ? abs(localPos.x - vRefPoint.x) : abs(localPos.y - vRefPoint.y);
float length = is_vertical ? abs(vPieceRect.z) : abs(vPieceRect.w);
if (distanceFromMiddle > 0.0) {
distance = length - distance;
}
oFragColor = 0.0 <= distance && distance <= length ?

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше