merge inbound to central. r=merge a=merge
This commit is contained in:
@@ -15,3 +15,4 @@ skip-if = buildapp == 'mulet'
|
||||
[test_canvas.html]
|
||||
[test_shadowroot.html]
|
||||
skip-if = stylo # bug 1293844
|
||||
support-files = test_shadowroot_subframe.html
|
||||
|
||||
@@ -8,31 +8,6 @@
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest() {
|
||||
testElm("component", {
|
||||
role: ROLE_GROUPING,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_PUSHBUTTON,
|
||||
},
|
||||
{
|
||||
role: ROLE_LINK,
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -46,13 +21,19 @@
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div role="group" id="component"></div>
|
||||
<script>
|
||||
var component = document.getElementById("component");
|
||||
var shadow = component.createShadowRoot();
|
||||
|
||||
shadow.innerHTML = "<button>Hello</button>" +
|
||||
'<a href="#"> World</a>';
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["dom.webcomponents.enabled", true]
|
||||
]
|
||||
}, function() {
|
||||
// This test loads in an iframe, to ensure that the element instance is
|
||||
// loaded with the correct value of the preference.
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.src = "test_shadowroot_subframe.html";
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
43
accessible/tests/mochitest/elm/test_shadowroot_subframe.html
Normal file
43
accessible/tests/mochitest/elm/test_shadowroot_subframe.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>ShadowRoot tests</title>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="application/javascript" src="../common.js"></script>
|
||||
<script type="application/javascript" src="../role.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
let SimpleTest = window.parent.SimpleTest;
|
||||
let ok = window.parent.ok;
|
||||
let is = window.parent.is;
|
||||
|
||||
function doTest() {
|
||||
testElm("component", {
|
||||
role: ROLE_GROUPING,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_PUSHBUTTON,
|
||||
},
|
||||
{
|
||||
role: ROLE_LINK,
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div role="group" id="component"></div>
|
||||
<script>
|
||||
var component = document.getElementById("component");
|
||||
var shadow = component.attachShadow({mode: "open"});
|
||||
|
||||
shadow.innerHTML = "<button>Hello</button>" +
|
||||
'<a href="#"> World</a>';
|
||||
</script>
|
||||
</body>
|
||||
@@ -9,6 +9,7 @@ skip-if = (os == "android" || appname == "b2g")
|
||||
[test_general.html]
|
||||
[test_menu.xul]
|
||||
[test_shadowroot.html]
|
||||
support-files = test_shadowroot_subframe.html
|
||||
[test_zoom.html]
|
||||
[test_zoom_text.html]
|
||||
[test_zoom_tree.xul]
|
||||
|
||||
@@ -8,26 +8,6 @@
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../layout.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest() {
|
||||
var componentAcc = getAccessible("component1");
|
||||
testChildAtPoint(componentAcc, 1, 1, componentAcc.firstChild,
|
||||
componentAcc.firstChild);
|
||||
|
||||
componentAcc = getAccessible("component2");
|
||||
testChildAtPoint(componentAcc, 1, 1, componentAcc.firstChild,
|
||||
componentAcc.firstChild);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -41,31 +21,19 @@
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div role="group" class="components" id="component1" style="display: inline-block;">
|
||||
<!--
|
||||
<div role="button" id="component-child"
|
||||
style="width: 100px; height: 100px; background-color: pink;">
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
<div role="group" class="components" id="component2" style="display: inline-block;">
|
||||
<!--
|
||||
<button>Hello world</button>
|
||||
-->
|
||||
</div>
|
||||
<script>
|
||||
// This routine adds the comment children of each 'component' to its
|
||||
// shadow root.
|
||||
var components = document.querySelectorAll(".components");
|
||||
for (var i = 0; i < components.length; i++) {
|
||||
var component = components[i];
|
||||
var shadow = component.createShadowRoot();
|
||||
for (var child = component.firstChild; child; child = child.nextSibling) {
|
||||
if (child.nodeType === 8)
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
shadow.innerHTML = child.data;
|
||||
}
|
||||
}
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["dom.webcomponents.enabled", true]
|
||||
]
|
||||
}, function() {
|
||||
// This test loads in an iframe, to ensure that the element instance is
|
||||
// loaded with the correct value of the preference.
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.src = "test_shadowroot_subframe.html";
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>ShadowRoot hit tests</title>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="application/javascript" src="../common.js"></script>
|
||||
<script type="application/javascript" src="../layout.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
let SimpleTest = window.parent.SimpleTest;
|
||||
let ok = window.parent.ok;
|
||||
let is = window.parent.is;
|
||||
|
||||
function doTest() {
|
||||
var componentAcc = getAccessible("component1");
|
||||
testChildAtPoint(componentAcc, 1, 1, componentAcc.firstChild,
|
||||
componentAcc.firstChild);
|
||||
|
||||
componentAcc = getAccessible("component2");
|
||||
testChildAtPoint(componentAcc, 1, 1, componentAcc.firstChild,
|
||||
componentAcc.firstChild);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div role="group" class="components" id="component1" style="display: inline-block;">
|
||||
<!--
|
||||
<div role="button" id="component-child"
|
||||
style="width: 100px; height: 100px; background-color: pink;">
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
<div role="group" class="components" id="component2" style="display: inline-block;">
|
||||
<!--
|
||||
<button>Hello world</button>
|
||||
-->
|
||||
</div>
|
||||
<script>
|
||||
// This routine adds the comment children of each 'component' to its
|
||||
// shadow root.
|
||||
var components = document.querySelectorAll(".components");
|
||||
for (var i = 0; i < components.length; i++) {
|
||||
var component = components[i];
|
||||
var shadow = component.attachShadow({mode: "open"});
|
||||
for (var child = component.firstChild; child; child = child.nextSibling) {
|
||||
if (child.nodeType === 8)
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
shadow.innerHTML = child.data;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -15,6 +15,7 @@ support-files =
|
||||
[test_bug1175913.html]
|
||||
[test_bug1189277.html]
|
||||
[test_bug1276857.html]
|
||||
support-files = test_bug1276857_subframe.html
|
||||
[test_canvas.html]
|
||||
[test_colorpicker.xul]
|
||||
[test_contextmenu.xul]
|
||||
|
||||
@@ -18,9 +18,14 @@
|
||||
|
||||
<script type="application/javascript">
|
||||
function runTest() {
|
||||
let iframe = document.getElementById("iframe");
|
||||
|
||||
// children change will recreate the table
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, getNode("c1"))
|
||||
new invokerChecker(EVENT_REORDER, () => {
|
||||
let doc = getNode("iframe").contentDocument;
|
||||
return doc && doc.getElementById("c1");
|
||||
})
|
||||
];
|
||||
|
||||
this.invoke = function runTest_invoke() {
|
||||
@@ -33,9 +38,9 @@
|
||||
{ TEXT_LEAF: [] } // More text
|
||||
]
|
||||
};
|
||||
testAccessibleTree("c1", tree);
|
||||
testAccessibleTree(iframe.contentDocument.getElementById("c1"), tree);
|
||||
|
||||
getNode("c1_t").querySelector("span").remove();
|
||||
iframe.contentDocument.getElementById("c1_t").querySelector("span").remove();
|
||||
};
|
||||
|
||||
this.finalCheck = function runTest_finalCheck() {
|
||||
@@ -45,7 +50,7 @@
|
||||
{ TEXT_LEAF: [] } // More text
|
||||
]
|
||||
};
|
||||
testAccessibleTree("c1", tree);
|
||||
testAccessibleTree(iframe.contentDocument.getElementById("c1"), tree);
|
||||
};
|
||||
|
||||
this.getID = function runTest_getID() {
|
||||
@@ -56,7 +61,10 @@
|
||||
function runShadowTest() {
|
||||
// children change will recreate the table
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, "c2")
|
||||
new invokerChecker(EVENT_REORDER, () => {
|
||||
let doc = getNode("iframe").contentDocument;
|
||||
return doc && doc.getElementById("c2");
|
||||
})
|
||||
];
|
||||
|
||||
this.invoke = function runShadowTest_invoke() {
|
||||
@@ -69,9 +77,10 @@
|
||||
{ TEXT_LEAF: [] } // More text
|
||||
]
|
||||
};
|
||||
testAccessibleTree("c2", tree);
|
||||
testAccessibleTree(iframe.contentDocument.getElementById("c2"), tree);
|
||||
|
||||
gShadowRoot.firstElementChild.querySelector("span").remove();
|
||||
var shadowRoot = iframe.contentDocument.getElementById("c2_c").shadowRoot;
|
||||
shadowRoot.firstElementChild.querySelector("span").remove();
|
||||
};
|
||||
|
||||
this.finalCheck = function runShadowTest_finalCheck() {
|
||||
@@ -81,7 +90,7 @@
|
||||
{ TEXT_LEAF: [] } // More text
|
||||
]
|
||||
};
|
||||
testAccessibleTree("c2", tree);
|
||||
testAccessibleTree(iframe.contentDocument.getElementById("c2"), tree);
|
||||
};
|
||||
|
||||
this.getID = function runShadowTest_getID() {
|
||||
@@ -101,39 +110,22 @@
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["dom.webcomponents.enabled", true]
|
||||
]
|
||||
}, function() {
|
||||
// This test loads in an iframe, to ensure that the element instance is
|
||||
// loaded with the correct value of the preference.
|
||||
let iframe = document.createElement("iframe");
|
||||
iframe.id = "iframe";
|
||||
iframe.src = "test_bug1276857_subframe.html";
|
||||
addA11yLoadEvent(doTest, iframe.contentWindow);
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="c1">
|
||||
<div id="c1_t" style="display: table" role="presentation">
|
||||
Some text
|
||||
<span style="display: table-cell">something with accessibles goes here</span>
|
||||
More text
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template id="tmpl">
|
||||
<div style="display: table" role="presentation">
|
||||
Some text
|
||||
<span style="display: table-cell">something with accessibles goes here</span>
|
||||
More text
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div id="c2"><div id="c2_c" role="presentation"></div></div>
|
||||
|
||||
<script>
|
||||
var gShadowRoot = document.getElementById("c2_c").createShadowRoot();
|
||||
var tmpl = document.getElementById("tmpl");
|
||||
gShadowRoot.appendChild(document.importNode(tmpl.content, true));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>DOM mutations test</title>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="application/javascript" src="../role.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="c1">
|
||||
<div id="c1_t" style="display: table" role="presentation">
|
||||
Some text
|
||||
<span style="display: table-cell">something with accessibles goes here</span>
|
||||
More text
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template id="tmpl">
|
||||
<div style="display: table" role="presentation">
|
||||
Some text
|
||||
<span style="display: table-cell">something with accessibles goes here</span>
|
||||
More text
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div id="c2"><div id="c2_c" role="presentation"></div></div>
|
||||
|
||||
<script>
|
||||
var gShadowRoot = document.getElementById("c2_c").attachShadow({mode: "open"});
|
||||
var tmpl = document.getElementById("tmpl");
|
||||
gShadowRoot.appendChild(document.importNode(tmpl.content, true));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -523,8 +523,6 @@ pref("general.warnOnAboutConfig", false);
|
||||
// applications, but without it there isn't a really good way to prevent chrome
|
||||
// spoofing, see bug 337344
|
||||
pref("dom.disable_window_open_feature.location", true);
|
||||
// prevent JS from setting status messages
|
||||
pref("dom.disable_window_status_change", true);
|
||||
// allow JS to move and resize existing windows
|
||||
pref("dom.disable_window_move_resize", false);
|
||||
// prevent JS from monkeying with window focus, etc
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
This is the PDF.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 2.0.244
|
||||
Current extension version is: 2.0.250
|
||||
|
||||
Taken from upstream commit: 5bf4fb97
|
||||
Taken from upstream commit: 6b2ed504
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
exports["pdfjs-dist/build/pdf"] = factory();
|
||||
else
|
||||
root["pdfjs-dist/build/pdf"] = root.pdfjsDistBuildPdf = factory();
|
||||
})(this, function() {
|
||||
})(typeof self !== 'undefined' ? self : this, function() {
|
||||
return /******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
@@ -1936,7 +1936,7 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
|
||||
if (worker.destroyed) {
|
||||
return Promise.reject(new Error('Worker was destroyed'));
|
||||
}
|
||||
let apiVersion = '2.0.244';
|
||||
let apiVersion = '2.0.250';
|
||||
source.disableRange = (0, _dom_utils.getDefaultSetting)('disableRange');
|
||||
source.disableAutoFetch = (0, _dom_utils.getDefaultSetting)('disableAutoFetch');
|
||||
source.disableStream = (0, _dom_utils.getDefaultSetting)('disableStream');
|
||||
@@ -3233,8 +3233,8 @@ var InternalRenderTask = function InternalRenderTaskClosure() {
|
||||
}();
|
||||
var version, build;
|
||||
{
|
||||
exports.version = version = '2.0.244';
|
||||
exports.build = build = '5bf4fb97';
|
||||
exports.version = version = '2.0.250';
|
||||
exports.build = build = '6b2ed504';
|
||||
}
|
||||
exports.getDocument = getDocument;
|
||||
exports.LoopbackPort = LoopbackPort;
|
||||
@@ -4621,8 +4621,8 @@ exports.SVGGraphics = SVGGraphics;
|
||||
"use strict";
|
||||
|
||||
|
||||
var pdfjsVersion = '2.0.244';
|
||||
var pdfjsBuild = '5bf4fb97';
|
||||
var pdfjsVersion = '2.0.250';
|
||||
var pdfjsBuild = '6b2ed504';
|
||||
var pdfjsSharedUtil = __w_pdfjs_require__(0);
|
||||
var pdfjsDisplayGlobal = __w_pdfjs_require__(12);
|
||||
var pdfjsDisplayAPI = __w_pdfjs_require__(3);
|
||||
@@ -7744,8 +7744,8 @@ if (!_global_scope2.default.PDFJS) {
|
||||
}
|
||||
var PDFJS = _global_scope2.default.PDFJS;
|
||||
{
|
||||
PDFJS.version = '2.0.244';
|
||||
PDFJS.build = '5bf4fb97';
|
||||
PDFJS.version = '2.0.250';
|
||||
PDFJS.build = '6b2ed504';
|
||||
}
|
||||
PDFJS.pdfBug = false;
|
||||
if (PDFJS.verbosity !== undefined) {
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
exports["pdfjs-dist/build/pdf.worker"] = factory();
|
||||
else
|
||||
root["pdfjs-dist/build/pdf.worker"] = root.pdfjsDistBuildPdfWorker = factory();
|
||||
})(this, function() {
|
||||
})(typeof self !== 'undefined' ? self : this, function() {
|
||||
return /******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
@@ -12230,8 +12230,9 @@ var JpxImage = function JpxImageClosure() {
|
||||
precision: (data[j] & 0x7F) + 1,
|
||||
isSigned: !!(data[j] & 0x80),
|
||||
XRsiz: data[j + 1],
|
||||
YRsiz: data[j + 1]
|
||||
YRsiz: data[j + 2]
|
||||
};
|
||||
j += 3;
|
||||
calculateComponentDimensions(component, siz);
|
||||
components.push(component);
|
||||
}
|
||||
@@ -20783,8 +20784,8 @@ exports.PostScriptCompiler = PostScriptCompiler;
|
||||
"use strict";
|
||||
|
||||
|
||||
var pdfjsVersion = '2.0.244';
|
||||
var pdfjsBuild = '5bf4fb97';
|
||||
var pdfjsVersion = '2.0.250';
|
||||
var pdfjsBuild = '6b2ed504';
|
||||
var pdfjsCoreWorker = __w_pdfjs_require__(19);
|
||||
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
|
||||
|
||||
@@ -20979,7 +20980,7 @@ var WorkerMessageHandler = {
|
||||
var cancelXHRs = null;
|
||||
var WorkerTasks = [];
|
||||
let apiVersion = docParams.apiVersion;
|
||||
let workerVersion = '2.0.244';
|
||||
let workerVersion = '2.0.250';
|
||||
if (apiVersion !== null && apiVersion !== workerVersion) {
|
||||
throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
|
||||
}
|
||||
|
||||
@@ -22,16 +22,6 @@
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.dialog-button-box {
|
||||
padding-bottom: 8px;
|
||||
padding-inline-start: 8px;
|
||||
padding-inline-end: 8px;
|
||||
}
|
||||
|
||||
.prefwindow[type="child"] .dialog-button-box {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
/* General Pane */
|
||||
#useFirefoxSync,
|
||||
#getStarted {
|
||||
|
||||
@@ -24,11 +24,6 @@
|
||||
padding-inline-end: 20px;
|
||||
}
|
||||
|
||||
.dialog-button-box {
|
||||
margin: 0 12px 12px;
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
description {
|
||||
margin-bottom: 4px !important;
|
||||
}
|
||||
|
||||
@@ -68,3 +68,7 @@ groupbox description {
|
||||
menulist label {
|
||||
font-weight: unset;
|
||||
}
|
||||
|
||||
.dialog-button-box {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@@ -28,16 +28,6 @@
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.dialog-button-box {
|
||||
padding-bottom: 10px;
|
||||
padding-inline-start: 8px;
|
||||
padding-inline-end: 10px;
|
||||
}
|
||||
|
||||
.prefwindow[type="child"] .dialog-button-box {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
/* General Pane */
|
||||
|
||||
#useFirefoxSync,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
This is the debugger.html project output.
|
||||
See https://github.com/devtools-html/debugger.html
|
||||
|
||||
Taken from upstream commit: f98e56ff661460044382df55bd33cea601e093f0
|
||||
Taken from upstream commit: 0bcf3e687305960077e1255510e424d0437a3b69
|
||||
|
||||
Packages:
|
||||
- babel-plugin-transform-es2015-modules-commonjs @6.26.0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -96,6 +96,8 @@ skip-if = os == "linux" # bug 1351952
|
||||
[browser_dbg-layout-changes.js]
|
||||
[browser_dbg-outline.js]
|
||||
[browser_dbg-pause-exceptions.js]
|
||||
[browser_dbg-pause-ux.js]
|
||||
skip-if = os == "win"
|
||||
[browser_dbg-navigation.js]
|
||||
[browser_dbg-minified.js]
|
||||
[browser_dbg-pretty-print.js]
|
||||
@@ -103,6 +105,7 @@ skip-if = os == "linux" # bug 1351952
|
||||
[browser_dbg-pretty-print-paused.js]
|
||||
[browser_dbg-preview.js]
|
||||
skip-if = true # regular failures during release in Bug 1415300
|
||||
[browser_dbg-preview-source-maps.js]
|
||||
[browser_dbg-returnvalues.js]
|
||||
[browser_dbg-scopes-mutations.js]
|
||||
[browser_dbg-search-file.js]
|
||||
|
||||
@@ -11,9 +11,11 @@ add_task(async function() {
|
||||
// reload.
|
||||
await addBreakpoint(dbg, "scripts.html", 18);
|
||||
reload(dbg);
|
||||
|
||||
await waitForDispatch(dbg, "NAVIGATE");
|
||||
await waitForSelectedSource(dbg, "doc-scripts.html");
|
||||
await waitForPaused(dbg);
|
||||
|
||||
await waitForLoadedSource(dbg, "doc-scripts.html");
|
||||
assertPausedLocation(dbg);
|
||||
await resume(dbg);
|
||||
|
||||
|
||||
@@ -17,24 +17,25 @@ add_task(async function() {
|
||||
|
||||
// Wait for the source text to load and make sure we're in the right
|
||||
// place.
|
||||
await waitForLoadedSource(dbg, sourceUrl);
|
||||
await waitForSelectedSource(dbg, sourceUrl);
|
||||
log(`loaded source`);
|
||||
|
||||
// TODO: revisit highlighting lines when the debugger opens
|
||||
// assertHighlightLocation(dbg, "long.js", 66);
|
||||
|
||||
// Jump to line 16 and make sure the editor scrolled.
|
||||
log(`Select line 16 and make sure the editor scrolled.`);
|
||||
await selectSource(dbg, "long.js", 16);
|
||||
await waitForElement(dbg, ".CodeMirror-code > .highlight-line");
|
||||
assertHighlightLocation(dbg, "long.js", 16);
|
||||
|
||||
// Make sure only one line is ever highlighted and the flash
|
||||
// animation is cancelled on old lines.
|
||||
log(`Select several locations and check that we have one highlight`);
|
||||
await selectSource(dbg, "long.js", 17);
|
||||
await selectSource(dbg, "long.js", 18);
|
||||
assertHighlightLocation(dbg, "long.js", 18);
|
||||
|
||||
// Test jumping to a line in a source that exists but hasn't been
|
||||
// loaded yet.
|
||||
log(`Select an unloaded source`);
|
||||
selectSource(dbg, "simple1.js", 6);
|
||||
|
||||
// Make sure the source is in the loading state, wait for it to be
|
||||
@@ -42,7 +43,7 @@ add_task(async function() {
|
||||
const simple1 = findSource(dbg, "simple1.js");
|
||||
is(getSource(getState(), simple1.id).get("loadedState"), "loading");
|
||||
|
||||
await waitForLoadedSource(dbg, "simple1.js");
|
||||
await waitForSelectedSource(dbg, "simple1.js");
|
||||
ok(getSource(getState(), simple1.id).get("text"));
|
||||
assertHighlightLocation(dbg, "simple1.js", 6);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function getScrollTop(dbg) {
|
||||
return getCM(dbg).doc.scrollTop;
|
||||
}
|
||||
|
||||
async function waitForMatch(dbg, { matchIndex, count }) {
|
||||
await waitForState(
|
||||
dbg,
|
||||
state => {
|
||||
const result = dbg.selectors.getFileSearchResults(state);
|
||||
return result.matchIndex == matchIndex && result.count == count;
|
||||
},
|
||||
"wait for match"
|
||||
);
|
||||
}
|
||||
|
||||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-scripts.html");
|
||||
|
||||
// Make sure that we can set a breakpoint on a line out of the
|
||||
// viewport, and that pausing there scrolls the editor to it.
|
||||
let longSrc = findSource(dbg, "long.js");
|
||||
await addBreakpoint(dbg, longSrc, 66);
|
||||
invokeInTab("testModel");
|
||||
await waitForPaused(dbg);
|
||||
|
||||
const pauseScrollTop = getScrollTop(dbg);
|
||||
|
||||
log("1. adding a breakpoint should not scroll the editor");
|
||||
getCM(dbg).scrollTo(0, 0);
|
||||
await addBreakpoint(dbg, longSrc, 11);
|
||||
is(getScrollTop(dbg), 0, "scroll position");
|
||||
|
||||
log("2. searching should jump to the match");
|
||||
pressKey(dbg, "fileSearch");
|
||||
type(dbg, "check");
|
||||
await waitForMatch(dbg, { matchIndex: 0, count: 2 });
|
||||
const matchScrollTop = getScrollTop(dbg);
|
||||
ok(pauseScrollTop != matchScrollTop, "did not jump to debug line");
|
||||
});
|
||||
@@ -0,0 +1,63 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function getCoordsFromPosition(cm, { line, ch }) {
|
||||
return cm.charCoords({ line: ~~line, ch: ~~ch });
|
||||
}
|
||||
|
||||
function hoverAtPos(dbg, { line, ch }) {
|
||||
const cm = getCM(dbg);
|
||||
const coords = getCoordsFromPosition(cm, { line: line - 1, ch });
|
||||
const tokenEl = dbg.win.document.elementFromPoint(coords.left, coords.top);
|
||||
tokenEl.dispatchEvent(
|
||||
new MouseEvent("mouseover", {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
view: dbg.win
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function assertTooltip(dbg, { result, expression }) {
|
||||
const previewEl = findElement(dbg, "tooltip");
|
||||
is(previewEl.innerText, result, "Preview text shown to user");
|
||||
|
||||
const preview = dbg.selectors.getPreview(dbg.getState());
|
||||
is(`${preview.result}`, result, "Preview.result");
|
||||
is(preview.updating, false, "Preview.updating");
|
||||
is(preview.expression, expression, "Preview.expression");
|
||||
}
|
||||
|
||||
function assertPopup(dbg, { field, value, expression }) {
|
||||
const previewEl = findElement(dbg, "popup");
|
||||
is(previewEl.innerText, "", "Preview text shown to user");
|
||||
|
||||
const preview = dbg.selectors.getPreview(dbg.getState());
|
||||
|
||||
is(
|
||||
`${preview.result.preview.ownProperties[field].value}`,
|
||||
value,
|
||||
"Preview.result"
|
||||
);
|
||||
is(preview.updating, false, "Preview.updating");
|
||||
is(preview.expression, expression, "Preview.expression");
|
||||
}
|
||||
|
||||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-sourcemaps.html");
|
||||
const { selectors: { getSelectedSource }, getState } = dbg;
|
||||
|
||||
await waitForSources(dbg, "entry.js", "output.js", "times2.js", "opts.js");
|
||||
await selectSource(dbg, "times2");
|
||||
await addBreakpoint(dbg, "times2", 2);
|
||||
|
||||
invokeInTab("keepMeAlive");
|
||||
await waitForPaused(dbg);
|
||||
await waitForSelectedSource(dbg, "times2");
|
||||
|
||||
const tooltipPreviewed = waitForDispatch(dbg, "SET_PREVIEW");
|
||||
hoverAtPos(dbg, { line: 2, ch: 9 });
|
||||
|
||||
await tooltipPreviewed;
|
||||
assertTooltip(dbg, { result: 4, expression: "x" });
|
||||
});
|
||||
@@ -208,7 +208,7 @@ function waitForSources(dbg, ...sources) {
|
||||
}
|
||||
|
||||
if (!sourceExists(store.getState())) {
|
||||
return waitForState(dbg, sourceExists);
|
||||
return waitForState(dbg, sourceExists, `source ${url}`);
|
||||
}
|
||||
})
|
||||
);
|
||||
@@ -313,8 +313,14 @@ function assertDebugLine(dbg, line) {
|
||||
);
|
||||
|
||||
const debugLine =
|
||||
findElementWithSelector(dbg, ".new-debug-line") ||
|
||||
findElementWithSelector(dbg, ".new-debug-line-error");
|
||||
findElement(dbg, "debugLine") || findElement(dbg, "debugErrorLine");
|
||||
|
||||
is(
|
||||
findAllElements(dbg, "debugLine").length +
|
||||
findAllElements(dbg, "debugErrorLine").length,
|
||||
1,
|
||||
"There is only one line"
|
||||
);
|
||||
|
||||
ok(isVisibleInEditor(dbg, debugLine), "debug line is visible");
|
||||
|
||||
@@ -935,6 +941,8 @@ const selectors = {
|
||||
pauseOnExceptions: ".pause-exceptions",
|
||||
breakpoint: ".CodeMirror-code > .new-breakpoint",
|
||||
highlightLine: ".CodeMirror-code > .highlight-line",
|
||||
debugLine: ".new-debug-line",
|
||||
debugErrorLine: ".new-debug-line-error",
|
||||
codeMirror: ".CodeMirror",
|
||||
resume: ".resume.active",
|
||||
sourceTabs: ".source-tabs",
|
||||
|
||||
@@ -34,6 +34,7 @@ class GridItem extends PureComponent {
|
||||
this.setGridColor = this.setGridColor.bind(this);
|
||||
this.translateNodeFrontToGrip = this.translateNodeFrontToGrip.bind(this);
|
||||
this.onGridCheckboxClick = this.onGridCheckboxClick.bind(this);
|
||||
this.onGridInspectIconClick = this.onGridInspectIconClick.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -114,10 +115,15 @@ class GridItem extends PureComponent {
|
||||
onToggleGridHighlighter(grid.nodeFront);
|
||||
}
|
||||
|
||||
onGridInspectIconClick(nodeFront) {
|
||||
let { setSelectedNode } = this.props;
|
||||
setSelectedNode(nodeFront, "layout-panel").catch(e => console.error(e));
|
||||
nodeFront.scrollIntoView().catch(e => console.error(e));
|
||||
}
|
||||
|
||||
render() {
|
||||
let {
|
||||
grid,
|
||||
setSelectedNode,
|
||||
onHideBoxModelHighlighter,
|
||||
onShowBoxModelHighlighterForNode,
|
||||
} = this.props;
|
||||
@@ -142,7 +148,7 @@ class GridItem extends PureComponent {
|
||||
object: this.translateNodeFrontToGrip(nodeFront),
|
||||
onDOMNodeMouseOut: () => onHideBoxModelHighlighter(),
|
||||
onDOMNodeMouseOver: () => onShowBoxModelHighlighterForNode(nodeFront),
|
||||
onInspectIconClick: () => setSelectedNode(nodeFront, "layout-panel"),
|
||||
onInspectIconClick: () => this.onGridInspectIconClick(nodeFront),
|
||||
}
|
||||
)
|
||||
),
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# wasmparser version
|
||||
|
||||
Current vesion is: 0.4.11
|
||||
Current vesion is: 0.5.2
|
||||
|
||||
# Upgrade process
|
||||
|
||||
1. Pull latest release from npm and extract WasmDis.js and WasmParser.js, e.g.
|
||||
|
||||
```
|
||||
curl https://registry.npmjs.org/wasmparser/-/wasmparser-0.4.11.tgz | tar -x --strip-components 2 package/dist/{WasmDis,WasmParser}.js
|
||||
curl https://registry.npmjs.org/wasmparser/-/wasmparser-0.5.2.tgz | tar -x --strip-components 2 package/dist/{WasmDis,WasmParser}.js
|
||||
```
|
||||
|
||||
2. Remove reference to source maps (last line)
|
||||
|
||||
152
devtools/client/shared/vendor/WasmDis.js
vendored
152
devtools/client/shared/vendor/WasmDis.js
vendored
@@ -69,6 +69,16 @@ function memoryAddressToString(address, code) {
|
||||
case 55 /* i64_store */:
|
||||
case 43 /* f64_load */:
|
||||
case 57 /* f64_store */:
|
||||
case 65026 /* i64_atomic_wait */:
|
||||
case 65041 /* i64_atomic_load */:
|
||||
case 65048 /* i64_atomic_store */:
|
||||
case 65055 /* i64_atomic_rmw_add */:
|
||||
case 65062 /* i64_atomic_rmw_sub */:
|
||||
case 65069 /* i64_atomic_rmw_and */:
|
||||
case 65076 /* i64_atomic_rmw_or */:
|
||||
case 65083 /* i64_atomic_rmw_xor */:
|
||||
case 65090 /* i64_atomic_rmw_xchg */:
|
||||
case 65097 /* i64_atomic_rmw_cmpxchg */:
|
||||
defaultAlignFlags = 3;
|
||||
break;
|
||||
case 40 /* i32_load */:
|
||||
@@ -78,6 +88,26 @@ function memoryAddressToString(address, code) {
|
||||
case 62 /* i64_store32 */:
|
||||
case 42 /* f32_load */:
|
||||
case 56 /* f32_store */:
|
||||
case 65024 /* atomic_wake */:
|
||||
case 65025 /* i32_atomic_wait */:
|
||||
case 65040 /* i32_atomic_load */:
|
||||
case 65046 /* i64_atomic_load32_u */:
|
||||
case 65047 /* i32_atomic_store */:
|
||||
case 65053 /* i64_atomic_store32 */:
|
||||
case 65054 /* i32_atomic_rmw_add */:
|
||||
case 65060 /* i64_atomic_rmw32_u_add */:
|
||||
case 65061 /* i32_atomic_rmw_sub */:
|
||||
case 65067 /* i64_atomic_rmw32_u_sub */:
|
||||
case 65068 /* i32_atomic_rmw_and */:
|
||||
case 65074 /* i64_atomic_rmw32_u_and */:
|
||||
case 65075 /* i32_atomic_rmw_or */:
|
||||
case 65081 /* i64_atomic_rmw32_u_or */:
|
||||
case 65082 /* i32_atomic_rmw_xor */:
|
||||
case 65088 /* i64_atomic_rmw32_u_xor */:
|
||||
case 65089 /* i32_atomic_rmw_xchg */:
|
||||
case 65095 /* i64_atomic_rmw32_u_xchg */:
|
||||
case 65096 /* i32_atomic_rmw_cmpxchg */:
|
||||
case 65102 /* i64_atomic_rmw32_u_cmpxchg */:
|
||||
defaultAlignFlags = 2;
|
||||
break;
|
||||
case 46 /* i32_load16_s */:
|
||||
@@ -86,6 +116,24 @@ function memoryAddressToString(address, code) {
|
||||
case 51 /* i64_load16_u */:
|
||||
case 59 /* i32_store16 */:
|
||||
case 61 /* i64_store16 */:
|
||||
case 65043 /* i32_atomic_load16_u */:
|
||||
case 65045 /* i64_atomic_load16_u */:
|
||||
case 65050 /* i32_atomic_store16 */:
|
||||
case 65052 /* i64_atomic_store16 */:
|
||||
case 65057 /* i32_atomic_rmw16_u_add */:
|
||||
case 65059 /* i64_atomic_rmw16_u_add */:
|
||||
case 65064 /* i32_atomic_rmw16_u_sub */:
|
||||
case 65066 /* i64_atomic_rmw16_u_sub */:
|
||||
case 65071 /* i32_atomic_rmw16_u_and */:
|
||||
case 65073 /* i64_atomic_rmw16_u_and */:
|
||||
case 65078 /* i32_atomic_rmw16_u_or */:
|
||||
case 65080 /* i64_atomic_rmw16_u_or */:
|
||||
case 65085 /* i32_atomic_rmw16_u_xor */:
|
||||
case 65087 /* i64_atomic_rmw16_u_xor */:
|
||||
case 65092 /* i32_atomic_rmw16_u_xchg */:
|
||||
case 65094 /* i64_atomic_rmw16_u_xchg */:
|
||||
case 65099 /* i32_atomic_rmw16_u_cmpxchg */:
|
||||
case 65101 /* i64_atomic_rmw16_u_cmpxchg */:
|
||||
defaultAlignFlags = 1;
|
||||
break;
|
||||
case 44 /* i32_load8_s */:
|
||||
@@ -94,6 +142,24 @@ function memoryAddressToString(address, code) {
|
||||
case 49 /* i64_load8_u */:
|
||||
case 58 /* i32_store8 */:
|
||||
case 60 /* i64_store8 */:
|
||||
case 65042 /* i32_atomic_load8_u */:
|
||||
case 65044 /* i64_atomic_load8_u */:
|
||||
case 65049 /* i32_atomic_store8 */:
|
||||
case 65051 /* i64_atomic_store8 */:
|
||||
case 65056 /* i32_atomic_rmw8_u_add */:
|
||||
case 65058 /* i64_atomic_rmw8_u_add */:
|
||||
case 65063 /* i32_atomic_rmw8_u_sub */:
|
||||
case 65065 /* i64_atomic_rmw8_u_sub */:
|
||||
case 65070 /* i32_atomic_rmw8_u_and */:
|
||||
case 65072 /* i64_atomic_rmw8_u_and */:
|
||||
case 65077 /* i32_atomic_rmw8_u_or */:
|
||||
case 65079 /* i64_atomic_rmw8_u_or */:
|
||||
case 65084 /* i32_atomic_rmw8_u_xor */:
|
||||
case 65086 /* i64_atomic_rmw8_u_xor */:
|
||||
case 65091 /* i32_atomic_rmw8_u_xchg */:
|
||||
case 65093 /* i64_atomic_rmw8_u_xchg */:
|
||||
case 65098 /* i32_atomic_rmw8_u_cmpxchg */:
|
||||
case 65100 /* i64_atomic_rmw8_u_cmpxchg */:
|
||||
defaultAlignFlags = 0;
|
||||
break;
|
||||
}
|
||||
@@ -384,7 +450,7 @@ var WasmDisassembler = (function () {
|
||||
return backrefLabel.label || '' + depth;
|
||||
};
|
||||
WasmDisassembler.prototype.printOperator = function (operator) {
|
||||
var code = operator.code;
|
||||
var code = operator.code | 0;
|
||||
this.appendBuffer(getOperatorName(code));
|
||||
switch (code) {
|
||||
case 2 /* block */:
|
||||
@@ -476,6 +542,72 @@ var WasmDisassembler = (function () {
|
||||
case 60 /* i64_store8 */:
|
||||
case 61 /* i64_store16 */:
|
||||
case 62 /* i64_store32 */:
|
||||
case 65024 /* atomic_wake */:
|
||||
case 65025 /* i32_atomic_wait */:
|
||||
case 65026 /* i64_atomic_wait */:
|
||||
case 65040 /* i32_atomic_load */:
|
||||
case 65041 /* i64_atomic_load */:
|
||||
case 65042 /* i32_atomic_load8_u */:
|
||||
case 65043 /* i32_atomic_load16_u */:
|
||||
case 65044 /* i64_atomic_load8_u */:
|
||||
case 65045 /* i64_atomic_load16_u */:
|
||||
case 65046 /* i64_atomic_load32_u */:
|
||||
case 65047 /* i32_atomic_store */:
|
||||
case 65048 /* i64_atomic_store */:
|
||||
case 65049 /* i32_atomic_store8 */:
|
||||
case 65050 /* i32_atomic_store16 */:
|
||||
case 65051 /* i64_atomic_store8 */:
|
||||
case 65052 /* i64_atomic_store16 */:
|
||||
case 65053 /* i64_atomic_store32 */:
|
||||
case 65054 /* i32_atomic_rmw_add */:
|
||||
case 65055 /* i64_atomic_rmw_add */:
|
||||
case 65056 /* i32_atomic_rmw8_u_add */:
|
||||
case 65057 /* i32_atomic_rmw16_u_add */:
|
||||
case 65058 /* i64_atomic_rmw8_u_add */:
|
||||
case 65059 /* i64_atomic_rmw16_u_add */:
|
||||
case 65060 /* i64_atomic_rmw32_u_add */:
|
||||
case 65061 /* i32_atomic_rmw_sub */:
|
||||
case 65062 /* i64_atomic_rmw_sub */:
|
||||
case 65063 /* i32_atomic_rmw8_u_sub */:
|
||||
case 65064 /* i32_atomic_rmw16_u_sub */:
|
||||
case 65065 /* i64_atomic_rmw8_u_sub */:
|
||||
case 65066 /* i64_atomic_rmw16_u_sub */:
|
||||
case 65067 /* i64_atomic_rmw32_u_sub */:
|
||||
case 65068 /* i32_atomic_rmw_and */:
|
||||
case 65069 /* i64_atomic_rmw_and */:
|
||||
case 65070 /* i32_atomic_rmw8_u_and */:
|
||||
case 65071 /* i32_atomic_rmw16_u_and */:
|
||||
case 65072 /* i64_atomic_rmw8_u_and */:
|
||||
case 65073 /* i64_atomic_rmw16_u_and */:
|
||||
case 65074 /* i64_atomic_rmw32_u_and */:
|
||||
case 65075 /* i32_atomic_rmw_or */:
|
||||
case 65076 /* i64_atomic_rmw_or */:
|
||||
case 65077 /* i32_atomic_rmw8_u_or */:
|
||||
case 65078 /* i32_atomic_rmw16_u_or */:
|
||||
case 65079 /* i64_atomic_rmw8_u_or */:
|
||||
case 65080 /* i64_atomic_rmw16_u_or */:
|
||||
case 65081 /* i64_atomic_rmw32_u_or */:
|
||||
case 65082 /* i32_atomic_rmw_xor */:
|
||||
case 65083 /* i64_atomic_rmw_xor */:
|
||||
case 65084 /* i32_atomic_rmw8_u_xor */:
|
||||
case 65085 /* i32_atomic_rmw16_u_xor */:
|
||||
case 65086 /* i64_atomic_rmw8_u_xor */:
|
||||
case 65087 /* i64_atomic_rmw16_u_xor */:
|
||||
case 65088 /* i64_atomic_rmw32_u_xor */:
|
||||
case 65089 /* i32_atomic_rmw_xchg */:
|
||||
case 65090 /* i64_atomic_rmw_xchg */:
|
||||
case 65091 /* i32_atomic_rmw8_u_xchg */:
|
||||
case 65092 /* i32_atomic_rmw16_u_xchg */:
|
||||
case 65093 /* i64_atomic_rmw8_u_xchg */:
|
||||
case 65094 /* i64_atomic_rmw16_u_xchg */:
|
||||
case 65095 /* i64_atomic_rmw32_u_xchg */:
|
||||
case 65096 /* i32_atomic_rmw_cmpxchg */:
|
||||
case 65097 /* i64_atomic_rmw_cmpxchg */:
|
||||
case 65098 /* i32_atomic_rmw8_u_cmpxchg */:
|
||||
case 65099 /* i32_atomic_rmw16_u_cmpxchg */:
|
||||
case 65100 /* i64_atomic_rmw8_u_cmpxchg */:
|
||||
case 65101 /* i64_atomic_rmw16_u_cmpxchg */:
|
||||
case 65102 /* i64_atomic_rmw32_u_cmpxchg */:
|
||||
var memoryAddress = memoryAddressToString(operator.memoryAddress, operator.code);
|
||||
if (memoryAddress !== null) {
|
||||
this.appendBuffer(' ');
|
||||
@@ -620,9 +752,12 @@ var WasmDisassembler = (function () {
|
||||
case 15 /* MEMORY_SECTION_ENTRY */:
|
||||
var memoryInfo = reader.result;
|
||||
var memoryName = this._nameResolver.getMemoryName(this._memoryCount++, false);
|
||||
this.appendBuffer(" (memory " + memoryName + " " + memoryInfo.limits.initial);
|
||||
if (memoryInfo.limits.maximum !== undefined) {
|
||||
this.appendBuffer(" " + memoryInfo.limits.maximum);
|
||||
this.appendBuffer(" (memory " + memoryName + " ");
|
||||
if (memoryInfo.shared) {
|
||||
this.appendBuffer("(shared " + limitsToString(memoryInfo.limits) + ")");
|
||||
}
|
||||
else {
|
||||
this.appendBuffer(limitsToString(memoryInfo.limits));
|
||||
}
|
||||
this.appendBuffer(')');
|
||||
this.newLine();
|
||||
@@ -681,7 +816,14 @@ var WasmDisassembler = (function () {
|
||||
case 2 /* Memory */:
|
||||
var memoryImportInfo = importInfo.type;
|
||||
var memoryName = this._nameResolver.getMemoryName(this._memoryCount++, false);
|
||||
this.appendBuffer(" (memory " + memoryName + " " + limitsToString(memoryImportInfo.limits) + ")");
|
||||
this.appendBuffer(" (memory " + memoryName + " ");
|
||||
if (memoryImportInfo.shared) {
|
||||
this.appendBuffer("(shared " + limitsToString(memoryImportInfo.limits) + ")");
|
||||
}
|
||||
else {
|
||||
this.appendBuffer(limitsToString(memoryImportInfo.limits));
|
||||
}
|
||||
this.appendBuffer(')');
|
||||
break;
|
||||
case 3 /* Global */:
|
||||
var globalImportInfo = importInfo.type;
|
||||
|
||||
368
devtools/client/shared/vendor/WasmParser.js
vendored
368
devtools/client/shared/vendor/WasmParser.js
vendored
@@ -208,11 +208,98 @@ var OperatorCode;
|
||||
OperatorCode[OperatorCode["i64_reinterpret_f64"] = 189] = "i64_reinterpret_f64";
|
||||
OperatorCode[OperatorCode["f32_reinterpret_i32"] = 190] = "f32_reinterpret_i32";
|
||||
OperatorCode[OperatorCode["f64_reinterpret_i64"] = 191] = "f64_reinterpret_i64";
|
||||
OperatorCode[OperatorCode["i32_extend8_s"] = 192] = "i32_extend8_s";
|
||||
OperatorCode[OperatorCode["i32_extend16_s"] = 193] = "i32_extend16_s";
|
||||
OperatorCode[OperatorCode["i64_extend8_s"] = 194] = "i64_extend8_s";
|
||||
OperatorCode[OperatorCode["i64_extend16_s"] = 195] = "i64_extend16_s";
|
||||
OperatorCode[OperatorCode["i64_extend32_s"] = 196] = "i64_extend32_s";
|
||||
OperatorCode[OperatorCode["prefix_0xfc"] = 252] = "prefix_0xfc";
|
||||
OperatorCode[OperatorCode["prefix_0xfe"] = 254] = "prefix_0xfe";
|
||||
OperatorCode[OperatorCode["i32_trunc_s_sat_f32"] = 64512] = "i32_trunc_s_sat_f32";
|
||||
OperatorCode[OperatorCode["i32_trunc_u_sat_f32"] = 64513] = "i32_trunc_u_sat_f32";
|
||||
OperatorCode[OperatorCode["i32_trunc_s_sat_f64"] = 64514] = "i32_trunc_s_sat_f64";
|
||||
OperatorCode[OperatorCode["i32_trunc_u_sat_f64"] = 64515] = "i32_trunc_u_sat_f64";
|
||||
OperatorCode[OperatorCode["i64_trunc_s_sat_f32"] = 64516] = "i64_trunc_s_sat_f32";
|
||||
OperatorCode[OperatorCode["i64_trunc_u_sat_f32"] = 64517] = "i64_trunc_u_sat_f32";
|
||||
OperatorCode[OperatorCode["i64_trunc_s_sat_f64"] = 64518] = "i64_trunc_s_sat_f64";
|
||||
OperatorCode[OperatorCode["i64_trunc_u_sat_f64"] = 64519] = "i64_trunc_u_sat_f64";
|
||||
OperatorCode[OperatorCode["atomic_wake"] = 65024] = "atomic_wake";
|
||||
OperatorCode[OperatorCode["i32_atomic_wait"] = 65025] = "i32_atomic_wait";
|
||||
OperatorCode[OperatorCode["i64_atomic_wait"] = 65026] = "i64_atomic_wait";
|
||||
OperatorCode[OperatorCode["i32_atomic_load"] = 65040] = "i32_atomic_load";
|
||||
OperatorCode[OperatorCode["i64_atomic_load"] = 65041] = "i64_atomic_load";
|
||||
OperatorCode[OperatorCode["i32_atomic_load8_u"] = 65042] = "i32_atomic_load8_u";
|
||||
OperatorCode[OperatorCode["i32_atomic_load16_u"] = 65043] = "i32_atomic_load16_u";
|
||||
OperatorCode[OperatorCode["i64_atomic_load8_u"] = 65044] = "i64_atomic_load8_u";
|
||||
OperatorCode[OperatorCode["i64_atomic_load16_u"] = 65045] = "i64_atomic_load16_u";
|
||||
OperatorCode[OperatorCode["i64_atomic_load32_u"] = 65046] = "i64_atomic_load32_u";
|
||||
OperatorCode[OperatorCode["i32_atomic_store"] = 65047] = "i32_atomic_store";
|
||||
OperatorCode[OperatorCode["i64_atomic_store"] = 65048] = "i64_atomic_store";
|
||||
OperatorCode[OperatorCode["i32_atomic_store8"] = 65049] = "i32_atomic_store8";
|
||||
OperatorCode[OperatorCode["i32_atomic_store16"] = 65050] = "i32_atomic_store16";
|
||||
OperatorCode[OperatorCode["i64_atomic_store8"] = 65051] = "i64_atomic_store8";
|
||||
OperatorCode[OperatorCode["i64_atomic_store16"] = 65052] = "i64_atomic_store16";
|
||||
OperatorCode[OperatorCode["i64_atomic_store32"] = 65053] = "i64_atomic_store32";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw_add"] = 65054] = "i32_atomic_rmw_add";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw_add"] = 65055] = "i64_atomic_rmw_add";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw8_u_add"] = 65056] = "i32_atomic_rmw8_u_add";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw16_u_add"] = 65057] = "i32_atomic_rmw16_u_add";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw8_u_add"] = 65058] = "i64_atomic_rmw8_u_add";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw16_u_add"] = 65059] = "i64_atomic_rmw16_u_add";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw32_u_add"] = 65060] = "i64_atomic_rmw32_u_add";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw_sub"] = 65061] = "i32_atomic_rmw_sub";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw_sub"] = 65062] = "i64_atomic_rmw_sub";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw8_u_sub"] = 65063] = "i32_atomic_rmw8_u_sub";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw16_u_sub"] = 65064] = "i32_atomic_rmw16_u_sub";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw8_u_sub"] = 65065] = "i64_atomic_rmw8_u_sub";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw16_u_sub"] = 65066] = "i64_atomic_rmw16_u_sub";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw32_u_sub"] = 65067] = "i64_atomic_rmw32_u_sub";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw_and"] = 65068] = "i32_atomic_rmw_and";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw_and"] = 65069] = "i64_atomic_rmw_and";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw8_u_and"] = 65070] = "i32_atomic_rmw8_u_and";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw16_u_and"] = 65071] = "i32_atomic_rmw16_u_and";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw8_u_and"] = 65072] = "i64_atomic_rmw8_u_and";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw16_u_and"] = 65073] = "i64_atomic_rmw16_u_and";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw32_u_and"] = 65074] = "i64_atomic_rmw32_u_and";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw_or"] = 65075] = "i32_atomic_rmw_or";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw_or"] = 65076] = "i64_atomic_rmw_or";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw8_u_or"] = 65077] = "i32_atomic_rmw8_u_or";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw16_u_or"] = 65078] = "i32_atomic_rmw16_u_or";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw8_u_or"] = 65079] = "i64_atomic_rmw8_u_or";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw16_u_or"] = 65080] = "i64_atomic_rmw16_u_or";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw32_u_or"] = 65081] = "i64_atomic_rmw32_u_or";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw_xor"] = 65082] = "i32_atomic_rmw_xor";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw_xor"] = 65083] = "i64_atomic_rmw_xor";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw8_u_xor"] = 65084] = "i32_atomic_rmw8_u_xor";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw16_u_xor"] = 65085] = "i32_atomic_rmw16_u_xor";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw8_u_xor"] = 65086] = "i64_atomic_rmw8_u_xor";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw16_u_xor"] = 65087] = "i64_atomic_rmw16_u_xor";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw32_u_xor"] = 65088] = "i64_atomic_rmw32_u_xor";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw_xchg"] = 65089] = "i32_atomic_rmw_xchg";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw_xchg"] = 65090] = "i64_atomic_rmw_xchg";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw8_u_xchg"] = 65091] = "i32_atomic_rmw8_u_xchg";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw16_u_xchg"] = 65092] = "i32_atomic_rmw16_u_xchg";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw8_u_xchg"] = 65093] = "i64_atomic_rmw8_u_xchg";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw16_u_xchg"] = 65094] = "i64_atomic_rmw16_u_xchg";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw32_u_xchg"] = 65095] = "i64_atomic_rmw32_u_xchg";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw_cmpxchg"] = 65096] = "i32_atomic_rmw_cmpxchg";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw_cmpxchg"] = 65097] = "i64_atomic_rmw_cmpxchg";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw8_u_cmpxchg"] = 65098] = "i32_atomic_rmw8_u_cmpxchg";
|
||||
OperatorCode[OperatorCode["i32_atomic_rmw16_u_cmpxchg"] = 65099] = "i32_atomic_rmw16_u_cmpxchg";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw8_u_cmpxchg"] = 65100] = "i64_atomic_rmw8_u_cmpxchg";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw16_u_cmpxchg"] = 65101] = "i64_atomic_rmw16_u_cmpxchg";
|
||||
OperatorCode[OperatorCode["i64_atomic_rmw32_u_cmpxchg"] = 65102] = "i64_atomic_rmw32_u_cmpxchg";
|
||||
})(OperatorCode = exports.OperatorCode || (exports.OperatorCode = {}));
|
||||
;
|
||||
exports.OperatorCodeNames = [
|
||||
"unreachable", "nop", "block", "loop", "if", "else", undefined, undefined, undefined, undefined, undefined, "end", "br", "br_if", "br_table", "return", "call", "call_indirect", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, "drop", "select", undefined, undefined, undefined, undefined, "get_local", "set_local", "tee_local", "get_global", "set_global", undefined, undefined, undefined, "i32.load", "i64.load", "f32.load", "f64.load", "i32.load8_s", "i32.load8_u", "i32.load16_s", "i32.load16_u", "i64.load8_s", "i64.load8_u", "i64.load16_s", "i64.load16_u", "i64.load32_s", "i64.load32_u", "i32.store", "i64.store", "f32.store", "f64.store", "i32.store8", "i32.store16", "i64.store8", "i64.store16", "i64.store32", "current_memory", "grow_memory", "i32.const", "i64.const", "f32.const", "f64.const", "i32.eqz", "i32.eq", "i32.ne", "i32.lt_s", "i32.lt_u", "i32.gt_s", "i32.gt_u", "i32.le_s", "i32.le_u", "i32.ge_s", "i32.ge_u", "i64.eqz", "i64.eq", "i64.ne", "i64.lt_s", "i64.lt_u", "i64.gt_s", "i64.gt_u", "i64.le_s", "i64.le_u", "i64.ge_s", "i64.ge_u", "f32.eq", "f32.ne", "f32.lt", "f32.gt", "f32.le", "f32.ge", "f64.eq", "f64.ne", "f64.lt", "f64.gt", "f64.le", "f64.ge", "i32.clz", "i32.ctz", "i32.popcnt", "i32.add", "i32.sub", "i32.mul", "i32.div_s", "i32.div_u", "i32.rem_s", "i32.rem_u", "i32.and", "i32.or", "i32.xor", "i32.shl", "i32.shr_s", "i32.shr_u", "i32.rotl", "i32.rotr", "i64.clz", "i64.ctz", "i64.popcnt", "i64.add", "i64.sub", "i64.mul", "i64.div_s", "i64.div_u", "i64.rem_s", "i64.rem_u", "i64.and", "i64.or", "i64.xor", "i64.shl", "i64.shr_s", "i64.shr_u", "i64.rotl", "i64.rotr", "f32.abs", "f32.neg", "f32.ceil", "f32.floor", "f32.trunc", "f32.nearest", "f32.sqrt", "f32.add", "f32.sub", "f32.mul", "f32.div", "f32.min", "f32.max", "f32.copysign", "f64.abs", "f64.neg", "f64.ceil", "f64.floor", "f64.trunc", "f64.nearest", "f64.sqrt", "f64.add", "f64.sub", "f64.mul", "f64.div", "f64.min", "f64.max", "f64.copysign", "i32.wrap/i64", "i32.trunc_s/f32", "i32.trunc_u/f32", "i32.trunc_s/f64", "i32.trunc_u/f64", "i64.extend_s/i32", "i64.extend_u/i32", "i64.trunc_s/f32", "i64.trunc_u/f32", "i64.trunc_s/f64", "i64.trunc_u/f64", "f32.convert_s/i32", "f32.convert_u/i32", "f32.convert_s/i64", "f32.convert_u/i64", "f32.demote/f64", "f64.convert_s/i32", "f64.convert_u/i32", "f64.convert_s/i64", "f64.convert_u/i64", "f64.promote/f32", "i32.reinterpret/f32", "i64.reinterpret/f64", "f32.reinterpret/i32", "f64.reinterpret/i64", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined
|
||||
"unreachable", "nop", "block", "loop", "if", "else", undefined, undefined, undefined, undefined, undefined, "end", "br", "br_if", "br_table", "return", "call", "call_indirect", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, "drop", "select", undefined, undefined, undefined, undefined, "get_local", "set_local", "tee_local", "get_global", "set_global", undefined, undefined, undefined, "i32.load", "i64.load", "f32.load", "f64.load", "i32.load8_s", "i32.load8_u", "i32.load16_s", "i32.load16_u", "i64.load8_s", "i64.load8_u", "i64.load16_s", "i64.load16_u", "i64.load32_s", "i64.load32_u", "i32.store", "i64.store", "f32.store", "f64.store", "i32.store8", "i32.store16", "i64.store8", "i64.store16", "i64.store32", "current_memory", "grow_memory", "i32.const", "i64.const", "f32.const", "f64.const", "i32.eqz", "i32.eq", "i32.ne", "i32.lt_s", "i32.lt_u", "i32.gt_s", "i32.gt_u", "i32.le_s", "i32.le_u", "i32.ge_s", "i32.ge_u", "i64.eqz", "i64.eq", "i64.ne", "i64.lt_s", "i64.lt_u", "i64.gt_s", "i64.gt_u", "i64.le_s", "i64.le_u", "i64.ge_s", "i64.ge_u", "f32.eq", "f32.ne", "f32.lt", "f32.gt", "f32.le", "f32.ge", "f64.eq", "f64.ne", "f64.lt", "f64.gt", "f64.le", "f64.ge", "i32.clz", "i32.ctz", "i32.popcnt", "i32.add", "i32.sub", "i32.mul", "i32.div_s", "i32.div_u", "i32.rem_s", "i32.rem_u", "i32.and", "i32.or", "i32.xor", "i32.shl", "i32.shr_s", "i32.shr_u", "i32.rotl", "i32.rotr", "i64.clz", "i64.ctz", "i64.popcnt", "i64.add", "i64.sub", "i64.mul", "i64.div_s", "i64.div_u", "i64.rem_s", "i64.rem_u", "i64.and", "i64.or", "i64.xor", "i64.shl", "i64.shr_s", "i64.shr_u", "i64.rotl", "i64.rotr", "f32.abs", "f32.neg", "f32.ceil", "f32.floor", "f32.trunc", "f32.nearest", "f32.sqrt", "f32.add", "f32.sub", "f32.mul", "f32.div", "f32.min", "f32.max", "f32.copysign", "f64.abs", "f64.neg", "f64.ceil", "f64.floor", "f64.trunc", "f64.nearest", "f64.sqrt", "f64.add", "f64.sub", "f64.mul", "f64.div", "f64.min", "f64.max", "f64.copysign", "i32.wrap/i64", "i32.trunc_s/f32", "i32.trunc_u/f32", "i32.trunc_s/f64", "i32.trunc_u/f64", "i64.extend_s/i32", "i64.extend_u/i32", "i64.trunc_s/f32", "i64.trunc_u/f32", "i64.trunc_s/f64", "i64.trunc_u/f64", "f32.convert_s/i32", "f32.convert_u/i32", "f32.convert_s/i64", "f32.convert_u/i64", "f32.demote/f64", "f64.convert_s/i32", "f64.convert_u/i32", "f64.convert_s/i64", "f64.convert_u/i64", "f64.promote/f32", "i32.reinterpret/f32", "i64.reinterpret/f64", "f32.reinterpret/i32", "f64.reinterpret/i64", "i32.extend8_s", "i32.extend16_s", "i64.extend8_s", "i64.extend16_s", "i64.extend32_s", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined
|
||||
];
|
||||
["i32.trunc_s:sat/f32", "i32.trunc_u:sat/f32", "i32.trunc_s:sat/f64", "i32.trunc_u:sat/f64", "i64.trunc_s:sat/f32", "i64.trunc_u:sat/f32", "i64.trunc_s:sat/f64", "i64.trunc_u:sat/f64"].forEach(function (s, i) {
|
||||
exports.OperatorCodeNames[0xfc00 | i] = s;
|
||||
});
|
||||
["atomic.wake", "i32.atomic.wait", "i64.atomic.wait", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, "i32.atomic.load", "i64.atomic.load", "i32.atomic.load8_u", "i32.atomic.load16_u", "i64.atomic.load8_u", "i64.atomic.load16_u", "i64.atomic.load32_u", "i32.atomic.store", "i64.atomic.store", "i32.atomic.store8", "i32.atomic.store16", "i64.atomic.store8", "i64.atomic.store16", "i64.atomic.store32", "i32.atomic.rmw.add", "i64.atomic.rmw.add", "i32.atomic.rmw8_u.add", "i32.atomic.rmw16_u.add", "i64.atomic.rmw8_u.add", "i64.atomic.rmw16_u.add", "i64.atomic.rmw32_u.add", "i32.atomic.rmw.sub", "i64.atomic.rmw.sub", "i32.atomic.rmw8_u.sub", "i32.atomic.rmw16_u.sub", "i64.atomic.rmw8_u.sub", "i64.atomic.rmw16_u.sub", "i64.atomic.rmw32_u.sub", "i32.atomic.rmw.and", "i64.atomic.rmw.and", "i32.atomic.rmw8_u.and", "i32.atomic.rmw16_u.and", "i64.atomic.rmw8_u.and", "i64.atomic.rmw16_u.and", "i64.atomic.rmw32_u.and", "i32.atomic.rmw.or", "i64.atomic.rmw.or", "i32.atomic.rmw8_u.or", "i32.atomic.rmw16_u.or", "i64.atomic.rmw8_u.or", "i64.atomic.rmw16_u.or", "i64.atomic.rmw32_u.or", "i32.atomic.rmw.xor", "i64.atomic.rmw.xor", "i32.atomic.rmw8_u.xor", "i32.atomic.rmw16_u.xor", "i64.atomic.rmw8_u.xor", "i64.atomic.rmw16_u.xor", "i64.atomic.rmw32_u.xor", "i32.atomic.rmw.xchg", "i64.atomic.rmw.xchg", "i32.atomic.rmw8_u.xchg", "i32.atomic.rmw16_u.xchg", "i64.atomic.rmw8_u.xchg", "i64.atomic.rmw16_u.xchg", "i64.atomic.rmw32_u.xchg", "i32.atomic.rmw.cmpxchg", "i64.atomic.rmw.cmpxchg", "i32.atomic.rmw8_u.cmpxchg", "i32.atomic.rmw16_u.cmpxchg", "i64.atomic.rmw8_u.cmpxchg", "i64.atomic.rmw16_u.cmpxchg", "i64.atomic.rmw32_u.cmpxchg"].forEach(function (s, i) {
|
||||
exports.OperatorCodeNames[0xfe00 | i] = s;
|
||||
});
|
||||
var ExternalKind;
|
||||
(function (ExternalKind) {
|
||||
ExternalKind[ExternalKind["Function"] = 0] = "Function";
|
||||
@@ -537,22 +624,24 @@ var BinaryReader = (function () {
|
||||
returns: returnTypes
|
||||
};
|
||||
};
|
||||
BinaryReader.prototype.readResizableLimits = function () {
|
||||
var flags = this.readVarUint32() >>> 0;
|
||||
BinaryReader.prototype.readResizableLimits = function (maxPresent) {
|
||||
var initial = this.readVarUint32() >>> 0;
|
||||
var maximum;
|
||||
if (flags & 0x1) {
|
||||
if (maxPresent) {
|
||||
maximum = this.readVarUint32() >>> 0;
|
||||
}
|
||||
return { flags: flags, initial: initial, maximum: maximum };
|
||||
return { initial: initial, maximum: maximum };
|
||||
};
|
||||
BinaryReader.prototype.readTableType = function () {
|
||||
var elementType = this.readVarInt7();
|
||||
var limits = this.readResizableLimits();
|
||||
var flags = this.readVarUint32() >>> 0;
|
||||
var limits = this.readResizableLimits(!!(flags & 0x01));
|
||||
return { elementType: elementType, limits: limits };
|
||||
};
|
||||
BinaryReader.prototype.readMemoryType = function () {
|
||||
return { limits: this.readResizableLimits() };
|
||||
var flags = this.readVarUint32() >>> 0;
|
||||
var shared = !!(flags & 0x02);
|
||||
return { limits: this.readResizableLimits(!!(flags & 0x01)), shared: shared };
|
||||
};
|
||||
BinaryReader.prototype.readGlobalType = function () {
|
||||
if (!this.hasVarIntBytes()) {
|
||||
@@ -920,6 +1009,117 @@ var BinaryReader = (function () {
|
||||
this._sectionEntriesLeft--;
|
||||
return true;
|
||||
};
|
||||
BinaryReader.prototype.readCodeOperator_0xfc = function () {
|
||||
var code = this._data[this._pos++] | 0xfc00;
|
||||
switch (code) {
|
||||
case 64512 /* i32_trunc_s_sat_f32 */:
|
||||
case 64513 /* i32_trunc_u_sat_f32 */:
|
||||
case 64514 /* i32_trunc_s_sat_f64 */:
|
||||
case 64515 /* i32_trunc_u_sat_f64 */:
|
||||
case 64516 /* i64_trunc_s_sat_f32 */:
|
||||
case 64517 /* i64_trunc_u_sat_f32 */:
|
||||
case 64518 /* i64_trunc_s_sat_f64 */:
|
||||
case 64519 /* i64_trunc_u_sat_f64 */:
|
||||
break;
|
||||
default:
|
||||
this.error = new Error("Unknown operator: " + code);
|
||||
this.state = -1 /* ERROR */;
|
||||
return true;
|
||||
}
|
||||
this.result = { code: code,
|
||||
blockType: undefined, brDepth: undefined, brTable: undefined,
|
||||
funcIndex: undefined, typeIndex: undefined, localIndex: undefined,
|
||||
globalIndex: undefined, memoryAddress: undefined, literal: undefined };
|
||||
return true;
|
||||
};
|
||||
BinaryReader.prototype.readCodeOperator_0xfe = function () {
|
||||
var MAX_CODE_OPERATOR_0XFE_SIZE = 11;
|
||||
var pos = this._pos;
|
||||
if (!this._eof && pos + MAX_CODE_OPERATOR_0XFE_SIZE > this._length) {
|
||||
return false;
|
||||
}
|
||||
var code = this._data[this._pos++] | 0xfe00;
|
||||
var memoryAddress;
|
||||
switch (code) {
|
||||
case 65024 /* atomic_wake */:
|
||||
case 65025 /* i32_atomic_wait */:
|
||||
case 65026 /* i64_atomic_wait */:
|
||||
case 65040 /* i32_atomic_load */:
|
||||
case 65041 /* i64_atomic_load */:
|
||||
case 65042 /* i32_atomic_load8_u */:
|
||||
case 65043 /* i32_atomic_load16_u */:
|
||||
case 65044 /* i64_atomic_load8_u */:
|
||||
case 65045 /* i64_atomic_load16_u */:
|
||||
case 65046 /* i64_atomic_load32_u */:
|
||||
case 65047 /* i32_atomic_store */:
|
||||
case 65048 /* i64_atomic_store */:
|
||||
case 65049 /* i32_atomic_store8 */:
|
||||
case 65050 /* i32_atomic_store16 */:
|
||||
case 65051 /* i64_atomic_store8 */:
|
||||
case 65052 /* i64_atomic_store16 */:
|
||||
case 65053 /* i64_atomic_store32 */:
|
||||
case 65054 /* i32_atomic_rmw_add */:
|
||||
case 65055 /* i64_atomic_rmw_add */:
|
||||
case 65056 /* i32_atomic_rmw8_u_add */:
|
||||
case 65057 /* i32_atomic_rmw16_u_add */:
|
||||
case 65058 /* i64_atomic_rmw8_u_add */:
|
||||
case 65059 /* i64_atomic_rmw16_u_add */:
|
||||
case 65060 /* i64_atomic_rmw32_u_add */:
|
||||
case 65061 /* i32_atomic_rmw_sub */:
|
||||
case 65062 /* i64_atomic_rmw_sub */:
|
||||
case 65063 /* i32_atomic_rmw8_u_sub */:
|
||||
case 65064 /* i32_atomic_rmw16_u_sub */:
|
||||
case 65065 /* i64_atomic_rmw8_u_sub */:
|
||||
case 65066 /* i64_atomic_rmw16_u_sub */:
|
||||
case 65067 /* i64_atomic_rmw32_u_sub */:
|
||||
case 65068 /* i32_atomic_rmw_and */:
|
||||
case 65069 /* i64_atomic_rmw_and */:
|
||||
case 65070 /* i32_atomic_rmw8_u_and */:
|
||||
case 65071 /* i32_atomic_rmw16_u_and */:
|
||||
case 65072 /* i64_atomic_rmw8_u_and */:
|
||||
case 65073 /* i64_atomic_rmw16_u_and */:
|
||||
case 65074 /* i64_atomic_rmw32_u_and */:
|
||||
case 65075 /* i32_atomic_rmw_or */:
|
||||
case 65076 /* i64_atomic_rmw_or */:
|
||||
case 65077 /* i32_atomic_rmw8_u_or */:
|
||||
case 65078 /* i32_atomic_rmw16_u_or */:
|
||||
case 65079 /* i64_atomic_rmw8_u_or */:
|
||||
case 65080 /* i64_atomic_rmw16_u_or */:
|
||||
case 65081 /* i64_atomic_rmw32_u_or */:
|
||||
case 65082 /* i32_atomic_rmw_xor */:
|
||||
case 65083 /* i64_atomic_rmw_xor */:
|
||||
case 65084 /* i32_atomic_rmw8_u_xor */:
|
||||
case 65085 /* i32_atomic_rmw16_u_xor */:
|
||||
case 65086 /* i64_atomic_rmw8_u_xor */:
|
||||
case 65087 /* i64_atomic_rmw16_u_xor */:
|
||||
case 65088 /* i64_atomic_rmw32_u_xor */:
|
||||
case 65089 /* i32_atomic_rmw_xchg */:
|
||||
case 65090 /* i64_atomic_rmw_xchg */:
|
||||
case 65091 /* i32_atomic_rmw8_u_xchg */:
|
||||
case 65092 /* i32_atomic_rmw16_u_xchg */:
|
||||
case 65093 /* i64_atomic_rmw8_u_xchg */:
|
||||
case 65094 /* i64_atomic_rmw16_u_xchg */:
|
||||
case 65095 /* i64_atomic_rmw32_u_xchg */:
|
||||
case 65096 /* i32_atomic_rmw_cmpxchg */:
|
||||
case 65097 /* i64_atomic_rmw_cmpxchg */:
|
||||
case 65098 /* i32_atomic_rmw8_u_cmpxchg */:
|
||||
case 65099 /* i32_atomic_rmw16_u_cmpxchg */:
|
||||
case 65100 /* i64_atomic_rmw8_u_cmpxchg */:
|
||||
case 65101 /* i64_atomic_rmw16_u_cmpxchg */:
|
||||
case 65102 /* i64_atomic_rmw32_u_cmpxchg */:
|
||||
memoryAddress = this.readMemoryImmediate();
|
||||
break;
|
||||
default:
|
||||
this.error = new Error("Unknown operator: " + code);
|
||||
this.state = -1 /* ERROR */;
|
||||
return true;
|
||||
}
|
||||
this.result = { code: code,
|
||||
blockType: undefined, brDepth: undefined, brTable: undefined,
|
||||
funcIndex: undefined, typeIndex: undefined, localIndex: undefined,
|
||||
globalIndex: undefined, memoryAddress: memoryAddress, literal: undefined };
|
||||
return true;
|
||||
};
|
||||
BinaryReader.prototype.readCodeOperator = function () {
|
||||
if (this.state === 30 /* CODE_OPERATOR */ &&
|
||||
this._pos >= this._functionRange.end) {
|
||||
@@ -938,7 +1138,7 @@ var BinaryReader = (function () {
|
||||
if (!this._eof && pos + MAX_CODE_OPERATOR_SIZE > this._length) {
|
||||
return false;
|
||||
}
|
||||
var code = this._data[this._pos++];
|
||||
var code = this._data[this._pos++] | 0;
|
||||
var blockType, brDepth, brTable, funcIndex, typeIndex, localIndex, globalIndex, memoryAddress, literal, reserved;
|
||||
switch (code) {
|
||||
case 2 /* block */:
|
||||
@@ -1025,6 +1225,158 @@ var BinaryReader = (function () {
|
||||
literal = new DataView(this._data.buffer, this._data.byteOffset).getFloat64(this._pos, true);
|
||||
this._pos += 8;
|
||||
break;
|
||||
case 252 /* prefix_0xfc */:
|
||||
if (this.readCodeOperator_0xfc()) {
|
||||
return true;
|
||||
}
|
||||
this._pos = pos;
|
||||
return false;
|
||||
case 254 /* prefix_0xfe */:
|
||||
if (this.readCodeOperator_0xfe()) {
|
||||
return true;
|
||||
}
|
||||
this._pos = pos;
|
||||
return false;
|
||||
case 0 /* unreachable */:
|
||||
case 1 /* nop */:
|
||||
case 5 /* else */:
|
||||
case 11 /* end */:
|
||||
case 15 /* return */:
|
||||
case 26 /* drop */:
|
||||
case 27 /* select */:
|
||||
case 69 /* i32_eqz */:
|
||||
case 70 /* i32_eq */:
|
||||
case 71 /* i32_ne */:
|
||||
case 72 /* i32_lt_s */:
|
||||
case 73 /* i32_lt_u */:
|
||||
case 74 /* i32_gt_s */:
|
||||
case 75 /* i32_gt_u */:
|
||||
case 76 /* i32_le_s */:
|
||||
case 77 /* i32_le_u */:
|
||||
case 78 /* i32_ge_s */:
|
||||
case 79 /* i32_ge_u */:
|
||||
case 80 /* i64_eqz */:
|
||||
case 81 /* i64_eq */:
|
||||
case 82 /* i64_ne */:
|
||||
case 83 /* i64_lt_s */:
|
||||
case 84 /* i64_lt_u */:
|
||||
case 85 /* i64_gt_s */:
|
||||
case 86 /* i64_gt_u */:
|
||||
case 87 /* i64_le_s */:
|
||||
case 88 /* i64_le_u */:
|
||||
case 89 /* i64_ge_s */:
|
||||
case 90 /* i64_ge_u */:
|
||||
case 91 /* f32_eq */:
|
||||
case 92 /* f32_ne */:
|
||||
case 93 /* f32_lt */:
|
||||
case 94 /* f32_gt */:
|
||||
case 95 /* f32_le */:
|
||||
case 96 /* f32_ge */:
|
||||
case 97 /* f64_eq */:
|
||||
case 98 /* f64_ne */:
|
||||
case 99 /* f64_lt */:
|
||||
case 100 /* f64_gt */:
|
||||
case 101 /* f64_le */:
|
||||
case 102 /* f64_ge */:
|
||||
case 103 /* i32_clz */:
|
||||
case 104 /* i32_ctz */:
|
||||
case 105 /* i32_popcnt */:
|
||||
case 106 /* i32_add */:
|
||||
case 107 /* i32_sub */:
|
||||
case 108 /* i32_mul */:
|
||||
case 109 /* i32_div_s */:
|
||||
case 110 /* i32_div_u */:
|
||||
case 111 /* i32_rem_s */:
|
||||
case 112 /* i32_rem_u */:
|
||||
case 113 /* i32_and */:
|
||||
case 114 /* i32_or */:
|
||||
case 115 /* i32_xor */:
|
||||
case 116 /* i32_shl */:
|
||||
case 117 /* i32_shr_s */:
|
||||
case 118 /* i32_shr_u */:
|
||||
case 119 /* i32_rotl */:
|
||||
case 120 /* i32_rotr */:
|
||||
case 121 /* i64_clz */:
|
||||
case 122 /* i64_ctz */:
|
||||
case 123 /* i64_popcnt */:
|
||||
case 124 /* i64_add */:
|
||||
case 125 /* i64_sub */:
|
||||
case 126 /* i64_mul */:
|
||||
case 127 /* i64_div_s */:
|
||||
case 128 /* i64_div_u */:
|
||||
case 129 /* i64_rem_s */:
|
||||
case 130 /* i64_rem_u */:
|
||||
case 131 /* i64_and */:
|
||||
case 132 /* i64_or */:
|
||||
case 133 /* i64_xor */:
|
||||
case 134 /* i64_shl */:
|
||||
case 135 /* i64_shr_s */:
|
||||
case 136 /* i64_shr_u */:
|
||||
case 137 /* i64_rotl */:
|
||||
case 138 /* i64_rotr */:
|
||||
case 139 /* f32_abs */:
|
||||
case 140 /* f32_neg */:
|
||||
case 141 /* f32_ceil */:
|
||||
case 142 /* f32_floor */:
|
||||
case 143 /* f32_trunc */:
|
||||
case 144 /* f32_nearest */:
|
||||
case 145 /* f32_sqrt */:
|
||||
case 146 /* f32_add */:
|
||||
case 147 /* f32_sub */:
|
||||
case 148 /* f32_mul */:
|
||||
case 149 /* f32_div */:
|
||||
case 150 /* f32_min */:
|
||||
case 151 /* f32_max */:
|
||||
case 152 /* f32_copysign */:
|
||||
case 153 /* f64_abs */:
|
||||
case 154 /* f64_neg */:
|
||||
case 155 /* f64_ceil */:
|
||||
case 156 /* f64_floor */:
|
||||
case 157 /* f64_trunc */:
|
||||
case 158 /* f64_nearest */:
|
||||
case 159 /* f64_sqrt */:
|
||||
case 160 /* f64_add */:
|
||||
case 161 /* f64_sub */:
|
||||
case 162 /* f64_mul */:
|
||||
case 163 /* f64_div */:
|
||||
case 164 /* f64_min */:
|
||||
case 165 /* f64_max */:
|
||||
case 166 /* f64_copysign */:
|
||||
case 167 /* i32_wrap_i64 */:
|
||||
case 168 /* i32_trunc_s_f32 */:
|
||||
case 169 /* i32_trunc_u_f32 */:
|
||||
case 170 /* i32_trunc_s_f64 */:
|
||||
case 171 /* i32_trunc_u_f64 */:
|
||||
case 172 /* i64_extend_s_i32 */:
|
||||
case 173 /* i64_extend_u_i32 */:
|
||||
case 174 /* i64_trunc_s_f32 */:
|
||||
case 175 /* i64_trunc_u_f32 */:
|
||||
case 176 /* i64_trunc_s_f64 */:
|
||||
case 177 /* i64_trunc_u_f64 */:
|
||||
case 178 /* f32_convert_s_i32 */:
|
||||
case 179 /* f32_convert_u_i32 */:
|
||||
case 180 /* f32_convert_s_i64 */:
|
||||
case 181 /* f32_convert_u_i64 */:
|
||||
case 182 /* f32_demote_f64 */:
|
||||
case 183 /* f64_convert_s_i32 */:
|
||||
case 184 /* f64_convert_u_i32 */:
|
||||
case 185 /* f64_convert_s_i64 */:
|
||||
case 186 /* f64_convert_u_i64 */:
|
||||
case 187 /* f64_promote_f32 */:
|
||||
case 188 /* i32_reinterpret_f32 */:
|
||||
case 189 /* i64_reinterpret_f64 */:
|
||||
case 190 /* f32_reinterpret_i32 */:
|
||||
case 191 /* f64_reinterpret_i64 */:
|
||||
case 192 /* i32_extend8_s */:
|
||||
case 193 /* i32_extend16_s */:
|
||||
case 194 /* i64_extend8_s */:
|
||||
case 195 /* i64_extend16_s */:
|
||||
case 196 /* i64_extend32_s */:
|
||||
break;
|
||||
default:
|
||||
this.error = new Error("Unknown operator: " + code);
|
||||
this.state = -1 /* ERROR */;
|
||||
return true;
|
||||
}
|
||||
this.result = { code: code,
|
||||
blockType: blockType, brDepth: brDepth, brTable: brTable,
|
||||
|
||||
@@ -191,6 +191,7 @@
|
||||
#include "nsRect.h"
|
||||
#include "nsRefreshTimer.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "nsIServiceWorkerManager.h"
|
||||
#include "nsSHistory.h"
|
||||
#include "nsStructuredCloneContainer.h"
|
||||
#include "nsSubDocumentFrame.h"
|
||||
@@ -2792,7 +2793,7 @@ nsDocShell::MaybeCreateInitialClientSource(nsIPrincipal* aPrincipal)
|
||||
// Don't pre-allocate the client when we are sandboxed. The inherited
|
||||
// principal does not take sandboxing into account.
|
||||
// TODO: Refactor sandboxing principal code out so we can use it here.
|
||||
if (!aPrincipal && (mSandboxFlags & SANDBOXED_ORIGIN)) {
|
||||
if (!aPrincipal && mSandboxFlags) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2834,18 +2835,34 @@ nsDocShell::MaybeCreateInitialClientSource(nsIPrincipal* aPrincipal)
|
||||
return;
|
||||
}
|
||||
|
||||
// We're done if there is no parent controller or if this docshell
|
||||
// is not permitted to control for some reason.
|
||||
Maybe<ServiceWorkerDescriptor> controller(parentInner->GetController());
|
||||
if (controller.isNothing()) {
|
||||
if (controller.isNothing() || !ServiceWorkerAllowedToControlWindow(nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIServiceWorkerManager> swm = mozilla::services::GetServiceWorkerManager();
|
||||
if (!swm) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the parent is controlled then propagate that controller to the
|
||||
// initial about:blank client as well. This will set the controller
|
||||
// in the ClientManagerService in the parent.
|
||||
RefPtr<ClientHandle> handle =
|
||||
ClientManager::CreateHandle(mInitialClientSource->Info(),
|
||||
parentInner->EventTargetFor(TaskCategory::Other));
|
||||
handle->Control(controller.ref());
|
||||
//
|
||||
// Note: If the registration is missing from the SWM we avoid setting
|
||||
// the controller on the client. We can do this synchronously
|
||||
// for now since SWM is in the child process. In the future
|
||||
// when SWM is in the parent process we will probably have to
|
||||
// always set the initial client source and then somehow clear
|
||||
// it if we find the registration is acutally gone. Its also
|
||||
// possible this race only occurs in cases where the resulting
|
||||
// window is no longer exposed. For example, in theory the SW
|
||||
// should not go away if our parent window is controlled.
|
||||
if (!swm->StartControlling(mInitialClientSource->Info(), controller.ref())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Also mark the ClientSource as controlled directly in case script
|
||||
// immediately accesses navigator.serviceWorker.controller.
|
||||
@@ -14085,6 +14102,54 @@ nsDocShell::CanSetOriginAttributes()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocShell::ServiceWorkerAllowedToControlWindow(nsIURI* aURI)
|
||||
{
|
||||
// NOTE: Ideally this method would call one of the
|
||||
// nsContentUtils::StorageAllowed*() methods to determine if the
|
||||
// interception is allowed. Unfortunately we cannot safely do this
|
||||
// before the first window loads in the child process because the
|
||||
// permission manager might not have all its data yet. Therefore,
|
||||
// we use this somewhat lame alternate implementation here. Once
|
||||
// interception is moved to the parent process we should switch
|
||||
// to calling nsContentUtils::StorageAllowed*(). See bug 1428130.
|
||||
|
||||
if (UsePrivateBrowsing() || mSandboxFlags) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t cookieBehavior = nsContentUtils::CookiesBehavior();
|
||||
uint32_t lifetimePolicy = nsContentUtils::CookiesLifetimePolicy();
|
||||
if (cookieBehavior == nsICookieService::BEHAVIOR_REJECT ||
|
||||
lifetimePolicy == nsICookieService::ACCEPT_SESSION) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aURI || cookieBehavior == nsICookieService::BEHAVIOR_ACCEPT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> parent;
|
||||
GetSameTypeParent(getter_AddRefs(parent));
|
||||
nsCOMPtr<nsPIDOMWindowOuter> parentWindow = parent ? parent->GetWindow()
|
||||
: nullptr;
|
||||
if (parentWindow) {
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
|
||||
do_GetService(THIRDPARTYUTIL_CONTRACTID, &rv);
|
||||
if (thirdPartyUtil) {
|
||||
bool isThirdPartyURI = true;
|
||||
rv = thirdPartyUtil->IsThirdPartyWindow(parentWindow, aURI,
|
||||
&isThirdPartyURI);
|
||||
if (NS_SUCCEEDED(rv) && isThirdPartyURI) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocShell::SetOriginAttributes(const OriginAttributes& aAttrs)
|
||||
{
|
||||
@@ -14289,27 +14354,11 @@ nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNonSubresourceReques
|
||||
bool* aShouldIntercept)
|
||||
{
|
||||
*aShouldIntercept = false;
|
||||
// No in private browsing
|
||||
if (UsePrivateBrowsing()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mSandboxFlags) {
|
||||
// If we're sandboxed, don't intercept.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t cookieBehavior = nsContentUtils::CookiesBehavior();
|
||||
if (cookieBehavior == nsICookieService::BEHAVIOR_REJECT) {
|
||||
// If cookies are disabled, don't intercept.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
if (!swm) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// For subresource requests we base our decision solely on the client's
|
||||
// controller value. Any settings that would have blocked service worker
|
||||
// access should have been set before the initial navigation created the
|
||||
// window.
|
||||
if (!aIsNonSubresourceRequest) {
|
||||
nsCOMPtr<nsIDocument> doc = GetDocument();
|
||||
if (!doc) {
|
||||
@@ -14325,27 +14374,19 @@ nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNonSubresourceReques
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If the user has set a cookie policy that restricts cookies, then
|
||||
// avoid intercepting 3rd party iframes.
|
||||
if (cookieBehavior != nsICookieService::BEHAVIOR_ACCEPT) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> parent;
|
||||
GetSameTypeParent(getter_AddRefs(parent));
|
||||
nsCOMPtr<nsPIDOMWindowOuter> parentWindow = parent ? parent->GetWindow()
|
||||
: nullptr;
|
||||
if (parentWindow) {
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
|
||||
do_GetService(THIRDPARTYUTIL_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool isThirdPartyURI = true;
|
||||
rv = thirdPartyUtil->IsThirdPartyWindow(parentWindow, aURI, &isThirdPartyURI);
|
||||
if (NS_SUCCEEDED(rv) && isThirdPartyURI) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
// For navigations, first check to see if we are allowed to control a
|
||||
// window with the given URL.
|
||||
if (!ServiceWorkerAllowedToControlWindow(aURI)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
if (!swm) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We're allowed to control a window, so check with the ServiceWorkerManager
|
||||
// for a matching service worker.
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
BasePrincipal::CreateCodebasePrincipal(aURI, mOriginAttributes);
|
||||
*aShouldIntercept = swm->IsAvailable(principal, aURI);
|
||||
|
||||
@@ -352,6 +352,19 @@ public:
|
||||
mAncestorOuterWindowIDs = mozilla::Move(aAncestorOuterWindowIDs);
|
||||
}
|
||||
|
||||
bool CanSetOriginAttributes();
|
||||
|
||||
// Determine if a service worker is allowed to control a window in this
|
||||
// docshell with the given URL. If there are any reasons it should not,
|
||||
// this will return false. If true is returned then the window *may* be
|
||||
// controlled. The caller must still consult either the parent controller
|
||||
// or the ServiceWorkerManager to determine if a service worker should
|
||||
// actually control the window.
|
||||
//
|
||||
// A nullptr URL is considered to be an about:blank window and will not
|
||||
// trigger 3rd party iframe checks.
|
||||
bool ServiceWorkerAllowedToControlWindow(nsIURI* aURI);
|
||||
|
||||
const mozilla::OriginAttributes& GetOriginAttributes()
|
||||
{
|
||||
return mOriginAttributes;
|
||||
|
||||
@@ -2937,6 +2937,11 @@ public:
|
||||
return sCookiesBehavior;
|
||||
}
|
||||
|
||||
static uint32_t CookiesLifetimePolicy()
|
||||
{
|
||||
return sCookiesLifetimePolicy;
|
||||
}
|
||||
|
||||
// The order of these entries matters, as we use std::min for total ordering
|
||||
// of permissions. Private Browsing is considered to be more limiting
|
||||
// then session scoping
|
||||
|
||||
@@ -5599,7 +5599,10 @@ nsDocument::DispatchContentLoadedEvents()
|
||||
using mozilla::dom::workers::ServiceWorkerManager;
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
if (swm) {
|
||||
swm->MaybeCheckNavigationUpdate(this);
|
||||
Maybe<ClientInfo> clientInfo = GetClientInfo();
|
||||
if (clientInfo.isSome()) {
|
||||
swm->MaybeCheckNavigationUpdate(clientInfo.ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1786,11 +1786,34 @@ nsGlobalWindowInner::EnsureClientSource()
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the final ClientSource principal matches the final document
|
||||
// principal. The ClientChannelHelper handles things like network
|
||||
// redirects, but there are other ways the document principal can change.
|
||||
// For example, if something sets the nsIChannel.owner property, then
|
||||
// the final channel principal can be anything. Unfortunately there is
|
||||
// no good way to detect this until after the channel completes loading.
|
||||
//
|
||||
// For now we handle this just by reseting the ClientSource. This will
|
||||
// result in a new ClientSource with the correct principal being created.
|
||||
// To APIs like ServiceWorker and Clients API it will look like there was
|
||||
// an initial content page created that was then immediately replaced.
|
||||
// This is pretty close to what we are actually doing.
|
||||
if (mClientSource) {
|
||||
nsCOMPtr<nsIPrincipal> clientPrincipal(mClientSource->Info().GetPrincipal());
|
||||
if (!clientPrincipal || !clientPrincipal->Equals(mDoc->NodePrincipal())) {
|
||||
mClientSource.reset();
|
||||
}
|
||||
}
|
||||
|
||||
// If we don't have a reserved client or an initial client, then create
|
||||
// one now. This can happen in certain cases where we avoid preallocating
|
||||
// the client in the docshell. This mainly occurs in situations where
|
||||
// the principal is not clearly inherited from the parent; e.g. sandboxed
|
||||
// iframes, window.open(), etc.
|
||||
//
|
||||
// We also do this late ClientSource creation if the final document ended
|
||||
// up with a different principal.
|
||||
//
|
||||
// TODO: We may not be marking initial about:blank documents created
|
||||
// this way as controlled by a service worker properly. The
|
||||
// controller should be coming from the same place as the inheritted
|
||||
@@ -1804,13 +1827,23 @@ nsGlobalWindowInner::EnsureClientSource()
|
||||
mDoc->NodePrincipal());
|
||||
MOZ_DIAGNOSTIC_ASSERT(mClientSource);
|
||||
newClientSource = true;
|
||||
|
||||
// Note, we don't apply the loadinfo controller below if we create
|
||||
// the ClientSource here.
|
||||
}
|
||||
|
||||
// The load may have started controlling the Client as well. If
|
||||
// so, mark it as controlled immediately here. The actor may
|
||||
// or may not have been notified by the parent side about being
|
||||
// controlled yet.
|
||||
if (loadInfo) {
|
||||
//
|
||||
// Note: We should be careful not to control a client that was created late.
|
||||
// These clients were not seen by the ServiceWorkerManager when it
|
||||
// marked the LoadInfo controlled and it won't know about them. Its
|
||||
// also possible we are creating the client late due to the final
|
||||
// principal changing and these clients should definitely not be
|
||||
// controlled by a service worker with a different principal.
|
||||
else if (loadInfo) {
|
||||
const Maybe<ServiceWorkerDescriptor> controller = loadInfo->GetController();
|
||||
if (controller.isSome()) {
|
||||
mClientSource->SetController(controller.ref());
|
||||
|
||||
@@ -3117,11 +3117,10 @@ nsGlobalWindowOuter::SetStatusOuter(const nsAString& aStatus)
|
||||
mStatus = aStatus;
|
||||
|
||||
/*
|
||||
* If caller is not chrome and dom.disable_window_status_change is true,
|
||||
* prevent propagating window.status to the UI by exiting early
|
||||
* If caller is not chrome, prevent propagating window.status to the UI by
|
||||
* exiting early.
|
||||
*/
|
||||
|
||||
if (!CanSetProperty("dom.disable_window_status_change")) {
|
||||
if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -579,6 +579,7 @@ skip-if = toolkit == 'android' #bug 687032
|
||||
skip-if = stylo # bug 1293844
|
||||
[test_bug1037687.html]
|
||||
skip-if = stylo # bug 1293844
|
||||
support-files = test_bug1037687_subframe.html
|
||||
[test_bug1043106.html]
|
||||
[test_bug1057176.html]
|
||||
[test_bug1060938.html]
|
||||
|
||||
@@ -15,12 +15,25 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1025933
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function test() {
|
||||
var s = document.getElementById("host").createShadowRoot();
|
||||
s.innerHTML = '<div style="width:100px;height:100px;background:red"></div>';
|
||||
var el = s.firstElementChild;
|
||||
is(el.clientWidth, 100);
|
||||
is(el.clientHeight, 100);
|
||||
SimpleTest.finish();
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["dom.webcomponents.enabled", true]
|
||||
]
|
||||
}, function() {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.srcdoc = '<div id="content"> <div id="host"></div </div>';
|
||||
|
||||
iframe.onload = function() {
|
||||
var s = iframe.contentDocument.getElementById("host").attachShadow({mode: 'open'});
|
||||
s.innerHTML = '<div style="width:100px;height:100px;background:red"></div>';
|
||||
var el = s.firstElementChild;
|
||||
is(el.clientWidth, 100);
|
||||
is(el.clientHeight, 100);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -28,9 +41,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1025933
|
||||
<body onload="test()">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1025933">Mozilla Bug 1025933</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<div id="host"></div>
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
@@ -8,49 +8,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1037687
|
||||
<title>Test for Bug 1037687</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 1037687 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var host;
|
||||
var sr;
|
||||
var embed;
|
||||
var object;
|
||||
var iframe;
|
||||
var resourceLoadCount = 0;
|
||||
|
||||
function resourceLoaded(event) {
|
||||
++resourceLoadCount;
|
||||
ok(true, event.target + " got " + event.load);
|
||||
if (resourceLoadCount == 3) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
function createResource(sr, type) {
|
||||
var el = document.createElement(type);
|
||||
var attrName = type == "object" ? "data" : "src";
|
||||
el.setAttribute(attrName, "file_mozfiledataurl_img.jpg");
|
||||
el.onload = resourceLoaded;
|
||||
var info = document.createElement("div");
|
||||
info.textContent = type;
|
||||
sr.appendChild(info);
|
||||
sr.appendChild(el);
|
||||
}
|
||||
|
||||
function test() {
|
||||
host = document.getElementById("host");
|
||||
sr = host.createShadowRoot();
|
||||
embed = createResource(sr, "embed");
|
||||
object = createResource(sr, "object");
|
||||
iframe = createResource(sr, "iframe");
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="test()">
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1037687">Mozilla Bug 1037687</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
@@ -58,6 +17,20 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1037687
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<div id="host"></div>
|
||||
<script type="application/javascript">
|
||||
/** Test for Bug 1037687 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["dom.webcomponents.enabled", true]
|
||||
]
|
||||
}, function() {
|
||||
// This test loads in an iframe, to ensure that the element instance is
|
||||
// loaded with the correct value of the preference.
|
||||
let iframe = document.createElement("iframe");
|
||||
iframe.src = "test_bug1037687_subframe.html";
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
47
dom/base/test/test_bug1037687_subframe.html
Normal file
47
dom/base/test/test_bug1037687_subframe.html
Normal file
@@ -0,0 +1,47 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script type="application/javascript">
|
||||
var SimpleTest = window.parent.SimpleTest;
|
||||
var ok = window.parent.ok;
|
||||
var is = window.parent.is;
|
||||
|
||||
var host;
|
||||
var sr;
|
||||
var embed;
|
||||
var object;
|
||||
var iframe;
|
||||
var resourceLoadCount = 0;
|
||||
|
||||
function resourceLoaded(event) {
|
||||
++resourceLoadCount;
|
||||
ok(true, event.target + " got " + event.load);
|
||||
if (resourceLoadCount == 3) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
function createResource(sr, type) {
|
||||
var el = document.createElement(type);
|
||||
var attrName = type == "object" ? "data" : "src";
|
||||
el.setAttribute(attrName, "file_mozfiledataurl_img.jpg");
|
||||
el.onload = resourceLoaded;
|
||||
var info = document.createElement("div");
|
||||
info.textContent = type;
|
||||
sr.appendChild(info);
|
||||
sr.appendChild(el);
|
||||
}
|
||||
|
||||
function test() {
|
||||
host = document.getElementById("host");
|
||||
sr = host.attachShadow({mode: 'open'});
|
||||
embed = createResource(sr, "embed");
|
||||
object = createResource(sr, "object");
|
||||
iframe = createResource(sr, "iframe");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="test()">
|
||||
<div id="host"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -65,6 +65,16 @@ ClientHandle::StartOp(const ClientOpConstructorArgs& aArgs)
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
void
|
||||
ClientHandle::OnShutdownThing()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(ClientHandle);
|
||||
if (!mDetachPromise) {
|
||||
return;
|
||||
}
|
||||
mDetachPromise->Resolve(true, __func__);
|
||||
}
|
||||
|
||||
ClientHandle::ClientHandle(ClientManager* aManager,
|
||||
nsISerialEventTarget* aSerialEventTarget,
|
||||
const ClientInfo& aClientInfo)
|
||||
@@ -182,5 +192,21 @@ ClientHandle::PostMessage(StructuredCloneData& aData,
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
RefPtr<GenericPromise>
|
||||
ClientHandle::OnDetach()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(ClientSource);
|
||||
|
||||
if (!mDetachPromise) {
|
||||
mDetachPromise = new GenericPromise::Private(__func__);
|
||||
if (IsShutdown()) {
|
||||
mDetachPromise->Resolve(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<GenericPromise> ref(mDetachPromise);
|
||||
return Move(ref);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -42,6 +42,7 @@ class ClientHandle final : public ClientThing<ClientHandleChild>
|
||||
|
||||
RefPtr<ClientManager> mManager;
|
||||
nsCOMPtr<nsISerialEventTarget> mSerialEventTarget;
|
||||
RefPtr<GenericPromise::Private> mDetachPromise;
|
||||
ClientInfo mClientInfo;
|
||||
|
||||
~ClientHandle();
|
||||
@@ -52,6 +53,10 @@ class ClientHandle final : public ClientThing<ClientHandleChild>
|
||||
already_AddRefed<ClientOpPromise>
|
||||
StartOp(const ClientOpConstructorArgs& aArgs);
|
||||
|
||||
// ClientThing interface
|
||||
void
|
||||
OnShutdownThing() override;
|
||||
|
||||
// Private methods called by ClientHandleChild
|
||||
void
|
||||
ExecutionReady(const ClientInfo& aClientInfo);
|
||||
@@ -90,6 +95,17 @@ public:
|
||||
PostMessage(ipc::StructuredCloneData& aData,
|
||||
const ServiceWorkerDescriptor& aSource);
|
||||
|
||||
// Return a Promise that resolves when the ClientHandle object is detached
|
||||
// from its remote actors. This will happen if the ClientSource is destroyed
|
||||
// and triggers the cleanup of the handle actors. It will also naturally
|
||||
// happen when the ClientHandle is de-referenced and tears down its own
|
||||
// actors.
|
||||
//
|
||||
// Note: This method can only be called on the ClientHandle owning thread,
|
||||
// but the MozPromise lets you Then() to another thread.
|
||||
RefPtr<GenericPromise>
|
||||
OnDetach();
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(ClientHandle);
|
||||
};
|
||||
|
||||
|
||||
@@ -7,11 +7,13 @@
|
||||
#include "ClientInfo.h"
|
||||
|
||||
#include "mozilla/dom/ClientIPCTypes.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
using mozilla::ipc::PrincipalInfo;
|
||||
using mozilla::ipc::PrincipalInfoToPrincipal;
|
||||
|
||||
ClientInfo::ClientInfo(const nsID& aId,
|
||||
ClientType aType,
|
||||
@@ -138,5 +140,13 @@ ClientInfo::IsPrivateBrowsing() const
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal>
|
||||
ClientInfo::GetPrincipal() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsCOMPtr<nsIPrincipal> ref = PrincipalInfoToPrincipal(PrincipalInfo());
|
||||
return Move(ref);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -95,6 +95,11 @@ public:
|
||||
// Determine if the client is in private browsing mode.
|
||||
bool
|
||||
IsPrivateBrowsing() const;
|
||||
|
||||
// Get a main-thread nsIPrincipal for the client. This may return nullptr
|
||||
// if the PrincipalInfo() fails to deserialize for some reason.
|
||||
nsCOMPtr<nsIPrincipal>
|
||||
GetPrincipal() const;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
||||
@@ -206,6 +206,14 @@ ClientSource::WorkerExecutionReady(WorkerPrivate* aWorkerPrivate)
|
||||
return;
|
||||
}
|
||||
|
||||
// A client without access to storage should never be controlled by
|
||||
// a service worker. Check this here in case we were controlled before
|
||||
// execution ready. We can't reliably determine what our storage policy
|
||||
// is before execution ready, unfortunately.
|
||||
if (mController.isSome()) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate->IsStorageAllowed());
|
||||
}
|
||||
|
||||
// Its safe to store the WorkerPrivate* here because the ClientSource
|
||||
// is explicitly destroyed by WorkerPrivate before exiting its run loop.
|
||||
MOZ_DIAGNOSTIC_ASSERT(mOwner.is<Nothing>());
|
||||
@@ -235,6 +243,15 @@ ClientSource::WindowExecutionReady(nsPIDOMWindowInner* aInnerWindow)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// A client without access to storage should never be controlled by
|
||||
// a service worker. Check this here in case we were controlled before
|
||||
// execution ready. We can't reliably determine what our storage policy
|
||||
// is before execution ready, unfortunately.
|
||||
if (mController.isSome()) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(nsContentUtils::StorageAllowedForWindow(aInnerWindow) ==
|
||||
nsContentUtils::StorageAccess::eAllow);
|
||||
}
|
||||
|
||||
// Don't use nsAutoCString here since IPC requires a full nsCString anyway.
|
||||
nsCString spec;
|
||||
|
||||
@@ -290,6 +307,10 @@ ClientSource::DocShellExecutionReady(nsIDocShell* aDocShell)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// Note: We don't assert storage access for a controlled client. If
|
||||
// the about:blank actually gets used then WindowExecutionReady() will
|
||||
// get called which asserts storage access.
|
||||
|
||||
// TODO: dedupe this with WindowExecutionReady
|
||||
FrameType frameType = FrameType::Top_level;
|
||||
if (!outer->IsTopLevelWindow()) {
|
||||
@@ -360,6 +381,16 @@ ClientSource::SetController(const ServiceWorkerDescriptor& aServiceWorker)
|
||||
// this invariant.
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mClientInfo.IsPrivateBrowsing());
|
||||
|
||||
// A client without access to storage should never be controlled a
|
||||
// a service worker. If we are already execution ready with a real
|
||||
// window or worker, then verify assert the storage policy is correct.
|
||||
if (GetInnerWindow()) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(nsContentUtils::StorageAllowedForWindow(GetInnerWindow()) ==
|
||||
nsContentUtils::StorageAccess::eAllow);
|
||||
} else if (GetWorkerPrivate()) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(GetWorkerPrivate()->IsStorageAllowed());
|
||||
}
|
||||
|
||||
if (mController.isSome() && mController.ref() == aServiceWorker) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -90,6 +90,15 @@ protected:
|
||||
mActor->MaybeStartTeardown();
|
||||
mActor = nullptr;
|
||||
}
|
||||
|
||||
OnShutdownThing();
|
||||
}
|
||||
|
||||
// Allow extending classes to take action when shutdown.
|
||||
virtual void
|
||||
OnShutdownThing()
|
||||
{
|
||||
// by default do nothing
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -106,6 +115,8 @@ public:
|
||||
// instead of calling ShutdownThing() to avoid calling MaybeStartTeardown()
|
||||
// on the destroyed actor.
|
||||
mShutdown = true;
|
||||
|
||||
OnShutdownThing();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1263,23 +1263,6 @@ IMEContentObserver::ClearAddedNodesDuringDocumentChange()
|
||||
", finished storing consecutive nodes", this));
|
||||
}
|
||||
|
||||
// static
|
||||
nsIContent*
|
||||
IMEContentObserver::GetChildNode(nsINode* aParent, int32_t aOffset)
|
||||
{
|
||||
if (!aParent->HasChildren() || aOffset < 0 ||
|
||||
aOffset >= static_cast<int32_t>(aParent->Length())) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!aOffset) {
|
||||
return aParent->GetFirstChild();
|
||||
}
|
||||
if (aOffset == static_cast<int32_t>(aParent->Length() - 1)) {
|
||||
return aParent->GetLastChild();
|
||||
}
|
||||
return aParent->GetChildAt_Deprecated(aOffset);
|
||||
}
|
||||
|
||||
bool
|
||||
IMEContentObserver::IsNextNodeOfLastAddedNode(nsINode* aParent,
|
||||
nsIContent* aChild) const
|
||||
|
||||
@@ -188,12 +188,6 @@ private:
|
||||
bool IsSafeToNotifyIME() const;
|
||||
bool IsEditorComposing() const;
|
||||
|
||||
/**
|
||||
* nsINode::GetChildAt() is slow. So, this avoids to use it if it's
|
||||
* first child or last child of aParent.
|
||||
*/
|
||||
static nsIContent* GetChildNode(nsINode* aParent, int32_t aOffset);
|
||||
|
||||
// Following methods are called by DocumentObserver when
|
||||
// beginning to update the contents and ending updating the contents.
|
||||
void BeginDocumentUpdate();
|
||||
|
||||
@@ -13,38 +13,48 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1079236
|
||||
|
||||
/** Test for Bug 1079236 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(runTests);
|
||||
function runTests() {
|
||||
var iframe = document.createElement('iframe');
|
||||
document.body.appendChild(iframe);
|
||||
iframe.contentDocument.body.innerHTML = '<div id="content"></div>';
|
||||
|
||||
function runTests() {
|
||||
var c = document.getElementById("content");
|
||||
var sr = c.createShadowRoot();
|
||||
sr.innerHTML = "<input type='file'" + ">";
|
||||
var file = sr.firstChild;
|
||||
is(file.type, "file");
|
||||
file.offsetLeft; // Flush layout because dispatching mouse events.
|
||||
document.body.onmousemove = function(e) {
|
||||
is(e.target, c, "Event target should be the element in non-Shadow DOM");
|
||||
if (e.originalTarget == file) {
|
||||
is(e.originalTarget, file,
|
||||
"type='file' implementation doesn't seem to have native anonymous content");
|
||||
} else {
|
||||
var wrapped = SpecialPowers.wrap(e.originalTarget);
|
||||
isnot(wrapped, file, "Shouldn't have the same event.target and event.originalTarget");
|
||||
var c = iframe.contentDocument.getElementById("content");
|
||||
var sr = c.attachShadow({mode: 'open'});
|
||||
sr.innerHTML = "<input type='file'" + ">";
|
||||
var file = sr.firstChild;
|
||||
is(file.type, "file");
|
||||
file.offsetLeft; // Flush layout because dispatching mouse events.
|
||||
iframe.contentDocument.body.onmousemove = function(e) {
|
||||
is(e.target, c, "Event target should be the element in non-Shadow DOM");
|
||||
if (e.originalTarget == file) {
|
||||
is(e.originalTarget, file,
|
||||
"type='file' implementation doesn't seem to have native anonymous content");
|
||||
} else {
|
||||
var wrapped = SpecialPowers.wrap(e.originalTarget);
|
||||
isnot(wrapped, file, "Shouldn't have the same event.target and event.originalTarget");
|
||||
}
|
||||
|
||||
ok(!("composedTarget" in e), "Events shouldn't have composedTarget in non-chrome context!");
|
||||
e = SpecialPowers.wrap(e);
|
||||
var composedTarget = SpecialPowers.unwrap(e.composedTarget);
|
||||
ok(composedTarget, file, "composedTarget should be the file object.");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
ok(!("composedTarget" in e), "Events shouldn't have composedTarget in non-chrome context!");
|
||||
e = SpecialPowers.wrap(e);
|
||||
var composedTarget = SpecialPowers.unwrap(e.composedTarget);
|
||||
ok(composedTarget, file, "composedTarget should be the file object.");
|
||||
|
||||
SimpleTest.finish();
|
||||
var r = file.getBoundingClientRect();
|
||||
synthesizeMouse(file, r.width / 6, r.height / 2, { type: "mousemove"}, iframe.contentWindow);
|
||||
iframe.contentDocument.body.onmousemove = null;
|
||||
}
|
||||
|
||||
var r = file.getBoundingClientRect();
|
||||
synthesizeMouse(file, r.width / 6, r.height / 2, { type: "mousemove"} );
|
||||
document.body.onmousemove = null;
|
||||
}
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(() => {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["dom.webcomponents.enabled", true]
|
||||
]
|
||||
}, runTests);
|
||||
});
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
@@ -10,37 +10,47 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1145910
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
div:active {
|
||||
color: rgb(0, 255, 0);
|
||||
}
|
||||
</style>
|
||||
<div id="host">Foo</div>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 1145910 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SimpleTest.waitForFocus(function() {
|
||||
var host = document.getElementById("host");
|
||||
var shadow = host.createShadowRoot();
|
||||
function runTests() {
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
document.body.appendChild(iframe);
|
||||
iframe.contentDocument.body.innerHTML =
|
||||
'<style> div:active { color: rgb(0, 255, 0); } </style> <div id="host">Foo</div>';
|
||||
|
||||
var host = iframe.contentDocument.getElementById("host");
|
||||
var shadow = host.attachShadow({mode: 'open'});
|
||||
shadow.innerHTML = '<style>div:active { color: rgb(0, 255, 0); }</style><div id="inner">Bar</div>';
|
||||
var inner = shadow.getElementById("inner");
|
||||
var iframeWin = iframe.contentWindow;
|
||||
|
||||
is(window.getComputedStyle(host).color, "rgb(0, 0, 0)", "The host should not be active");
|
||||
is(window.getComputedStyle(inner).color, "rgb(0, 0, 0)", "The div inside the shadow root should not be active.");
|
||||
is(iframeWin.getComputedStyle(host).color, "rgb(0, 0, 0)", "The host should not be active");
|
||||
is(iframeWin.getComputedStyle(inner).color, "rgb(0, 0, 0)", "The div inside the shadow root should not be active.");
|
||||
|
||||
synthesizeMouseAtCenter(host, { type: "mousedown" });
|
||||
synthesizeMouseAtCenter(host, { type: "mousedown" }, iframeWin);
|
||||
|
||||
is(window.getComputedStyle(inner).color, "rgb(0, 255, 0)", "Div inside shadow root should be active.");
|
||||
is(window.getComputedStyle(host).color, "rgb(0, 255, 0)", "Host should be active when the inner div is made active.");
|
||||
is(iframeWin.getComputedStyle(inner).color, "rgb(0, 255, 0)", "Div inside shadow root should be active.");
|
||||
is(iframeWin.getComputedStyle(host).color, "rgb(0, 255, 0)", "Host should be active when the inner div is made active.");
|
||||
|
||||
synthesizeMouseAtCenter(host, { type: "mouseup" });
|
||||
synthesizeMouseAtCenter(host, { type: "mouseup" }, iframeWin);
|
||||
|
||||
is(window.getComputedStyle(inner).color, "rgb(0, 0, 0)", "Div inside shadow root should no longer be active.");
|
||||
is(window.getComputedStyle(host).color, "rgb(0, 0, 0)", "Host should no longer be active.");
|
||||
is(iframeWin.getComputedStyle(inner).color, "rgb(0, 0, 0)", "Div inside shadow root should no longer be active.");
|
||||
is(iframeWin.getComputedStyle(host).color, "rgb(0, 0, 0)", "Host should no longer be active.");
|
||||
|
||||
SimpleTest.finish();
|
||||
};
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(() => {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["dom.webcomponents.enabled", true]
|
||||
]
|
||||
}, runTests);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
@@ -10,32 +10,44 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1150308
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="host"><span id="distributeme">Foo</span></div>
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 1150308 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SimpleTest.waitForFocus(function() {
|
||||
var host = document.getElementById("host");
|
||||
var shadow = host.createShadowRoot();
|
||||
shadow.innerHTML = '<style>.bar:active { color: rgb(0, 255, 0); }</style><div class="bar" id="inner"><content></content></div>';
|
||||
function runTests() {
|
||||
var iframe = document.createElement('iframe');
|
||||
document.body.appendChild(iframe);
|
||||
iframe.contentDocument.body.innerHTML =
|
||||
'<div id="host"><span id="distributeme">Foo</span></div>';
|
||||
|
||||
var host = iframe.contentDocument.getElementById("host");
|
||||
var shadow = host.attachShadow({mode: 'open'});
|
||||
shadow.innerHTML = '<style>.bar:active { color: rgb(0, 255, 0); }</style><div class="bar" id="inner"><slot></slot></div>';
|
||||
var inner = shadow.getElementById("inner");
|
||||
var distributed = document.getElementById("distributeme");
|
||||
var distributed = iframe.contentDocument.getElementById("distributeme");
|
||||
var iframeWin = iframe.contentWindow;
|
||||
|
||||
is(window.getComputedStyle(inner).color, "rgb(0, 0, 0)", "The div inside the shadow root should not be active.");
|
||||
is(iframeWin.getComputedStyle(inner).color, "rgb(0, 0, 0)", "The div inside the shadow root should not be active.");
|
||||
|
||||
synthesizeMouseAtCenter(distributed, { type: "mousedown" });
|
||||
synthesizeMouseAtCenter(distributed, { type: "mousedown" }, iframeWin);
|
||||
|
||||
is(window.getComputedStyle(inner).color, "rgb(0, 255, 0)", "Div inside shadow root should be active.");
|
||||
is(iframeWin.getComputedStyle(inner).color, "rgb(0, 255, 0)", "Div inside shadow root should be active.");
|
||||
|
||||
synthesizeMouseAtCenter(distributed, { type: "mouseup" });
|
||||
synthesizeMouseAtCenter(distributed, { type: "mouseup" }, iframeWin);
|
||||
|
||||
is(window.getComputedStyle(inner).color, "rgb(0, 0, 0)", "Div inside shadow root should no longer be active.");
|
||||
is(iframeWin.getComputedStyle(inner).color, "rgb(0, 0, 0)", "Div inside shadow root should no longer be active.");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
};
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(() => {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["dom.webcomponents.enabled", true]
|
||||
]
|
||||
}, runTests);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,20 +6,21 @@
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script>
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.webcomponents.enabled", true]
|
||||
]});
|
||||
|
||||
function runTests()
|
||||
{
|
||||
let dragService = SpecialPowers.Cc["@mozilla.org/widget/dragservice;1"].
|
||||
getService(SpecialPowers.Ci.nsIDragService);
|
||||
|
||||
let shadow = document.querySelector('#outter').createShadowRoot();
|
||||
let target = document.createElement('a');
|
||||
let linkText = document.createTextNode("Drag me if you can!");
|
||||
let iframe = document.createElement('iframe');
|
||||
document.body.appendChild(iframe);
|
||||
iframe.contentDocument.body.innerHTML = '<div id="outter"/>';
|
||||
|
||||
let iframeDoc = iframe.contentDocument;
|
||||
let iframeWin = iframe.contentWindow;
|
||||
|
||||
let shadow = iframeDoc.querySelector('#outter').attachShadow({mode: 'open'});
|
||||
let target = iframeDoc.createElement('a');
|
||||
let linkText = iframeDoc.createTextNode("Drag me if you can!");
|
||||
target.appendChild(linkText);
|
||||
target.href = "http://www.mozilla.org/";
|
||||
shadow.appendChild(target);
|
||||
@@ -35,20 +36,29 @@ function runTests()
|
||||
}
|
||||
|
||||
ok(!dragService.getCurrentSession(), "There shouldn't be a drag session!");
|
||||
window.addEventListener("dragstart", trapDrag, true);
|
||||
synthesizeMouse(target, 2, 2, { type: "mousedown" });
|
||||
synthesizeMouse(target, 11, 11, { type: "mousemove" });
|
||||
synthesizeMouse(target, 20, 20, { type: "mousemove" });
|
||||
window.removeEventListener("dragstart", trapDrag, true);
|
||||
iframeWin.addEventListener("dragstart", trapDrag, true);
|
||||
synthesizeMouse(target, 2, 2, { type: "mousedown" }, iframeWin);
|
||||
synthesizeMouse(target, 11, 11, { type: "mousemove" }, iframeWin);
|
||||
synthesizeMouse(target, 20, 20, { type: "mousemove" }, iframeWin);
|
||||
iframeWin.removeEventListener("dragstart", trapDrag, true);
|
||||
ok(dragService.getCurrentSession(), "Drag session is available.");
|
||||
dragService.endDragSession(false);
|
||||
ok(!dragService.getCurrentSession(), "There shouldn't be a drag session anymore!");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(() => {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["dom.webcomponents.enabled", true]
|
||||
]
|
||||
}, runTests);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<body onload="window.setTimeout(runTests, 0);">
|
||||
<div id="outter"/>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -37,7 +37,7 @@ BlobSet::AppendVoidPtr(const void* aData, uint32_t aLength)
|
||||
nsresult
|
||||
BlobSet::AppendString(const nsAString& aString, bool nativeEOL)
|
||||
{
|
||||
nsAutoCString utf8Str;
|
||||
nsCString utf8Str;
|
||||
if (NS_WARN_IF(!AppendUTF16toUTF8(aString, utf8Str, mozilla::fallible))) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,17 @@ interface nsIInterceptedChannel;
|
||||
interface nsIPrincipal;
|
||||
interface nsIRunnable;
|
||||
interface nsIURI;
|
||||
%{C++
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class ClientInfo;
|
||||
class ServiceWorkerDescriptor;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
%}
|
||||
|
||||
[ref] native const_ClientInfoRef(const mozilla::dom::ClientInfo);
|
||||
[ref] native const_ServiceWorkerDescriptorRef(const mozilla::dom::ServiceWorkerDescriptor);
|
||||
|
||||
[scriptable, uuid(52ee2c9d-ee87-4caf-9588-23ae77ff8798)]
|
||||
interface nsIServiceWorkerUnregisterCallback : nsISupports
|
||||
@@ -150,6 +161,9 @@ interface nsIServiceWorkerManager : nsISupports
|
||||
*/
|
||||
[notxpcom,nostdcall] void MaybeStartControlling(in nsIDocument aDoc);
|
||||
|
||||
[notxpcom, nostdcall] bool StartControlling(in const_ClientInfoRef aClientInfo,
|
||||
in const_ServiceWorkerDescriptorRef aServiceWorker);
|
||||
|
||||
/**
|
||||
* Documents that have called MaybeStartControlling() should call this when
|
||||
* they are destroyed. This function may be called multiple times, and is
|
||||
|
||||
@@ -507,7 +507,7 @@ var interfaceNamesInGlobalScope =
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"HTMLSelectElement",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"HTMLSlotElement",
|
||||
{name: "HTMLSlotElement", disabled: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"HTMLSourceElement",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
@@ -843,7 +843,7 @@ var interfaceNamesInGlobalScope =
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "ScopedCredentialInfo", disabled: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"ShadowRoot", // Bogus, but the test harness forces it on. See bug 1159768.
|
||||
{name: "ShadowRoot", disabled: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"SharedWorker",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
||||
30
dom/tests/mochitest/webcomponents/head.js
Normal file
30
dom/tests/mochitest/webcomponents/head.js
Normal file
@@ -0,0 +1,30 @@
|
||||
/* 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";
|
||||
|
||||
/**
|
||||
* Set dom.webcomponents.enabled pref to true and loads an iframe, to ensure
|
||||
* that the Element instance is loaded with the correct value of the
|
||||
* preference.
|
||||
*
|
||||
* @return {Promise} promise that resolves when iframe is loaded.
|
||||
*/
|
||||
function setWebComponentsPrefAndCreateIframe(aSrcDoc) {
|
||||
return new Promise(function (aResolve, aReject) {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["dom.webcomponents.enabled", true]
|
||||
]
|
||||
}, () => {
|
||||
let iframe = document.createElement("iframe");
|
||||
iframe.onload = function () { aResolve(iframe.contentDocument); }
|
||||
iframe.onerror = function () { aReject('Failed to load iframe'); }
|
||||
if (aSrcDoc) {
|
||||
iframe.srcdoc = aSrcDoc;
|
||||
}
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -2,13 +2,12 @@
|
||||
support-files =
|
||||
inert_style.css
|
||||
dummy_page.html
|
||||
head.js
|
||||
|
||||
[test_bug900724.html]
|
||||
[test_bug1017896.html]
|
||||
[test_bug1176757.html]
|
||||
[test_bug1276240.html]
|
||||
[test_content_element.html]
|
||||
skip-if = true # Triggers assertions about flattened tree inconsistencies and it's going away in bug 1418002.
|
||||
[test_custom_element_callback_innerhtml.html]
|
||||
[test_custom_element_htmlconstructor.html]
|
||||
skip-if = os == 'android' # bug 1323645
|
||||
|
||||
@@ -5,13 +5,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1176757
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1176757</title>
|
||||
<script type="text/javascript" src="head.js"></script>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1176757">Mozilla Bug 1176757</a>
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1176757">Mozilla Bug 1176757</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
@@ -20,19 +21,24 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1176757
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 1176757 **/
|
||||
var element = document.createElement("a");
|
||||
var shadowRoot = element.createShadowRoot();
|
||||
var thrownException = false;
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
setWebComponentsPrefAndCreateIframe()
|
||||
.then((aDocument) => {
|
||||
var element = aDocument.createElement("div");
|
||||
var shadowRoot = element.attachShadow({mode: "open"});
|
||||
var thrownException = false;
|
||||
|
||||
try {
|
||||
shadowRoot.cloneNode();
|
||||
} catch(err) {
|
||||
thrownException = err;
|
||||
}
|
||||
try {
|
||||
shadowRoot.cloneNode();
|
||||
} catch(err) {
|
||||
thrownException = err;
|
||||
}
|
||||
|
||||
ok(thrownException !== false, "An exception should've been thrown");
|
||||
is(thrownException.name, "DataCloneError", "A DataCloneError exception should've been thrown");
|
||||
ok(thrownException !== false, "An exception should've been thrown");
|
||||
is(thrownException.name, "DataCloneError", "A DataCloneError exception should've been thrown");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
@@ -5,83 +5,89 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1269155
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1269155</title>
|
||||
<script type="text/javascript" src="head.js"></script>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1269155">Mozilla Bug 1269155</a>
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1269155">Mozilla Bug 1269155</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 1269155 **/
|
||||
var host = document.querySelector('#content');
|
||||
var root = host.createShadowRoot();
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var header1 = document.createElement('h1');
|
||||
header1.textContent = 'Shadow Header1';
|
||||
var content = '<div id="content" style="display: none"> </div>';
|
||||
setWebComponentsPrefAndCreateIframe(content)
|
||||
.then((aDocument) => {
|
||||
var host = aDocument.querySelector('#content');
|
||||
var root = host.attachShadow({mode: "open"});
|
||||
|
||||
var paragraph1 = document.createElement('p');
|
||||
paragraph1.textContent = 'shadow text paragraph1';
|
||||
var header1 = aDocument.createElement('h1');
|
||||
header1.textContent = 'Shadow Header1';
|
||||
|
||||
root.appendChild(header1);
|
||||
root.appendChild(paragraph1);
|
||||
var paragraph1 = aDocument.createElement('p');
|
||||
paragraph1.textContent = 'shadow text paragraph1';
|
||||
|
||||
var root2 = paragraph1.createShadowRoot();
|
||||
var header2 = document.createElement('h2');
|
||||
header2.textContent = 'Shadow Header2';
|
||||
root.appendChild(header1);
|
||||
root.appendChild(paragraph1);
|
||||
|
||||
var paragraph2 = document.createElement('p');
|
||||
paragraph2.textContent = 'shadow text paragraph2';
|
||||
root2.appendChild(header2);
|
||||
root2.appendChild(paragraph2);
|
||||
var root2 = paragraph1.attachShadow({mode: "open"});
|
||||
var header2 = aDocument.createElement('h2');
|
||||
header2.textContent = 'Shadow Header2';
|
||||
|
||||
var paragraph2 = aDocument.createElement('p');
|
||||
paragraph2.textContent = 'shadow text paragraph2';
|
||||
root2.appendChild(header2);
|
||||
root2.appendChild(paragraph2);
|
||||
|
||||
|
||||
var frag = document.createDocumentFragment();
|
||||
var paragraph3 = document.createElement('p');
|
||||
paragraph3.textContent = 'fragment paragraph3';
|
||||
frag.appendChild(paragraph3);
|
||||
var frag = aDocument.createDocumentFragment();
|
||||
var paragraph3 = aDocument.createElement('p');
|
||||
paragraph3.textContent = 'fragment paragraph3';
|
||||
frag.appendChild(paragraph3);
|
||||
|
||||
var root3 = paragraph3.createShadowRoot();
|
||||
var header4 = document.createElement('h2');
|
||||
header4.textContent = 'Shadow Header3';
|
||||
var root3 = paragraph3.attachShadow({mode: "open"});
|
||||
var header4 = aDocument.createElement('h2');
|
||||
header4.textContent = 'Shadow Header3';
|
||||
|
||||
var paragraph4 = document.createElement('p');
|
||||
paragraph4.textContent = 'shadow text paragraph4';
|
||||
var paragraph4 = aDocument.createElement('p');
|
||||
paragraph4.textContent = 'shadow text paragraph4';
|
||||
|
||||
root3.appendChild(header4);
|
||||
root3.appendChild(paragraph4);
|
||||
root3.appendChild(header4);
|
||||
root3.appendChild(paragraph4);
|
||||
|
||||
//shadow dom without compose
|
||||
is(root.getRootNode(), root, "root.getRootNode() should be root.");
|
||||
is(root2.getRootNode(), root2, "root2.getRootNode() should be root.");
|
||||
is(root3.getRootNode(), root3, "root3.getRootNode() should be root.");
|
||||
is(header1.getRootNode(), root, "header1.getRootNode() should be root.");
|
||||
is(header2.getRootNode(), root2, "header1.getRootNode() should be root2.");
|
||||
is(header4.getRootNode(), root3, "header1.getRootNode() should be root3.");
|
||||
//shadow dom with compose
|
||||
is(root.getRootNode({ composed: true }), document, "root.getRootNode() with composed flag should be document.");
|
||||
is(root2.getRootNode({ composed: true }), document, "root2.getRootNode() with composed flag should be document.");
|
||||
is(root3.getRootNode({ composed: true }), frag, "root3.getRootNode() with composed flag should be frag.");
|
||||
is(header1.getRootNode({ composed: true }) , document, "header1.getRootNode() with composed flag should be document.");
|
||||
is(header2.getRootNode({ composed: true }) , document, "header2.getRootNode() with composed flag should be document.");
|
||||
is(header4.getRootNode({ composed: true }) , frag, "head4.getRootNode() with composed flag should be frag.");
|
||||
//dom without compose
|
||||
is(host.getRootNode(), document, "host.getRootNode() should be document.");
|
||||
is(header1.getRootNode(), root, "header1.getRootNode() should be root.");
|
||||
is(paragraph1.getRootNode(), root, "paragraph1.getRootNode() should be root.");
|
||||
is(frag.getRootNode(), frag, "frag.getRootNode() should be frag.");
|
||||
//dom with compose
|
||||
is(host.getRootNode({ composed: true }) , document, "host.getRootNode() with composed flag should be document.");
|
||||
is(header1.getRootNode({ composed: true }) , document, "header1.getRootNode() with composed flag should be document.");
|
||||
is(paragraph1.getRootNode({ composed: true }) , document, "paragraph1.getRootNode() with composed flag should be document.");
|
||||
is(frag.getRootNode({ composed: true }) , frag, "frag.getRootNode() with composed flag should be frag.");
|
||||
//shadow dom without compose
|
||||
is(root.getRootNode(), root, "root.getRootNode() should be root.");
|
||||
is(root2.getRootNode(), root2, "root2.getRootNode() should be root.");
|
||||
is(root3.getRootNode(), root3, "root3.getRootNode() should be root.");
|
||||
is(header1.getRootNode(), root, "header1.getRootNode() should be root.");
|
||||
is(header2.getRootNode(), root2, "header1.getRootNode() should be root2.");
|
||||
is(header4.getRootNode(), root3, "header1.getRootNode() should be root3.");
|
||||
//shadow dom with compose
|
||||
is(root.getRootNode({ composed: true }), aDocument, "root.getRootNode() with composed flag should be document.");
|
||||
is(root2.getRootNode({ composed: true }), aDocument, "root2.getRootNode() with composed flag should be document.");
|
||||
is(root3.getRootNode({ composed: true }), frag, "root3.getRootNode() with composed flag should be frag.");
|
||||
is(header1.getRootNode({ composed: true }) , aDocument, "header1.getRootNode() with composed flag should be document.");
|
||||
is(header2.getRootNode({ composed: true }) , aDocument, "header2.getRootNode() with composed flag should be document.");
|
||||
is(header4.getRootNode({ composed: true }) , frag, "head4.getRootNode() with composed flag should be frag.");
|
||||
//dom without compose
|
||||
is(host.getRootNode(), aDocument, "host.getRootNode() should be document.");
|
||||
is(header1.getRootNode(), root, "header1.getRootNode() should be root.");
|
||||
is(paragraph1.getRootNode(), root, "paragraph1.getRootNode() should be root.");
|
||||
is(frag.getRootNode(), frag, "frag.getRootNode() should be frag.");
|
||||
//dom with compose
|
||||
is(host.getRootNode({ composed: true }) , aDocument, "host.getRootNode() with composed flag should be document.");
|
||||
is(header1.getRootNode({ composed: true }) , aDocument, "header1.getRootNode() with composed flag should be document.");
|
||||
is(paragraph1.getRootNode({ composed: true }) , aDocument, "paragraph1.getRootNode() with composed flag should be document.");
|
||||
is(frag.getRootNode({ composed: true }) , frag, "frag.getRootNode() with composed flag should be frag.");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=806506
|
||||
-->
|
||||
<head>
|
||||
<title>Test for HTMLContent element</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="grabme"></div>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=806506">Bug 806506</a>
|
||||
<script>
|
||||
// Create a ShadowRoot and append some nodes, containing an insertion point with a universal selector.
|
||||
var shadow = $("grabme").createShadowRoot();
|
||||
shadow.innerHTML = '<span><content id="point"></content></span>';
|
||||
|
||||
// Get the insertion point from the ShadowRoot and check that child of host is distributed.
|
||||
// Insertion point should match everything because the selector set is empty.
|
||||
var insertionPoint = shadow.getElementById("point");
|
||||
$("grabme").innerHTML = '<div id="distme"></div>';
|
||||
var distNodes = insertionPoint.getDistributedNodes();
|
||||
is(distNodes[0], $("distme"), "Child of bound content should be distributed into insertion point with universal selector.");
|
||||
is(distNodes.length, 1, "Should only have one child distributed into insertion point.");
|
||||
|
||||
// Add another node to bound content and make sure that the node list is static and does not change.
|
||||
var someSpan = document.createElement("span");
|
||||
$("grabme").appendChild(someSpan);
|
||||
is(distNodes.length, 1, "NodeList from getDistributedNodes should be static.");
|
||||
|
||||
// Test content select.
|
||||
$("grabme").innerHTML = '<div id="first" class="tall"></div><div id="second" class="skinny"></div>';
|
||||
shadow.innerHTML = '<span><content select=".tall" id="point"></content></span>';
|
||||
var insertionPoint = shadow.getElementById("point");
|
||||
distNodes = insertionPoint.getDistributedNodes();
|
||||
is(distNodes.length, 1, "Insertion point should only match element with the 'tall' class.");
|
||||
is(distNodes[0], $("first"), "Insertion point should only match element with the 'tall' class.");
|
||||
|
||||
// Get rid of the select attribute and check that the insertion point matches everything.
|
||||
insertionPoint.removeAttribute("select");
|
||||
is(insertionPoint.getDistributedNodes().length, 2, "After removing the 'select' attribute, the insertion point should match everything.");
|
||||
|
||||
// Set an invalid selector and make sure that nothing is matched.
|
||||
insertionPoint.setAttribute("select", "div:first-child");
|
||||
is(insertionPoint.getDistributedNodes().length, 0, "Invalid selectors should match nothing.");
|
||||
|
||||
// all compound selectors must only be permitted simple selectors.
|
||||
insertionPoint.setAttribute("select", "div:first-child, span");
|
||||
is(insertionPoint.getDistributedNodes().length, 0, "Invalid selectors should match nothing.");
|
||||
|
||||
// Test multiple compound selectors.
|
||||
$("grabme").innerHTML = '<div id="first"></div><span id="second"></span><span data-match-me="pickme" id="third"></span>';
|
||||
insertionPoint.setAttribute("select", "span[data-match-me=pickme], div");
|
||||
distNodes = insertionPoint.getDistributedNodes();
|
||||
is(distNodes.length, 2, "Insertion point selector should only match two nodes.");
|
||||
is(distNodes[0], $("first"), "First child node should match selector.");
|
||||
is(distNodes[1], $("third"), "Third child node should match selector.");
|
||||
|
||||
// Test select property
|
||||
insertionPoint.select = "#second, #third";
|
||||
distNodes = insertionPoint.getDistributedNodes();
|
||||
is(distNodes.length, 2, "Insertion point selector (set using property) should only match two nodes.");
|
||||
is(distNodes[0], $("second"), "First child node should match selector.");
|
||||
is(distNodes[1], $("third"), "Third child node should match selector.");
|
||||
is(insertionPoint.select, "#second, #third", "select property should be transparent.");
|
||||
|
||||
// Empty set of selectors should match everything.
|
||||
insertionPoint.select = "";
|
||||
is(insertionPoint.getDistributedNodes().length, 3, "Empty set of selectors (set using property) should match everything.");
|
||||
|
||||
// Remove insertion point and make sure that the point does not have any nodes distributed.
|
||||
$("grabme").innerHTML = '<div></div><span></span>';
|
||||
insertionPoint.removeAttribute("select");
|
||||
is(insertionPoint.getDistributedNodes().length, 2, "Insertion point with univeral selector should match two nodes.");
|
||||
var insertionParent = insertionPoint.parentNode;
|
||||
insertionParent.removeChild(insertionPoint);
|
||||
is(insertionPoint.getDistributedNodes().length, 0, "Insertion point should match no nodes after removal.");
|
||||
insertionParent.appendChild(insertionPoint);
|
||||
is(insertionPoint.getDistributedNodes().length, 2, "Insertion point should match two nodes after appending.");
|
||||
|
||||
// Test multiple insertion points and check tree order distribution of points.
|
||||
// Append two divs and three spans into host.
|
||||
$("grabme").innerHTML = '<div></div><span></span><div></div><span></span><span></span>';
|
||||
shadow.innerHTML = '<content select="div" id="divpoint"></content><content select="div, span" id="allpoint"></content>';
|
||||
// Insertion point matching div
|
||||
var divPoint = shadow.getElementById("divpoint");
|
||||
// Insertion point matching span and div
|
||||
var allPoint = shadow.getElementById("allpoint");
|
||||
|
||||
is(divPoint.getDistributedNodes().length, 2, "Two div nodes should be distributed into divPoint.");
|
||||
is(allPoint.getDistributedNodes().length, 3, "Remaining nodes should be distributed into allPoint.");
|
||||
|
||||
shadow.removeChild(allPoint);
|
||||
is(divPoint.getDistributedNodes().length, 2, "Number of div distributed into insertion point should not change.");
|
||||
is(allPoint.getDistributedNodes().length, 0, "Removed insertion point should not have any nodes.");
|
||||
|
||||
shadow.insertBefore(allPoint, divPoint);
|
||||
is(allPoint.getDistributedNodes().length, 5, "allPoint should have nodes distributed before divPoint.");
|
||||
is(divPoint.getDistributedNodes().length, 0, "divPoint should have no distributed nodes because they are all distributed to allPoint.");
|
||||
|
||||
// Make sure that fallback content are in the distributed nodes.
|
||||
$("grabme").innerHTML = '<div id="one"></div><div id="two"></div>';
|
||||
shadow.innerHTML = '<content select="#nothing" id="point"><span id="fallback"></span></content>';
|
||||
insertionPoint = shadow.getElementById("point");
|
||||
is(insertionPoint.getDistributedNodes().length, 1, "There should be one distributed node from fallback content.");
|
||||
is(insertionPoint.getDistributedNodes()[0].id, "fallback", "Distributed node should be fallback content.");
|
||||
|
||||
$("grabme").innerHTML = '';
|
||||
shadow.innerHTML = '<content select="div" id="point"><span id="one"></span><span id="two"></span></content>';
|
||||
insertionPoint = shadow.getElementById("point");
|
||||
// Make sure that two fallback nodes are distributed into the insertion point.
|
||||
is(insertionPoint.getDistributedNodes().length, 2, "There should be two distributed nodes from fallback content.");
|
||||
is(insertionPoint.getDistributedNodes()[0].id, "one", "First distributed node should have an ID of one.");
|
||||
is(insertionPoint.getDistributedNodes()[1].id, "two", "Second distributed node should have an ID of two.");
|
||||
|
||||
// Append a node that gets matched by the insertion point, thus causing the fallback content to be removed.
|
||||
var matchingDiv = document.createElement("div");
|
||||
matchingDiv.id = "three";
|
||||
$("grabme").appendChild(matchingDiv);
|
||||
is(insertionPoint.getDistributedNodes().length, 1, "There should be one node distributed from the host.");
|
||||
is(insertionPoint.getDistributedNodes()[0].id, "three", "Node distriubted from host should have id of three.");
|
||||
|
||||
// Remove the matching node from the host and make sure that the fallback content gets distributed.
|
||||
$("grabme").removeChild(matchingDiv);
|
||||
is(insertionPoint.getDistributedNodes().length, 2, "There should be two distributed nodes from fallback content.");
|
||||
is(insertionPoint.getDistributedNodes()[0].id, "one", "First distributed node should have an ID of one.");
|
||||
is(insertionPoint.getDistributedNodes()[1].id, "two", "Second distributed node should have an ID of two.");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,115 +5,124 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1087460
|
||||
-->
|
||||
<head>
|
||||
<title>Test for custom element callbacks in shadow DOM.</title>
|
||||
<script type="text/javascript" src="head.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1087460">Bug 1087460</a>
|
||||
<div id="container"></div>
|
||||
|
||||
<script>
|
||||
|
||||
// Test callback for custom element when used after registration.
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var connectedCallbackCount = 0;
|
||||
var disconnectedCallbackCount = 0;
|
||||
var attributeChangedCallbackCount = 0;
|
||||
var content = '<div id="container"></div>';
|
||||
setWebComponentsPrefAndCreateIframe(content)
|
||||
.then((aDocument) => {
|
||||
|
||||
class Foo extends HTMLElement
|
||||
{
|
||||
connectedCallback() {
|
||||
connectedCallbackCount++;
|
||||
}
|
||||
// Test callback for custom element when used after registration.
|
||||
|
||||
disconnectedCallback() {
|
||||
disconnectedCallbackCount++;
|
||||
}
|
||||
var iframeWin = aDocument.defaultView;
|
||||
var connectedCallbackCount = 0;
|
||||
var disconnectedCallbackCount = 0;
|
||||
var attributeChangedCallbackCount = 0;
|
||||
|
||||
attributeChangedCallback(aName, aOldValue, aNewValue) {
|
||||
attributeChangedCallbackCount++;
|
||||
}
|
||||
class Foo extends iframeWin.HTMLElement
|
||||
{
|
||||
connectedCallback() {
|
||||
connectedCallbackCount++;
|
||||
}
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["data-foo"];
|
||||
}
|
||||
}
|
||||
disconnectedCallback() {
|
||||
disconnectedCallbackCount++;
|
||||
}
|
||||
|
||||
customElements.define("x-foo", Foo);
|
||||
attributeChangedCallback(aName, aOldValue, aNewValue) {
|
||||
attributeChangedCallbackCount++;
|
||||
}
|
||||
|
||||
var container = document.getElementById("container");
|
||||
var shadow = container.createShadowRoot();
|
||||
var customElem = document.createElement("x-foo");
|
||||
static get observedAttributes() {
|
||||
return ["data-foo"];
|
||||
}
|
||||
}
|
||||
|
||||
is(attributeChangedCallbackCount, 0, "attributeChangedCallback should not be called after just creating an element.");
|
||||
customElem.setAttribute("data-foo", "bar");
|
||||
is(attributeChangedCallbackCount, 1, "attributeChangedCallback should be called after setting an attribute.");
|
||||
iframeWin.customElements.define("x-foo", Foo);
|
||||
|
||||
is(connectedCallbackCount, 0, "connectedCallback should not be called on an element that is not in a document/composed document.");
|
||||
shadow.appendChild(customElem);
|
||||
is(connectedCallbackCount, 1, "connectedCallback should be called after attaching custom element to the composed document.");
|
||||
var container = aDocument.getElementById("container");
|
||||
var shadow = container.attachShadow({mode: "open"});
|
||||
var customElem = aDocument.createElement("x-foo");
|
||||
|
||||
is(disconnectedCallbackCount, 0, "disconnectedCallback should not be called without detaching custom element.");
|
||||
shadow.removeChild(customElem);
|
||||
is(disconnectedCallbackCount, 1, "disconnectedCallback should be called after detaching custom element from the composed document.");
|
||||
is(attributeChangedCallbackCount, 0, "attributeChangedCallback should not be called after just creating an element.");
|
||||
customElem.setAttribute("data-foo", "bar");
|
||||
is(attributeChangedCallbackCount, 1, "attributeChangedCallback should be called after setting an attribute.");
|
||||
|
||||
// Test callback for custom element already in the composed doc when created.
|
||||
is(connectedCallbackCount, 0, "connectedCallback should not be called on an element that is not in a document/composed document.");
|
||||
shadow.appendChild(customElem);
|
||||
is(connectedCallbackCount, 1, "connectedCallback should be called after attaching custom element to the composed document.");
|
||||
|
||||
connectedCallbackCount = 0;
|
||||
disconnectedCallbackCount = 0;
|
||||
attributeChangedCallbackCount = 0;
|
||||
is(disconnectedCallbackCount, 0, "disconnectedCallback should not be called without detaching custom element.");
|
||||
shadow.removeChild(customElem);
|
||||
is(disconnectedCallbackCount, 1, "disconnectedCallback should be called after detaching custom element from the composed document.");
|
||||
|
||||
shadow.innerHTML = "<x-foo></x-foo>";
|
||||
is(connectedCallbackCount, 1, "connectedCallback should be called after creating an element in the composed document.");
|
||||
// Test callback for custom element already in the composed doc when created.
|
||||
|
||||
shadow.innerHTML = "";
|
||||
is(disconnectedCallbackCount, 1, "disconnectedCallback should be called after detaching custom element from the composed document.");
|
||||
connectedCallbackCount = 0;
|
||||
disconnectedCallbackCount = 0;
|
||||
attributeChangedCallbackCount = 0;
|
||||
|
||||
// Test callback for custom element in shadow DOM when host attached/detached to/from document.
|
||||
shadow.innerHTML = "<x-foo></x-foo>";
|
||||
is(connectedCallbackCount, 1, "connectedCallback should be called after creating an element in the composed document.");
|
||||
|
||||
connectedCallbackCount = 0;
|
||||
disconnectedCallbackCount = 0;
|
||||
attributeChangedCallbackCount = 0;
|
||||
shadow.innerHTML = "";
|
||||
is(disconnectedCallbackCount, 1, "disconnectedCallback should be called after detaching custom element from the composed document.");
|
||||
|
||||
var host = document.createElement("div");
|
||||
shadow = host.createShadowRoot();
|
||||
customElem = document.createElement("x-foo");
|
||||
// Test callback for custom element in shadow DOM when host attached/detached to/from document.
|
||||
|
||||
is(connectedCallbackCount, 0, "connectedCallback should not be called on newly created element.");
|
||||
shadow.appendChild(customElem);
|
||||
is(connectedCallbackCount, 0, "connectedCallback should not be called on attaching to a tree that is not in the composed document.");
|
||||
connectedCallbackCount = 0;
|
||||
disconnectedCallbackCount = 0;
|
||||
attributeChangedCallbackCount = 0;
|
||||
|
||||
is(disconnectedCallbackCount, 0, "disconnectedCallback should not be called.");
|
||||
shadow.removeChild(customElem);
|
||||
is(disconnectedCallbackCount, 0, "disconnectedCallback should not be called when detaching from a tree that is not in the composed document.");
|
||||
var host = aDocument.createElement("div");
|
||||
shadow = host.attachShadow({mode: "open"});
|
||||
customElem = aDocument.createElement("x-foo");
|
||||
|
||||
shadow.appendChild(customElem);
|
||||
is(connectedCallbackCount, 0, "connectedCallback should still not be called after reattaching to a shadow tree that is not in the composed document.");
|
||||
is(connectedCallbackCount, 0, "connectedCallback should not be called on newly created element.");
|
||||
shadow.appendChild(customElem);
|
||||
is(connectedCallbackCount, 0, "connectedCallback should not be called on attaching to a tree that is not in the composed document.");
|
||||
|
||||
container.appendChild(host);
|
||||
is(connectedCallbackCount, 1, "connectedCallback should be called after host is inserted into document.");
|
||||
is(disconnectedCallbackCount, 0, "disconnectedCallback should not be called.");
|
||||
shadow.removeChild(customElem);
|
||||
is(disconnectedCallbackCount, 0, "disconnectedCallback should not be called when detaching from a tree that is not in the composed document.");
|
||||
|
||||
container.removeChild(host);
|
||||
is(disconnectedCallbackCount, 1, "disconnectedCallback should be called after host is removed from document.");
|
||||
shadow.appendChild(customElem);
|
||||
is(connectedCallbackCount, 0, "connectedCallback should still not be called after reattaching to a shadow tree that is not in the composed document.");
|
||||
|
||||
// Test callback for custom element for upgraded element.
|
||||
container.appendChild(host);
|
||||
is(connectedCallbackCount, 1, "connectedCallback should be called after host is inserted into document.");
|
||||
|
||||
connectedCallbackCount = 0;
|
||||
disconnectedCallbackCount = 0;
|
||||
attributeChangedCallbackCount = 0;
|
||||
container.removeChild(host);
|
||||
is(disconnectedCallbackCount, 1, "disconnectedCallback should be called after host is removed from document.");
|
||||
|
||||
shadow = container.shadowRoot;
|
||||
shadow.innerHTML = "<x-bar></x-bar>";
|
||||
// Test callback for custom element for upgraded element.
|
||||
|
||||
class Bar extends HTMLElement {
|
||||
connectedCallback() {
|
||||
connectedCallbackCount++;
|
||||
}
|
||||
};
|
||||
connectedCallbackCount = 0;
|
||||
disconnectedCallbackCount = 0;
|
||||
attributeChangedCallbackCount = 0;
|
||||
|
||||
customElements.define("x-bar", Bar);
|
||||
is(connectedCallbackCount, 1, "connectedCallback should be called after upgrading element in composed document.");
|
||||
shadow = container.shadowRoot;
|
||||
shadow.innerHTML = "<x-bar></x-bar>";
|
||||
|
||||
class Bar extends iframeWin.HTMLElement {
|
||||
connectedCallback() {
|
||||
connectedCallbackCount++;
|
||||
}
|
||||
};
|
||||
|
||||
iframeWin.customElements.define("x-bar", Bar);
|
||||
is(connectedCallbackCount, 1, "connectedCallback should be called after upgrading element in composed document.");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -5,21 +5,31 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1062578
|
||||
-->
|
||||
<head>
|
||||
<title>Test for creating style in shadow root of host not in document.</title>
|
||||
<script type="text/javascript" src="head.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="grabme"></div>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1062578">Bug 1062578</a>
|
||||
<script>
|
||||
var host = document.createElement("div");
|
||||
var shadow = host.createShadowRoot();
|
||||
shadow.innerHTML = '<style> #inner { height: 200px; } </style><div id="inner">Hello</div>';
|
||||
|
||||
grabme.appendChild(host);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var inner = shadow.getElementById("inner");
|
||||
is(getComputedStyle(inner, null).getPropertyValue("height"), "200px", "Style in shadow root should take effect.");
|
||||
var content = '<div id="grabme"></div>';
|
||||
setWebComponentsPrefAndCreateIframe(content)
|
||||
.then((aDocument) => {
|
||||
var host = aDocument.createElement("div");
|
||||
var shadow = host.attachShadow({mode: "open"});
|
||||
shadow.innerHTML = '<style> #inner { height: 200px; } </style><div id="inner">Hello</div>';
|
||||
|
||||
var iframeWin = aDocument.defaultView;
|
||||
iframeWin.grabme.appendChild(host);
|
||||
|
||||
var inner = shadow.getElementById("inner");
|
||||
is(iframeWin.getComputedStyle(inner, null).getPropertyValue("height"), "200px", "Style in shadow root should take effect.");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -5,6 +5,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1177991
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1177991</title>
|
||||
<script type="text/javascript" src="head.js"></script>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
@@ -18,18 +19,23 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1177991
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var thrownException = false;
|
||||
var shadowRoot = document.createElement('a').createShadowRoot();
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
setWebComponentsPrefAndCreateIframe()
|
||||
.then((aDocument) => {
|
||||
var thrownException = false;
|
||||
var shadowRoot = aDocument.createElement('div').attachShadow({mode: "open"});
|
||||
|
||||
try {
|
||||
document.adoptNode(shadowRoot);
|
||||
} catch(err) {
|
||||
thrownException = err;
|
||||
}
|
||||
try {
|
||||
aDocument.adoptNode(shadowRoot);
|
||||
} catch(err) {
|
||||
thrownException = err;
|
||||
}
|
||||
|
||||
ok(thrownException !== false, "A HierarchyRequestError");
|
||||
is(thrownException.name, "HierarchyRequestError", "A HierarchyRequestError should've been thrown");
|
||||
ok(thrownException !== false, "A HierarchyRequestError");
|
||||
is(thrownException.name, "HierarchyRequestError", "A HierarchyRequestError should've been thrown");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
@@ -5,6 +5,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1177914
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1177914</title>
|
||||
<script type="text/javascript" src="head.js"></script>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
@@ -18,19 +19,23 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1177914
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var thrownException = false;
|
||||
var shadowRoot = document.createElement('a').createShadowRoot();
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
setWebComponentsPrefAndCreateIframe()
|
||||
.then((aDocument) => {
|
||||
var thrownException = false;
|
||||
var shadowRoot = aDocument.createElement('div').attachShadow({mode: "open"});
|
||||
|
||||
try {
|
||||
document.importNode(shadowRoot);
|
||||
} catch(err) {
|
||||
thrownException = err;
|
||||
}
|
||||
try {
|
||||
aDocument.importNode(shadowRoot);
|
||||
} catch(err) {
|
||||
thrownException = err;
|
||||
}
|
||||
|
||||
ok(thrownException !== false, "A HierarchyRequestError");
|
||||
is(thrownException.name, "NotSupportedError", "A NotSupportedError exception should've been thrown");
|
||||
|
||||
ok(thrownException !== false, "An exception should've been thrown");
|
||||
is(thrownException.name, "NotSupportedError", "A NotSupportedError exception should've been thrown");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
@@ -5,6 +5,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=887541
|
||||
-->
|
||||
<head>
|
||||
<title>Test for event retargeting in web components</title>
|
||||
<script type="text/javascript" src="head.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
@@ -12,136 +13,141 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=887541
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=887541">Bug 887541</a>
|
||||
<script>
|
||||
|
||||
/*
|
||||
* Creates an event listener with an expected event target.
|
||||
*/
|
||||
function createEventListener(expectedTarget, msg) {
|
||||
return function(e) {
|
||||
is(e.target, expectedTarget, msg);
|
||||
};
|
||||
}
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
setWebComponentsPrefAndCreateIframe()
|
||||
.then((aDocument) => {
|
||||
/*
|
||||
* Creates an event listener with an expected event target.
|
||||
*/
|
||||
function createEventListener(expectedTarget, msg) {
|
||||
return function(e) {
|
||||
is(e.target, expectedTarget, msg);
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Test of event retargeting through a basic ShadowRoot with a content insertion point.
|
||||
*
|
||||
* <div elemThree> ---- <shadow-root shadowOne>
|
||||
* | |
|
||||
* <div elemOne> <content elemTwo>
|
||||
*
|
||||
* Dispatch event on elemOne
|
||||
*/
|
||||
/*
|
||||
* Test of event retargeting through a basic ShadowRoot with a content insertion point.
|
||||
*
|
||||
* <div elemThree> ---- <shadow-root shadowOne>
|
||||
* | |
|
||||
* <div elemOne> <content elemTwo>
|
||||
*
|
||||
* Dispatch event on elemOne
|
||||
*/
|
||||
|
||||
var elemOne = document.createElement("div");
|
||||
var elemTwo = document.createElement("content");
|
||||
var elemThree = document.createElement("div");
|
||||
var shadowOne = elemThree.createShadowRoot();
|
||||
var elemOne = aDocument.createElement("div");
|
||||
var elemTwo = aDocument.createElement("content");
|
||||
var elemThree = aDocument.createElement("div");
|
||||
var shadowOne = elemThree.attachShadow({mode: "open"});
|
||||
|
||||
elemThree.appendChild(elemOne);
|
||||
shadowOne.appendChild(elemTwo);
|
||||
elemThree.appendChild(elemOne);
|
||||
shadowOne.appendChild(elemTwo);
|
||||
|
||||
elemOne.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemOne."));
|
||||
elemTwo.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemTwo."));
|
||||
elemThree.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemThree."));
|
||||
shadowOne.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of shadowOne."));
|
||||
elemOne.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemOne."));
|
||||
elemTwo.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemTwo."));
|
||||
elemThree.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemThree."));
|
||||
shadowOne.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of shadowOne."));
|
||||
|
||||
var customEvent = new CustomEvent("custom", { "bubbles" : true });
|
||||
elemOne.dispatchEvent(customEvent);
|
||||
var customEvent = new CustomEvent("custom", { "bubbles" : true });
|
||||
elemOne.dispatchEvent(customEvent);
|
||||
|
||||
/*
|
||||
* Test of event retargeting through a basic ShadowRoot with a content insertion point.
|
||||
*
|
||||
* <div elemThree> ---- <shadow-root shadowOne>
|
||||
* | |
|
||||
* <div elemOne> <content elemTwo>
|
||||
*
|
||||
* Dispatch event on elemTwo
|
||||
*/
|
||||
/*
|
||||
* Test of event retargeting through a basic ShadowRoot with a content insertion point.
|
||||
*
|
||||
* <div elemThree> ---- <shadow-root shadowOne>
|
||||
* | |
|
||||
* <div elemOne> <content elemTwo>
|
||||
*
|
||||
* Dispatch event on elemTwo
|
||||
*/
|
||||
|
||||
elemOne = document.createElement("div");
|
||||
elemTwo = document.createElement("content");
|
||||
elemThree = document.createElement("div");
|
||||
shadowOne = elemThree.createShadowRoot();
|
||||
elemOne = aDocument.createElement("div");
|
||||
elemTwo = aDocument.createElement("content");
|
||||
elemThree = aDocument.createElement("div");
|
||||
shadowOne = elemThree.attachShadow({mode: "open"});
|
||||
|
||||
elemThree.appendChild(elemOne);
|
||||
shadowOne.appendChild(elemTwo);
|
||||
elemThree.appendChild(elemOne);
|
||||
shadowOne.appendChild(elemTwo);
|
||||
|
||||
elemTwo.addEventListener("custom", createEventListener(elemTwo, "elemTwo is in common ancestor tree of elemTwo."));
|
||||
elemThree.addEventListener("custom", createEventListener(elemThree, "elemThree is in common ancestor tree of elemThree."));
|
||||
shadowOne.addEventListener("custom", createEventListener(elemTwo, "elemTwo is in common ancestor tree of shadowOne."));
|
||||
elemTwo.addEventListener("custom", createEventListener(elemTwo, "elemTwo is in common ancestor tree of elemTwo."));
|
||||
elemThree.addEventListener("custom", createEventListener(elemThree, "elemThree is in common ancestor tree of elemThree."));
|
||||
shadowOne.addEventListener("custom", createEventListener(elemTwo, "elemTwo is in common ancestor tree of shadowOne."));
|
||||
|
||||
customEvent = new CustomEvent("custom", { "bubbles" : true });
|
||||
elemTwo.dispatchEvent(customEvent);
|
||||
customEvent = new CustomEvent("custom", { "bubbles" : true });
|
||||
elemTwo.dispatchEvent(customEvent);
|
||||
|
||||
/*
|
||||
* Test of event retargeting through a nested ShadowRoots with content insertion points.
|
||||
*
|
||||
* <div elemFive> --- <shadow-root shadowTwo>
|
||||
* | |
|
||||
* <div elemOne> <div elemFour> ----- <shadow-root shadowOne>
|
||||
* | |
|
||||
* <content elemTwo> <content elemThree>
|
||||
*
|
||||
* Dispatch custom event on elemOne.
|
||||
*/
|
||||
/*
|
||||
* Test of event retargeting through a nested ShadowRoots with content insertion points.
|
||||
*
|
||||
* <div elemFive> --- <shadow-root shadowTwo>
|
||||
* | |
|
||||
* <div elemOne> <div elemFour> ----- <shadow-root shadowOne>
|
||||
* | |
|
||||
* <content elemTwo> <content elemThree>
|
||||
*
|
||||
* Dispatch custom event on elemOne.
|
||||
*/
|
||||
|
||||
elemOne = document.createElement("div");
|
||||
elemTwo = document.createElement("content");
|
||||
elemThree = document.createElement("content");
|
||||
var elemFour = document.createElement("div");
|
||||
var elemFive = document.createElement("div");
|
||||
var shadowTwo = elemFive.createShadowRoot();
|
||||
shadowOne = elemFour.createShadowRoot();
|
||||
elemOne = aDocument.createElement("div");
|
||||
elemTwo = aDocument.createElement("content");
|
||||
elemThree = aDocument.createElement("content");
|
||||
var elemFour = aDocument.createElement("div");
|
||||
var elemFive = aDocument.createElement("div");
|
||||
var shadowTwo = elemFive.attachShadow({mode: "open"});
|
||||
shadowOne = elemFour.attachShadow({mode: "open"});
|
||||
|
||||
elemFive.appendChild(elemOne);
|
||||
shadowTwo.appendChild(elemFour);
|
||||
elemFour.appendChild(elemTwo);
|
||||
shadowOne.appendChild(elemThree);
|
||||
elemFive.appendChild(elemOne);
|
||||
shadowTwo.appendChild(elemFour);
|
||||
elemFour.appendChild(elemTwo);
|
||||
shadowOne.appendChild(elemThree);
|
||||
|
||||
elemOne.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemOne."));
|
||||
elemTwo.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemTwo."));
|
||||
elemThree.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemThree."));
|
||||
elemFour.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemFour."));
|
||||
elemFive.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemFive."));
|
||||
shadowOne.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of shadowOne."));
|
||||
shadowTwo.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of shadowTwo."));
|
||||
elemOne.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemOne."));
|
||||
elemTwo.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemTwo."));
|
||||
elemThree.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemThree."));
|
||||
elemFour.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemFour."));
|
||||
elemFive.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of elemFive."));
|
||||
shadowOne.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of shadowOne."));
|
||||
shadowTwo.addEventListener("custom", createEventListener(elemOne, "elemOne is in common ancestor tree of shadowTwo."));
|
||||
|
||||
customEvent = new CustomEvent("custom", { "bubbles" : true });
|
||||
elemOne.dispatchEvent(customEvent);
|
||||
customEvent = new CustomEvent("custom", { "bubbles" : true });
|
||||
elemOne.dispatchEvent(customEvent);
|
||||
|
||||
/*
|
||||
* Test of event retargeting through a nested ShadowRoots with content insertion points.
|
||||
*
|
||||
* <div elemFive> --- <shadow-root shadowTwo>
|
||||
* | |
|
||||
* <div elemOne> <div elemFour> ----- <shadow-root shadowOne>
|
||||
* | |
|
||||
* <content elemTwo> <content elemThree>
|
||||
*
|
||||
* Dispatch custom event on elemThree.
|
||||
*/
|
||||
/*
|
||||
* Test of event retargeting through a nested ShadowRoots with content insertion points.
|
||||
*
|
||||
* <div elemFive> --- <shadow-root shadowTwo>
|
||||
* | |
|
||||
* <div elemOne> <div elemFour> ----- <shadow-root shadowOne>
|
||||
* | |
|
||||
* <content elemTwo> <content elemThree>
|
||||
*
|
||||
* Dispatch custom event on elemThree.
|
||||
*/
|
||||
|
||||
elemOne = document.createElement("div");
|
||||
elemTwo = document.createElement("content");
|
||||
elemThree = document.createElement("content");
|
||||
elemFour = document.createElement("div");
|
||||
elemFive = document.createElement("div");
|
||||
shadowTwo = elemFive.createShadowRoot();
|
||||
shadowOne = elemFour.createShadowRoot();
|
||||
elemOne = aDocument.createElement("div");
|
||||
elemTwo = aDocument.createElement("content");
|
||||
elemThree = aDocument.createElement("content");
|
||||
elemFour = aDocument.createElement("div");
|
||||
elemFive = aDocument.createElement("div");
|
||||
shadowTwo = elemFive.attachShadow({mode: "open"});
|
||||
shadowOne = elemFour.attachShadow({mode: "open"});
|
||||
|
||||
elemFive.appendChild(elemOne);
|
||||
shadowTwo.appendChild(elemFour);
|
||||
elemFour.appendChild(elemTwo);
|
||||
shadowOne.appendChild(elemThree);
|
||||
elemFive.appendChild(elemOne);
|
||||
shadowTwo.appendChild(elemFour);
|
||||
elemFour.appendChild(elemTwo);
|
||||
shadowOne.appendChild(elemThree);
|
||||
|
||||
elemThree.addEventListener("custom", createEventListener(elemThree, "elemThree is in common ancestor tree of elemThree."));
|
||||
elemFour.addEventListener("custom", createEventListener(elemFour, "elemFour is in common ancestor tree of elemFour."));
|
||||
elemFive.addEventListener("custom", createEventListener(elemFive, "elemFive is in common ancestor tree of elemFive."));
|
||||
shadowOne.addEventListener("custom", createEventListener(elemThree, "elemThree is in common ancestor tree of shadowOne."));
|
||||
shadowTwo.addEventListener("custom", createEventListener(elemFour, "elemFour is in common ancestor tree of shadowTwo."));
|
||||
elemThree.addEventListener("custom", createEventListener(elemThree, "elemThree is in common ancestor tree of elemThree."));
|
||||
elemFour.addEventListener("custom", createEventListener(elemFour, "elemFour is in common ancestor tree of elemFour."));
|
||||
elemFive.addEventListener("custom", createEventListener(elemFive, "elemFive is in common ancestor tree of elemFive."));
|
||||
shadowOne.addEventListener("custom", createEventListener(elemThree, "elemThree is in common ancestor tree of shadowOne."));
|
||||
shadowTwo.addEventListener("custom", createEventListener(elemFour, "elemFour is in common ancestor tree of shadowTwo."));
|
||||
|
||||
customEvent = new CustomEvent("custom", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
customEvent = new CustomEvent("custom", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -5,6 +5,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=887541
|
||||
-->
|
||||
<head>
|
||||
<title>Test for event model in web components</title>
|
||||
<script type="text/javascript" src="head.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
@@ -15,154 +16,159 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=887541
|
||||
var els = SpecialPowers.Cc["@mozilla.org/eventlistenerservice;1"]
|
||||
.getService(SpecialPowers.Ci.nsIEventListenerService);
|
||||
|
||||
function eventListener(e) {
|
||||
eventChain.push(this);
|
||||
}
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
setWebComponentsPrefAndCreateIframe()
|
||||
.then((aDocument) => {
|
||||
function eventListener(e) {
|
||||
eventChain.push(this);
|
||||
}
|
||||
|
||||
function isEventChain(actual, expected, msg) {
|
||||
is(actual.length, expected.length, msg);
|
||||
for (var i = 0; i < expected.length; i++) {
|
||||
is(actual[i], expected[i], msg + " at " + i);
|
||||
}
|
||||
function isEventChain(actual, expected, msg) {
|
||||
is(actual.length, expected.length, msg);
|
||||
for (var i = 0; i < expected.length; i++) {
|
||||
is(actual[i], expected[i], msg + " at " + i);
|
||||
}
|
||||
|
||||
if (0 < actual.length) {
|
||||
var chain = els.getEventTargetChainFor(actual[0], false); // Events should be dispatched on actual[0].
|
||||
ok(expected.length < chain.length, "There should be additional chrome event targets.");
|
||||
}
|
||||
}
|
||||
if (0 < actual.length) {
|
||||
var chain = els.getEventTargetChainFor(actual[0], false); // Events should be dispatched on actual[0].
|
||||
ok(expected.length < chain.length, "There should be additional chrome event targets.");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* <div elemOne> ------ <shadow-root shadowOne>
|
||||
* |
|
||||
* <span elemTwo>
|
||||
* |
|
||||
* <span elemThree>
|
||||
*/
|
||||
/*
|
||||
* <div elemOne> ------ <shadow-root shadowOne>
|
||||
* |
|
||||
* <span elemTwo>
|
||||
* |
|
||||
* <span elemThree>
|
||||
*/
|
||||
|
||||
var elemOne = document.createElement("div");
|
||||
var elemTwo = document.createElement("span");
|
||||
var elemThree = document.createElement("span");
|
||||
var shadowOne = elemOne.createShadowRoot();
|
||||
var elemOne = aDocument.createElement("div");
|
||||
var elemTwo = aDocument.createElement("span");
|
||||
var elemThree = aDocument.createElement("span");
|
||||
var shadowOne = elemOne.attachShadow({mode: "open"});
|
||||
|
||||
shadowOne.appendChild(elemTwo);
|
||||
elemTwo.appendChild(elemThree);
|
||||
shadowOne.appendChild(elemTwo);
|
||||
elemTwo.appendChild(elemThree);
|
||||
|
||||
// Test stopping "abort" event.
|
||||
// Test stopping "abort" event.
|
||||
|
||||
elemOne.addEventListener("abort", eventListener);
|
||||
elemTwo.addEventListener("abort", eventListener);
|
||||
elemThree.addEventListener("abort", eventListener);
|
||||
shadowOne.addEventListener("abort", eventListener);
|
||||
elemOne.addEventListener("abort", eventListener);
|
||||
elemTwo.addEventListener("abort", eventListener);
|
||||
elemThree.addEventListener("abort", eventListener);
|
||||
shadowOne.addEventListener("abort", eventListener);
|
||||
|
||||
var eventChain = [];
|
||||
var eventChain = [];
|
||||
|
||||
var customEvent = new CustomEvent("abort", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that abort event is stopped at shadow root.");
|
||||
var customEvent = new CustomEvent("abort", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that abort event is stopped at shadow root.");
|
||||
|
||||
// Test stopping "error" event.
|
||||
// Test stopping "error" event.
|
||||
|
||||
elemOne.addEventListener("error", eventListener);
|
||||
elemTwo.addEventListener("error", eventListener);
|
||||
elemThree.addEventListener("error", eventListener);
|
||||
shadowOne.addEventListener("error", eventListener);
|
||||
elemOne.addEventListener("error", eventListener);
|
||||
elemTwo.addEventListener("error", eventListener);
|
||||
elemThree.addEventListener("error", eventListener);
|
||||
shadowOne.addEventListener("error", eventListener);
|
||||
|
||||
eventChain = [];
|
||||
eventChain = [];
|
||||
|
||||
customEvent = new CustomEvent("error", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that error event is stopped at shadow root.");
|
||||
customEvent = new CustomEvent("error", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that error event is stopped at shadow root.");
|
||||
|
||||
// Test stopping "select" event.
|
||||
// Test stopping "select" event.
|
||||
|
||||
elemOne.addEventListener("select", eventListener);
|
||||
elemTwo.addEventListener("select", eventListener);
|
||||
elemThree.addEventListener("select", eventListener);
|
||||
shadowOne.addEventListener("select", eventListener);
|
||||
elemOne.addEventListener("select", eventListener);
|
||||
elemTwo.addEventListener("select", eventListener);
|
||||
elemThree.addEventListener("select", eventListener);
|
||||
shadowOne.addEventListener("select", eventListener);
|
||||
|
||||
eventChain = [];
|
||||
eventChain = [];
|
||||
|
||||
customEvent = new CustomEvent("select", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that select event is stopped at shadow root.");
|
||||
customEvent = new CustomEvent("select", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that select event is stopped at shadow root.");
|
||||
|
||||
// Test stopping "change" event.
|
||||
// Test stopping "change" event.
|
||||
|
||||
elemOne.addEventListener("change", eventListener);
|
||||
elemTwo.addEventListener("change", eventListener);
|
||||
elemThree.addEventListener("change", eventListener);
|
||||
shadowOne.addEventListener("change", eventListener);
|
||||
elemOne.addEventListener("change", eventListener);
|
||||
elemTwo.addEventListener("change", eventListener);
|
||||
elemThree.addEventListener("change", eventListener);
|
||||
shadowOne.addEventListener("change", eventListener);
|
||||
|
||||
eventChain = [];
|
||||
eventChain = [];
|
||||
|
||||
customEvent = new CustomEvent("change", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
customEvent = new CustomEvent("change", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
|
||||
// Test stopping "reset" event.
|
||||
// Test stopping "reset" event.
|
||||
|
||||
elemOne.addEventListener("reset", eventListener);
|
||||
elemTwo.addEventListener("reset", eventListener);
|
||||
elemThree.addEventListener("reset", eventListener);
|
||||
shadowOne.addEventListener("reset", eventListener);
|
||||
elemOne.addEventListener("reset", eventListener);
|
||||
elemTwo.addEventListener("reset", eventListener);
|
||||
elemThree.addEventListener("reset", eventListener);
|
||||
shadowOne.addEventListener("reset", eventListener);
|
||||
|
||||
eventChain = [];
|
||||
eventChain = [];
|
||||
|
||||
customEvent = new CustomEvent("reset", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that reset event is stopped at shadow root.");
|
||||
customEvent = new CustomEvent("reset", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that reset event is stopped at shadow root.");
|
||||
|
||||
// Test stopping "load" event.
|
||||
// Test stopping "load" event.
|
||||
|
||||
elemOne.addEventListener("load", eventListener);
|
||||
elemTwo.addEventListener("load", eventListener);
|
||||
elemThree.addEventListener("load", eventListener);
|
||||
shadowOne.addEventListener("load", eventListener);
|
||||
elemOne.addEventListener("load", eventListener);
|
||||
elemTwo.addEventListener("load", eventListener);
|
||||
elemThree.addEventListener("load", eventListener);
|
||||
shadowOne.addEventListener("load", eventListener);
|
||||
|
||||
eventChain = [];
|
||||
eventChain = [];
|
||||
|
||||
customEvent = new CustomEvent("load", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that load event is stopped at shadow root.");
|
||||
customEvent = new CustomEvent("load", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that load event is stopped at shadow root.");
|
||||
|
||||
// Test stopping "resize" event.
|
||||
// Test stopping "resize" event.
|
||||
|
||||
elemOne.addEventListener("resize", eventListener);
|
||||
elemTwo.addEventListener("resize", eventListener);
|
||||
elemThree.addEventListener("resize", eventListener);
|
||||
shadowOne.addEventListener("resize", eventListener);
|
||||
elemOne.addEventListener("resize", eventListener);
|
||||
elemTwo.addEventListener("resize", eventListener);
|
||||
elemThree.addEventListener("resize", eventListener);
|
||||
shadowOne.addEventListener("resize", eventListener);
|
||||
|
||||
eventChain = [];
|
||||
eventChain = [];
|
||||
|
||||
customEvent = new CustomEvent("resize", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that resize event is stopped at shadow root.");
|
||||
customEvent = new CustomEvent("resize", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that resize event is stopped at shadow root.");
|
||||
|
||||
// Test stopping "scroll" event.
|
||||
// Test stopping "scroll" event.
|
||||
|
||||
elemOne.addEventListener("scroll", eventListener);
|
||||
elemTwo.addEventListener("scroll", eventListener);
|
||||
elemThree.addEventListener("scroll", eventListener);
|
||||
shadowOne.addEventListener("scroll", eventListener);
|
||||
elemOne.addEventListener("scroll", eventListener);
|
||||
elemTwo.addEventListener("scroll", eventListener);
|
||||
elemThree.addEventListener("scroll", eventListener);
|
||||
shadowOne.addEventListener("scroll", eventListener);
|
||||
|
||||
eventChain = [];
|
||||
eventChain = [];
|
||||
|
||||
customEvent = new CustomEvent("scroll", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that scroll event is stopped at shadow root.");
|
||||
customEvent = new CustomEvent("scroll", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that scroll event is stopped at shadow root.");
|
||||
|
||||
// Test stopping "selectstart" event.
|
||||
// Test stopping "selectstart" event.
|
||||
|
||||
elemOne.addEventListener("selectstart", eventListener);
|
||||
elemTwo.addEventListener("selectstart", eventListener);
|
||||
elemThree.addEventListener("selectstart", eventListener);
|
||||
shadowOne.addEventListener("selectstart", eventListener);
|
||||
elemOne.addEventListener("selectstart", eventListener);
|
||||
elemTwo.addEventListener("selectstart", eventListener);
|
||||
elemThree.addEventListener("selectstart", eventListener);
|
||||
shadowOne.addEventListener("selectstart", eventListener);
|
||||
|
||||
eventChain = [];
|
||||
eventChain = [];
|
||||
|
||||
customEvent = new CustomEvent("selectstart", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that selectstart event is stopped at shadow root.");
|
||||
customEvent = new CustomEvent("selectstart", { "bubbles" : true });
|
||||
elemThree.dispatchEvent(customEvent);
|
||||
isEventChain(eventChain, [elemThree, elemTwo, shadowOne], "Test that selectstart event is stopped at shadow root.");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -5,79 +5,87 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=806506
|
||||
-->
|
||||
<head>
|
||||
<title>Test for ShadowRoot</title>
|
||||
<script type="text/javascript" src="head.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="movedtoshadow" class="testclass"></div>
|
||||
<svg id="svgmovedtoshadow"></svg>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=806506">Bug 806506</a>
|
||||
<script>
|
||||
// Create ShadowRoot.
|
||||
var element = document.createElement("div");
|
||||
ok(!element.shadowRoot, "div element should not have a shadow root.");
|
||||
var shadow = element.createShadowRoot();
|
||||
is(element.shadowRoot, shadow, "shadowRoot property should return the same shadow root that was just created.");
|
||||
|
||||
// Move an element from the document to the ShadowRoot.
|
||||
var inShadowEl = document.getElementById("movedtoshadow");
|
||||
var inShadowSVGEl = document.getElementById("svgmovedtoshadow");
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// Test getElementById
|
||||
ok(!shadow.getElementById("movedtoshadow"), "Element not in ShadowRoot should not be accessible from ShadowRoot API.");
|
||||
ok(!shadow.getElementById("svgmovedtoshadow"), "SVG element not in ShadowRoot should not be accessible from ShadowRoot API.");
|
||||
shadow.appendChild(inShadowEl);
|
||||
shadow.appendChild(inShadowSVGEl);
|
||||
is(shadow.getElementById("movedtoshadow"), inShadowEl, "Element appended to a ShadowRoot should be accessible from ShadowRoot API.");
|
||||
ok(!document.getElementById("movedtoshadow"), "Element appended to a ShadowRoot should not be accessible from document.");
|
||||
is(shadow.getElementById("svgmovedtoshadow"), inShadowSVGEl, "SVG element appended to a ShadowRoot should be accessible from ShadowRoot API.");
|
||||
ok(!document.getElementById("svgmovedtoshadow"), "SVG element appended to a ShadowRoot should not be accessible from document.");
|
||||
var content = '<div id="movedtoshadow" class="testclass"></div>' +
|
||||
'<svg id="svgmovedtoshadow"></svg>';
|
||||
setWebComponentsPrefAndCreateIframe(content)
|
||||
.then((aDocument) => {
|
||||
// Create ShadowRoot.
|
||||
var element = aDocument.createElement("div");
|
||||
ok(!element.shadowRoot, "div element should not have a shadow root.");
|
||||
var shadow = element.attachShadow({mode: "open"});
|
||||
is(element.shadowRoot, shadow, "shadowRoot property should return the same shadow root that was just created.");
|
||||
|
||||
// Test getElementsByClassName
|
||||
is(document.getElementsByClassName("testclass").length, 0, "Element removed from DOM should not be accessible by DOM accessors.");
|
||||
is(shadow.getElementsByClassName("testclass").length, 1, "Element added to ShadowRoot should be accessible by ShadowRoot API.");
|
||||
// Move an element from the document to the ShadowRoot.
|
||||
var inShadowEl = aDocument.getElementById("movedtoshadow");
|
||||
var inShadowSVGEl = aDocument.getElementById("svgmovedtoshadow");
|
||||
|
||||
// Test getElementsByTagName{NS}
|
||||
is(document.getElementsByTagName("div").length, 0, "Element removed from DOM should not be accessible from DOM accessors.");
|
||||
is(shadow.getElementsByTagName("div").length, 1, "Elements in the ShadowRoot should be accessible from the ShadowRoot API.");
|
||||
is(document.getElementsByTagName("svg").length, 0, "SVG elements removed from DOM should not be accessible from DOM accessors.");
|
||||
is(shadow.getElementsByTagName("svg").length, 1, "SVG element in the ShadowRoot should be accessible from the ShadowRoot API.");
|
||||
is(shadow.getElementsByTagNameNS("http://www.w3.org/2000/svg", "svg").length, 1, "SVG element in the ShadowRoot should be accessible from the ShadowRoot API.");
|
||||
// Test getElementById
|
||||
ok(!shadow.getElementById("movedtoshadow"), "Element not in ShadowRoot should not be accessible from ShadowRoot API.");
|
||||
ok(!shadow.getElementById("svgmovedtoshadow"), "SVG element not in ShadowRoot should not be accessible from ShadowRoot API.");
|
||||
shadow.appendChild(inShadowEl);
|
||||
shadow.appendChild(inShadowSVGEl);
|
||||
is(shadow.getElementById("movedtoshadow"), inShadowEl, "Element appended to a ShadowRoot should be accessible from ShadowRoot API.");
|
||||
ok(!aDocument.getElementById("movedtoshadow"), "Element appended to a ShadowRoot should not be accessible from document.");
|
||||
is(shadow.getElementById("svgmovedtoshadow"), inShadowSVGEl, "SVG element appended to a ShadowRoot should be accessible from ShadowRoot API.");
|
||||
ok(!aDocument.getElementById("svgmovedtoshadow"), "SVG element appended to a ShadowRoot should not be accessible from document.");
|
||||
|
||||
// Remove elements from ShadowRoot and make sure that they are no longer accessible via the ShadowRoot API.
|
||||
shadow.removeChild(inShadowEl);
|
||||
shadow.removeChild(inShadowSVGEl);
|
||||
ok(!shadow.getElementById("movedtoshadow"), "ShadowRoot API should not be able to access elements removed from ShadowRoot.");
|
||||
ok(!shadow.getElementById("svgmovedtoshadow"), "ShadowRoot API should not be able to access elements removed from ShadowRoot.");
|
||||
is(shadow.getElementsByClassName("testclass").length, 0, "ShadowRoot getElementsByClassName should not be able to access elements removed from ShadowRoot.");
|
||||
is(shadow.getElementsByTagName("svg").length, 0, "ShadowRoot getElementsByTagName should not be able to access elements removed from ShadowRoot.");
|
||||
is(shadow.getElementsByTagNameNS("http://www.w3.org/2000/svg", "svg").length, 0, "ShadowRoot getElementsByTagNameNS should not be able to access elements removed from ShadowRoot.");
|
||||
// Test getElementsByClassName
|
||||
is(aDocument.getElementsByClassName("testclass").length, 0, "Element removed from DOM should not be accessible by DOM accessors.");
|
||||
is(shadow.getElementsByClassName("testclass").length, 1, "Element added to ShadowRoot should be accessible by ShadowRoot API.");
|
||||
|
||||
// Test querySelector on element in a ShadowRoot.
|
||||
element = document.createElement("div");
|
||||
shadow = element.createShadowRoot();
|
||||
var parentDiv = document.createElement("div");
|
||||
var childSpan = document.createElement("span");
|
||||
childSpan.id = "innerdiv";
|
||||
parentDiv.appendChild(childSpan);
|
||||
is(parentDiv.querySelector("#innerdiv"), childSpan, "ID query selector should work on element in ShadowRoot.");
|
||||
is(parentDiv.querySelector("span"), childSpan, "Tag query selector should work on element in ShadowRoot.");
|
||||
// Test getElementsByTagName{NS}
|
||||
is(aDocument.getElementsByTagName("div").length, 0, "Element removed from DOM should not be accessible from DOM accessors.");
|
||||
is(shadow.getElementsByTagName("div").length, 1, "Elements in the ShadowRoot should be accessible from the ShadowRoot API.");
|
||||
is(aDocument.getElementsByTagName("svg").length, 0, "SVG elements removed from DOM should not be accessible from DOM accessors.");
|
||||
is(shadow.getElementsByTagName("svg").length, 1, "SVG element in the ShadowRoot should be accessible from the ShadowRoot API.");
|
||||
is(shadow.getElementsByTagNameNS("http://www.w3.org/2000/svg", "svg").length, 1, "SVG element in the ShadowRoot should be accessible from the ShadowRoot API.");
|
||||
|
||||
// Test that exception is thrown when trying to create a cycle with host node.
|
||||
element = document.createElement("div");
|
||||
shadow = element.createShadowRoot();
|
||||
try {
|
||||
shadow.appendChild(element);
|
||||
ok(false, "Excpetion should be thrown when creating a cycle with host content.");
|
||||
} catch (ex) {
|
||||
ok(true, "Excpetion should be thrown when creating a cycle with host content.");
|
||||
}
|
||||
// Remove elements from ShadowRoot and make sure that they are no longer accessible via the ShadowRoot API.
|
||||
shadow.removeChild(inShadowEl);
|
||||
shadow.removeChild(inShadowSVGEl);
|
||||
ok(!shadow.getElementById("movedtoshadow"), "ShadowRoot API should not be able to access elements removed from ShadowRoot.");
|
||||
ok(!shadow.getElementById("svgmovedtoshadow"), "ShadowRoot API should not be able to access elements removed from ShadowRoot.");
|
||||
is(shadow.getElementsByClassName("testclass").length, 0, "ShadowRoot getElementsByClassName should not be able to access elements removed from ShadowRoot.");
|
||||
is(shadow.getElementsByTagName("svg").length, 0, "ShadowRoot getElementsByTagName should not be able to access elements removed from ShadowRoot.");
|
||||
is(shadow.getElementsByTagNameNS("http://www.w3.org/2000/svg", "svg").length, 0, "ShadowRoot getElementsByTagNameNS should not be able to access elements removed from ShadowRoot.");
|
||||
|
||||
// Basic innerHTML tests.
|
||||
shadow.innerHTML = '<span id="first"></span><div id="second"></div>';
|
||||
is(shadow.childNodes.length, 2, "There should be two children in the ShadowRoot.");
|
||||
is(shadow.getElementById("second").tagName, "DIV", "Elements created by innerHTML should be accessible by ShadowRoot API.");
|
||||
// Test querySelector on element in a ShadowRoot.
|
||||
element = aDocument.createElement("div");
|
||||
shadow = element.attachShadow({mode: "open"});
|
||||
var parentDiv = aDocument.createElement("div");
|
||||
var childSpan = aDocument.createElement("span");
|
||||
childSpan.id = "innerdiv";
|
||||
parentDiv.appendChild(childSpan);
|
||||
is(parentDiv.querySelector("#innerdiv"), childSpan, "ID query selector should work on element in ShadowRoot.");
|
||||
is(parentDiv.querySelector("span"), childSpan, "Tag query selector should work on element in ShadowRoot.");
|
||||
|
||||
// Test that exception is thrown when trying to create a cycle with host node.
|
||||
element = aDocument.createElement("div");
|
||||
shadow = element.attachShadow({mode: "open"});
|
||||
try {
|
||||
shadow.appendChild(element);
|
||||
ok(false, "Excpetion should be thrown when creating a cycle with host content.");
|
||||
} catch (ex) {
|
||||
ok(true, "Excpetion should be thrown when creating a cycle with host content.");
|
||||
}
|
||||
|
||||
// Basic innerHTML tests.
|
||||
shadow.innerHTML = '<span id="first"></span><div id="second"></div>';
|
||||
is(shadow.childNodes.length, 2, "There should be two children in the ShadowRoot.");
|
||||
is(shadow.getElementById("second").tagName, "DIV", "Elements created by innerHTML should be accessible by ShadowRoot API.");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -5,40 +5,45 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=806506
|
||||
-->
|
||||
<head>
|
||||
<title>Test for inert elements in ShadowRoot</title>
|
||||
<script type="text/javascript" src="head.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onload="runChecks();">
|
||||
<div id="grabme"></div>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=806506">Bug 806506</a>
|
||||
<script>
|
||||
|
||||
var element = document.getElementById("grabme");
|
||||
var shadow = element.createShadowRoot();
|
||||
|
||||
// Check that <base> is inert.
|
||||
shadow.innerHTML = '<base href="http://www.example.org/" />';
|
||||
isnot(document.baseURI, "http://www.example.org/", "Base element should be inert in ShadowRoot.");
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// Check that <link> is inert.
|
||||
var numStyleBeforeLoad = document.styleSheets.length;
|
||||
var content = '<div id="grabme"></div>';
|
||||
setWebComponentsPrefAndCreateIframe(content)
|
||||
.then((aDocument) => {
|
||||
function runChecks() {
|
||||
isnot(aDocument.defaultView.getComputedStyle(shadowSpan, null).getPropertyValue("padding-top"), "10px", "Link element should be inert.");
|
||||
is(aDocument.styleSheets.length, numStyleBeforeLoad, "Document style count should remain the same because the style should not be in the doucment.");
|
||||
is(shadow.styleSheets.length, 0, "Inert link should not add style to ShadowRoot.");
|
||||
// Remove link to make sure we don't get assertions.
|
||||
shadow.removeChild(shadowStyle);
|
||||
SimpleTest.finish();
|
||||
};
|
||||
|
||||
shadow.innerHTML = '<link id="shadowlink" rel="stylesheet" type="text/css" href="inert_style.css" /><span id="shadowspan"></span>';
|
||||
shadow.applyAuthorStyles = true;
|
||||
var shadowSpan = shadow.getElementById("shadowspan");
|
||||
var shadowStyle = shadow.getElementById("shadowlink");
|
||||
var element = aDocument.getElementById("grabme");
|
||||
var shadow = element.attachShadow({mode: "open"});
|
||||
|
||||
function runChecks() {
|
||||
isnot(getComputedStyle(shadowSpan, null).getPropertyValue("padding-top"), "10px", "Link element should be inert.");
|
||||
is(document.styleSheets.length, numStyleBeforeLoad, "Document style count should remain the same because the style should not be in the doucment.");
|
||||
is(shadow.styleSheets.length, 0, "Inert link should not add style to ShadowRoot.");
|
||||
// Remove link to make sure we don't get assertions.
|
||||
shadow.removeChild(shadowStyle);
|
||||
SimpleTest.finish();
|
||||
};
|
||||
// Check that <base> is inert.
|
||||
shadow.innerHTML = '<base href="http://www.example.org/" />';
|
||||
isnot(aDocument.baseURI, "http://www.example.org/", "Base element should be inert in ShadowRoot.");
|
||||
|
||||
// Check that <link> is inert.
|
||||
var numStyleBeforeLoad = aDocument.styleSheets.length;
|
||||
|
||||
shadow.innerHTML = '<link id="shadowlink" rel="stylesheet" type="text/css" href="inert_style.css" /><span id="shadowspan"></span>';
|
||||
shadow.applyAuthorStyles = true;
|
||||
var shadowSpan = shadow.getElementById("shadowspan");
|
||||
var shadowStyle = shadow.getElementById("shadowlink");
|
||||
|
||||
runChecks();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -5,12 +5,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=806506
|
||||
-->
|
||||
<head>
|
||||
<title>Test for ShadowRoot styling</title>
|
||||
<script type="text/javascript" src="head.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="tall" id="bodydiv"></div>
|
||||
<div id="container"></div>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=806506">Bug 806506</a>
|
||||
<script>
|
||||
|
||||
@@ -18,70 +17,80 @@ if (!SpecialPowers.DOMWindowUtils.isStyledByServo) {
|
||||
SimpleTest.expectAssertions(3, 3); // GeckoRestyleManager stuff.
|
||||
}
|
||||
|
||||
// Create ShadowRoot.
|
||||
var container = document.getElementById("container");
|
||||
var elem = document.createElement("div");
|
||||
container.appendChild(elem); // Put ShadowRoot host in document.
|
||||
var root = elem.createShadowRoot();
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// A style element that will be appended into the ShadowRoot.
|
||||
var shadowStyle = document.createElement("style");
|
||||
shadowStyle.innerHTML = ".tall { height: 100px; } .fat { padding-left: inherit; }";
|
||||
var content = '<div class="tall" id="bodydiv"></div>' +
|
||||
'<div id="container"></div>';
|
||||
setWebComponentsPrefAndCreateIframe(content)
|
||||
.then((aDocument) => {
|
||||
var iframeWin = aDocument.defaultView;
|
||||
|
||||
root.innerHTML = '<div id="divtostyle" class="tall fat"></div>';
|
||||
var divToStyle = root.getElementById("divtostyle");
|
||||
// Create ShadowRoot.
|
||||
var container = aDocument.getElementById("container");
|
||||
var elem = aDocument.createElement("div");
|
||||
container.appendChild(elem); // Put ShadowRoot host in document.
|
||||
var root = elem.attachShadow({mode: "open"});
|
||||
|
||||
// Make sure styleSheet counts are correct after appending a style to the ShadowRoot.
|
||||
is(document.styleSheets.length, 1, "There should only be one style sheet on the document from the test style sheet.");
|
||||
is(root.styleSheets.length, 0, "The ShadowRoot should have no style sheets.");
|
||||
root.appendChild(shadowStyle);
|
||||
is(document.styleSheets.length, 1, "Styles in the ShadowRoot element should not be accessible from the document.");
|
||||
is(root.styleSheets.length, 1, "ShadowRoot should have one style sheet from the appened style.");
|
||||
is(root.styleSheets[0].ownerNode, shadowStyle, "First style in ShadowRoot should match the style that was just appended.");
|
||||
// A style element that will be appended into the ShadowRoot.
|
||||
var shadowStyle = aDocument.createElement("style");
|
||||
shadowStyle.innerHTML = ".tall { height: 100px; } .fat { padding-left: inherit; }";
|
||||
|
||||
var dummyStyle = document.createElement("style");
|
||||
root.appendChild(dummyStyle);
|
||||
is(root.styleSheets.length, 2, "ShadowRoot should have an additional style from appending dummyStyle.");
|
||||
is(root.styleSheets[1].ownerNode, dummyStyle, "Second style in ShadowRoot should be the dummyStyle.");
|
||||
root.removeChild(dummyStyle);
|
||||
is(root.styleSheets.length, 1, "Removing dummyStyle should remove it from the ShadowRoot style sheets.");
|
||||
is(root.styleSheets[0].ownerNode, shadowStyle, "The style sheet remaining in the ShadowRoot should be shadowStyle.");
|
||||
root.innerHTML = '<div id="divtostyle" class="tall fat"></div>';
|
||||
var divToStyle = root.getElementById("divtostyle");
|
||||
|
||||
// Make sure that elements outside of the ShadowRoot are not affected by the ShadowRoot style.
|
||||
isnot(getComputedStyle(document.getElementById("bodydiv"), null).getPropertyValue("height"), "100px", "Style sheets in ShadowRoot should not apply to elements no in the ShadowRoot.");
|
||||
// Make sure styleSheet counts are correct after appending a style to the ShadowRoot.
|
||||
is(aDocument.styleSheets.length, 0, "There shouldn't be any style sheet in the test frame document.");
|
||||
is(root.styleSheets.length, 0, "The ShadowRoot should have no style sheets.");
|
||||
root.appendChild(shadowStyle);
|
||||
is(aDocument.styleSheets.length, 0, "Styles in the ShadowRoot element should not be accessible from the document.");
|
||||
is(root.styleSheets.length, 1, "ShadowRoot should have one style sheet from the appened style.");
|
||||
is(root.styleSheets[0].ownerNode, shadowStyle, "First style in ShadowRoot should match the style that was just appended.");
|
||||
|
||||
// Make sure that elements in the ShadowRoot are styled according to the ShadowRoot style.
|
||||
is(getComputedStyle(divToStyle, null).getPropertyValue("height"), "100px", "ShadowRoot style sheets should apply to elements in ShadowRoot.");
|
||||
var dummyStyle = aDocument.createElement("style");
|
||||
root.appendChild(dummyStyle);
|
||||
is(root.styleSheets.length, 2, "ShadowRoot should have an additional style from appending dummyStyle.");
|
||||
is(root.styleSheets[1].ownerNode, dummyStyle, "Second style in ShadowRoot should be the dummyStyle.");
|
||||
root.removeChild(dummyStyle);
|
||||
is(root.styleSheets.length, 1, "Removing dummyStyle should remove it from the ShadowRoot style sheets.");
|
||||
is(root.styleSheets[0].ownerNode, shadowStyle, "The style sheet remaining in the ShadowRoot should be shadowStyle.");
|
||||
|
||||
// Tests for applyAuthorStyles.
|
||||
var authorStyle = document.createElement("style");
|
||||
authorStyle.innerHTML = ".fat { padding-right: 20px; padding-left: 30px; }";
|
||||
document.body.appendChild(authorStyle);
|
||||
// Make sure that elements outside of the ShadowRoot are not affected by the ShadowRoot style.
|
||||
isnot(iframeWin.getComputedStyle(aDocument.getElementById("bodydiv"), null).getPropertyValue("height"), "100px", "Style sheets in ShadowRoot should not apply to elements no in the ShadowRoot.");
|
||||
|
||||
is(root.applyAuthorStyles, false, "applyAuthorStyles defaults to false.");
|
||||
isnot(getComputedStyle(divToStyle, null).getPropertyValue("padding-right"), "20px", "Author styles should not apply to ShadowRoot when ShadowRoot.applyAuthorStyles is false.");
|
||||
root.applyAuthorStyles = true;
|
||||
is(root.applyAuthorStyles, true, "applyAuthorStyles was set to true.");
|
||||
is(getComputedStyle(divToStyle, null).getPropertyValue("padding-right"), "20px", "Author styles should apply to ShadowRoot when ShadowRoot.applyAuthorStyles is true.");
|
||||
root.applyAuthorStyles = false;
|
||||
is(root.applyAuthorStyles, false, "applyAuthorStyles was set to false.");
|
||||
isnot(getComputedStyle(divToStyle, null).getPropertyValue("padding-right"), "20px", "Author styles should not apply to ShadowRoot when ShadowRoot.applyAuthorStyles is false.");
|
||||
// Make sure that elements in the ShadowRoot are styled according to the ShadowRoot style.
|
||||
is(iframeWin.getComputedStyle(divToStyle, null).getPropertyValue("height"), "100px", "ShadowRoot style sheets should apply to elements in ShadowRoot.");
|
||||
|
||||
// Test dynamic changes to style in ShadowRoot.
|
||||
root.innerHTML = '<div id="divtostyle" class="dummy"></div>';
|
||||
divToStyle = root.getElementById("divtostyle");
|
||||
var dummyShadowStyle = document.createElement("style");
|
||||
dummyShadowStyle.innerHTML = ".dummy { height: 300px; }";
|
||||
root.appendChild(dummyShadowStyle);
|
||||
is(getComputedStyle(divToStyle, null).getPropertyValue("height"), "300px", "Dummy element in ShadowRoot should be styled by style in ShadowRoot.");
|
||||
dummyShadowStyle.innerHTML = ".dummy { height: 200px; }";
|
||||
is(getComputedStyle(divToStyle, null).getPropertyValue("height"), "200px", "Dynamic changes to styles in ShadowRoot should change style of affected elements.");
|
||||
// Tests for applyAuthorStyles.
|
||||
var authorStyle = aDocument.createElement("style");
|
||||
authorStyle.innerHTML = ".fat { padding-right: 20px; padding-left: 30px; }";
|
||||
aDocument.body.appendChild(authorStyle);
|
||||
|
||||
// Test id selector in ShadowRoot style.
|
||||
root.innerHTML = '<style>#divtostyle { padding-top: 10px; }</style><div id="divtostyle"></div>';
|
||||
divToStyle = root.getElementById("divtostyle");
|
||||
is(getComputedStyle(divToStyle, null).getPropertyValue("padding-top"), "10px", "ID selector in style selector should match element.");
|
||||
is(root.applyAuthorStyles, false, "applyAuthorStyles defaults to false.");
|
||||
isnot(iframeWin.getComputedStyle(divToStyle, null).getPropertyValue("padding-right"), "20px", "Author styles should not apply to ShadowRoot when ShadowRoot.applyAuthorStyles is false.");
|
||||
root.applyAuthorStyles = true;
|
||||
is(root.applyAuthorStyles, true, "applyAuthorStyles was set to true.");
|
||||
is(iframeWin.getComputedStyle(divToStyle, null).getPropertyValue("padding-right"), "20px", "Author styles should apply to ShadowRoot when ShadowRoot.applyAuthorStyles is true.");
|
||||
root.applyAuthorStyles = false;
|
||||
is(root.applyAuthorStyles, false, "applyAuthorStyles was set to false.");
|
||||
isnot(iframeWin.getComputedStyle(divToStyle, null).getPropertyValue("padding-right"), "20px", "Author styles should not apply to ShadowRoot when ShadowRoot.applyAuthorStyles is false.");
|
||||
|
||||
// Test dynamic changes to style in ShadowRoot.
|
||||
root.innerHTML = '<div id="divtostyle" class="dummy"></div>';
|
||||
divToStyle = root.getElementById("divtostyle");
|
||||
var dummyShadowStyle = aDocument.createElement("style");
|
||||
dummyShadowStyle.innerHTML = ".dummy { height: 300px; }";
|
||||
root.appendChild(dummyShadowStyle);
|
||||
is(iframeWin.getComputedStyle(divToStyle, null).getPropertyValue("height"), "300px", "Dummy element in ShadowRoot should be styled by style in ShadowRoot.");
|
||||
dummyShadowStyle.innerHTML = ".dummy { height: 200px; }";
|
||||
is(iframeWin.getComputedStyle(divToStyle, null).getPropertyValue("height"), "200px", "Dynamic changes to styles in ShadowRoot should change style of affected elements.");
|
||||
|
||||
// Test id selector in ShadowRoot style.
|
||||
root.innerHTML = '<style>#divtostyle { padding-top: 10px; }</style><div id="divtostyle"></div>';
|
||||
divToStyle = root.getElementById("divtostyle");
|
||||
is(iframeWin.getComputedStyle(divToStyle, null).getPropertyValue("padding-top"), "10px", "ID selector in style selector should match element.");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -5,38 +5,48 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=806506
|
||||
-->
|
||||
<head>
|
||||
<title>Test for ShadowRoot style order</title>
|
||||
<script type="text/javascript" src="head.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=806506">Bug 806506</a>
|
||||
<script>
|
||||
// Create ShadowRoot.
|
||||
var container = document.getElementById("container");
|
||||
var elem = document.createElement("div");
|
||||
container.appendChild(elem); // Put ShadowRoot host in document.
|
||||
var root = elem.createShadowRoot();
|
||||
|
||||
// Style elements that will be appended into the ShadowRoot.
|
||||
var tallShadowStyle = document.createElement("style");
|
||||
tallShadowStyle.innerHTML = ".tall { height: 100px; }";
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var veryTallShadowStyle = document.createElement("style");
|
||||
veryTallShadowStyle.innerHTML = ".tall { height: 200px; }";
|
||||
var content = '<div id="container"></div>';
|
||||
setWebComponentsPrefAndCreateIframe(content)
|
||||
.then((aDocument) => {
|
||||
var iframeWin = aDocument.defaultView;
|
||||
|
||||
var divToStyle = document.createElement("div");
|
||||
divToStyle.setAttribute("class", "tall");
|
||||
root.appendChild(divToStyle);
|
||||
// Create ShadowRoot.
|
||||
var container = aDocument.getElementById("container");
|
||||
var elem = aDocument.createElement("div");
|
||||
container.appendChild(elem); // Put ShadowRoot host in document.
|
||||
var root = elem.attachShadow({mode: "open"});
|
||||
|
||||
// Make sure the styles are applied in tree order.
|
||||
root.appendChild(tallShadowStyle);
|
||||
is(root.styleSheets.length, 1, "ShadowRoot should have one style sheet.");
|
||||
is(window.getComputedStyle(divToStyle).getPropertyValue("height"), "100px", "Style in ShadowRoot should apply to elements in ShadowRoot.");
|
||||
root.appendChild(veryTallShadowStyle);
|
||||
is(root.styleSheets.length, 2, "ShadowRoot should have two style sheets.");
|
||||
is(window.getComputedStyle(divToStyle).getPropertyValue("height"), "200px", "Style in ShadowRoot should apply to elements in ShadowRoot in tree order.");
|
||||
// Style elements that will be appended into the ShadowRoot.
|
||||
var tallShadowStyle = aDocument.createElement("style");
|
||||
tallShadowStyle.innerHTML = ".tall { height: 100px; }";
|
||||
|
||||
var veryTallShadowStyle = aDocument.createElement("style");
|
||||
veryTallShadowStyle.innerHTML = ".tall { height: 200px; }";
|
||||
|
||||
var divToStyle = aDocument.createElement("div");
|
||||
divToStyle.setAttribute("class", "tall");
|
||||
root.appendChild(divToStyle);
|
||||
|
||||
// Make sure the styles are applied in tree order.
|
||||
root.appendChild(tallShadowStyle);
|
||||
is(root.styleSheets.length, 1, "ShadowRoot should have one style sheet.");
|
||||
is(iframeWin.getComputedStyle(divToStyle).getPropertyValue("height"), "100px", "Style in ShadowRoot should apply to elements in ShadowRoot.");
|
||||
root.appendChild(veryTallShadowStyle);
|
||||
is(root.styleSheets.length, 2, "ShadowRoot should have two style sheets.");
|
||||
is(iframeWin.getComputedStyle(divToStyle).getPropertyValue("height"), "200px", "Style in ShadowRoot should apply to elements in ShadowRoot in tree order.");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -5,24 +5,35 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=806506
|
||||
-->
|
||||
<head>
|
||||
<title>Test for styling fallback content</title>
|
||||
<script type="text/javascript" src="head.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="grabme"></div>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=806506">Bug 806506</a>
|
||||
<script>
|
||||
var host = document.getElementById("grabme");
|
||||
var shadow = host.createShadowRoot();
|
||||
shadow.innerHTML = '<style id="innerstyle"></style><span id="container"><content><span id="innerspan">Hello</span></content></span>';
|
||||
var innerStyle = shadow.getElementById("innerstyle");
|
||||
|
||||
innerStyle.innerHTML = '#innerspan { margin-top: 10px; }';
|
||||
var innerSpan = shadow.getElementById("innerspan");
|
||||
is(getComputedStyle(innerSpan, null).getPropertyValue("margin-top"), "10px", "Default content should be style by id selector.");
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
innerStyle.innerHTML = '#container > content > #innerspan { margin-top: 30px; }';
|
||||
is(getComputedStyle(innerSpan, null).getPropertyValue("margin-top"), "30px", "Default content should be style by child combinators.");
|
||||
var content = '<div id="grabme"></div>';
|
||||
setWebComponentsPrefAndCreateIframe(content)
|
||||
.then((aDocument) => {
|
||||
var iframeWin = aDocument.defaultView;
|
||||
|
||||
var host = aDocument.getElementById("grabme");
|
||||
var shadow = host.attachShadow({mode: "open"});
|
||||
shadow.innerHTML = '<style id="innerstyle"></style><span id="container"><slot><span id="innerspan">Hello</span></slot></span>';
|
||||
var innerStyle = shadow.getElementById("innerstyle");
|
||||
|
||||
innerStyle.innerHTML = '#innerspan { margin-top: 10px; }';
|
||||
var innerSpan = shadow.getElementById("innerspan");
|
||||
is(iframeWin.getComputedStyle(innerSpan, null).getPropertyValue("margin-top"), "10px", "Default content should be style by id selector.");
|
||||
|
||||
innerStyle.innerHTML = '#container > slot > #innerspan { margin-top: 30px; }';
|
||||
is(iframeWin.getComputedStyle(innerSpan, null).getPropertyValue("margin-top"), "30px", "Default content should be style by child combinators.");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -313,6 +313,75 @@ ServiceWorkerManager::Init(ServiceWorkerRegistrar* aRegistrar)
|
||||
mActor = static_cast<ServiceWorkerManagerChild*>(actor);
|
||||
}
|
||||
|
||||
RefPtr<GenericPromise>
|
||||
ServiceWorkerManager::StartControllingClient(const ClientInfo& aClientInfo,
|
||||
ServiceWorkerRegistrationInfo* aRegistrationInfo)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(aRegistrationInfo->GetActive());
|
||||
|
||||
RefPtr<GenericPromise> ref;
|
||||
|
||||
const ServiceWorkerDescriptor& active =
|
||||
aRegistrationInfo->GetActive()->Descriptor();
|
||||
|
||||
auto entry = mControlledClients.LookupForAdd(aClientInfo.Id());
|
||||
if (entry) {
|
||||
RefPtr<ServiceWorkerRegistrationInfo> old =
|
||||
entry.Data()->mRegistrationInfo.forget();
|
||||
|
||||
ref = Move(entry.Data()->mClientHandle->Control(active));
|
||||
entry.Data()->mRegistrationInfo = aRegistrationInfo;
|
||||
|
||||
if (old != aRegistrationInfo) {
|
||||
StopControllingRegistration(old);
|
||||
aRegistrationInfo->StartControllingClient();
|
||||
}
|
||||
|
||||
Telemetry::Accumulate(Telemetry::SERVICE_WORKER_CONTROLLED_DOCUMENTS, 1);
|
||||
|
||||
return Move(ref);
|
||||
}
|
||||
|
||||
RefPtr<ClientHandle> clientHandle =
|
||||
ClientManager::CreateHandle(aClientInfo,
|
||||
SystemGroup::EventTargetFor(TaskCategory::Other));
|
||||
|
||||
ref = Move(clientHandle->Control(active));
|
||||
|
||||
aRegistrationInfo->StartControllingClient();
|
||||
|
||||
entry.OrInsert([&] {
|
||||
return new ControlledClientData(clientHandle, aRegistrationInfo);
|
||||
});
|
||||
|
||||
RefPtr<ServiceWorkerManager> self(this);
|
||||
clientHandle->OnDetach()->Then(
|
||||
SystemGroup::EventTargetFor(TaskCategory::Other), __func__,
|
||||
[self = Move(self), aClientInfo] {
|
||||
self->StopControllingClient(aClientInfo);
|
||||
});
|
||||
|
||||
Telemetry::Accumulate(Telemetry::SERVICE_WORKER_CONTROLLED_DOCUMENTS, 1);
|
||||
|
||||
return Move(ref);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::StopControllingClient(const ClientInfo& aClientInfo)
|
||||
{
|
||||
auto entry = mControlledClients.Lookup(aClientInfo.Id());
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerRegistrationInfo> reg =
|
||||
entry.Data()->mRegistrationInfo.forget();
|
||||
|
||||
entry.Remove();
|
||||
|
||||
StopControllingRegistration(reg);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::MaybeStartShutdown()
|
||||
{
|
||||
@@ -1432,8 +1501,13 @@ ServiceWorkerManager::GetActiveWorkerInfoForDocument(nsIDocument* aDocument)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
Maybe<ClientInfo> clientInfo(aDocument->GetClientInfo());
|
||||
if (clientInfo.isNothing()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerRegistrationInfo> registration;
|
||||
GetDocumentRegistration(aDocument, getter_AddRefs(registration));
|
||||
GetClientRegistration(clientInfo.ref(), getter_AddRefs(registration));
|
||||
|
||||
if (!registration) {
|
||||
return nullptr;
|
||||
@@ -1578,7 +1652,7 @@ ServiceWorkerManager::WorkerIsIdle(ServiceWorkerInfo* aWorker)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!reg->IsControllingDocuments() && reg->mPendingUninstall) {
|
||||
if (!reg->IsControllingClients() && reg->mPendingUninstall) {
|
||||
RemoveRegistration(reg);
|
||||
return;
|
||||
}
|
||||
@@ -2269,15 +2343,25 @@ ServiceWorkerManager::RemoveScopeAndRegistration(ServiceWorkerRegistrationInfo*
|
||||
entry.Remove();
|
||||
}
|
||||
|
||||
// The registration should generally only be removed if there are no controlled
|
||||
// documents, but mControlledDocuments can contain references to potentially
|
||||
// controlled docs. This happens when the service worker is not active yet.
|
||||
// We must purge these references since we are evicting the registration.
|
||||
// Verify there are no controlled clients for the purged registration.
|
||||
for (auto iter = swm->mControlledClients.Iter(); !iter.Done(); iter.Next()) {
|
||||
auto& reg = iter.UserData()->mRegistrationInfo;
|
||||
if (reg->mScope.Equals(aRegistration->mScope)) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(false,
|
||||
"controlled client when removing registration");
|
||||
iter.Remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Registration lifecycle is managed via mControlledClients now. Do not
|
||||
// assert on on mControlledDocuments as races may cause this to still be
|
||||
// set when the registration is destroyed.
|
||||
for (auto iter = swm->mControlledDocuments.Iter(); !iter.Done(); iter.Next()) {
|
||||
ServiceWorkerRegistrationInfo* reg = iter.UserData();
|
||||
MOZ_ASSERT(reg);
|
||||
if (reg->mScope.Equals(aRegistration->mScope)) {
|
||||
iter.Remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2308,32 +2392,49 @@ ServiceWorkerManager::MaybeStartControlling(nsIDocument* aDoc)
|
||||
MOZ_ASSERT(aDoc);
|
||||
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||
GetServiceWorkerRegistrationInfo(aDoc);
|
||||
if (registration) {
|
||||
if (registration && registration->GetActive() &&
|
||||
aDoc->GetSandboxFlags() == 0) {
|
||||
MOZ_ASSERT(!mControlledDocuments.Contains(aDoc));
|
||||
StartControllingADocument(registration, aDoc);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceWorkerManager::StartControlling(const ClientInfo& aClientInfo,
|
||||
const ServiceWorkerDescriptor& aServiceWorker)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
PrincipalInfoToPrincipal(aServiceWorker.PrincipalInfo());
|
||||
NS_ENSURE_TRUE(principal, false);
|
||||
|
||||
nsCOMPtr<nsIURI> scope;
|
||||
nsresult rv =
|
||||
NS_NewURI(getter_AddRefs(scope), aServiceWorker.Scope(), nullptr, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||
GetServiceWorkerRegistrationInfo(principal, scope);
|
||||
NS_ENSURE_TRUE(registration, false);
|
||||
|
||||
StartControllingClient(aClientInfo, registration);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::MaybeStopControlling(nsIDocument* aDoc)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aDoc);
|
||||
RefPtr<ServiceWorkerRegistrationInfo> registration;
|
||||
mControlledDocuments.Remove(aDoc, getter_AddRefs(registration));
|
||||
// A document which was uncontrolled does not maintain that state itself, so
|
||||
// it will always call MaybeStopControlling() even if there isn't an
|
||||
// associated registration. So this check is required.
|
||||
if (registration) {
|
||||
StopControllingADocument(registration);
|
||||
}
|
||||
mControlledDocuments.Remove(aDoc);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::MaybeCheckNavigationUpdate(nsIDocument* aDoc)
|
||||
ServiceWorkerManager::MaybeCheckNavigationUpdate(const ClientInfo& aClientInfo)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aDoc);
|
||||
// We perform these success path navigation update steps when the
|
||||
// document tells us its more or less done loading. This avoids
|
||||
// slowing down page load and also lets pages consistently get
|
||||
@@ -2343,52 +2444,27 @@ ServiceWorkerManager::MaybeCheckNavigationUpdate(nsIDocument* aDoc)
|
||||
// 9.8.22 Else: (respondWith was entered and succeeded)
|
||||
// If request is a non-subresource request, then: Invoke Soft Update
|
||||
// algorithm.
|
||||
RefPtr<ServiceWorkerRegistrationInfo> registration;
|
||||
mControlledDocuments.Get(aDoc, getter_AddRefs(registration));
|
||||
if (registration) {
|
||||
registration->MaybeScheduleUpdate();
|
||||
ControlledClientData* data = mControlledClients.Get(aClientInfo.Id());
|
||||
if (data && data->mRegistrationInfo) {
|
||||
data->mRegistrationInfo->MaybeScheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<GenericPromise>
|
||||
void
|
||||
ServiceWorkerManager::StartControllingADocument(ServiceWorkerRegistrationInfo* aRegistration,
|
||||
nsIDocument* aDoc)
|
||||
{
|
||||
MOZ_ASSERT(aRegistration);
|
||||
MOZ_ASSERT(aDoc);
|
||||
|
||||
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
auto storageAllowed = nsContentUtils::StorageAllowedForDocument(aDoc);
|
||||
MOZ_DIAGNOSTIC_ASSERT(storageAllowed == nsContentUtils::StorageAccess::eAllow);
|
||||
#endif // MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
|
||||
RefPtr<GenericPromise> ref = GenericPromise::CreateAndResolve(true, __func__);
|
||||
|
||||
aRegistration->StartControllingADocument();
|
||||
mControlledDocuments.Put(aDoc, aRegistration);
|
||||
|
||||
// Mark the document's ClientSource as controlled using the ClientHandle
|
||||
// interface. While we could get at the ClientSource directly from the
|
||||
// document here, our goal is to move ServiceWorkerManager to a separate
|
||||
// process. Using the ClientHandle supports this remote operation.
|
||||
ServiceWorkerInfo* activeWorker = aRegistration->GetActive();
|
||||
Maybe<ClientInfo> clientInfo = aDoc->GetClientInfo();
|
||||
if (activeWorker && clientInfo.isSome()) {
|
||||
RefPtr<ClientHandle> clientHandle =
|
||||
ClientManager::CreateHandle(clientInfo.ref(),
|
||||
SystemGroup::EventTargetFor(TaskCategory::Other));
|
||||
ref = Move(clientHandle->Control(activeWorker->Descriptor()));
|
||||
}
|
||||
|
||||
Telemetry::Accumulate(Telemetry::SERVICE_WORKER_CONTROLLED_DOCUMENTS, 1);
|
||||
return Move(ref);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::StopControllingADocument(ServiceWorkerRegistrationInfo* aRegistration)
|
||||
ServiceWorkerManager::StopControllingRegistration(ServiceWorkerRegistrationInfo* aRegistration)
|
||||
{
|
||||
aRegistration->StopControllingADocument();
|
||||
if (aRegistration->IsControllingDocuments() || !aRegistration->IsIdle()) {
|
||||
aRegistration->StopControllingClient();
|
||||
if (aRegistration->IsControllingClients() || !aRegistration->IsIdle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2718,10 +2794,7 @@ ServiceWorkerManager::DispatchFetchEvent(const OriginAttributes& aOriginAttribut
|
||||
// First, attempt to mark the reserved client controlled directly. This
|
||||
// will update the controlled status in the ClientManagerService in the
|
||||
// parent. It will also eventually propagate back to the ClientSource.
|
||||
RefPtr<ClientHandle> clientHandle =
|
||||
ClientManager::CreateHandle(clientInfo.ref(),
|
||||
SystemGroup::EventTargetFor(TaskCategory::Other));
|
||||
clientHandle->Control(serviceWorker->Descriptor());
|
||||
StartControllingClient(clientInfo.ref(), registration);
|
||||
}
|
||||
|
||||
// But we also note the reserved state on the LoadInfo. This allows the
|
||||
@@ -2785,20 +2858,21 @@ ServiceWorkerManager::IsAvailable(nsIPrincipal* aPrincipal,
|
||||
}
|
||||
|
||||
nsresult
|
||||
ServiceWorkerManager::GetDocumentRegistration(nsIDocument* aDoc,
|
||||
ServiceWorkerRegistrationInfo** aRegistrationInfo)
|
||||
ServiceWorkerManager::GetClientRegistration(const ClientInfo& aClientInfo,
|
||||
ServiceWorkerRegistrationInfo** aRegistrationInfo)
|
||||
{
|
||||
RefPtr<ServiceWorkerRegistrationInfo> registration;
|
||||
if (!mControlledDocuments.Get(aDoc, getter_AddRefs(registration))) {
|
||||
ControlledClientData* data = mControlledClients.Get(aClientInfo.Id());
|
||||
if (!data || !data->mRegistrationInfo) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// If the document is controlled, the current worker MUST be non-null.
|
||||
if (!registration->GetActive()) {
|
||||
if (!data->mRegistrationInfo->GetActive()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
registration.forget(aRegistrationInfo);
|
||||
RefPtr<ServiceWorkerRegistrationInfo> ref = data->mRegistrationInfo;
|
||||
ref.forget(aRegistrationInfo);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -3169,13 +3243,21 @@ ServiceWorkerManager::MaybeClaimClient(nsIDocument* aDocument,
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
Maybe<ClientInfo> clientInfo(aDocument->GetClientInfo());
|
||||
if (NS_WARN_IF(clientInfo.isNothing())) {
|
||||
ref = GenericPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR,
|
||||
__func__);
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
// The registration that should be controlling the client
|
||||
RefPtr<ServiceWorkerRegistrationInfo> matchingRegistration =
|
||||
GetServiceWorkerRegistrationInfo(aDocument);
|
||||
|
||||
// The registration currently controlling the client
|
||||
RefPtr<ServiceWorkerRegistrationInfo> controllingRegistration;
|
||||
GetDocumentRegistration(aDocument, getter_AddRefs(controllingRegistration));
|
||||
GetClientRegistration(clientInfo.ref(),
|
||||
getter_AddRefs(controllingRegistration));
|
||||
|
||||
if (aWorkerRegistration != matchingRegistration ||
|
||||
aWorkerRegistration == controllingRegistration) {
|
||||
@@ -3183,11 +3265,8 @@ ServiceWorkerManager::MaybeClaimClient(nsIDocument* aDocument,
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
if (controllingRegistration) {
|
||||
StopControllingADocument(controllingRegistration);
|
||||
}
|
||||
|
||||
ref = StartControllingADocument(aWorkerRegistration, aDocument);
|
||||
StartControllingADocument(aWorkerRegistration, aDocument);
|
||||
ref = StartControllingClient(clientInfo.ref(), aWorkerRegistration);
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
@@ -3248,31 +3327,19 @@ ServiceWorkerManager::UpdateClientControllers(ServiceWorkerRegistrationInfo* aRe
|
||||
RefPtr<ServiceWorkerInfo> activeWorker = aRegistration->GetActive();
|
||||
MOZ_DIAGNOSTIC_ASSERT(activeWorker);
|
||||
|
||||
AutoTArray<nsCOMPtr<nsIDocument>, 16> docList;
|
||||
for (auto iter = mControlledDocuments.Iter(); !iter.Done(); iter.Next()) {
|
||||
if (iter.UserData() != aRegistration) {
|
||||
AutoTArray<RefPtr<ClientHandle>, 16> handleList;
|
||||
for (auto iter = mControlledClients.Iter(); !iter.Done(); iter.Next()) {
|
||||
if (iter.UserData()->mRegistrationInfo != aRegistration) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(iter.Key());
|
||||
if (NS_WARN_IF(!doc)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
docList.AppendElement(doc.forget());
|
||||
handleList.AppendElement(iter.UserData()->mClientHandle);
|
||||
}
|
||||
|
||||
// Fire event after iterating mControlledDocuments is done to prevent
|
||||
// Fire event after iterating mControlledClients is done to prevent
|
||||
// modification by reentering from the event handlers during iteration.
|
||||
for (auto& doc : docList) {
|
||||
Maybe<ClientInfo> clientInfo = doc->GetClientInfo();
|
||||
if (clientInfo.isNothing()) {
|
||||
continue;
|
||||
}
|
||||
RefPtr<ClientHandle> clientHandle =
|
||||
ClientManager::CreateHandle(clientInfo.ref(),
|
||||
SystemGroup::EventTargetFor(TaskCategory::Other));
|
||||
clientHandle->Control(activeWorker->Descriptor());
|
||||
for (auto& handle : handleList) {
|
||||
handle->Control(activeWorker->Descriptor());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/ClientHandle.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/ServiceWorkerCommon.h"
|
||||
#include "mozilla/dom/ServiceWorkerRegistrar.h"
|
||||
@@ -105,6 +106,21 @@ public:
|
||||
|
||||
nsRefPtrHashtable<nsISupportsHashKey, ServiceWorkerRegistrationInfo> mControlledDocuments;
|
||||
|
||||
struct ControlledClientData
|
||||
{
|
||||
RefPtr<ClientHandle> mClientHandle;
|
||||
RefPtr<ServiceWorkerRegistrationInfo> mRegistrationInfo;
|
||||
|
||||
ControlledClientData(ClientHandle* aClientHandle,
|
||||
ServiceWorkerRegistrationInfo* aRegistrationInfo)
|
||||
: mClientHandle(aClientHandle)
|
||||
, mRegistrationInfo(aRegistrationInfo)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
nsClassHashtable<nsIDHashKey, ControlledClientData> mControlledClients;
|
||||
|
||||
// Track all documents that have attempted to register a service worker for a
|
||||
// given scope.
|
||||
typedef nsTArray<nsCOMPtr<nsIWeakReference>> WeakDocumentList;
|
||||
@@ -304,7 +320,7 @@ public:
|
||||
ServiceWorkerRegistrationListener* aListener);
|
||||
|
||||
void
|
||||
MaybeCheckNavigationUpdate(nsIDocument* aDoc);
|
||||
MaybeCheckNavigationUpdate(const ClientInfo& aClientInfo);
|
||||
|
||||
nsresult
|
||||
SendPushEvent(const nsACString& aOriginAttributes,
|
||||
@@ -328,6 +344,13 @@ private:
|
||||
void
|
||||
Init(ServiceWorkerRegistrar* aRegistrar);
|
||||
|
||||
RefPtr<GenericPromise>
|
||||
StartControllingClient(const ClientInfo& aClientInfo,
|
||||
ServiceWorkerRegistrationInfo* aRegistrationInfo);
|
||||
|
||||
void
|
||||
StopControllingClient(const ClientInfo& aClientInfo);
|
||||
|
||||
void
|
||||
MaybeStartShutdown();
|
||||
|
||||
@@ -349,8 +372,8 @@ private:
|
||||
Update(ServiceWorkerRegistrationInfo* aRegistration);
|
||||
|
||||
nsresult
|
||||
GetDocumentRegistration(nsIDocument* aDoc,
|
||||
ServiceWorkerRegistrationInfo** aRegistrationInfo);
|
||||
GetClientRegistration(const ClientInfo& aClientInfo,
|
||||
ServiceWorkerRegistrationInfo** aRegistrationInfo);
|
||||
|
||||
nsresult
|
||||
GetServiceWorkerForScope(nsPIDOMWindowInner* aWindow,
|
||||
@@ -375,12 +398,12 @@ private:
|
||||
void
|
||||
NotifyServiceWorkerRegistrationRemoved(ServiceWorkerRegistrationInfo* aRegistration);
|
||||
|
||||
RefPtr<GenericPromise>
|
||||
void
|
||||
StartControllingADocument(ServiceWorkerRegistrationInfo* aRegistration,
|
||||
nsIDocument* aDoc);
|
||||
|
||||
void
|
||||
StopControllingADocument(ServiceWorkerRegistrationInfo* aRegistration);
|
||||
StopControllingRegistration(ServiceWorkerRegistrationInfo* aRegistration);
|
||||
|
||||
already_AddRefed<ServiceWorkerRegistrationInfo>
|
||||
GetServiceWorkerRegistrationInfo(nsPIDOMWindowInner* aWindow);
|
||||
|
||||
@@ -81,7 +81,7 @@ ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(
|
||||
const nsACString& aScope,
|
||||
nsIPrincipal* aPrincipal,
|
||||
ServiceWorkerUpdateViaCache aUpdateViaCache)
|
||||
: mControlledDocumentsCounter(0)
|
||||
: mControlledClientsCounter(0)
|
||||
, mUpdateState(NoUpdate)
|
||||
, mCreationTime(PR_Now())
|
||||
, mCreationTimeStamp(TimeStamp::Now())
|
||||
@@ -94,9 +94,7 @@ ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(
|
||||
|
||||
ServiceWorkerRegistrationInfo::~ServiceWorkerRegistrationInfo()
|
||||
{
|
||||
if (IsControllingDocuments()) {
|
||||
NS_WARNING("ServiceWorkerRegistrationInfo is still controlling documents. This can be a bug or a leak in ServiceWorker API or in any other API that takes the document alive.");
|
||||
}
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsControllingClients());
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(ServiceWorkerRegistrationInfo, nsIServiceWorkerRegistrationInfo)
|
||||
@@ -248,7 +246,7 @@ void
|
||||
ServiceWorkerRegistrationInfo::TryToActivate()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
bool controlling = IsControllingDocuments();
|
||||
bool controlling = IsControllingClients();
|
||||
bool skipWaiting = mWaitingWorker && mWaitingWorker->SkipWaitingFlag();
|
||||
bool idle = IsIdle();
|
||||
if (idle && (!controlling || skipWaiting)) {
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace workers {
|
||||
class ServiceWorkerRegistrationInfo final
|
||||
: public nsIServiceWorkerRegistrationInfo
|
||||
{
|
||||
uint32_t mControlledDocumentsCounter;
|
||||
uint32_t mControlledClientsCounter;
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -79,22 +79,22 @@ public:
|
||||
GetServiceWorkerInfoById(uint64_t aId);
|
||||
|
||||
void
|
||||
StartControllingADocument()
|
||||
StartControllingClient()
|
||||
{
|
||||
++mControlledDocumentsCounter;
|
||||
++mControlledClientsCounter;
|
||||
}
|
||||
|
||||
void
|
||||
StopControllingADocument()
|
||||
StopControllingClient()
|
||||
{
|
||||
MOZ_ASSERT(mControlledDocumentsCounter);
|
||||
--mControlledDocumentsCounter;
|
||||
MOZ_ASSERT(mControlledClientsCounter);
|
||||
--mControlledClientsCounter;
|
||||
}
|
||||
|
||||
bool
|
||||
IsControllingDocuments() const
|
||||
IsControllingClients() const
|
||||
{
|
||||
return mActiveWorker && mControlledDocumentsCounter;
|
||||
return mActiveWorker && mControlledClientsCounter;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -138,7 +138,7 @@ ServiceWorkerUnregisterJob::Unregister()
|
||||
InvokeResultCallbacks(NS_OK);
|
||||
|
||||
// "If no service worker client is using registration..."
|
||||
if (!registration->IsControllingDocuments() && registration->IsIdle()) {
|
||||
if (!registration->IsControllingClients() && registration->IsIdle()) {
|
||||
// "Invoke [[Clear Registration]]..."
|
||||
swm->RemoveRegistration(registration);
|
||||
}
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
info("skip_waiting_scope/index.html shouldn't be launched directly!");
|
||||
}
|
||||
|
||||
navigator.serviceWorker.ready.then(function() {
|
||||
parent.postMessage("READY", "*");
|
||||
});
|
||||
|
||||
navigator.serviceWorker.oncontrollerchange = function() {
|
||||
parent.postMessage({
|
||||
event: "controllerchange",
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
var registration, iframe, content;
|
||||
|
||||
@@ -21,19 +22,9 @@
|
||||
{scope: "./skip_waiting_scope/"});
|
||||
}
|
||||
|
||||
function waitForActivated(swr) {
|
||||
async function waitForActivated(swr) {
|
||||
registration = swr;
|
||||
var promise = new Promise(function(resolve, reject) {
|
||||
window.onmessage = function(e) {
|
||||
if (e.data === "READY") {
|
||||
ok(true, "Active worker is activated now");
|
||||
resolve();
|
||||
} else {
|
||||
ok(false, "Wrong value. Somenting went wrong");
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
});
|
||||
await waitForState(registration.installing, "activated")
|
||||
|
||||
iframe = document.createElement("iframe");
|
||||
iframe.setAttribute("src", "skip_waiting_scope/index.html");
|
||||
@@ -41,7 +32,7 @@
|
||||
content = document.getElementById("content");
|
||||
content.appendChild(iframe);
|
||||
|
||||
return promise;
|
||||
await new Promise(resolve => iframe.onload = resolve);
|
||||
}
|
||||
|
||||
function checkWhetherItSkippedWaiting() {
|
||||
|
||||
@@ -82,9 +82,10 @@ function runTest(aExpectedResponses) {
|
||||
|
||||
// Verify that we can register and intercept a 3rd party iframe with
|
||||
// the given cookie policy.
|
||||
function testShouldIntercept(policy, done) {
|
||||
function testShouldIntercept(behavior, lifetime, done) {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["network.cookie.cookieBehavior", policy]
|
||||
["network.cookie.cookieBehavior", behavior],
|
||||
["network.cookie.lifetimePolicy", lifetime],
|
||||
]}, function() {
|
||||
runTest([{
|
||||
status: "ok"
|
||||
@@ -121,9 +122,10 @@ function testShouldIntercept(policy, done) {
|
||||
|
||||
// Verify that we cannot register a service worker in a 3rd party
|
||||
// iframe with the given cookie policy.
|
||||
function testShouldNotRegister(policy, done) {
|
||||
function testShouldNotRegister(behavior, lifetime, done) {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["network.cookie.cookieBehavior", policy]
|
||||
["network.cookie.cookieBehavior", behavior],
|
||||
["network.cookie.lifetimePolicy", lifetime],
|
||||
]}, function() {
|
||||
runTest([{
|
||||
status: "registrationfailed",
|
||||
@@ -152,9 +154,10 @@ function testShouldNotRegister(policy, done) {
|
||||
// Verify that if a service worker is already registered a 3rd
|
||||
// party iframe will still not be intercepted with the given cookie
|
||||
// policy.
|
||||
function testShouldNotIntercept(policy, done) {
|
||||
function testShouldNotIntercept(behavior, lifetime, done) {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["network.cookie.cookieBehavior", COOKIE_BEHAVIOR_ACCEPT]
|
||||
["network.cookie.cookieBehavior", BEHAVIOR_ACCEPT],
|
||||
["network.cookie.lifetimePolicy", LIFETIME_EXPIRE],
|
||||
]}, function() {
|
||||
runTest([{
|
||||
status: "ok"
|
||||
@@ -163,7 +166,8 @@ function testShouldNotIntercept(policy, done) {
|
||||
next: function() {
|
||||
iframe.addEventListener("load", testIframeLoaded);
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["network.cookie.cookieBehavior", policy],
|
||||
["network.cookie.cookieBehavior", behavior],
|
||||
["network.cookie.lifetimePolicy", lifetime],
|
||||
]}, function() {
|
||||
iframe.src = origin + basePath + "iframe1.html";
|
||||
});
|
||||
@@ -186,7 +190,8 @@ function testShouldNotIntercept(policy, done) {
|
||||
status: "getregistrationfailed",
|
||||
next: function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["network.cookie.cookieBehavior", COOKIE_BEHAVIOR_ACCEPT],
|
||||
["network.cookie.cookieBehavior", BEHAVIOR_ACCEPT],
|
||||
["network.cookie.lifetimePolicy", LIFETIME_EXPIRE],
|
||||
]}, function() {
|
||||
iframe.src = thirdPartyOrigin + basePath + "unregister.html";
|
||||
});
|
||||
@@ -204,10 +209,13 @@ function testShouldNotIntercept(policy, done) {
|
||||
});
|
||||
}
|
||||
|
||||
const COOKIE_BEHAVIOR_ACCEPT = 0;
|
||||
const COOKIE_BEHAVIOR_REJECTFOREIGN = 1;
|
||||
const COOKIE_BEHAVIOR_REJECT = 2;
|
||||
const COOKIE_BEHAVIOR_LIMITFOREIGN = 3;
|
||||
const BEHAVIOR_ACCEPT = 0;
|
||||
const BEHAVIOR_REJECTFOREIGN = 1;
|
||||
const BEHAVIOR_REJECT = 2;
|
||||
const BEHAVIOR_LIMITFOREIGN = 3;
|
||||
|
||||
const LIFETIME_EXPIRE = 0;
|
||||
const LIFETIME_SESSION = 2;
|
||||
|
||||
let steps = [() => {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
@@ -215,22 +223,37 @@ let steps = [() => {
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
["browser.dom.window.dump.enabled", true],
|
||||
["network.cookie.cookieBehavior", COOKIE_BEHAVIOR_ACCEPT]
|
||||
["network.cookie.cookieBehavior", BEHAVIOR_ACCEPT],
|
||||
["network.cookie.lifetimePolicy", LIFETIME_EXPIRE],
|
||||
]}, next);
|
||||
}, () => {
|
||||
testShouldIntercept(COOKIE_BEHAVIOR_ACCEPT, next);
|
||||
testShouldIntercept(BEHAVIOR_ACCEPT, LIFETIME_EXPIRE, next);
|
||||
}, () => {
|
||||
testShouldNotRegister(COOKIE_BEHAVIOR_REJECTFOREIGN, next);
|
||||
testShouldNotRegister(BEHAVIOR_REJECTFOREIGN, LIFETIME_EXPIRE, next);
|
||||
}, () => {
|
||||
testShouldNotIntercept(COOKIE_BEHAVIOR_REJECTFOREIGN, next);
|
||||
testShouldNotIntercept(BEHAVIOR_REJECTFOREIGN, LIFETIME_EXPIRE, next);
|
||||
}, () => {
|
||||
testShouldNotRegister(COOKIE_BEHAVIOR_REJECT, next);
|
||||
testShouldNotRegister(BEHAVIOR_REJECT, LIFETIME_EXPIRE, next);
|
||||
}, () => {
|
||||
testShouldNotIntercept(COOKIE_BEHAVIOR_REJECT, next);
|
||||
testShouldNotIntercept(BEHAVIOR_REJECT, LIFETIME_EXPIRE, next);
|
||||
}, () => {
|
||||
testShouldNotRegister(COOKIE_BEHAVIOR_LIMITFOREIGN, next);
|
||||
testShouldNotRegister(BEHAVIOR_LIMITFOREIGN, LIFETIME_EXPIRE, next);
|
||||
}, () => {
|
||||
testShouldNotIntercept(COOKIE_BEHAVIOR_LIMITFOREIGN, next);
|
||||
testShouldNotIntercept(BEHAVIOR_LIMITFOREIGN, LIFETIME_EXPIRE, next);
|
||||
}, () => {
|
||||
testShouldNotIntercept(BEHAVIOR_ACCEPT, LIFETIME_SESSION, next);
|
||||
}, () => {
|
||||
testShouldNotRegister(BEHAVIOR_REJECTFOREIGN, LIFETIME_SESSION, next);
|
||||
}, () => {
|
||||
testShouldNotIntercept(BEHAVIOR_REJECTFOREIGN, LIFETIME_SESSION, next);
|
||||
}, () => {
|
||||
testShouldNotRegister(BEHAVIOR_REJECT, LIFETIME_SESSION, next);
|
||||
}, () => {
|
||||
testShouldNotIntercept(BEHAVIOR_REJECT, LIFETIME_SESSION, next);
|
||||
}, () => {
|
||||
testShouldNotRegister(BEHAVIOR_LIMITFOREIGN, LIFETIME_SESSION, next);
|
||||
}, () => {
|
||||
testShouldNotIntercept(BEHAVIOR_LIMITFOREIGN, LIFETIME_SESSION, next);
|
||||
}];
|
||||
|
||||
</script>
|
||||
|
||||
@@ -13,14 +13,15 @@
|
||||
<p id="display"></p>
|
||||
<div id="content"></div>
|
||||
<pre id="test"></pre>
|
||||
<script src="utils.js"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
var registration;
|
||||
var promise;
|
||||
|
||||
function start() {
|
||||
return navigator.serviceWorker.register("worker_updatefoundevent.js",
|
||||
{ scope: "./updatefoundevent.html" })
|
||||
.then((swr) => registration = swr);
|
||||
async function start() {
|
||||
registration = await navigator.serviceWorker.register("worker_updatefoundevent.js",
|
||||
{ scope: "./updatefoundevent.html" })
|
||||
await waitForState(registration.installing, 'activated');
|
||||
}
|
||||
|
||||
function startWaitForUpdateFound() {
|
||||
|
||||
@@ -3,21 +3,16 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
onactivate = function(e) {
|
||||
e.waitUntil(new Promise(function(resolve, reject) {
|
||||
registration.onupdatefound = function(e) {
|
||||
clients.matchAll().then(function(clients) {
|
||||
if (!clients.length) {
|
||||
reject("No clients found");
|
||||
}
|
||||
|
||||
if (registration.scope.match(/updatefoundevent\.html$/)) {
|
||||
clients[0].postMessage("finish");
|
||||
resolve();
|
||||
} else {
|
||||
dump("Scope did not match");
|
||||
}
|
||||
}, reject);
|
||||
registration.onupdatefound = function(e) {
|
||||
clients.matchAll().then(function(clients) {
|
||||
if (!clients.length) {
|
||||
reject("No clients found");
|
||||
}
|
||||
}));
|
||||
|
||||
if (registration.scope.match(/updatefoundevent\.html$/)) {
|
||||
clients[0].postMessage("finish");
|
||||
} else {
|
||||
dump("Scope did not match");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -21,19 +21,6 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace wr {
|
||||
struct ColorF;
|
||||
|
||||
struct TypedSize2D_f32__LayerPixel;
|
||||
typedef TypedSize2D_f32__LayerPixel LayerSize;
|
||||
typedef LayerSize LayoutSize;
|
||||
|
||||
struct TypedRect_f32__LayerPixel;
|
||||
typedef TypedRect_f32__LayerPixel LayerRect;
|
||||
typedef LayerRect LayoutRect;
|
||||
|
||||
} // namespace wr
|
||||
|
||||
namespace gfx {
|
||||
template <class units, class F> struct RectTyped;
|
||||
} // namespace gfx
|
||||
|
||||
@@ -366,6 +366,23 @@ typedef GenericFlingAnimation FlingAnimation;
|
||||
* the main thread doesn't actually need to do a repaint. This pref allows the
|
||||
* main thread to skip doing those repaints in cases where it doesn't need to.
|
||||
*
|
||||
* \li\b apz.pinch_lock.mode
|
||||
* The preferred pinch locking style. See PinchLockMode for possible values.
|
||||
*
|
||||
* \li\b apz.pinch_lock.scroll_lock_threshold
|
||||
* Pinch locking is triggered if the user scrolls more than this distance
|
||||
* and pinches less than apz.pinch_lock.span_lock_threshold.\n
|
||||
* Units: (real-world, i.e. screen) inches
|
||||
*
|
||||
* \li\b apz.pinch_lock.span_breakout_threshold
|
||||
* Distance in inches the user must pinch before lock can be broken.\n
|
||||
* Units: (real-world, i.e. screen) inches measured between two touch points
|
||||
*
|
||||
* \li\b apz.pinch_lock.span_lock_threshold
|
||||
* Pinch locking is triggered if the user pinches less than this distance
|
||||
* and scrolls more than apz.pinch_lock.scroll_lock_threshold.\n
|
||||
* Units: (real-world, i.e. screen) inches measured between two touch points
|
||||
*
|
||||
* \li\b apz.popups.enabled
|
||||
* Determines whether APZ is used for XUL popup widgets with remote content.
|
||||
* Ideally, this should always be true, but it is currently not well tested, and
|
||||
@@ -759,6 +776,7 @@ AsyncPanZoomController::AsyncPanZoomController(uint64_t aLayersId,
|
||||
mX(this),
|
||||
mY(this),
|
||||
mPanDirRestricted(false),
|
||||
mPinchLocked(false),
|
||||
mZoomConstraints(false, false,
|
||||
mFrameMetrics.GetDevPixelsPerCSSPixel() * kViewportMinScale / ParentLayerToScreenScale(1),
|
||||
mFrameMetrics.GetDevPixelsPerCSSPixel() * kViewportMaxScale / ParentLayerToScreenScale(1)),
|
||||
@@ -864,6 +882,11 @@ AsyncPanZoomController::GetSecondTapTolerance()
|
||||
return static_cast<AxisLockMode>(gfxPrefs::APZAxisLockMode());
|
||||
}
|
||||
|
||||
/* static */AsyncPanZoomController::PinchLockMode AsyncPanZoomController::GetPinchLockMode()
|
||||
{
|
||||
return static_cast<PinchLockMode>(gfxPrefs::APZPinchLockMode());
|
||||
}
|
||||
|
||||
bool
|
||||
AsyncPanZoomController::ArePointerEventsConsumable(TouchBlockState* aBlock, uint32_t aTouchPoints) {
|
||||
if (aTouchPoints == 0) {
|
||||
@@ -1328,6 +1351,7 @@ nsEventStatus AsyncPanZoomController::OnTouchCancel(const MultiTouchInput& aEven
|
||||
nsEventStatus AsyncPanZoomController::OnScaleBegin(const PinchGestureInput& aEvent) {
|
||||
APZC_LOG("%p got a scale-begin in state %d\n", this, mState);
|
||||
|
||||
mPinchLocked = false;
|
||||
mPinchPaintTimerSet = false;
|
||||
// Note that there may not be a touch block at this point, if we received the
|
||||
// PinchGestureEvent directly from widget code without any touch events.
|
||||
@@ -1369,9 +1393,26 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
||||
ParentLayerCoord spanDistance = fabsf(aEvent.mPreviousSpan - aEvent.mCurrentSpan);
|
||||
ParentLayerPoint focusPoint, focusChange;
|
||||
{
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
|
||||
focusPoint = aEvent.mLocalFocusPoint - mFrameMetrics.GetCompositionBounds().TopLeft();
|
||||
focusChange = mLastZoomFocus - focusPoint;
|
||||
mLastZoomFocus = focusPoint;
|
||||
}
|
||||
|
||||
HandlePinchLocking(
|
||||
ToScreenCoordinates(ParentLayerPoint(0, spanDistance), focusPoint).Length(),
|
||||
ToScreenCoordinates(focusChange, focusPoint));
|
||||
bool allowZoom = mZoomConstraints.mAllowZoom && !mPinchLocked;
|
||||
|
||||
// If zooming is not allowed, this is a two-finger pan.
|
||||
// Tracking panning distance and velocity.
|
||||
if (!mZoomConstraints.mAllowZoom) {
|
||||
// UpdateWithTouchAtDevicePoint() acquires the tree lock, so
|
||||
// it cannot be called while the mRecursiveMutex lock is held.
|
||||
if (!allowZoom) {
|
||||
mX.UpdateWithTouchAtDevicePoint(aEvent.mLocalFocusPoint.x, 0, aEvent.mTime);
|
||||
mY.UpdateWithTouchAtDevicePoint(aEvent.mLocalFocusPoint.y, 0, aEvent.mTime);
|
||||
}
|
||||
@@ -1397,11 +1438,8 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
|
||||
CSSToParentLayerScale userZoom = mFrameMetrics.GetZoom().ToScaleFactor();
|
||||
ParentLayerPoint focusPoint = aEvent.mLocalFocusPoint - mFrameMetrics.GetCompositionBounds().TopLeft();
|
||||
CSSPoint cssFocusPoint = focusPoint / mFrameMetrics.GetZoom();
|
||||
|
||||
ParentLayerPoint focusChange = mLastZoomFocus - focusPoint;
|
||||
mLastZoomFocus = focusPoint;
|
||||
// If displacing by the change in focus point will take us off page bounds,
|
||||
// then reduce the displacement such that it doesn't.
|
||||
focusChange.x -= mX.DisplacementWillOverscrollAmount(focusChange.x);
|
||||
@@ -1439,12 +1477,9 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
|
||||
realMaxZoom = realMinZoom;
|
||||
}
|
||||
|
||||
bool doScale = (spanRatio > 1.0 && userZoom < realMaxZoom) ||
|
||||
(spanRatio < 1.0 && userZoom > realMinZoom);
|
||||
|
||||
if (!mZoomConstraints.mAllowZoom) {
|
||||
doScale = false;
|
||||
}
|
||||
bool doScale = allowZoom && (
|
||||
(spanRatio > 1.0 && userZoom < realMaxZoom) ||
|
||||
(spanRatio < 1.0 && userZoom > realMinZoom));
|
||||
|
||||
if (doScale) {
|
||||
spanRatio = clamped(spanRatio,
|
||||
@@ -2601,6 +2636,24 @@ void AsyncPanZoomController::HandlePanningUpdate(const ScreenPoint& aPanDistance
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::HandlePinchLocking(ScreenCoord spanDistance, ScreenPoint focusChange) {
|
||||
if (mPinchLocked) {
|
||||
if (GetPinchLockMode() == PINCH_STICKY) {
|
||||
ScreenCoord spanBreakoutThreshold = gfxPrefs::APZPinchLockSpanBreakoutThreshold() * APZCTreeManager::GetDPI();
|
||||
mPinchLocked = !(spanDistance > spanBreakoutThreshold);
|
||||
}
|
||||
} else {
|
||||
if (GetPinchLockMode() != PINCH_FREE) {
|
||||
ScreenCoord spanLockThreshold = gfxPrefs::APZPinchLockSpanLockThreshold() * APZCTreeManager::GetDPI();
|
||||
ScreenCoord scrollLockThreshold = gfxPrefs::APZPinchLockScrollLockThreshold() * APZCTreeManager::GetDPI();
|
||||
|
||||
if (spanDistance < spanLockThreshold && focusChange.Length() > scrollLockThreshold) {
|
||||
mPinchLocked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsEventStatus
|
||||
AsyncPanZoomController::StartPanning(const ParentLayerPoint& aStartPoint) {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
|
||||
@@ -655,6 +655,11 @@ protected:
|
||||
*/
|
||||
void HandlePanningUpdate(const ScreenPoint& aDelta);
|
||||
|
||||
/**
|
||||
* Set and update the pinch lock
|
||||
*/
|
||||
void HandlePinchLocking(ScreenCoord spanDistance, ScreenPoint focusChange);
|
||||
|
||||
/**
|
||||
* Sets up anything needed for panning. This takes us out of the "TOUCHING"
|
||||
* state and starts actually panning us.
|
||||
@@ -724,6 +729,14 @@ protected:
|
||||
|
||||
static AxisLockMode GetAxisLockMode();
|
||||
|
||||
enum PinchLockMode {
|
||||
PINCH_FREE, /* No locking at all */
|
||||
PINCH_STANDARD, /* Default pinch locking mode that remains locked until pinch gesture ends*/
|
||||
PINCH_STICKY, /* Allow lock to be broken, with hysteresis */
|
||||
};
|
||||
|
||||
static PinchLockMode GetPinchLockMode();
|
||||
|
||||
// Helper function for OnSingleTapUp(), OnSingleTapConfirmed(), and
|
||||
// OnLongPressUp().
|
||||
nsEventStatus GenerateSingleTap(GeckoContentController::TapType aType,
|
||||
@@ -800,6 +813,10 @@ private:
|
||||
// the touch-action CSS property.
|
||||
bool mPanDirRestricted;
|
||||
|
||||
// This flag is set to true when we are in a pinch-locked state. ie: user
|
||||
// is performing a two-finger pan rather than a pinch gesture
|
||||
bool mPinchLocked;
|
||||
|
||||
// Most up-to-date constraints on zooming. These should always be reasonable
|
||||
// values; for example, allowing a min zoom of 0.0 can cause very bad things
|
||||
// to happen.
|
||||
|
||||
@@ -137,14 +137,24 @@ public:
|
||||
if (entry.mManager->IsDestroyed()) {
|
||||
mKeys.RemoveElementAt(i);
|
||||
} else if (entry.mManager == aManager) {
|
||||
found = true;
|
||||
if (entry.mInvalidations != aInvalidations) {
|
||||
aManager->AddImageKeyForDiscard(entry.mImageKey);
|
||||
WebRenderBridgeChild* wrBridge = aManager->WrBridge();
|
||||
MOZ_ASSERT(wrBridge);
|
||||
|
||||
// Even if the manager is the same, its underlying WebRenderBridgeChild
|
||||
// can change state. If our namespace differs, then our old key has
|
||||
// already been discarded.
|
||||
bool ownsKey = wrBridge->GetNamespace() == entry.mImageKey.mNamespace;
|
||||
if (!ownsKey || entry.mInvalidations != aInvalidations) {
|
||||
if (ownsKey) {
|
||||
aManager->AddImageKeyForDiscard(entry.mImageKey);
|
||||
}
|
||||
entry.mInvalidations = aInvalidations;
|
||||
entry.mImageKey = aManager->WrBridge()->GetNextImageKey();
|
||||
entry.mImageKey = wrBridge->GetNextImageKey();
|
||||
aResources.AddExternalImage(mId, entry.mImageKey);
|
||||
}
|
||||
|
||||
key = entry.mImageKey;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ AsyncImagePipelineManager::UpdateWithoutExternalImage(wr::ResourceUpdateQueue& a
|
||||
wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat());
|
||||
|
||||
// Costly copy right here...
|
||||
wr::Vec_u8 bytes;
|
||||
wr::Vec<uint8_t> bytes;
|
||||
bytes.PushBytes(Range<uint8_t>(map.mData, size.height * map.mStride));
|
||||
|
||||
if (aOp == TextureHost::UPDATE_IMAGE) {
|
||||
|
||||
@@ -173,7 +173,7 @@ ShmSegmentsReader::ShmSegmentsReader(const nsTArray<ipc::Shmem>& aSmallShmems,
|
||||
}
|
||||
|
||||
bool
|
||||
ShmSegmentsReader::ReadLarge(const layers::OffsetRange& aRange, wr::Vec_u8& aInto)
|
||||
ShmSegmentsReader::ReadLarge(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto)
|
||||
{
|
||||
// source = zero is for small allocs.
|
||||
MOZ_RELEASE_ASSERT(aRange.source() != 0);
|
||||
@@ -193,7 +193,7 @@ ShmSegmentsReader::ReadLarge(const layers::OffsetRange& aRange, wr::Vec_u8& aInt
|
||||
}
|
||||
|
||||
bool
|
||||
ShmSegmentsReader::Read(const layers::OffsetRange& aRange, wr::Vec_u8& aInto)
|
||||
ShmSegmentsReader::Read(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto)
|
||||
{
|
||||
if (aRange.length() == 0) {
|
||||
return true;
|
||||
|
||||
@@ -51,10 +51,10 @@ public:
|
||||
ShmSegmentsReader(const nsTArray<ipc::Shmem>& aSmallShmems,
|
||||
const nsTArray<ipc::Shmem>& aLargeShmems);
|
||||
|
||||
bool Read(const layers::OffsetRange& aRange, wr::Vec_u8& aInto);
|
||||
bool Read(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
|
||||
|
||||
protected:
|
||||
bool ReadLarge(const layers::OffsetRange& aRange, wr::Vec_u8& aInto);
|
||||
bool ReadLarge(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
|
||||
|
||||
const nsTArray<ipc::Shmem>& mSmallAllocs;
|
||||
const nsTArray<ipc::Shmem>& mLargeAllocs;
|
||||
|
||||
@@ -289,7 +289,7 @@ WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResour
|
||||
switch (cmd.type()) {
|
||||
case OpUpdateResource::TOpAddImage: {
|
||||
const auto& op = cmd.get_OpAddImage();
|
||||
wr::Vec_u8 bytes;
|
||||
wr::Vec<uint8_t> bytes;
|
||||
if (!reader.Read(op.bytes(), bytes)) {
|
||||
return false;
|
||||
}
|
||||
@@ -298,7 +298,7 @@ WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResour
|
||||
}
|
||||
case OpUpdateResource::TOpUpdateImage: {
|
||||
const auto& op = cmd.get_OpUpdateImage();
|
||||
wr::Vec_u8 bytes;
|
||||
wr::Vec<uint8_t> bytes;
|
||||
if (!reader.Read(op.bytes(), bytes)) {
|
||||
return false;
|
||||
}
|
||||
@@ -307,7 +307,7 @@ WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResour
|
||||
}
|
||||
case OpUpdateResource::TOpAddBlobImage: {
|
||||
const auto& op = cmd.get_OpAddBlobImage();
|
||||
wr::Vec_u8 bytes;
|
||||
wr::Vec<uint8_t> bytes;
|
||||
if (!reader.Read(op.bytes(), bytes)) {
|
||||
return false;
|
||||
}
|
||||
@@ -316,7 +316,7 @@ WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResour
|
||||
}
|
||||
case OpUpdateResource::TOpUpdateBlobImage: {
|
||||
const auto& op = cmd.get_OpUpdateBlobImage();
|
||||
wr::Vec_u8 bytes;
|
||||
wr::Vec<uint8_t> bytes;
|
||||
if (!reader.Read(op.bytes(), bytes)) {
|
||||
return false;
|
||||
}
|
||||
@@ -332,7 +332,7 @@ WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResour
|
||||
}
|
||||
case OpUpdateResource::TOpAddRawFont: {
|
||||
const auto& op = cmd.get_OpAddRawFont();
|
||||
wr::Vec_u8 bytes;
|
||||
wr::Vec<uint8_t> bytes;
|
||||
if (!reader.Read(op.bytes(), bytes)) {
|
||||
return false;
|
||||
}
|
||||
@@ -341,7 +341,7 @@ WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResour
|
||||
}
|
||||
case OpUpdateResource::TOpAddFontDescriptor: {
|
||||
const auto& op = cmd.get_OpAddFontDescriptor();
|
||||
wr::Vec_u8 bytes;
|
||||
wr::Vec<uint8_t> bytes;
|
||||
if (!reader.Read(op.bytes(), bytes)) {
|
||||
return false;
|
||||
}
|
||||
@@ -350,7 +350,7 @@ WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResour
|
||||
}
|
||||
case OpUpdateResource::TOpAddFontInstance: {
|
||||
const auto& op = cmd.get_OpAddFontInstance();
|
||||
wr::Vec_u8 variations;
|
||||
wr::Vec<uint8_t> variations;
|
||||
if (!reader.Read(op.variations(), variations)) {
|
||||
return false;
|
||||
}
|
||||
@@ -440,7 +440,7 @@ WebRenderBridgeParent::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey
|
||||
|
||||
IntSize size = dSurf->GetSize();
|
||||
wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat());
|
||||
wr::Vec_u8 data;
|
||||
wr::Vec<uint8_t> data;
|
||||
data.PushBytes(Range<uint8_t>(map.mData, size.height * map.mStride));
|
||||
aResources.AddImage(keys[0], descriptor, data);
|
||||
dSurf->Unmap();
|
||||
@@ -611,7 +611,7 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
|
||||
}
|
||||
|
||||
|
||||
wr::Vec_u8 dlData(Move(dl));
|
||||
wr::Vec<uint8_t> dlData(Move(dl));
|
||||
|
||||
// If id namespaces do not match, it means the command is obsolete, probably
|
||||
// because the tab just moved to a new window.
|
||||
|
||||
@@ -333,6 +333,10 @@ private:
|
||||
DECL_GFX_PREF(Live, "apz.overscroll.stop_distance_threshold", APZOverscrollStopDistanceThreshold, float, 5.0f);
|
||||
DECL_GFX_PREF(Live, "apz.paint_skipping.enabled", APZPaintSkipping, bool, true);
|
||||
DECL_GFX_PREF(Live, "apz.peek_messages.enabled", APZPeekMessages, bool, true);
|
||||
DECL_GFX_PREF(Live, "apz.pinch_lock.mode", APZPinchLockMode, int32_t, 1);
|
||||
DECL_GFX_PREF(Live, "apz.pinch_lock.scroll_lock_threshold", APZPinchLockScrollLockThreshold, float, 1.0f / 32.0f);
|
||||
DECL_GFX_PREF(Live, "apz.pinch_lock.span_breakout_threshold", APZPinchLockSpanBreakoutThreshold, float, 1.0f / 32.0f);
|
||||
DECL_GFX_PREF(Live, "apz.pinch_lock.span_lock_threshold", APZPinchLockSpanLockThreshold, float, 1.0f / 32.0f);
|
||||
DECL_GFX_PREF(Live, "apz.popups.enabled", APZPopupsEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "apz.printtree", APZPrintTree, bool, false);
|
||||
DECL_GFX_PREF(Live, "apz.record_checkerboarding", APZRecordCheckerboarding, bool, false);
|
||||
|
||||
@@ -265,7 +265,7 @@ WebRenderAPI::SetDisplayList(gfx::Color aBgColor,
|
||||
wr::WrPipelineId pipeline_id,
|
||||
const LayoutSize& content_size,
|
||||
wr::BuiltDisplayListDescriptor dl_descriptor,
|
||||
wr::Vec_u8& dl_data,
|
||||
wr::Vec<uint8_t>& dl_data,
|
||||
ResourceUpdateQueue& aResources)
|
||||
{
|
||||
wr_api_set_display_list(mDocHandle,
|
||||
@@ -505,7 +505,7 @@ ResourceUpdateQueue::Clear()
|
||||
|
||||
void
|
||||
ResourceUpdateQueue::AddImage(ImageKey key, const ImageDescriptor& aDescriptor,
|
||||
wr::Vec_u8& aBytes)
|
||||
wr::Vec<uint8_t>& aBytes)
|
||||
{
|
||||
wr_resource_updates_add_image(mUpdates,
|
||||
key,
|
||||
@@ -515,7 +515,7 @@ ResourceUpdateQueue::AddImage(ImageKey key, const ImageDescriptor& aDescriptor,
|
||||
|
||||
void
|
||||
ResourceUpdateQueue::AddBlobImage(ImageKey key, const ImageDescriptor& aDescriptor,
|
||||
wr::Vec_u8& aBytes)
|
||||
wr::Vec<uint8_t>& aBytes)
|
||||
{
|
||||
wr_resource_updates_add_blob_image(mUpdates,
|
||||
key,
|
||||
@@ -552,7 +552,7 @@ ResourceUpdateQueue::AddExternalImageBuffer(ImageKey aKey,
|
||||
void
|
||||
ResourceUpdateQueue::UpdateImageBuffer(ImageKey aKey,
|
||||
const ImageDescriptor& aDescriptor,
|
||||
wr::Vec_u8& aBytes)
|
||||
wr::Vec<uint8_t>& aBytes)
|
||||
{
|
||||
wr_resource_updates_update_image(mUpdates,
|
||||
aKey,
|
||||
@@ -563,7 +563,7 @@ ResourceUpdateQueue::UpdateImageBuffer(ImageKey aKey,
|
||||
void
|
||||
ResourceUpdateQueue::UpdateBlobImage(ImageKey aKey,
|
||||
const ImageDescriptor& aDescriptor,
|
||||
wr::Vec_u8& aBytes,
|
||||
wr::Vec<uint8_t>& aBytes,
|
||||
const wr::DeviceUintRect& aDirtyRect)
|
||||
{
|
||||
wr_resource_updates_update_blob_image(mUpdates,
|
||||
@@ -595,13 +595,13 @@ ResourceUpdateQueue::DeleteImage(ImageKey aKey)
|
||||
}
|
||||
|
||||
void
|
||||
ResourceUpdateQueue::AddRawFont(wr::FontKey aKey, wr::Vec_u8& aBytes, uint32_t aIndex)
|
||||
ResourceUpdateQueue::AddRawFont(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes, uint32_t aIndex)
|
||||
{
|
||||
wr_resource_updates_add_raw_font(mUpdates, aKey, &aBytes.inner, aIndex);
|
||||
}
|
||||
|
||||
void
|
||||
ResourceUpdateQueue::AddFontDescriptor(wr::FontKey aKey, wr::Vec_u8& aBytes, uint32_t aIndex)
|
||||
ResourceUpdateQueue::AddFontDescriptor(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes, uint32_t aIndex)
|
||||
{
|
||||
wr_resource_updates_add_font_descriptor(mUpdates, aKey, &aBytes.inner, aIndex);
|
||||
}
|
||||
@@ -618,7 +618,7 @@ ResourceUpdateQueue::AddFontInstance(wr::FontInstanceKey aKey,
|
||||
float aGlyphSize,
|
||||
const wr::FontInstanceOptions* aOptions,
|
||||
const wr::FontInstancePlatformOptions* aPlatformOptions,
|
||||
wr::Vec_u8& aVariations)
|
||||
wr::Vec<uint8_t>& aVariations)
|
||||
{
|
||||
wr_resource_updates_add_font_instance(mUpdates, aKey, aFontKey, aGlyphSize,
|
||||
aOptions, aPlatformOptions,
|
||||
@@ -1131,7 +1131,7 @@ DisplayListBuilder::PushBorderImage(const wr::LayoutRect& aBounds,
|
||||
const wr::BorderWidths& aWidths,
|
||||
wr::ImageKey aImage,
|
||||
const wr::NinePatchDescriptor& aPatch,
|
||||
const wr::SideOffsets2D_f32& aOutset,
|
||||
const wr::SideOffsets2D<float>& aOutset,
|
||||
const wr::RepeatMode& aRepeatHorizontal,
|
||||
const wr::RepeatMode& aRepeatVertical)
|
||||
{
|
||||
@@ -1149,7 +1149,7 @@ DisplayListBuilder::PushBorderGradient(const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutPoint& aEndPoint,
|
||||
const nsTArray<wr::GradientStop>& aStops,
|
||||
wr::ExtendMode aExtendMode,
|
||||
const wr::SideOffsets2D_f32& aOutset)
|
||||
const wr::SideOffsets2D<float>& aOutset)
|
||||
{
|
||||
wr_dp_push_border_gradient(mWrState, aBounds, aClip, aIsBackfaceVisible,
|
||||
aWidths, aStartPoint, aEndPoint,
|
||||
@@ -1166,7 +1166,7 @@ DisplayListBuilder::PushBorderRadialGradient(const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutSize& aRadius,
|
||||
const nsTArray<wr::GradientStop>& aStops,
|
||||
wr::ExtendMode aExtendMode,
|
||||
const wr::SideOffsets2D_f32& aOutset)
|
||||
const wr::SideOffsets2D<float>& aOutset)
|
||||
{
|
||||
wr_dp_push_border_radial_gradient(
|
||||
mWrState, aBounds, aClip, aIsBackfaceVisible, aWidths, aCenter,
|
||||
|
||||
@@ -63,11 +63,11 @@ public:
|
||||
|
||||
void AddImage(wr::ImageKey aKey,
|
||||
const ImageDescriptor& aDescriptor,
|
||||
wr::Vec_u8& aBytes);
|
||||
wr::Vec<uint8_t>& aBytes);
|
||||
|
||||
void AddBlobImage(wr::ImageKey aKey,
|
||||
const ImageDescriptor& aDescriptor,
|
||||
wr::Vec_u8& aBytes);
|
||||
wr::Vec<uint8_t>& aBytes);
|
||||
|
||||
void AddExternalImageBuffer(ImageKey key,
|
||||
const ImageDescriptor& aDescriptor,
|
||||
@@ -81,11 +81,11 @@ public:
|
||||
|
||||
void UpdateImageBuffer(wr::ImageKey aKey,
|
||||
const ImageDescriptor& aDescriptor,
|
||||
wr::Vec_u8& aBytes);
|
||||
wr::Vec<uint8_t>& aBytes);
|
||||
|
||||
void UpdateBlobImage(wr::ImageKey aKey,
|
||||
const ImageDescriptor& aDescriptor,
|
||||
wr::Vec_u8& aBytes,
|
||||
wr::Vec<uint8_t>& aBytes,
|
||||
const wr::DeviceUintRect& aDirtyRect);
|
||||
|
||||
void UpdateExternalImage(ImageKey aKey,
|
||||
@@ -96,9 +96,9 @@ public:
|
||||
|
||||
void DeleteImage(wr::ImageKey aKey);
|
||||
|
||||
void AddRawFont(wr::FontKey aKey, wr::Vec_u8& aBytes, uint32_t aIndex);
|
||||
void AddRawFont(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes, uint32_t aIndex);
|
||||
|
||||
void AddFontDescriptor(wr::FontKey aKey, wr::Vec_u8& aBytes, uint32_t aIndex);
|
||||
void AddFontDescriptor(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes, uint32_t aIndex);
|
||||
|
||||
void DeleteFont(wr::FontKey aKey);
|
||||
|
||||
@@ -107,7 +107,7 @@ public:
|
||||
float aGlyphSize,
|
||||
const wr::FontInstanceOptions* aOptions,
|
||||
const wr::FontInstancePlatformOptions* aPlatformOptions,
|
||||
wr::Vec_u8& aVariations);
|
||||
wr::Vec<uint8_t>& aVariations);
|
||||
|
||||
void DeleteFontInstance(wr::FontInstanceKey aKey);
|
||||
|
||||
@@ -161,7 +161,7 @@ public:
|
||||
wr::WrPipelineId pipeline_id,
|
||||
const wr::LayoutSize& content_size,
|
||||
wr::BuiltDisplayListDescriptor dl_descriptor,
|
||||
wr::Vec_u8& dl_data,
|
||||
wr::Vec<uint8_t>& dl_data,
|
||||
ResourceUpdateQueue& aResources);
|
||||
|
||||
void ClearDisplayList(Epoch aEpoch, wr::WrPipelineId pipeline_id);
|
||||
@@ -361,7 +361,7 @@ public:
|
||||
const wr::BorderWidths& aWidths,
|
||||
wr::ImageKey aImage,
|
||||
const wr::NinePatchDescriptor& aPatch,
|
||||
const wr::SideOffsets2D_f32& aOutset,
|
||||
const wr::SideOffsets2D<float>& aOutset,
|
||||
const wr::RepeatMode& aRepeatHorizontal,
|
||||
const wr::RepeatMode& aRepeatVertical);
|
||||
|
||||
@@ -373,7 +373,7 @@ public:
|
||||
const wr::LayoutPoint& aEndPoint,
|
||||
const nsTArray<wr::GradientStop>& aStops,
|
||||
wr::ExtendMode aExtendMode,
|
||||
const wr::SideOffsets2D_f32& aOutset);
|
||||
const wr::SideOffsets2D<float>& aOutset);
|
||||
|
||||
void PushBorderRadialGradient(const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
@@ -383,7 +383,7 @@ public:
|
||||
const wr::LayoutSize& aRadius,
|
||||
const nsTArray<wr::GradientStop>& aStops,
|
||||
wr::ExtendMode aExtendMode,
|
||||
const wr::SideOffsets2D_f32& aOutset);
|
||||
const wr::SideOffsets2D<float>& aOutset);
|
||||
|
||||
void PushText(const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
|
||||
@@ -11,13 +11,15 @@
|
||||
namespace mozilla {
|
||||
namespace wr {
|
||||
|
||||
Vec_u8::Vec_u8(mozilla::ipc::ByteBuf&& aSrc) {
|
||||
inner.data = aSrc.mData;
|
||||
inner.length = aSrc.mLen;
|
||||
inner.capacity = aSrc.mCapacity;
|
||||
aSrc.mData = nullptr;
|
||||
aSrc.mLen = 0;
|
||||
aSrc.mCapacity = 0;
|
||||
void
|
||||
Assign_WrVecU8(wr::WrVecU8& aVec, mozilla::ipc::ByteBuf&& aOther)
|
||||
{
|
||||
aVec.data = aOther.mData;
|
||||
aVec.length = aOther.mLen;
|
||||
aVec.capacity = aOther.mCapacity;
|
||||
aOther.mData = nullptr;
|
||||
aOther.mLen = 0;
|
||||
aOther.mCapacity = 0;
|
||||
}
|
||||
|
||||
} // namespace wr
|
||||
|
||||
@@ -461,7 +461,7 @@ static inline wr::BorderWidths ToBorderWidths(float top, float right, float bott
|
||||
}
|
||||
|
||||
static inline wr::NinePatchDescriptor ToNinePatchDescriptor(uint32_t width, uint32_t height,
|
||||
const wr::SideOffsets2D_u32& slice)
|
||||
const wr::SideOffsets2D<uint32_t>& slice)
|
||||
{
|
||||
NinePatchDescriptor patch;
|
||||
patch.width = width;
|
||||
@@ -470,9 +470,9 @@ static inline wr::NinePatchDescriptor ToNinePatchDescriptor(uint32_t width, uint
|
||||
return patch;
|
||||
}
|
||||
|
||||
static inline wr::SideOffsets2D_u32 ToSideOffsets2D_u32(uint32_t top, uint32_t right, uint32_t bottom, uint32_t left)
|
||||
static inline wr::SideOffsets2D<uint32_t> ToSideOffsets2D_u32(uint32_t top, uint32_t right, uint32_t bottom, uint32_t left)
|
||||
{
|
||||
SideOffsets2D_u32 offset;
|
||||
SideOffsets2D<uint32_t> offset;
|
||||
offset.top = top;
|
||||
offset.right = right;
|
||||
offset.bottom = bottom;
|
||||
@@ -480,9 +480,9 @@ static inline wr::SideOffsets2D_u32 ToSideOffsets2D_u32(uint32_t top, uint32_t r
|
||||
return offset;
|
||||
}
|
||||
|
||||
static inline wr::SideOffsets2D_f32 ToSideOffsets2D_f32(float top, float right, float bottom, float left)
|
||||
static inline wr::SideOffsets2D<float> ToSideOffsets2D_f32(float top, float right, float bottom, float left)
|
||||
{
|
||||
SideOffsets2D_f32 offset;
|
||||
SideOffsets2D<float> offset;
|
||||
offset.top = top;
|
||||
offset.right = right;
|
||||
offset.bottom = bottom;
|
||||
@@ -571,21 +571,29 @@ inline mozilla::Range<uint8_t> MutByteSliceToRange(wr::MutByteSlice aWrSlice) {
|
||||
return mozilla::Range<uint8_t>(aWrSlice.buffer, aWrSlice.len);
|
||||
}
|
||||
|
||||
struct Vec_u8 {
|
||||
void Assign_WrVecU8(wr::WrVecU8& aVec, mozilla::ipc::ByteBuf&& aOther);
|
||||
|
||||
template<typename T>
|
||||
struct Vec;
|
||||
|
||||
template<>
|
||||
struct Vec<uint8_t> {
|
||||
wr::WrVecU8 inner;
|
||||
Vec_u8() {
|
||||
Vec() {
|
||||
SetEmpty();
|
||||
}
|
||||
Vec_u8(Vec_u8&) = delete;
|
||||
Vec_u8(Vec_u8&& src) {
|
||||
Vec(Vec&) = delete;
|
||||
Vec(Vec&& src) {
|
||||
inner = src.inner;
|
||||
src.SetEmpty();
|
||||
}
|
||||
|
||||
explicit Vec_u8(mozilla::ipc::ByteBuf&& aSrc);
|
||||
explicit Vec(mozilla::ipc::ByteBuf&& aSrc) {
|
||||
Assign_WrVecU8(inner, std::move(aSrc));
|
||||
}
|
||||
|
||||
Vec_u8&
|
||||
operator=(Vec_u8&& src) {
|
||||
Vec&
|
||||
operator=(Vec&& src) {
|
||||
inner = src.inner;
|
||||
src.SetEmpty();
|
||||
return *this;
|
||||
@@ -612,7 +620,7 @@ struct Vec_u8 {
|
||||
wr_vec_u8_push_bytes(&inner, RangeToByteSlice(aBytes));
|
||||
}
|
||||
|
||||
~Vec_u8() {
|
||||
~Vec() {
|
||||
if (inner.data) {
|
||||
wr_vec_u8_free(inner);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ rename_args = "GeckoCase"
|
||||
|
||||
[struct]
|
||||
derive_eq = true
|
||||
generic_template_specialization = false
|
||||
|
||||
[enum]
|
||||
add_sentinel = true
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* 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/. */
|
||||
|
||||
/* Generated with cbindgen:0.2.2 */
|
||||
/* Generated with cbindgen:0.3.3 */
|
||||
|
||||
/* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen.
|
||||
* To generate this file:
|
||||
@@ -14,8 +14,6 @@
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
extern "C" {
|
||||
|
||||
namespace mozilla {
|
||||
namespace wr {
|
||||
|
||||
@@ -237,10 +235,18 @@ enum class YuvColorSpace : uint32_t {
|
||||
Sentinel /* this must be last for serialization purposes. */
|
||||
};
|
||||
|
||||
struct Arc_VecU8;
|
||||
template<typename T>
|
||||
struct Arc;
|
||||
|
||||
// Geometry in the coordinate system of the render target (screen or intermediate
|
||||
// surface) in physical pixels.
|
||||
struct DevicePixel;
|
||||
|
||||
struct DocumentHandle;
|
||||
|
||||
// Geometry in a layer's local coordinate space (logical pixels).
|
||||
struct LayerPixel;
|
||||
|
||||
// The renderer is responsible for submitting to the GPU the work prepared by the
|
||||
// RenderBackend.
|
||||
struct Renderer;
|
||||
@@ -248,7 +254,17 @@ struct Renderer;
|
||||
// The resource updates for a given transaction (they must be applied in the same frame).
|
||||
struct ResourceUpdates;
|
||||
|
||||
struct Vec_u8;
|
||||
// Offset in number of tiles.
|
||||
struct Tiles;
|
||||
|
||||
// The default unit.
|
||||
struct UnknownUnit;
|
||||
|
||||
template<typename T>
|
||||
struct Vec;
|
||||
|
||||
// Geometry in the document's coordinate space (logical pixels).
|
||||
struct WorldPixel;
|
||||
|
||||
struct WrProgramCache;
|
||||
|
||||
@@ -285,11 +301,11 @@ struct FontKey {
|
||||
}
|
||||
};
|
||||
|
||||
typedef FontKey WrFontKey;
|
||||
using WrFontKey = FontKey;
|
||||
|
||||
typedef Arc_VecU8 ArcVecU8;
|
||||
using VecU8 = Vec<uint8_t>;
|
||||
|
||||
typedef Vec_u8 VecU8;
|
||||
using ArcVecU8 = Arc<VecU8>;
|
||||
|
||||
struct Epoch {
|
||||
uint32_t mHandle;
|
||||
@@ -305,13 +321,13 @@ struct Epoch {
|
||||
}
|
||||
};
|
||||
|
||||
typedef Epoch WrEpoch;
|
||||
using WrEpoch = Epoch;
|
||||
|
||||
// This type carries no valuable semantics for WR. However, it reflects the fact that
|
||||
// clients (Servo) may generate pipelines by different semi-independent sources.
|
||||
// These pipelines still belong to the same `IdNamespace` and the same `DocumentId`.
|
||||
// Having this extra Id field enables them to generate `PipelineId` without collision.
|
||||
typedef uint32_t PipelineSourceId;
|
||||
using PipelineSourceId = uint32_t;
|
||||
|
||||
// From the point of view of WR, `PipelineId` is completely opaque and generic as long as
|
||||
// it's clonable, serializable, comparable, and hashable.
|
||||
@@ -325,21 +341,22 @@ struct PipelineId {
|
||||
}
|
||||
};
|
||||
|
||||
typedef PipelineId WrPipelineId;
|
||||
using WrPipelineId = PipelineId;
|
||||
|
||||
struct TypedSize2D_f32__LayerPixel {
|
||||
float width;
|
||||
float height;
|
||||
template<typename T, typename U>
|
||||
struct TypedSize2D {
|
||||
T width;
|
||||
T height;
|
||||
|
||||
bool operator==(const TypedSize2D_f32__LayerPixel& aOther) const {
|
||||
bool operator==(const TypedSize2D& aOther) const {
|
||||
return width == aOther.width &&
|
||||
height == aOther.height;
|
||||
}
|
||||
};
|
||||
|
||||
typedef TypedSize2D_f32__LayerPixel LayerSize;
|
||||
using LayerSize = TypedSize2D<float, LayerPixel>;
|
||||
|
||||
typedef LayerSize LayoutSize;
|
||||
using LayoutSize = LayerSize;
|
||||
|
||||
// Describes the memory layout of a display list.
|
||||
//
|
||||
@@ -382,6 +399,11 @@ struct WrOpacityProperty {
|
||||
}
|
||||
};
|
||||
|
||||
// Geometry in a stacking context's local coordinate space (logical pixels).
|
||||
//
|
||||
// For now layout pixels are equivalent to layer pixels, but it may change.
|
||||
using LayoutPixel = LayerPixel;
|
||||
|
||||
// A 3d transform stored as a 4 by 4 matrix in row-major order in memory.
|
||||
//
|
||||
// Transforms can be parametrized over the source and destination units, to describe a
|
||||
@@ -393,25 +415,26 @@ struct WrOpacityProperty {
|
||||
// A pre-transformation corresponds to adding an operation that is applied before
|
||||
// the rest of the transformation, while a post-transformation adds an operation
|
||||
// that is applied after.
|
||||
struct TypedTransform3D_f32__LayoutPixel__LayoutPixel {
|
||||
float m11;
|
||||
float m12;
|
||||
float m13;
|
||||
float m14;
|
||||
float m21;
|
||||
float m22;
|
||||
float m23;
|
||||
float m24;
|
||||
float m31;
|
||||
float m32;
|
||||
float m33;
|
||||
float m34;
|
||||
float m41;
|
||||
float m42;
|
||||
float m43;
|
||||
float m44;
|
||||
template<typename T, typename Src, typename Dst>
|
||||
struct TypedTransform3D {
|
||||
T m11;
|
||||
T m12;
|
||||
T m13;
|
||||
T m14;
|
||||
T m21;
|
||||
T m22;
|
||||
T m23;
|
||||
T m24;
|
||||
T m31;
|
||||
T m32;
|
||||
T m33;
|
||||
T m34;
|
||||
T m41;
|
||||
T m42;
|
||||
T m43;
|
||||
T m44;
|
||||
|
||||
bool operator==(const TypedTransform3D_f32__LayoutPixel__LayoutPixel& aOther) const {
|
||||
bool operator==(const TypedTransform3D& aOther) const {
|
||||
return m11 == aOther.m11 &&
|
||||
m12 == aOther.m12 &&
|
||||
m13 == aOther.m13 &&
|
||||
@@ -431,27 +454,28 @@ struct TypedTransform3D_f32__LayoutPixel__LayoutPixel {
|
||||
}
|
||||
};
|
||||
|
||||
typedef TypedTransform3D_f32__LayoutPixel__LayoutPixel LayoutTransform;
|
||||
using LayoutTransform = TypedTransform3D<float, LayoutPixel, LayoutPixel>;
|
||||
|
||||
struct WrTransformProperty {
|
||||
uint64_t id;
|
||||
LayoutTransform transform;
|
||||
};
|
||||
|
||||
typedef IdNamespace WrIdNamespace;
|
||||
using WrIdNamespace = IdNamespace;
|
||||
|
||||
// A 2d Point tagged with a unit.
|
||||
struct TypedPoint2D_f32__WorldPixel {
|
||||
float x;
|
||||
float y;
|
||||
template<typename T, typename U>
|
||||
struct TypedPoint2D {
|
||||
T x;
|
||||
T y;
|
||||
|
||||
bool operator==(const TypedPoint2D_f32__WorldPixel& aOther) const {
|
||||
bool operator==(const TypedPoint2D& aOther) const {
|
||||
return x == aOther.x &&
|
||||
y == aOther.y;
|
||||
}
|
||||
};
|
||||
|
||||
typedef TypedPoint2D_f32__WorldPixel WorldPoint;
|
||||
using WorldPoint = TypedPoint2D<float, WorldPixel>;
|
||||
|
||||
// Represents RGBA screen colors with floating point numbers.
|
||||
//
|
||||
@@ -471,31 +495,21 @@ struct ColorF {
|
||||
}
|
||||
};
|
||||
|
||||
// A 2d Point tagged with a unit.
|
||||
struct TypedPoint2D_f32__LayerPixel {
|
||||
float x;
|
||||
float y;
|
||||
|
||||
bool operator==(const TypedPoint2D_f32__LayerPixel& aOther) const {
|
||||
return x == aOther.x &&
|
||||
y == aOther.y;
|
||||
}
|
||||
};
|
||||
|
||||
// A 2d Rectangle optionally tagged with a unit.
|
||||
struct TypedRect_f32__LayerPixel {
|
||||
TypedPoint2D_f32__LayerPixel origin;
|
||||
TypedSize2D_f32__LayerPixel size;
|
||||
template<typename T, typename U>
|
||||
struct TypedRect {
|
||||
TypedPoint2D<T, U> origin;
|
||||
TypedSize2D<T, U> size;
|
||||
|
||||
bool operator==(const TypedRect_f32__LayerPixel& aOther) const {
|
||||
bool operator==(const TypedRect& aOther) const {
|
||||
return origin == aOther.origin &&
|
||||
size == aOther.size;
|
||||
}
|
||||
};
|
||||
|
||||
typedef TypedRect_f32__LayerPixel LayerRect;
|
||||
using LayerRect = TypedRect<float, LayerPixel>;
|
||||
|
||||
typedef LayerRect LayoutRect;
|
||||
using LayoutRect = LayerRect;
|
||||
|
||||
struct BorderRadius {
|
||||
LayoutSize top_left;
|
||||
@@ -541,7 +555,7 @@ struct ImageKey {
|
||||
}
|
||||
};
|
||||
|
||||
typedef ImageKey WrImageKey;
|
||||
using WrImageKey = ImageKey;
|
||||
|
||||
struct WrImageMask {
|
||||
WrImageKey image;
|
||||
@@ -573,19 +587,20 @@ struct StickyOffsetBounds {
|
||||
};
|
||||
|
||||
// A 2d Vector tagged with a unit.
|
||||
struct TypedVector2D_f32__LayerPixel {
|
||||
float x;
|
||||
float y;
|
||||
template<typename T, typename U>
|
||||
struct TypedVector2D {
|
||||
T x;
|
||||
T y;
|
||||
|
||||
bool operator==(const TypedVector2D_f32__LayerPixel& aOther) const {
|
||||
bool operator==(const TypedVector2D& aOther) const {
|
||||
return x == aOther.x &&
|
||||
y == aOther.y;
|
||||
}
|
||||
};
|
||||
|
||||
typedef TypedVector2D_f32__LayerPixel LayerVector2D;
|
||||
using LayerVector2D = TypedVector2D<float, LayerPixel>;
|
||||
|
||||
typedef LayerVector2D LayoutVector2D;
|
||||
using LayoutVector2D = LayerVector2D;
|
||||
|
||||
struct BorderWidths {
|
||||
float left;
|
||||
@@ -611,9 +626,9 @@ struct BorderSide {
|
||||
}
|
||||
};
|
||||
|
||||
typedef TypedPoint2D_f32__LayerPixel LayerPoint;
|
||||
using LayerPoint = TypedPoint2D<float, LayerPixel>;
|
||||
|
||||
typedef LayerPoint LayoutPoint;
|
||||
using LayoutPoint = LayerPoint;
|
||||
|
||||
struct GradientStop {
|
||||
float offset;
|
||||
@@ -625,14 +640,14 @@ struct GradientStop {
|
||||
}
|
||||
};
|
||||
|
||||
// The default side offset type with no unit.
|
||||
struct SideOffsets2D_f32 {
|
||||
float top;
|
||||
float right;
|
||||
float bottom;
|
||||
float left;
|
||||
template<typename T, typename U>
|
||||
struct TypedSideOffsets2D {
|
||||
T top;
|
||||
T right;
|
||||
T bottom;
|
||||
T left;
|
||||
|
||||
bool operator==(const SideOffsets2D_f32& aOther) const {
|
||||
bool operator==(const TypedSideOffsets2D& aOther) const {
|
||||
return top == aOther.top &&
|
||||
right == aOther.right &&
|
||||
bottom == aOther.bottom &&
|
||||
@@ -641,24 +656,13 @@ struct SideOffsets2D_f32 {
|
||||
};
|
||||
|
||||
// The default side offset type with no unit.
|
||||
struct SideOffsets2D_u32 {
|
||||
uint32_t top;
|
||||
uint32_t right;
|
||||
uint32_t bottom;
|
||||
uint32_t left;
|
||||
|
||||
bool operator==(const SideOffsets2D_u32& aOther) const {
|
||||
return top == aOther.top &&
|
||||
right == aOther.right &&
|
||||
bottom == aOther.bottom &&
|
||||
left == aOther.left;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
using SideOffsets2D = TypedSideOffsets2D<T, UnknownUnit>;
|
||||
|
||||
struct NinePatchDescriptor {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
SideOffsets2D_u32 slice;
|
||||
SideOffsets2D<uint32_t> slice;
|
||||
|
||||
bool operator==(const NinePatchDescriptor& aOther) const {
|
||||
return width == aOther.width &&
|
||||
@@ -713,9 +717,9 @@ struct FontInstanceKey {
|
||||
}
|
||||
};
|
||||
|
||||
typedef FontInstanceKey WrFontInstanceKey;
|
||||
using WrFontInstanceKey = FontInstanceKey;
|
||||
|
||||
typedef uint32_t GlyphIndex;
|
||||
using GlyphIndex = uint32_t;
|
||||
|
||||
struct GlyphInstance {
|
||||
GlyphIndex index;
|
||||
@@ -735,9 +739,9 @@ struct GlyphOptions {
|
||||
}
|
||||
};
|
||||
|
||||
typedef YuvColorSpace WrYuvColorSpace;
|
||||
using WrYuvColorSpace = YuvColorSpace;
|
||||
|
||||
typedef LogLevelFilter WrLogLevelFilter;
|
||||
using WrLogLevelFilter = LogLevelFilter;
|
||||
|
||||
struct ByteSlice {
|
||||
const uint8_t *buffer;
|
||||
@@ -749,18 +753,7 @@ struct ByteSlice {
|
||||
}
|
||||
};
|
||||
|
||||
// A 2d Point tagged with a unit.
|
||||
struct TypedPoint2D_u16__Tiles {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
|
||||
bool operator==(const TypedPoint2D_u16__Tiles& aOther) const {
|
||||
return x == aOther.x &&
|
||||
y == aOther.y;
|
||||
}
|
||||
};
|
||||
|
||||
typedef TypedPoint2D_u16__Tiles TileOffset;
|
||||
using TileOffset = TypedPoint2D<uint16_t, Tiles>;
|
||||
|
||||
struct MutByteSlice {
|
||||
uint8_t *buffer;
|
||||
@@ -824,9 +817,9 @@ struct WrExternalImageId {
|
||||
}
|
||||
};
|
||||
|
||||
typedef WrExternalImage (*LockExternalImageCallback)(void*, WrExternalImageId, uint8_t);
|
||||
using LockExternalImageCallback = WrExternalImage(*)(void*, WrExternalImageId, uint8_t);
|
||||
|
||||
typedef void (*UnlockExternalImageCallback)(void*, WrExternalImageId, uint8_t);
|
||||
using UnlockExternalImageCallback = void(*)(void*, WrExternalImageId, uint8_t);
|
||||
|
||||
struct WrExternalImageHandler {
|
||||
void *external_image_obj;
|
||||
@@ -856,7 +849,7 @@ struct WrImageDescriptor {
|
||||
}
|
||||
};
|
||||
|
||||
typedef ExternalImageType WrExternalImageBufferType;
|
||||
using WrExternalImageBufferType = ExternalImageType;
|
||||
|
||||
// Represents RGBA screen colors with one byte per channel.
|
||||
//
|
||||
@@ -924,39 +917,9 @@ struct FontInstancePlatformOptions {
|
||||
};
|
||||
#endif
|
||||
|
||||
// A 2d Point tagged with a unit.
|
||||
struct TypedPoint2D_u32__DevicePixel {
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
using DeviceUintRect = TypedRect<uint32_t, DevicePixel>;
|
||||
|
||||
bool operator==(const TypedPoint2D_u32__DevicePixel& aOther) const {
|
||||
return x == aOther.x &&
|
||||
y == aOther.y;
|
||||
}
|
||||
};
|
||||
|
||||
struct TypedSize2D_u32__DevicePixel {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
|
||||
bool operator==(const TypedSize2D_u32__DevicePixel& aOther) const {
|
||||
return width == aOther.width &&
|
||||
height == aOther.height;
|
||||
}
|
||||
};
|
||||
|
||||
// A 2d Rectangle optionally tagged with a unit.
|
||||
struct TypedRect_u32__DevicePixel {
|
||||
TypedPoint2D_u32__DevicePixel origin;
|
||||
TypedSize2D_u32__DevicePixel size;
|
||||
|
||||
bool operator==(const TypedRect_u32__DevicePixel& aOther) const {
|
||||
return origin == aOther.origin &&
|
||||
size == aOther.size;
|
||||
}
|
||||
};
|
||||
|
||||
typedef TypedRect_u32__DevicePixel DeviceUintRect;
|
||||
extern "C" {
|
||||
|
||||
/* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen.
|
||||
* To generate this file:
|
||||
@@ -1184,7 +1147,7 @@ void wr_dp_push_border_gradient(WrState *aState,
|
||||
const GradientStop *aStops,
|
||||
size_t aStopsCount,
|
||||
ExtendMode aExtendMode,
|
||||
SideOffsets2D_f32 aOutset)
|
||||
SideOffsets2D<float> aOutset)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE
|
||||
@@ -1195,7 +1158,7 @@ void wr_dp_push_border_image(WrState *aState,
|
||||
BorderWidths aWidths,
|
||||
WrImageKey aImage,
|
||||
NinePatchDescriptor aPatch,
|
||||
SideOffsets2D_f32 aOutset,
|
||||
SideOffsets2D<float> aOutset,
|
||||
RepeatMode aRepeatHorizontal,
|
||||
RepeatMode aRepeatVertical)
|
||||
WR_FUNC;
|
||||
@@ -1211,7 +1174,7 @@ void wr_dp_push_border_radial_gradient(WrState *aState,
|
||||
const GradientStop *aStops,
|
||||
size_t aStopsCount,
|
||||
ExtendMode aExtendMode,
|
||||
SideOffsets2D_f32 aOutset)
|
||||
SideOffsets2D<float> aOutset)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE
|
||||
@@ -1638,11 +1601,11 @@ bool wr_window_new(WrWindowId aWindowId,
|
||||
uint32_t *aOutMaxTextureSize)
|
||||
WR_FUNC;
|
||||
|
||||
} // extern "C"
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
||||
|
||||
} // extern "C"
|
||||
|
||||
/* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen.
|
||||
* To generate this file:
|
||||
* 1. Get the latest cbindgen using `cargo install --force cbindgen`
|
||||
|
||||
6
js/src/jit-test/tests/ion/bug1404636.js
Normal file
6
js/src/jit-test/tests/ion/bug1404636.js
Normal file
@@ -0,0 +1,6 @@
|
||||
x = new Uint32Array(4);
|
||||
try {
|
||||
Math.max(Uint32Array.prototype)();
|
||||
} catch (e) {}
|
||||
x[3] = -1;
|
||||
assertEq(x.toString(), "0,0,0,4294967295");
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "jit/arm/CodeGenerator-arm.h"
|
||||
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
@@ -1429,11 +1430,22 @@ CodeGeneratorARM::visitUnbox(LUnbox* unbox)
|
||||
MUnbox* mir = unbox->mir();
|
||||
Register type = ToRegister(unbox->type());
|
||||
|
||||
ScratchRegisterScope scratch(masm);
|
||||
mozilla::Maybe<ScratchRegisterScope> scratch;
|
||||
scratch.emplace(masm);
|
||||
|
||||
JSValueTag tag = MIRTypeToTag(mir->type());
|
||||
if (mir->fallible()) {
|
||||
masm.ma_cmp(type, Imm32(MIRTypeToTag(mir->type())), scratch);
|
||||
masm.ma_cmp(type, Imm32(tag), *scratch);
|
||||
bailoutIf(Assembler::NotEqual, unbox->snapshot());
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
Label ok;
|
||||
masm.ma_cmp(type, Imm32(tag), *scratch);
|
||||
masm.ma_b(&ok, Assembler::Equal);
|
||||
scratch.reset();
|
||||
masm.assumeUnreachable("Infallible unbox type mismatch");
|
||||
masm.bind(&ok);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -115,6 +115,16 @@ CodeGeneratorX64::visitUnbox(LUnbox* unbox)
|
||||
MOZ_CRASH("Given MIRType cannot be unboxed.");
|
||||
}
|
||||
bailoutIf(cond, unbox->snapshot());
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
Operand input = ToOperand(unbox->getOperand(LUnbox::Input));
|
||||
JSValueTag tag = MIRTypeToTag(mir->type());
|
||||
Label ok;
|
||||
masm.splitTag(input, ScratchReg);
|
||||
masm.branch32(Assembler::Equal, ScratchReg, Imm32(tag), &ok);
|
||||
masm.assumeUnreachable("Infallible unbox type mismatch");
|
||||
masm.bind(&ok);
|
||||
#endif
|
||||
}
|
||||
|
||||
Operand input = ToOperand(unbox->getOperand(LUnbox::Input));
|
||||
|
||||
@@ -123,9 +123,17 @@ CodeGeneratorX86::visitUnbox(LUnbox* unbox)
|
||||
// inputs.
|
||||
MUnbox* mir = unbox->mir();
|
||||
|
||||
JSValueTag tag = MIRTypeToTag(mir->type());
|
||||
if (mir->fallible()) {
|
||||
masm.cmp32(ToOperand(unbox->type()), Imm32(MIRTypeToTag(mir->type())));
|
||||
masm.cmp32(ToOperand(unbox->type()), Imm32(tag));
|
||||
bailoutIf(Assembler::NotEqual, unbox->snapshot());
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
Label ok;
|
||||
masm.branch32(Assembler::Equal, ToOperand(unbox->type()), Imm32(tag), &ok);
|
||||
masm.assumeUnreachable("Infallible unbox type mismatch");
|
||||
masm.bind(&ok);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,20 +86,6 @@ BEGIN_TEST(testSavedStacks_RangeBasedForLoops)
|
||||
CHECK(obj->is<js::SavedFrame>());
|
||||
JS::Rooted<js::SavedFrame*> savedFrame(cx, &obj->as<js::SavedFrame>());
|
||||
|
||||
js::SavedFrame* f = savedFrame.get();
|
||||
for (auto& frame : *savedFrame.get()) {
|
||||
CHECK(&frame == f);
|
||||
f = f->getParent();
|
||||
}
|
||||
CHECK(f == nullptr);
|
||||
|
||||
const js::SavedFrame* cf = savedFrame.get();
|
||||
for (const auto& frame : *savedFrame.get()) {
|
||||
CHECK(&frame == cf);
|
||||
cf = cf->getParent();
|
||||
}
|
||||
CHECK(cf == nullptr);
|
||||
|
||||
JS::Rooted<js::SavedFrame*> rf(cx, savedFrame);
|
||||
for (JS::Handle<js::SavedFrame*> frame : js::SavedFrame::RootedRange(cx, rf)) {
|
||||
JS_GC(cx);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user