зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to fx-team. a=merge
This commit is contained in:
Коммит
efd6d32c77
|
@ -102,19 +102,28 @@ HTMLLIAccessible::UpdateBullet(bool aHasBullet)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this);
|
||||||
|
AutoTreeMutation mut(this);
|
||||||
|
|
||||||
DocAccessible* document = Document();
|
DocAccessible* document = Document();
|
||||||
if (aHasBullet) {
|
if (aHasBullet) {
|
||||||
mBullet = new HTMLListBulletAccessible(mContent, mDoc);
|
mBullet = new HTMLListBulletAccessible(mContent, mDoc);
|
||||||
document->BindToDocument(mBullet, nullptr);
|
document->BindToDocument(mBullet, nullptr);
|
||||||
InsertChildAt(0, mBullet);
|
InsertChildAt(0, mBullet);
|
||||||
|
|
||||||
|
nsRefPtr<AccShowEvent> event = new AccShowEvent(mBullet, mBullet->GetContent());
|
||||||
|
mDoc->FireDelayedEvent(event);
|
||||||
|
reorderEvent->AddSubMutationEvent(event);
|
||||||
} else {
|
} else {
|
||||||
|
nsRefPtr<AccHideEvent> event = new AccHideEvent(mBullet, mBullet->GetContent());
|
||||||
|
mDoc->FireDelayedEvent(event);
|
||||||
|
reorderEvent->AddSubMutationEvent(event);
|
||||||
|
|
||||||
RemoveChild(mBullet);
|
RemoveChild(mBullet);
|
||||||
document->UnbindFromDocument(mBullet);
|
|
||||||
mBullet = nullptr;
|
mBullet = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXXtodo: fire show/hide and reorder events. That's hard to make it
|
mDoc->FireDelayedEvent(reorderEvent);
|
||||||
// right now because coalescence happens by DOM node.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
[test_bug884251.xhtml]
|
[test_bug884251.xhtml]
|
||||||
[test_bug895082.html]
|
[test_bug895082.html]
|
||||||
[test_bug1040735.html]
|
[test_bug1040735.html]
|
||||||
|
[test_bug1100602.html]
|
||||||
[test_canvas.html]
|
[test_canvas.html]
|
||||||
[test_colorpicker.xul]
|
[test_colorpicker.xul]
|
||||||
[test_contextmenu.xul]
|
[test_contextmenu.xul]
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Test hide/show events for HTMLListBulletAccessibles on list restyle</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||||
|
|
||||||
|
<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="../name.js"></script>
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="../events.js"></script>
|
||||||
|
|
||||||
|
<script type="application/javascript">
|
||||||
|
/**
|
||||||
|
* Change list style type to none.
|
||||||
|
*/
|
||||||
|
function hideBullet()
|
||||||
|
{
|
||||||
|
this.eventSeq = [];
|
||||||
|
this.liAcc = getAccessible("list_element");
|
||||||
|
this.bullet = this.liAcc.firstChild;
|
||||||
|
|
||||||
|
this.eventSeq.push(new invokerChecker(EVENT_HIDE, this.bullet));
|
||||||
|
this.eventSeq.push(new invokerChecker(EVENT_REORDER, this.liAcc));
|
||||||
|
|
||||||
|
this.invoke = function hideBullet_invoke()
|
||||||
|
{
|
||||||
|
getNode("list").setAttribute("style", "list-style-type: none;");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.finalCheck = function hideBullet_finalCheck()
|
||||||
|
{
|
||||||
|
is(this.liAcc.name, "list element",
|
||||||
|
"Check that first child of LI is not a bullet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getID = function hideBullet_getID()
|
||||||
|
{
|
||||||
|
return "Hide bullet by setting style to none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change list style type to circles.
|
||||||
|
*/
|
||||||
|
function showBullet()
|
||||||
|
{
|
||||||
|
this.eventSeq = [];
|
||||||
|
this.liAcc = getAccessible("list_element");
|
||||||
|
|
||||||
|
this.eventSeq.push(new invokerChecker(EVENT_SHOW,
|
||||||
|
function(aNode) { return aNode.firstChild; },
|
||||||
|
this.liAcc));
|
||||||
|
this.eventSeq.push(new invokerChecker(EVENT_REORDER, this.liAcc));
|
||||||
|
|
||||||
|
this.invoke = function showBullet_invoke()
|
||||||
|
{
|
||||||
|
getNode("list").setAttribute("style", "list-style-type: circle;");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.finalCheck = function showBullet_finalCheck()
|
||||||
|
{
|
||||||
|
is(this.liAcc.name, "◦ list element",
|
||||||
|
"Check that first child of LI is a circle bullet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getID = function showBullet_getID()
|
||||||
|
{
|
||||||
|
return "Show bullet by setting style to circle";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var gQueue = null;
|
||||||
|
function doTest()
|
||||||
|
{
|
||||||
|
|
||||||
|
var list = getNode("list");
|
||||||
|
list.setAttribute("style", "list-style-type: circle;");
|
||||||
|
|
||||||
|
gQueue = new eventQueue();
|
||||||
|
gQueue.push(new hideBullet());
|
||||||
|
gQueue.push(new showBullet());
|
||||||
|
gQueue.invoke(); // SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
addA11yLoadEvent(doTest);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<a target="_blank"
|
||||||
|
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1100602"
|
||||||
|
title="[e10s] crash in mozilla::a11y::ProxyAccessible::Shutdown()">
|
||||||
|
Mozilla Bug 1100602
|
||||||
|
</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none"></div>
|
||||||
|
<pre id="test">
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<ol id="list">
|
||||||
|
<li id="list_element">list element</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6ef08964711f461a8e6326eae911789d1ec220c"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
|
@ -125,7 +125,7 @@
|
||||||
<project name="device-shinano-common" path="device/sony/shinano-common" remote="b2g" revision="e9ef670a15d56ea312e70d4b11c4aaeac404f9d2"/>
|
<project name="device-shinano-common" path="device/sony/shinano-common" remote="b2g" revision="e9ef670a15d56ea312e70d4b11c4aaeac404f9d2"/>
|
||||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="1bb28abbc215f45220620af5cd60a8ac1be93722"/>
|
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="1bb28abbc215f45220620af5cd60a8ac1be93722"/>
|
||||||
<project name="device/qcom/common" path="device/qcom/common" revision="2501e5940ba69ece7654ff85611c76ae5bda299c"/>
|
<project name="device/qcom/common" path="device/qcom/common" revision="2501e5940ba69ece7654ff85611c76ae5bda299c"/>
|
||||||
<project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="5ada05ac150f643ef19e87015df7e106b88effe7"/>
|
<project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="d415406c7d810321a7cdd9af9c6271b2a378794c"/>
|
||||||
<project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="d61fc97258c8b0c362430dd2eb195dcc4d266f14"/>
|
<project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="d61fc97258c8b0c362430dd2eb195dcc4d266f14"/>
|
||||||
<project name="init_sh" path="external/init_sh" remote="b2g" revision="3bdd26e092db9c47c5beb04b4809a35f8f767b8a"/>
|
<project name="init_sh" path="external/init_sh" remote="b2g" revision="3bdd26e092db9c47c5beb04b4809a35f8f767b8a"/>
|
||||||
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="0a01977f34d6e86fe23d6c0ec75e96ba988bbebb"/>
|
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="0a01977f34d6e86fe23d6c0ec75e96ba988bbebb"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6ef08964711f461a8e6326eae911789d1ec220c"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c6ef08964711f461a8e6326eae911789d1ec220c"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>
|
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</project>
|
</project>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6ef08964711f461a8e6326eae911789d1ec220c"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cfa80d0c1c13a13a64b049173ea3a1d605f2cffd"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cfa80d0c1c13a13a64b049173ea3a1d605f2cffd"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6ef08964711f461a8e6326eae911789d1ec220c"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6ef08964711f461a8e6326eae911789d1ec220c"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c6ef08964711f461a8e6326eae911789d1ec220c"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>
|
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6ef08964711f461a8e6326eae911789d1ec220c"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
"git": {
|
"git": {
|
||||||
"git_revision": "803d04e3829fd4fe9261211aa0ddca6b79d4e328",
|
"git_revision": "c6ef08964711f461a8e6326eae911789d1ec220c",
|
||||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||||
"branch": ""
|
"branch": ""
|
||||||
},
|
},
|
||||||
"revision": "ad35f158cbd79823e9449f30df5d693613eef17f",
|
"revision": "422a64c4639a399fda83fb6ba9af46254a659421",
|
||||||
"repo_path": "integration/gaia-central"
|
"repo_path": "integration/gaia-central"
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</project>
|
</project>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6ef08964711f461a8e6326eae911789d1ec220c"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cfa80d0c1c13a13a64b049173ea3a1d605f2cffd"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cfa80d0c1c13a13a64b049173ea3a1d605f2cffd"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6ef08964711f461a8e6326eae911789d1ec220c"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
|
|
|
@ -5198,6 +5198,17 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
|
||||||
// Broken Content Detected. e.g. Content-MD5 check failure.
|
// Broken Content Detected. e.g. Content-MD5 check failure.
|
||||||
error.AssignLiteral("corruptedContentError");
|
error.AssignLiteral("corruptedContentError");
|
||||||
break;
|
break;
|
||||||
|
case NS_ERROR_INTERCEPTION_FAILED:
|
||||||
|
case NS_ERROR_OPAQUE_INTERCEPTION_DISABLED:
|
||||||
|
case NS_ERROR_BAD_OPAQUE_INTERCEPTION_REQUEST_MODE:
|
||||||
|
case NS_ERROR_INTERCEPTED_ERROR_RESPONSE:
|
||||||
|
case NS_ERROR_INTERCEPTED_USED_RESPONSE:
|
||||||
|
case NS_ERROR_CLIENT_REQUEST_OPAQUE_INTERCEPTION:
|
||||||
|
// ServiceWorker intercepted request, but something went wrong.
|
||||||
|
nsContentUtils::MaybeReportInterceptionErrorToConsole(GetDocument(),
|
||||||
|
aError);
|
||||||
|
error.AssignLiteral("corruptedContentError");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -7825,6 +7836,12 @@ nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
|
||||||
aStatus == NS_ERROR_UNSAFE_CONTENT_TYPE ||
|
aStatus == NS_ERROR_UNSAFE_CONTENT_TYPE ||
|
||||||
aStatus == NS_ERROR_REMOTE_XUL ||
|
aStatus == NS_ERROR_REMOTE_XUL ||
|
||||||
aStatus == NS_ERROR_OFFLINE ||
|
aStatus == NS_ERROR_OFFLINE ||
|
||||||
|
aStatus == NS_ERROR_INTERCEPTION_FAILED ||
|
||||||
|
aStatus == NS_ERROR_OPAQUE_INTERCEPTION_DISABLED ||
|
||||||
|
aStatus == NS_ERROR_BAD_OPAQUE_INTERCEPTION_REQUEST_MODE ||
|
||||||
|
aStatus == NS_ERROR_INTERCEPTED_ERROR_RESPONSE ||
|
||||||
|
aStatus == NS_ERROR_INTERCEPTED_USED_RESPONSE ||
|
||||||
|
aStatus == NS_ERROR_CLIENT_REQUEST_OPAQUE_INTERCEPTION ||
|
||||||
NS_ERROR_GET_MODULE(aStatus) == NS_ERROR_MODULE_SECURITY) {
|
NS_ERROR_GET_MODULE(aStatus) == NS_ERROR_MODULE_SECURITY) {
|
||||||
// Errors to be shown for any frame
|
// Errors to be shown for any frame
|
||||||
DisplayLoadError(aStatus, url, nullptr, aChannel);
|
DisplayLoadError(aStatus, url, nullptr, aChannel);
|
||||||
|
@ -14091,7 +14108,7 @@ nsDocShell::ChannelIntercepted(nsIInterceptedChannel* aChannel)
|
||||||
{
|
{
|
||||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
if (!swm) {
|
if (!swm) {
|
||||||
aChannel->Cancel();
|
aChannel->Cancel(NS_ERROR_INTERCEPTION_FAILED);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,22 +23,13 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(URL)
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(URL, mParent, mSearchParams)
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(URL)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSearchParams)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(URL)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSearchParams)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(URL)
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(URL)
|
||||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(URL)
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(URL)
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL)
|
||||||
|
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ class URL final : public URLSearchParamsObserver
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS(URL)
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(URL)
|
||||||
|
|
||||||
URL(nsISupports* aParent, already_AddRefed<nsIURI> aURI);
|
URL(nsISupports* aParent, already_AddRefed<nsIURI> aURI);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
window.mozRequestAnimationFrame(null);
|
window.requestAnimationFrame(null);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<script>
|
<script>
|
||||||
mozCancelRequestAnimationFrame(mozRequestAnimationFrame(function() {}));
|
cancelRequestAnimationFrame(requestAnimationFrame(function() {}));
|
||||||
mozRequestAnimationFrame(function() {});
|
requestAnimationFrame(function() {});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -3417,6 +3417,36 @@ nsContentUtils::ReportToConsole(uint32_t aErrorFlags,
|
||||||
aLineNumber, aColumnNumber);
|
aLineNumber, aColumnNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ nsresult
|
||||||
|
nsContentUtils::MaybeReportInterceptionErrorToConsole(nsIDocument* aDocument,
|
||||||
|
nsresult aError)
|
||||||
|
{
|
||||||
|
const char* messageName = nullptr;
|
||||||
|
if (aError == NS_ERROR_INTERCEPTION_FAILED) {
|
||||||
|
messageName = "InterceptionFailed";
|
||||||
|
} else if (aError == NS_ERROR_OPAQUE_INTERCEPTION_DISABLED) {
|
||||||
|
messageName = "OpaqueInterceptionDisabled";
|
||||||
|
} else if (aError == NS_ERROR_BAD_OPAQUE_INTERCEPTION_REQUEST_MODE) {
|
||||||
|
messageName = "BadOpaqueInterceptionRequestMode";
|
||||||
|
} else if (aError == NS_ERROR_INTERCEPTED_ERROR_RESPONSE) {
|
||||||
|
messageName = "InterceptedErrorResponse";
|
||||||
|
} else if (aError == NS_ERROR_INTERCEPTED_USED_RESPONSE) {
|
||||||
|
messageName = "InterceptedUsedResponse";
|
||||||
|
} else if (aError == NS_ERROR_CLIENT_REQUEST_OPAQUE_INTERCEPTION) {
|
||||||
|
messageName = "ClientRequestOpaqueInterception";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (messageName) {
|
||||||
|
return ReportToConsole(nsIScriptError::warningFlag,
|
||||||
|
NS_LITERAL_CSTRING("Service Worker Interception"),
|
||||||
|
aDocument,
|
||||||
|
nsContentUtils::eDOM_PROPERTIES,
|
||||||
|
messageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* static */ nsresult
|
/* static */ nsresult
|
||||||
nsContentUtils::ReportToConsoleNonLocalized(const nsAString& aErrorText,
|
nsContentUtils::ReportToConsoleNonLocalized(const nsAString& aErrorText,
|
||||||
|
|
|
@ -842,6 +842,9 @@ public:
|
||||||
uint32_t aLineNumber = 0,
|
uint32_t aLineNumber = 0,
|
||||||
uint32_t aColumnNumber = 0);
|
uint32_t aColumnNumber = 0);
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
MaybeReportInterceptionErrorToConsole(nsIDocument* aDocument, nsresult aError);
|
||||||
|
|
||||||
static void LogMessageToConsole(const char* aMsg, ...);
|
static void LogMessageToConsole(const char* aMsg, ...);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1761,10 +1761,10 @@ private:
|
||||||
void EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
|
void EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
|
||||||
bool aUpdateCSSLoader);
|
bool aUpdateCSSLoader);
|
||||||
|
|
||||||
// Revoke any pending notifications due to mozRequestAnimationFrame calls
|
// Revoke any pending notifications due to requestAnimationFrame calls
|
||||||
void RevokeAnimationFrameNotifications();
|
void RevokeAnimationFrameNotifications();
|
||||||
// Reschedule any notifications we need to handle
|
// Reschedule any notifications we need to handle
|
||||||
// mozRequestAnimationFrame, if it's OK to do so.
|
// requestAnimationFrame, if it's OK to do so.
|
||||||
void MaybeRescheduleAnimationFrameNotifications();
|
void MaybeRescheduleAnimationFrameNotifications();
|
||||||
|
|
||||||
// These are not implemented and not supported.
|
// These are not implemented and not supported.
|
||||||
|
|
|
@ -823,6 +823,7 @@ GK_ATOM(onMozScrolledAreaChanged, "onMozScrolledAreaChanged")
|
||||||
GK_ATOM(onmoznetworkupload, "onmoznetworkupload")
|
GK_ATOM(onmoznetworkupload, "onmoznetworkupload")
|
||||||
GK_ATOM(onmoznetworkdownload, "onmoznetworkdownload")
|
GK_ATOM(onmoznetworkdownload, "onmoznetworkdownload")
|
||||||
GK_ATOM(onnewrdsgroup, "onnewrdsgroup")
|
GK_ATOM(onnewrdsgroup, "onnewrdsgroup")
|
||||||
|
GK_ATOM(onnotificationclick, "onnotificationclick")
|
||||||
GK_ATOM(onnoupdate, "onnoupdate")
|
GK_ATOM(onnoupdate, "onnoupdate")
|
||||||
GK_ATOM(onobsolete, "onobsolete")
|
GK_ATOM(onobsolete, "onobsolete")
|
||||||
GK_ATOM(ononline, "ononline")
|
GK_ATOM(ononline, "ononline")
|
||||||
|
|
|
@ -2709,11 +2709,9 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
||||||
// We wait to fire the debugger hook until the window is all set up and hooked
|
// We wait to fire the debugger hook until the window is all set up and hooked
|
||||||
// up with the outer. See bug 969156.
|
// up with the outer. See bug 969156.
|
||||||
if (createdInnerWindow) {
|
if (createdInnerWindow) {
|
||||||
// AutoEntryScript required to invoke debugger hook, which is a
|
nsContentUtils::AddScriptRunner(
|
||||||
// Gecko-specific concept at present.
|
NS_NewRunnableMethod(newInnerWindow,
|
||||||
AutoEntryScript aes(newInnerWindow, "nsGlobalWindow report new global");
|
&nsGlobalWindow::FireOnNewGlobalObject));
|
||||||
JS::Rooted<JSObject*> global(aes.cx(), newInnerWindow->GetWrapper());
|
|
||||||
JS_FireOnNewGlobalObject(aes.cx(), global);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newInnerWindow && !newInnerWindow->mHasNotifiedGlobalCreated && mDoc) {
|
if (newInnerWindow && !newInnerWindow->mHasNotifiedGlobalCreated && mDoc) {
|
||||||
|
@ -14167,6 +14165,18 @@ nsGlobalWindow::SetReplaceableWindowCoord(JSContext* aCx,
|
||||||
(this->*aSetter)(value, aError);
|
(this->*aSetter)(value, aError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsGlobalWindow::FireOnNewGlobalObject()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(IsInnerWindow());
|
||||||
|
|
||||||
|
// AutoEntryScript required to invoke debugger hook, which is a
|
||||||
|
// Gecko-specific concept at present.
|
||||||
|
AutoEntryScript aes(this, "nsGlobalWindow report new global");
|
||||||
|
JS::Rooted<JSObject*> global(aes.cx(), GetWrapper());
|
||||||
|
JS_FireOnNewGlobalObject(aes.cx(), global);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WINDOWS_
|
#ifdef _WINDOWS_
|
||||||
#error "Never include windows.h in this file!"
|
#error "Never include windows.h in this file!"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1538,6 +1538,11 @@ protected:
|
||||||
// show, in that case we show a separate dialog to ask this question.
|
// show, in that case we show a separate dialog to ask this question.
|
||||||
bool ConfirmDialogIfNeeded();
|
bool ConfirmDialogIfNeeded();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Fire the JS engine's onNewGlobalObject hook. Only used on inner windows.
|
||||||
|
void FireOnNewGlobalObject();
|
||||||
|
|
||||||
|
protected:
|
||||||
// When adding new member variables, be careful not to create cycles
|
// When adding new member variables, be careful not to create cycles
|
||||||
// through JavaScript. If there is any chance that a member variable
|
// through JavaScript. If there is any chance that a member variable
|
||||||
// could own objects that are implemented in JavaScript, then those
|
// could own objects that are implemented in JavaScript, then those
|
||||||
|
|
|
@ -22,7 +22,7 @@ SimpleTest.waitForExplicitFinish();
|
||||||
var counter = 3;
|
var counter = 3;
|
||||||
|
|
||||||
var called = false;
|
var called = false;
|
||||||
var handle1 = window.mozRequestAnimationFrame(function() {
|
var handle1 = window.requestAnimationFrame(function() {
|
||||||
called = true;
|
called = true;
|
||||||
});
|
});
|
||||||
ok(handle1 > 0, "Should get back a nonzero handle");
|
ok(handle1 > 0, "Should get back a nonzero handle");
|
||||||
|
@ -33,11 +33,11 @@ function checker() {
|
||||||
is(called, false, "Canceled callback should not have been called");
|
is(called, false, "Canceled callback should not have been called");
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
} else {
|
} else {
|
||||||
window.mozRequestAnimationFrame(checker);
|
window.requestAnimationFrame(checker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window.mozRequestAnimationFrame(checker);
|
window.requestAnimationFrame(checker);
|
||||||
window.mozCancelAnimationFrame(handle1);
|
window.cancelAnimationFrame(handle1);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
|
@ -27,7 +27,7 @@ function f() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.mozRequestAnimationFrame(f);
|
window.requestAnimationFrame(f);
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.open("GET", "file_bug675121.sjs", false);
|
xhr.open("GET", "file_bug675121.sjs", false);
|
||||||
xhrInProgress = true;
|
xhrInProgress = true;
|
||||||
|
|
|
@ -12,34 +12,34 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=
|
||||||
|
|
||||||
/** Test for Bug **/
|
/** Test for Bug **/
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
var unprefixedRan = false;
|
var firstRan = false;
|
||||||
var prefixedRan = false;
|
var secondRan = false;
|
||||||
function unprefixed(time) {
|
function second(time) {
|
||||||
is(prefixedRan, true, "We were called second");
|
is(firstRan, true, "We were called second");
|
||||||
unprefixedRan = true;
|
secondRan = true;
|
||||||
ok(Math.abs(time - performance.now()) < 3600000,
|
ok(Math.abs(time - performance.now()) < 3600000,
|
||||||
"An hour really shouldn't have passed here");
|
"An hour really shouldn't have passed here");
|
||||||
ok(Math.abs(time - Date.now()) > 3600000,
|
ok(Math.abs(time - Date.now()) > 3600000,
|
||||||
"More than an hour should have passed since 1970");
|
"More than an hour should have passed since 1970");
|
||||||
}
|
}
|
||||||
function prefixed(time) {
|
function first(time) {
|
||||||
is(unprefixedRan, false, "Prefixed was called first");
|
is(secondRan, false, "second() was called first");
|
||||||
prefixedRan = true;
|
firstRan = true;
|
||||||
ok(Math.abs(time - Date.now()) < 3600000,
|
ok(Math.abs(time - performance.now()) < 3600000,
|
||||||
"Our time should be comparable to Date.now()");
|
"An hour really shouldn't have passed here either");
|
||||||
ok(Math.abs(time - performance.now()) > 3600000,
|
ok(Math.abs(time - Date.now()) > 3600000,
|
||||||
"Our time should not be comparable to performance.now()");
|
"More than an hour should have passed since 1970 here either");
|
||||||
}
|
}
|
||||||
function prefixed2() {
|
function third() {
|
||||||
ok(prefixedRan, "We should be after the other prefixed call");
|
ok(firstRan, "We should be after the first call");
|
||||||
ok(unprefixedRan, "We should be after the unprefixed call");
|
ok(secondRan, "We should be after the second call");
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
window.mozRequestAnimationFrame(prefixed);
|
window.requestAnimationFrame(first);
|
||||||
window.requestAnimationFrame(unprefixed);
|
window.requestAnimationFrame(second);
|
||||||
window.mozRequestAnimationFrame(prefixed2);
|
window.requestAnimationFrame(third);
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -869,6 +869,14 @@ DOMInterfaces = {
|
||||||
'nativeType': 'nsINodeList',
|
'nativeType': 'nsINodeList',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'NotificationEvent': {
|
||||||
|
'headerFile': 'mozilla/dom/NotificationEvent.h',
|
||||||
|
'nativeType': 'mozilla::dom::workers::NotificationEvent',
|
||||||
|
'binaryNames': {
|
||||||
|
'notification': 'notification_'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
'OfflineAudioContext': {
|
'OfflineAudioContext': {
|
||||||
'nativeType': 'mozilla::dom::AudioContext',
|
'nativeType': 'mozilla::dom::AudioContext',
|
||||||
},
|
},
|
||||||
|
|
|
@ -73,3 +73,6 @@ MSG_DEF(MSG_INVALID_URL_SCHEME, 2, JSEXN_TYPEERR, "{0} URL {1} must be either ht
|
||||||
MSG_DEF(MSG_RESPONSE_URL_IS_NULL, 0, JSEXN_TYPEERR, "Cannot set Response.finalURL when Response.url is null.")
|
MSG_DEF(MSG_RESPONSE_URL_IS_NULL, 0, JSEXN_TYPEERR, "Cannot set Response.finalURL when Response.url is null.")
|
||||||
MSG_DEF(MSG_RESPONSE_HAS_VARY_STAR, 0, JSEXN_TYPEERR, "Invalid Response object with a 'Vary: *' header.")
|
MSG_DEF(MSG_RESPONSE_HAS_VARY_STAR, 0, JSEXN_TYPEERR, "Invalid Response object with a 'Vary: *' header.")
|
||||||
MSG_DEF(MSG_BAD_FORMDATA, 0, JSEXN_TYPEERR, "Could not parse content as FormData.")
|
MSG_DEF(MSG_BAD_FORMDATA, 0, JSEXN_TYPEERR, "Could not parse content as FormData.")
|
||||||
|
MSG_DEF(MSG_NO_ACTIVE_WORKER, 1, JSEXN_TYPEERR, "No active worker for scope {0}.")
|
||||||
|
MSG_DEF(MSG_NOTIFICATION_PERMISSION_DENIED, 0, JSEXN_TYPEERR, "Permission to show Notification denied.")
|
||||||
|
MSG_DEF(MSG_NOTIFICATION_NO_CONSTRUCTOR_IN_SERVICEWORKER, 0, JSEXN_TYPEERR, "Notification constructor cannot be used in ServiceWorkerGlobalScope. Use registration.showNotification() instead.")
|
||||||
|
|
|
@ -622,7 +622,7 @@ const KineticPanning = {
|
||||||
v.y * Math.exp(-t / c) * -c + a.y * t * t + v.y * c);
|
v.y * Math.exp(-t / c) * -c + a.y * t * t + v.y * c);
|
||||||
}
|
}
|
||||||
|
|
||||||
let startTime = content.mozAnimationStartTime;
|
let startTime = content.performance.now();
|
||||||
let elapsedTime = 0, targetedTime = 0, averageTime = 0;
|
let elapsedTime = 0, targetedTime = 0, averageTime = 0;
|
||||||
|
|
||||||
let velocity = this._velocity;
|
let velocity = this._velocity;
|
||||||
|
@ -667,9 +667,9 @@ const KineticPanning = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
content.mozRequestAnimationFrame(callback);
|
content.requestAnimationFrame(callback);
|
||||||
}).bind(this);
|
}).bind(this);
|
||||||
|
|
||||||
content.mozRequestAnimationFrame(callback);
|
content.requestAnimationFrame(callback);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -62,7 +62,7 @@ function initGL(canvas) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function rAF(func) {
|
function rAF(func) {
|
||||||
var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame;
|
var raf = window.requestAnimationFrame;
|
||||||
raf(func);
|
raf(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,10 +55,10 @@ function runTest() {
|
||||||
scrollDown15PxWithPixelScrolling(scrollbox);
|
scrollDown15PxWithPixelScrolling(scrollbox);
|
||||||
|
|
||||||
// wait for the next refresh driver run
|
// wait for the next refresh driver run
|
||||||
win.mozRequestAnimationFrame(function() {
|
win.requestAnimationFrame(function() {
|
||||||
// actually, wait for the next one before checking results, since
|
// actually, wait for the next one before checking results, since
|
||||||
// scrolling might not be flushed until after this code has run
|
// scrolling might not be flushed until after this code has run
|
||||||
win.mozRequestAnimationFrame(function() {
|
win.requestAnimationFrame(function() {
|
||||||
is(scrollbox.scrollTop, scrollTopBefore + 15,
|
is(scrollbox.scrollTop, scrollTopBefore + 15,
|
||||||
"Pixel scrolling should have finished after one refresh driver iteration. " +
|
"Pixel scrolling should have finished after one refresh driver iteration. " +
|
||||||
"We shouldn't be scrolling smoothly, even though the pref is set.");
|
"We shouldn't be scrolling smoothly, even though the pref is set.");
|
||||||
|
|
|
@ -195,5 +195,44 @@ InternalRequest::MapContentPolicyTypeToRequestContext(nsContentPolicyType aConte
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
InternalRequest::IsNavigationRequest() const
|
||||||
|
{
|
||||||
|
// https://fetch.spec.whatwg.org/#navigation-request-context
|
||||||
|
//
|
||||||
|
// A navigation request context is one of "form", "frame", "hyperlink",
|
||||||
|
// "iframe", "internal" (as long as context frame type is not "none"),
|
||||||
|
// "location", "metarefresh", and "prerender".
|
||||||
|
//
|
||||||
|
// TODO: include equivalent check for "form" context
|
||||||
|
// TODO: include equivalent check for "prerender" context
|
||||||
|
return mContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT ||
|
||||||
|
mContentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT ||
|
||||||
|
mContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_FRAME ||
|
||||||
|
mContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_IFRAME ||
|
||||||
|
mContentPolicyType == nsIContentPolicy::TYPE_REFRESH;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
InternalRequest::IsWorkerRequest() const
|
||||||
|
{
|
||||||
|
// https://fetch.spec.whatwg.org/#worker-request-context
|
||||||
|
//
|
||||||
|
// A worker request context is one of "serviceworker", "sharedworker", and
|
||||||
|
// "worker".
|
||||||
|
//
|
||||||
|
// Note, service workers are not included here because currently there is
|
||||||
|
// no way to generate a Request with a "serviceworker" RequestContext.
|
||||||
|
// ServiceWorker scripts cannot be intercepted.
|
||||||
|
return mContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
|
||||||
|
mContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
InternalRequest::IsClientRequest() const
|
||||||
|
{
|
||||||
|
return IsNavigationRequest() || IsWorkerRequest();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -356,6 +356,16 @@ public:
|
||||||
mCreatedByFetchEvent = false;
|
mCreatedByFetchEvent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsNavigationRequest() const;
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsWorkerRequest() const;
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsClientRequest() const;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Does not copy mBodyStream. Use fallible Clone() for complete copy.
|
// Does not copy mBodyStream. Use fallible Clone() for complete copy.
|
||||||
explicit InternalRequest(const InternalRequest& aOther);
|
explicit InternalRequest(const InternalRequest& aOther);
|
||||||
|
|
|
@ -33,7 +33,7 @@ interface nsIServiceWorkerInfo : nsISupports
|
||||||
readonly attribute DOMString waitingCacheName;
|
readonly attribute DOMString waitingCacheName;
|
||||||
};
|
};
|
||||||
|
|
||||||
[scriptable, builtinclass, uuid(e9abb123-0099-4d9e-85db-c8cd0aff19e6)]
|
[scriptable, builtinclass, uuid(ed1cbbf2-0400-4caa-8eb2-b09d21a94e20)]
|
||||||
interface nsIServiceWorkerManager : nsISupports
|
interface nsIServiceWorkerManager : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -126,6 +126,17 @@ interface nsIServiceWorkerManager : nsISupports
|
||||||
in nsIServiceWorkerUnregisterCallback aCallback,
|
in nsIServiceWorkerUnregisterCallback aCallback,
|
||||||
in DOMString aScope);
|
in DOMString aScope);
|
||||||
|
|
||||||
|
void sendNotificationClickEvent(in ACString aOriginSuffix,
|
||||||
|
in ACString scope,
|
||||||
|
in AString aID,
|
||||||
|
in AString aTitle,
|
||||||
|
in AString aDir,
|
||||||
|
in AString aLang,
|
||||||
|
in AString aBody,
|
||||||
|
in AString aTag,
|
||||||
|
in AString aIcon,
|
||||||
|
in AString aData,
|
||||||
|
in AString aBehavior);
|
||||||
void sendPushEvent(in ACString aOriginAttributes,
|
void sendPushEvent(in ACString aOriginAttributes,
|
||||||
in ACString aScope,
|
in ACString aScope,
|
||||||
in DOMString aData);
|
in DOMString aData);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include "domstubs.idl"
|
#include "domstubs.idl"
|
||||||
|
|
||||||
[scriptable, uuid(9f1c43b9-f01b-4c87-ad3d-1a86520c2159)]
|
[scriptable, uuid(c1622232-259c-43b0-b52e-89c39dcd9796)]
|
||||||
interface nsINotificationStorageCallback : nsISupports
|
interface nsINotificationStorageCallback : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -28,7 +28,8 @@ interface nsINotificationStorageCallback : nsISupports
|
||||||
in DOMString tag,
|
in DOMString tag,
|
||||||
in DOMString icon,
|
in DOMString icon,
|
||||||
in DOMString data,
|
in DOMString data,
|
||||||
in DOMString behavior);
|
in DOMString behavior,
|
||||||
|
in DOMString serviceWorkerRegistrationID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback function used to notify C++ the we have returned
|
* Callback function used to notify C++ the we have returned
|
||||||
|
@ -41,7 +42,7 @@ interface nsINotificationStorageCallback : nsISupports
|
||||||
/**
|
/**
|
||||||
* Interface for notification persistence layer.
|
* Interface for notification persistence layer.
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(cac01fb0-c2eb-4252-b2f4-5b1fac933bd4)]
|
[scriptable, uuid(17f85e52-fe57-440e-9ba1-5c312ca02b95)]
|
||||||
interface nsINotificationStorage : nsISupports
|
interface nsINotificationStorage : nsISupports
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -61,6 +62,10 @@ interface nsINotificationStorage : nsISupports
|
||||||
* Stored in the database to avoid re-computing
|
* Stored in the database to avoid re-computing
|
||||||
* it. Built from origin and tag or id depending
|
* it. Built from origin and tag or id depending
|
||||||
* whether there is a tag defined.
|
* whether there is a tag defined.
|
||||||
|
* @param registrationID: Opaque string that identifies the service worker
|
||||||
|
* registration this Notification is associated with.
|
||||||
|
* May be empty. Only set for Notifications created by
|
||||||
|
* showNotification().
|
||||||
*/
|
*/
|
||||||
void put(in DOMString origin,
|
void put(in DOMString origin,
|
||||||
in DOMString id,
|
in DOMString id,
|
||||||
|
@ -72,7 +77,8 @@ interface nsINotificationStorage : nsISupports
|
||||||
in DOMString icon,
|
in DOMString icon,
|
||||||
in DOMString alertName,
|
in DOMString alertName,
|
||||||
in DOMString data,
|
in DOMString data,
|
||||||
in DOMString behavior);
|
in DOMString behavior,
|
||||||
|
in DOMString serviceWorkerRegistrationID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a list of notifications.
|
* Retrieve a list of notifications.
|
||||||
|
@ -86,6 +92,20 @@ interface nsINotificationStorage : nsISupports
|
||||||
in DOMString tag,
|
in DOMString tag,
|
||||||
in nsINotificationStorageCallback aCallback);
|
in nsINotificationStorageCallback aCallback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a notification by ID.
|
||||||
|
*
|
||||||
|
* @param origin: the origin/app for which to fetch notifications.
|
||||||
|
* @param id: the id of the notification.
|
||||||
|
* @param callback: nsINotificationStorageCallback whose Handle method will
|
||||||
|
* be called *at most once* if the notification with that ID is found. Not
|
||||||
|
* called if that ID is not found. Done() will be called right after
|
||||||
|
* Handle().
|
||||||
|
*/
|
||||||
|
void getByID(in DOMString origin,
|
||||||
|
in DOMString id,
|
||||||
|
in nsINotificationStorageCallback aCallback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a notification from storage.
|
* Remove a notification from storage.
|
||||||
*
|
*
|
||||||
|
|
|
@ -166,3 +166,15 @@ HittingMaxWorkersPerDomain=A ServiceWorker could not be started immediately beca
|
||||||
PannerNodeDopplerWarning=Use of setVelocity on the PannerNode and AudioListener, and speedOfSound and dopplerFactor on the AudioListener are deprecated and those members will be removed. For more help https://developer.mozilla.org/en-US/docs/Web/API/AudioListener#Deprecated_features
|
PannerNodeDopplerWarning=Use of setVelocity on the PannerNode and AudioListener, and speedOfSound and dopplerFactor on the AudioListener are deprecated and those members will be removed. For more help https://developer.mozilla.org/en-US/docs/Web/API/AudioListener#Deprecated_features
|
||||||
# LOCALIZATION NOTE: Do not translate "Worker".
|
# LOCALIZATION NOTE: Do not translate "Worker".
|
||||||
EmptyWorkerSourceWarning=Attempting to create a Worker from an empty source. This is probably unintentional.
|
EmptyWorkerSourceWarning=Attempting to create a Worker from an empty source. This is probably unintentional.
|
||||||
|
# LOCALIZATION NOTE: Do not translate "ServiceWorker".
|
||||||
|
InterceptionFailed=ServiceWorker network interception failed due to an unexpected error.
|
||||||
|
# LOCALIZATION NOTE: Do not translate "ServiceWorker", "FetchEvent.respondWith()", "opaque", or "Response".
|
||||||
|
OpaqueInterceptionDisabled=A ServiceWorker passed an opaque Response to FetchEvent.respondWith() while opaque interception is disabled.
|
||||||
|
# LOCALIZATION NOTE: Do not translate "ServiceWorker", "FetchEvent.respondWith()", "FetchEvent.request.type", "same-origin", "cors", "no-cors", "opaque", "Response", or "RequestMode".
|
||||||
|
BadOpaqueInterceptionRequestMode=A ServiceWorker passed an opaque Response to FetchEvent.respondWith() while the FetchEvent.request.type was either "same-origin" or "cors". Opaque Response objects are only valid when the RequestMode is "no-cors".
|
||||||
|
# LOCALIZATION NOTE: Do not translate "ServiceWorker", "Error", "Response", "FetchEvent.respondWith()", or "fetch()".
|
||||||
|
InterceptedErrorResponse=A ServiceWorker passed an Error Response to FetchEvent.respondWith(). This typically means the ServiceWorker performed an invalid fetch() call.
|
||||||
|
# LOCALIZATION NOTE: Do not translate "ServiceWorker", "Response", "FetchEvent.respondWith()", or "Response.clone()".
|
||||||
|
InterceptedUsedResponse=A ServiceWorker passed a used Response to FetchEvent.respondWith(). The body of a Response may only be read once. Use Response.clone() to access the body multiple times.
|
||||||
|
# LOCALIZATION NOTE: Do not translate "ServiceWorker", "Response", "FetchEvent.respondWith()", "FetchEvent.request", or "Worker".
|
||||||
|
ClientRequestOpaqueInterception=A ServiceWorker passed an opaque Response to FetchEvent.respondWith() while FetchEvent.request was a client request. A client request is generally a browser navigation or top-level Worker script.
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -115,6 +115,8 @@ class Notification : public DOMEventTargetHelper
|
||||||
friend class NotificationPermissionRequest;
|
friend class NotificationPermissionRequest;
|
||||||
friend class NotificationObserver;
|
friend class NotificationObserver;
|
||||||
friend class NotificationStorageCallback;
|
friend class NotificationStorageCallback;
|
||||||
|
friend class ServiceWorkerNotificationObserver;
|
||||||
|
friend class WorkerGetRunnable;
|
||||||
friend class WorkerNotificationObserver;
|
friend class WorkerNotificationObserver;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -134,6 +136,31 @@ public:
|
||||||
const nsAString& aTitle,
|
const nsAString& aTitle,
|
||||||
const NotificationOptions& aOption,
|
const NotificationOptions& aOption,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used when dispatching the ServiceWorkerEvent.
|
||||||
|
*
|
||||||
|
* Does not initialize the Notification's behavior.
|
||||||
|
* This is because:
|
||||||
|
* 1) The Notification is not shown to the user and so the behavior
|
||||||
|
* parameters don't matter.
|
||||||
|
* 2) The default binding requires main thread for parsing the JSON from the
|
||||||
|
* string behavior.
|
||||||
|
*/
|
||||||
|
static already_AddRefed<Notification>
|
||||||
|
ConstructFromFields(
|
||||||
|
nsIGlobalObject* aGlobal,
|
||||||
|
const nsAString& aID,
|
||||||
|
const nsAString& aTitle,
|
||||||
|
const nsAString& aDir,
|
||||||
|
const nsAString& aLang,
|
||||||
|
const nsAString& aBody,
|
||||||
|
const nsAString& aTag,
|
||||||
|
const nsAString& aIcon,
|
||||||
|
const nsAString& aData,
|
||||||
|
const nsAString& aServiceWorkerRegistrationID,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
void GetID(nsAString& aRetval) {
|
void GetID(nsAString& aRetval) {
|
||||||
aRetval = mID;
|
aRetval = mID;
|
||||||
}
|
}
|
||||||
|
@ -189,10 +216,30 @@ public:
|
||||||
static NotificationPermission GetPermission(const GlobalObject& aGlobal,
|
static NotificationPermission GetPermission(const GlobalObject& aGlobal,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
static already_AddRefed<Promise>
|
||||||
|
Get(nsPIDOMWindow* aWindow,
|
||||||
|
const GetNotificationOptions& aFilter,
|
||||||
|
const nsAString& aScope,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
static already_AddRefed<Promise> Get(const GlobalObject& aGlobal,
|
static already_AddRefed<Promise> Get(const GlobalObject& aGlobal,
|
||||||
const GetNotificationOptions& aFilter,
|
const GetNotificationOptions& aFilter,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
static already_AddRefed<Promise> WorkerGet(workers::WorkerPrivate* aWorkerPrivate,
|
||||||
|
const GetNotificationOptions& aFilter,
|
||||||
|
const nsAString& aScope,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
// Notification implementation of
|
||||||
|
// ServiceWorkerRegistration.showNotification.
|
||||||
|
static already_AddRefed<Promise>
|
||||||
|
ShowPersistentNotification(nsIGlobalObject* aGlobal,
|
||||||
|
const nsAString& aScope,
|
||||||
|
const nsAString& aTitle,
|
||||||
|
const NotificationOptions& aOptions,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
nsPIDOMWindow* GetParentObject()
|
nsPIDOMWindow* GetParentObject()
|
||||||
|
@ -233,15 +280,20 @@ public:
|
||||||
bool AddRefObject();
|
bool AddRefObject();
|
||||||
void ReleaseObject();
|
void ReleaseObject();
|
||||||
|
|
||||||
|
static NotificationPermission GetPermission(nsIGlobalObject* aGlobal,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
static NotificationPermission GetPermissionInternal(nsIPrincipal* aPrincipal,
|
static NotificationPermission GetPermissionInternal(nsIPrincipal* aPrincipal,
|
||||||
ErrorResult& rv);
|
ErrorResult& rv);
|
||||||
|
|
||||||
bool DispatchClickEvent();
|
bool DispatchClickEvent();
|
||||||
|
bool DispatchNotificationClickEvent();
|
||||||
protected:
|
protected:
|
||||||
Notification(const nsAString& aID, const nsAString& aTitle, const nsAString& aBody,
|
Notification(nsIGlobalObject* aGlobal, const nsAString& aID,
|
||||||
|
const nsAString& aTitle, const nsAString& aBody,
|
||||||
NotificationDirection aDir, const nsAString& aLang,
|
NotificationDirection aDir, const nsAString& aLang,
|
||||||
const nsAString& aTag, const nsAString& aIconUrl,
|
const nsAString& aTag, const nsAString& aIconUrl,
|
||||||
const NotificationBehavior& aBehavior, nsIGlobalObject* aGlobal);
|
const NotificationBehavior& aBehavior);
|
||||||
|
|
||||||
static already_AddRefed<Notification> CreateInternal(nsIGlobalObject* aGlobal,
|
static already_AddRefed<Notification> CreateInternal(nsIGlobalObject* aGlobal,
|
||||||
const nsAString& aID,
|
const nsAString& aID,
|
||||||
|
@ -277,14 +329,29 @@ protected:
|
||||||
return NotificationDirection::Auto;
|
return NotificationDirection::Auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
static nsresult GetOrigin(nsPIDOMWindow* aWindow, nsString& aOrigin);
|
static nsresult GetOrigin(nsIPrincipal* aPrincipal, nsString& aOrigin);
|
||||||
nsresult GetOriginWorker(nsString& aOrigin);
|
|
||||||
|
|
||||||
void GetAlertName(nsAString& aRetval)
|
void GetAlertName(nsAString& aRetval)
|
||||||
{
|
{
|
||||||
|
workers::AssertIsOnMainThread();
|
||||||
|
if (mAlertName.IsEmpty()) {
|
||||||
|
SetAlertName();
|
||||||
|
}
|
||||||
aRetval = mAlertName;
|
aRetval = mAlertName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetScope(nsAString& aScope)
|
||||||
|
{
|
||||||
|
aScope = mScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SetScope(const nsAString& aScope)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mScope.IsEmpty());
|
||||||
|
mScope = aScope;
|
||||||
|
}
|
||||||
|
|
||||||
const nsString mID;
|
const nsString mID;
|
||||||
const nsString mTitle;
|
const nsString mTitle;
|
||||||
const nsString mBody;
|
const nsString mBody;
|
||||||
|
@ -299,6 +366,7 @@ protected:
|
||||||
nsCOMPtr<nsIVariant> mData;
|
nsCOMPtr<nsIVariant> mData;
|
||||||
|
|
||||||
nsString mAlertName;
|
nsString mAlertName;
|
||||||
|
nsString mScope;
|
||||||
|
|
||||||
// Main thread only.
|
// Main thread only.
|
||||||
bool mIsClosed;
|
bool mIsClosed;
|
||||||
|
@ -314,11 +382,25 @@ protected:
|
||||||
private:
|
private:
|
||||||
virtual ~Notification();
|
virtual ~Notification();
|
||||||
|
|
||||||
|
// Creates a Notification and shows it. Returns a reference to the
|
||||||
|
// Notification if result is NS_OK. The lifetime of this Notification is tied
|
||||||
|
// to an underlying NotificationRef. Do not hold a non-stack raw pointer to
|
||||||
|
// it. Be careful about thread safety if acquiring a strong reference.
|
||||||
|
static already_AddRefed<Notification>
|
||||||
|
CreateAndShow(nsIGlobalObject* aGlobal,
|
||||||
|
const nsAString& aTitle,
|
||||||
|
const NotificationOptions& aOptions,
|
||||||
|
const nsAString& aScope,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
nsIPrincipal* GetPrincipal();
|
nsIPrincipal* GetPrincipal();
|
||||||
|
|
||||||
nsresult PersistNotification();
|
nsresult PersistNotification();
|
||||||
void UnpersistNotification();
|
void UnpersistNotification();
|
||||||
|
|
||||||
|
void
|
||||||
|
SetAlertName();
|
||||||
|
|
||||||
bool IsTargetThread() const
|
bool IsTargetThread() const
|
||||||
{
|
{
|
||||||
return NS_IsMainThread() == !mWorkerPrivate;
|
return NS_IsMainThread() == !mWorkerPrivate;
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "NotificationEvent.h"
|
||||||
|
|
||||||
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
|
BEGIN_WORKERS_NAMESPACE
|
||||||
|
|
||||||
|
NotificationEvent::NotificationEvent(EventTarget* aOwner)
|
||||||
|
: ExtendableEvent(aOwner)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ADDREF_INHERITED(NotificationEvent, ExtendableEvent)
|
||||||
|
NS_IMPL_RELEASE_INHERITED(NotificationEvent, ExtendableEvent)
|
||||||
|
|
||||||
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(NotificationEvent)
|
||||||
|
NS_INTERFACE_MAP_END_INHERITING(ExtendableEvent)
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_INHERITED(NotificationEvent, ExtendableEvent, mNotification)
|
||||||
|
|
||||||
|
END_WORKERS_NAMESPACE
|
|
@ -0,0 +1,74 @@
|
||||||
|
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_workers_notificationevent_h__
|
||||||
|
#define mozilla_dom_workers_notificationevent_h__
|
||||||
|
|
||||||
|
#include "mozilla/dom/Event.h"
|
||||||
|
#include "mozilla/dom/NotificationEventBinding.h"
|
||||||
|
#include "mozilla/dom/ServiceWorkerEvents.h"
|
||||||
|
#include "mozilla/dom/workers/Workers.h"
|
||||||
|
|
||||||
|
BEGIN_WORKERS_NAMESPACE
|
||||||
|
|
||||||
|
class ServiceWorker;
|
||||||
|
class ServiceWorkerClient;
|
||||||
|
|
||||||
|
class NotificationEvent final : public ExtendableEvent
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
explicit NotificationEvent(EventTarget* aOwner);
|
||||||
|
~NotificationEvent()
|
||||||
|
{}
|
||||||
|
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(NotificationEvent, ExtendableEvent)
|
||||||
|
NS_FORWARD_TO_EVENT
|
||||||
|
|
||||||
|
virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
|
||||||
|
{
|
||||||
|
return NotificationEventBinding::Wrap(aCx, this, aGivenProto);
|
||||||
|
}
|
||||||
|
|
||||||
|
static already_AddRefed<NotificationEvent>
|
||||||
|
Constructor(mozilla::dom::EventTarget* aOwner,
|
||||||
|
const nsAString& aType,
|
||||||
|
const NotificationEventInit& aOptions,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
nsRefPtr<NotificationEvent> e = new NotificationEvent(aOwner);
|
||||||
|
bool trusted = e->Init(aOwner);
|
||||||
|
e->InitEvent(aType, aOptions.mBubbles, aOptions.mCancelable);
|
||||||
|
e->SetTrusted(trusted);
|
||||||
|
e->mNotification = aOptions.mNotification;
|
||||||
|
e->SetWantsPopupControlCheck(e->IsTrusted());
|
||||||
|
return e.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
static already_AddRefed<NotificationEvent>
|
||||||
|
Constructor(const GlobalObject& aGlobal,
|
||||||
|
const nsAString& aType,
|
||||||
|
const NotificationEventInit& aOptions,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
nsCOMPtr<EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
|
||||||
|
return Constructor(owner, aType, aOptions, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Notification>
|
||||||
|
Notification_()
|
||||||
|
{
|
||||||
|
nsRefPtr<Notification> n = mNotification;
|
||||||
|
return n.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsRefPtr<Notification> mNotification;
|
||||||
|
};
|
||||||
|
|
||||||
|
END_WORKERS_NAMESPACE
|
||||||
|
#endif /* mozilla_dom_workers_notificationevent_h__ */
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const DEBUG = false;
|
const DEBUG = true;
|
||||||
function debug(s) { dump("-*- NotificationStorage.js: " + s + "\n"); }
|
function debug(s) { dump("-*- NotificationStorage.js: " + s + "\n"); }
|
||||||
|
|
||||||
const Cc = Components.classes;
|
const Cc = Components.classes;
|
||||||
|
@ -84,8 +84,8 @@ NotificationStorage.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
put: function(origin, id, title, dir, lang, body, tag, icon, alertName,
|
put: function(origin, id, title, dir, lang, body, tag, icon, alertName,
|
||||||
data, behavior) {
|
data, behavior, serviceWorkerRegistrationID) {
|
||||||
if (DEBUG) { debug("PUT: " + id + ": " + title); }
|
if (DEBUG) { debug("PUT: " + origin + " " + id + ": " + title); }
|
||||||
var notification = {
|
var notification = {
|
||||||
id: id,
|
id: id,
|
||||||
title: title,
|
title: title,
|
||||||
|
@ -98,7 +98,8 @@ NotificationStorage.prototype = {
|
||||||
timestamp: new Date().getTime(),
|
timestamp: new Date().getTime(),
|
||||||
origin: origin,
|
origin: origin,
|
||||||
data: data,
|
data: data,
|
||||||
mozbehavior: behavior
|
mozbehavior: behavior,
|
||||||
|
serviceWorkerRegistrationID: serviceWorkerRegistrationID,
|
||||||
};
|
};
|
||||||
|
|
||||||
this._notifications[id] = notification;
|
this._notifications[id] = notification;
|
||||||
|
@ -134,6 +135,25 @@ NotificationStorage.prototype = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getByID: function(origin, id, callback) {
|
||||||
|
if (DEBUG) { debug("GETBYID: " + origin + " " + id); }
|
||||||
|
var GetByIDProxyCallback = function(id, originalCallback) {
|
||||||
|
this.searchID = id;
|
||||||
|
this.originalCallback = originalCallback;
|
||||||
|
var self = this;
|
||||||
|
this.handle = function(id, title, dir, lang, body, tag, icon, data, behavior, serviceWorkerRegistrationID) {
|
||||||
|
if (id == this.searchID) {
|
||||||
|
self.originalCallback.handle(id, title, dir, lang, body, tag, icon, data, behavior, serviceWorkerRegistrationID);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.done = function() {
|
||||||
|
self.originalCallback.done();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.get(origin, "", new GetByIDProxyCallback(id, callback));
|
||||||
|
},
|
||||||
|
|
||||||
delete: function(origin, id) {
|
delete: function(origin, id) {
|
||||||
if (DEBUG) { debug("DELETE: " + id); }
|
if (DEBUG) { debug("DELETE: " + id); }
|
||||||
var notification = this._notifications[id];
|
var notification = this._notifications[id];
|
||||||
|
@ -211,23 +231,30 @@ NotificationStorage.prototype = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass each notification back separately.
|
// Pass each notification back separately.
|
||||||
|
// The callback is called asynchronously to match the behaviour when
|
||||||
|
// fetching from the database.
|
||||||
notifications.forEach(function(notification) {
|
notifications.forEach(function(notification) {
|
||||||
try {
|
try {
|
||||||
callback.handle(notification.id,
|
Services.tm.currentThread.dispatch(
|
||||||
notification.title,
|
callback.handle.bind(callback,
|
||||||
notification.dir,
|
notification.id,
|
||||||
notification.lang,
|
notification.title,
|
||||||
notification.body,
|
notification.dir,
|
||||||
notification.tag,
|
notification.lang,
|
||||||
notification.icon,
|
notification.body,
|
||||||
notification.data,
|
notification.tag,
|
||||||
notification.mozbehavior);
|
notification.icon,
|
||||||
|
notification.data,
|
||||||
|
notification.mozbehavior,
|
||||||
|
notification.serviceWorkerRegistrationID),
|
||||||
|
Ci.nsIThread.DISPATCH_NORMAL);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (DEBUG) { debug("Error calling callback handle: " + e); }
|
if (DEBUG) { debug("Error calling callback handle: " + e); }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
callback.done();
|
Services.tm.currentThread.dispatch(callback.done,
|
||||||
|
Ci.nsIThread.DISPATCH_NORMAL);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (DEBUG) { debug("Error calling callback done: " + e); }
|
if (DEBUG) { debug("Error calling callback done: " + e); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,13 @@ EXTRA_JS_MODULES += [
|
||||||
EXPORTS.mozilla.dom += [
|
EXPORTS.mozilla.dom += [
|
||||||
'DesktopNotification.h',
|
'DesktopNotification.h',
|
||||||
'Notification.h',
|
'Notification.h',
|
||||||
|
'NotificationEvent.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
'DesktopNotification.cpp',
|
'DesktopNotification.cpp',
|
||||||
'Notification.cpp',
|
'Notification.cpp',
|
||||||
|
'NotificationEvent.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
FAIL_ON_WARNINGS = True
|
FAIL_ON_WARNINGS = True
|
||||||
|
|
|
@ -35,7 +35,7 @@ function start() {
|
||||||
canvas = document.getElementById("two");
|
canvas = document.getElementById("two");
|
||||||
paintCanvas();
|
paintCanvas();
|
||||||
|
|
||||||
mozRequestAnimationFrame(moveSomething);
|
requestAnimationFrame(moveSomething);
|
||||||
}
|
}
|
||||||
|
|
||||||
function paintCanvas() {
|
function paintCanvas() {
|
||||||
|
@ -52,7 +52,7 @@ function moveSomething() {
|
||||||
return finish();
|
return finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
mozRequestAnimationFrame(moveSomething);
|
requestAnimationFrame(moveSomething);
|
||||||
}
|
}
|
||||||
|
|
||||||
function finish() {
|
function finish() {
|
||||||
|
|
|
@ -1619,9 +1619,9 @@ PromiseWorkerProxy::RunCallback(JSContext* aCx,
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
MutexAutoLock lock(mCleanUpLock);
|
MutexAutoLock lock(GetCleanUpLock());
|
||||||
// If the worker thread's been cancelled we don't need to resolve the Promise.
|
// If the worker thread's been cancelled we don't need to resolve the Promise.
|
||||||
if (mCleanedUp) {
|
if (IsClean()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,10 @@ var MockServices = (function () {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
listener.observe(null, "alertshow", cookie);
|
listener.observe(null, "alertshow", cookie);
|
||||||
}, 100);
|
}, 100);
|
||||||
|
setTimeout(function () {
|
||||||
|
listener.observe(null, "alertclickcallback", cookie);
|
||||||
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ?? SpecialPowers.wrap(alertListener).observe(null, "alertclickcallback", cookie);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
showAppNotification: function(aImageUrl, aTitle, aText, aAlertListener, aDetails) {
|
showAppNotification: function(aImageUrl, aTitle, aText, aAlertListener, aDetails) {
|
||||||
|
|
|
@ -68,7 +68,7 @@ dictionary NotificationOptions {
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary GetNotificationOptions {
|
dictionary GetNotificationOptions {
|
||||||
DOMString tag;
|
DOMString tag = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary NotificationBehavior {
|
dictionary NotificationBehavior {
|
||||||
|
@ -93,3 +93,9 @@ enum NotificationDirection {
|
||||||
"rtl"
|
"rtl"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
partial interface ServiceWorkerRegistration {
|
||||||
|
[Throws]
|
||||||
|
Promise<void> showNotification(DOMString title, optional NotificationOptions options);
|
||||||
|
[Throws]
|
||||||
|
Promise<sequence<Notification>> getNotifications(optional GetNotificationOptions filter);
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* The origin of this IDL file is
|
||||||
|
* http://notifications.spec.whatwg.org/
|
||||||
|
*
|
||||||
|
* Copyright:
|
||||||
|
* To the extent possible under law, the editors have waived all copyright and
|
||||||
|
* related or neighboring rights to this work.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[Constructor(DOMString type, optional NotificationEventInit eventInitDict),
|
||||||
|
Exposed=ServiceWorker,Func="mozilla::dom::Notification::PrefEnabled"]
|
||||||
|
interface NotificationEvent : ExtendableEvent {
|
||||||
|
readonly attribute Notification notification;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary NotificationEventInit : ExtendableEventInit {
|
||||||
|
required Notification notification;
|
||||||
|
};
|
||||||
|
|
||||||
|
partial interface ServiceWorkerGlobalScope {
|
||||||
|
attribute EventHandler onnotificationclick;
|
||||||
|
};
|
|
@ -12,7 +12,7 @@
|
||||||
// https://github.com/slightlyoff/ServiceWorker/issues/189
|
// https://github.com/slightlyoff/ServiceWorker/issues/189
|
||||||
[Func="mozilla::dom::workers::ServiceWorkerVisible",
|
[Func="mozilla::dom::workers::ServiceWorkerVisible",
|
||||||
// FIXME(nsm): Bug 1113522. This is exposed to satisfy webidl constraints, but it won't actually work.
|
// FIXME(nsm): Bug 1113522. This is exposed to satisfy webidl constraints, but it won't actually work.
|
||||||
Exposed=(Worker,Window)]
|
Exposed=(Window,Worker)]
|
||||||
interface ServiceWorker : EventTarget {
|
interface ServiceWorker : EventTarget {
|
||||||
readonly attribute USVString scriptURL;
|
readonly attribute USVString scriptURL;
|
||||||
readonly attribute ServiceWorkerState state;
|
readonly attribute ServiceWorkerState state;
|
||||||
|
|
|
@ -335,6 +335,7 @@ WEBIDL_FILES = [
|
||||||
'NodeIterator.webidl',
|
'NodeIterator.webidl',
|
||||||
'NodeList.webidl',
|
'NodeList.webidl',
|
||||||
'Notification.webidl',
|
'Notification.webidl',
|
||||||
|
'NotificationEvent.webidl',
|
||||||
'NotifyPaintEvent.webidl',
|
'NotifyPaintEvent.webidl',
|
||||||
'OfflineAudioCompletionEvent.webidl',
|
'OfflineAudioCompletionEvent.webidl',
|
||||||
'OfflineAudioContext.webidl',
|
'OfflineAudioContext.webidl',
|
||||||
|
|
|
@ -66,7 +66,6 @@ using mozilla::dom::cache::Cache;
|
||||||
using mozilla::dom::cache::CacheStorage;
|
using mozilla::dom::cache::CacheStorage;
|
||||||
using mozilla::dom::Promise;
|
using mozilla::dom::Promise;
|
||||||
using mozilla::dom::PromiseNativeHandler;
|
using mozilla::dom::PromiseNativeHandler;
|
||||||
using mozilla::dom::workers::exceptions::ThrowDOMExceptionForNSResult;
|
|
||||||
using mozilla::ErrorResult;
|
using mozilla::ErrorResult;
|
||||||
using mozilla::ipc::PrincipalInfo;
|
using mozilla::ipc::PrincipalInfo;
|
||||||
using mozilla::UniquePtr;
|
using mozilla::UniquePtr;
|
||||||
|
@ -151,13 +150,6 @@ ChannelFromScriptURL(nsIPrincipal* principal,
|
||||||
return NS_ERROR_DOM_SECURITY_ERR;
|
return NS_ERROR_DOM_SECURITY_ERR;
|
||||||
}
|
}
|
||||||
} else if (aIsMainScript) {
|
} else if (aIsMainScript) {
|
||||||
// If this script loader is being used to make a new worker then we need
|
|
||||||
// to do a same-origin check. Otherwise we need to clear the load with the
|
|
||||||
// security manager.
|
|
||||||
nsCString scheme;
|
|
||||||
rv = uri->GetScheme(scheme);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// We pass true as the 3rd argument to checkMayLoad here.
|
// We pass true as the 3rd argument to checkMayLoad here.
|
||||||
// This allows workers in sandboxed documents to load data URLs
|
// This allows workers in sandboxed documents to load data URLs
|
||||||
// (and other URLs that inherit their principal from their
|
// (and other URLs that inherit their principal from their
|
||||||
|
@ -283,6 +275,8 @@ struct ScriptLoadInfo
|
||||||
|
|
||||||
CacheStatus mCacheStatus;
|
CacheStatus mCacheStatus;
|
||||||
|
|
||||||
|
Maybe<bool> mMutedErrorFlag;
|
||||||
|
|
||||||
bool Finished() const
|
bool Finished() const
|
||||||
{
|
{
|
||||||
return mLoadingFinished && !mCachePromise && !mChannel;
|
return mLoadingFinished && !mCachePromise && !mChannel;
|
||||||
|
@ -955,12 +949,33 @@ private:
|
||||||
|
|
||||||
NS_ASSERTION(aString, "This should never be null!");
|
NS_ASSERTION(aString, "This should never be null!");
|
||||||
|
|
||||||
// Make sure we're not seeing the result of a 404 or something by checking
|
|
||||||
// the 'requestSucceeded' attribute on the http channel.
|
|
||||||
nsCOMPtr<nsIRequest> request;
|
nsCOMPtr<nsIRequest> request;
|
||||||
nsresult rv = aLoader->GetRequest(getter_AddRefs(request));
|
nsresult rv = aLoader->GetRequest(getter_AddRefs(request));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
||||||
|
MOZ_ASSERT(channel);
|
||||||
|
|
||||||
|
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
||||||
|
NS_ASSERTION(ssm, "Should never be null!");
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPrincipal> channelPrincipal;
|
||||||
|
rv = ssm->GetChannelResultPrincipal(channel, getter_AddRefs(channelPrincipal));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIPrincipal* principal = mWorkerPrivate->GetPrincipal();
|
||||||
|
if (!principal) {
|
||||||
|
WorkerPrivate* parentWorker = mWorkerPrivate->GetParent();
|
||||||
|
MOZ_ASSERT(parentWorker, "Must have a parent!");
|
||||||
|
principal = parentWorker->GetPrincipal();
|
||||||
|
}
|
||||||
|
|
||||||
|
aLoadInfo.mMutedErrorFlag.emplace(principal->Subsumes(channelPrincipal));
|
||||||
|
|
||||||
|
// Make sure we're not seeing the result of a 404 or something by checking
|
||||||
|
// the 'requestSucceeded' attribute on the http channel.
|
||||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(request);
|
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(request);
|
||||||
if (httpChannel) {
|
if (httpChannel) {
|
||||||
bool requestSucceeded;
|
bool requestSucceeded;
|
||||||
|
@ -996,9 +1011,6 @@ private:
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
|
||||||
NS_ASSERTION(channel, "This should never fail!");
|
|
||||||
|
|
||||||
// Figure out what we actually loaded.
|
// Figure out what we actually loaded.
|
||||||
nsCOMPtr<nsIURI> finalURI;
|
nsCOMPtr<nsIURI> finalURI;
|
||||||
rv = NS_GetFinalChannelURI(channel, getter_AddRefs(finalURI));
|
rv = NS_GetFinalChannelURI(channel, getter_AddRefs(finalURI));
|
||||||
|
@ -1104,6 +1116,18 @@ private:
|
||||||
ScriptLoadInfo& loadInfo = mLoadInfos[aIndex];
|
ScriptLoadInfo& loadInfo = mLoadInfos[aIndex];
|
||||||
MOZ_ASSERT(loadInfo.mCacheStatus == ScriptLoadInfo::Cached);
|
MOZ_ASSERT(loadInfo.mCacheStatus == ScriptLoadInfo::Cached);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPrincipal> responsePrincipal =
|
||||||
|
PrincipalInfoToPrincipal(*aPrincipalInfo);
|
||||||
|
|
||||||
|
nsIPrincipal* principal = mWorkerPrivate->GetPrincipal();
|
||||||
|
if (!principal) {
|
||||||
|
WorkerPrivate* parentWorker = mWorkerPrivate->GetParent();
|
||||||
|
MOZ_ASSERT(parentWorker, "Must have a parent!");
|
||||||
|
principal = parentWorker->GetPrincipal();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadInfo.mMutedErrorFlag.emplace(principal->Subsumes(responsePrincipal));
|
||||||
|
|
||||||
// May be null.
|
// May be null.
|
||||||
nsIDocument* parentDoc = mWorkerPrivate->GetDocument();
|
nsIDocument* parentDoc = mWorkerPrivate->GetDocument();
|
||||||
|
|
||||||
|
@ -1126,8 +1150,6 @@ private:
|
||||||
nsILoadGroup* loadGroup = mWorkerPrivate->GetLoadGroup();
|
nsILoadGroup* loadGroup = mWorkerPrivate->GetLoadGroup();
|
||||||
MOZ_ASSERT(loadGroup);
|
MOZ_ASSERT(loadGroup);
|
||||||
|
|
||||||
nsCOMPtr<nsIPrincipal> responsePrincipal =
|
|
||||||
PrincipalInfoToPrincipal(*aPrincipalInfo);
|
|
||||||
mozilla::DebugOnly<bool> equal = false;
|
mozilla::DebugOnly<bool> equal = false;
|
||||||
MOZ_ASSERT(responsePrincipal && NS_SUCCEEDED(responsePrincipal->Equals(principal, &equal)));
|
MOZ_ASSERT(responsePrincipal && NS_SUCCEEDED(responsePrincipal->Equals(principal, &equal)));
|
||||||
MOZ_ASSERT(equal);
|
MOZ_ASSERT(equal);
|
||||||
|
@ -1567,7 +1589,7 @@ CacheScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aCont
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChannelGetterRunnable final : public nsRunnable
|
class ChannelGetterRunnable final : public nsRunnable
|
||||||
{
|
{
|
||||||
WorkerPrivate* mParentWorker;
|
WorkerPrivate* mParentWorker;
|
||||||
nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
|
nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
|
||||||
|
@ -1720,6 +1742,9 @@ ScriptExecutorRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||||
options.setVersion(JSVERSION_LATEST);
|
options.setVersion(JSVERSION_LATEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(loadInfo.mMutedErrorFlag.isSome());
|
||||||
|
options.setMutedErrors(loadInfo.mMutedErrorFlag.valueOr(true));
|
||||||
|
|
||||||
JS::SourceBufferHolder srcBuf(loadInfo.mScriptTextBuf,
|
JS::SourceBufferHolder srcBuf(loadInfo.mScriptTextBuf,
|
||||||
loadInfo.mScriptTextLength,
|
loadInfo.mScriptTextLength,
|
||||||
JS::SourceBufferHolder::GiveOwnership);
|
JS::SourceBufferHolder::GiveOwnership);
|
||||||
|
|
|
@ -79,16 +79,19 @@ namespace {
|
||||||
class CancelChannelRunnable final : public nsRunnable
|
class CancelChannelRunnable final : public nsRunnable
|
||||||
{
|
{
|
||||||
nsMainThreadPtrHandle<nsIInterceptedChannel> mChannel;
|
nsMainThreadPtrHandle<nsIInterceptedChannel> mChannel;
|
||||||
|
const nsresult mStatus;
|
||||||
public:
|
public:
|
||||||
explicit CancelChannelRunnable(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel)
|
CancelChannelRunnable(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
|
||||||
|
nsresult aStatus)
|
||||||
: mChannel(aChannel)
|
: mChannel(aChannel)
|
||||||
|
, mStatus(aStatus)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD Run()
|
NS_IMETHOD Run()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
nsresult rv = mChannel->Cancel();
|
nsresult rv = mChannel->Cancel(mStatus);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -146,15 +149,17 @@ class RespondWithHandler final : public PromiseNativeHandler
|
||||||
nsMainThreadPtrHandle<nsIInterceptedChannel> mInterceptedChannel;
|
nsMainThreadPtrHandle<nsIInterceptedChannel> mInterceptedChannel;
|
||||||
nsMainThreadPtrHandle<ServiceWorker> mServiceWorker;
|
nsMainThreadPtrHandle<ServiceWorker> mServiceWorker;
|
||||||
RequestMode mRequestMode;
|
RequestMode mRequestMode;
|
||||||
|
bool mIsClientRequest;
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
RespondWithHandler(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
|
RespondWithHandler(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
|
||||||
nsMainThreadPtrHandle<ServiceWorker>& aServiceWorker,
|
nsMainThreadPtrHandle<ServiceWorker>& aServiceWorker,
|
||||||
RequestMode aRequestMode)
|
RequestMode aRequestMode, bool aIsClientRequest)
|
||||||
: mInterceptedChannel(aChannel)
|
: mInterceptedChannel(aChannel)
|
||||||
, mServiceWorker(aServiceWorker)
|
, mServiceWorker(aServiceWorker)
|
||||||
, mRequestMode(aRequestMode)
|
, mRequestMode(aRequestMode)
|
||||||
|
, mIsClientRequest(aIsClientRequest)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +167,7 @@ public:
|
||||||
|
|
||||||
void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
|
void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
|
||||||
|
|
||||||
void CancelRequest();
|
void CancelRequest(nsresult aStatus);
|
||||||
private:
|
private:
|
||||||
~RespondWithHandler() {}
|
~RespondWithHandler() {}
|
||||||
};
|
};
|
||||||
|
@ -192,7 +197,8 @@ void RespondWithCopyComplete(void* aClosure, nsresult aStatus)
|
||||||
data->mInternalResponse,
|
data->mInternalResponse,
|
||||||
data->mWorkerChannelInfo);
|
data->mWorkerChannelInfo);
|
||||||
} else {
|
} else {
|
||||||
event = new CancelChannelRunnable(data->mInterceptedChannel);
|
event = new CancelChannelRunnable(data->mInterceptedChannel,
|
||||||
|
NS_ERROR_INTERCEPTION_FAILED);
|
||||||
}
|
}
|
||||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(event)));
|
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(event)));
|
||||||
}
|
}
|
||||||
|
@ -200,20 +206,28 @@ void RespondWithCopyComplete(void* aClosure, nsresult aStatus)
|
||||||
class MOZ_STACK_CLASS AutoCancel
|
class MOZ_STACK_CLASS AutoCancel
|
||||||
{
|
{
|
||||||
nsRefPtr<RespondWithHandler> mOwner;
|
nsRefPtr<RespondWithHandler> mOwner;
|
||||||
|
nsresult mStatus;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AutoCancel(RespondWithHandler* aOwner)
|
explicit AutoCancel(RespondWithHandler* aOwner)
|
||||||
: mOwner(aOwner)
|
: mOwner(aOwner)
|
||||||
|
, mStatus(NS_ERROR_INTERCEPTION_FAILED)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~AutoCancel()
|
~AutoCancel()
|
||||||
{
|
{
|
||||||
if (mOwner) {
|
if (mOwner) {
|
||||||
mOwner->CancelRequest();
|
mOwner->CancelRequest(mStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetCancelStatus(nsresult aStatus)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_FAILED(aStatus));
|
||||||
|
mStatus = aStatus;
|
||||||
|
}
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
mOwner = nullptr;
|
mOwner = nullptr;
|
||||||
|
@ -246,17 +260,35 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
||||||
// security implications are not a complete disaster.
|
// security implications are not a complete disaster.
|
||||||
if (response->Type() == ResponseType::Opaque &&
|
if (response->Type() == ResponseType::Opaque &&
|
||||||
!worker->OpaqueInterceptionEnabled()) {
|
!worker->OpaqueInterceptionEnabled()) {
|
||||||
|
autoCancel.SetCancelStatus(NS_ERROR_OPAQUE_INTERCEPTION_DISABLED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Section 4.2, step 2.2 "If either response's type is "opaque" and request's
|
// Section 4.2, step 2.2:
|
||||||
// mode is not "no-cors" or response's type is error, return a network error."
|
// If one of the following conditions is true, return a network error:
|
||||||
if (((response->Type() == ResponseType::Opaque) && (mRequestMode != RequestMode::No_cors)) ||
|
// * response's type is "error".
|
||||||
response->Type() == ResponseType::Error) {
|
// * request's mode is not "no-cors" and response's type is "opaque".
|
||||||
|
// * request is a client request and response's type is neither "basic"
|
||||||
|
// nor "default".
|
||||||
|
|
||||||
|
if (response->Type() == ResponseType::Error) {
|
||||||
|
autoCancel.SetCancelStatus(NS_ERROR_INTERCEPTED_ERROR_RESPONSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response->Type() == ResponseType::Opaque && mRequestMode != RequestMode::No_cors) {
|
||||||
|
autoCancel.SetCancelStatus(NS_ERROR_BAD_OPAQUE_INTERCEPTION_REQUEST_MODE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mIsClientRequest && response->Type() != ResponseType::Basic &&
|
||||||
|
response->Type() != ResponseType::Default) {
|
||||||
|
autoCancel.SetCancelStatus(NS_ERROR_CLIENT_REQUEST_OPAQUE_INTERCEPTION);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_WARN_IF(response->BodyUsed())) {
|
if (NS_WARN_IF(response->BodyUsed())) {
|
||||||
|
autoCancel.SetCancelStatus(NS_ERROR_INTERCEPTED_USED_RESPONSE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,13 +334,14 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
||||||
void
|
void
|
||||||
RespondWithHandler::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
RespondWithHandler::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
||||||
{
|
{
|
||||||
CancelRequest();
|
CancelRequest(NS_ERROR_INTERCEPTION_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RespondWithHandler::CancelRequest()
|
RespondWithHandler::CancelRequest(nsresult aStatus)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIRunnable> runnable = new CancelChannelRunnable(mInterceptedChannel);
|
nsCOMPtr<nsIRunnable> runnable =
|
||||||
|
new CancelChannelRunnable(mInterceptedChannel, aStatus);
|
||||||
NS_DispatchToMainThread(runnable);
|
NS_DispatchToMainThread(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,9 +370,11 @@ FetchEvent::RespondWith(const ResponseOrPromise& aArg, ErrorResult& aRv)
|
||||||
} else if (aArg.IsPromise()) {
|
} else if (aArg.IsPromise()) {
|
||||||
promise = &aArg.GetAsPromise();
|
promise = &aArg.GetAsPromise();
|
||||||
}
|
}
|
||||||
|
nsRefPtr<InternalRequest> ir = mRequest->GetInternalRequest();
|
||||||
mWaitToRespond = true;
|
mWaitToRespond = true;
|
||||||
nsRefPtr<RespondWithHandler> handler =
|
nsRefPtr<RespondWithHandler> handler =
|
||||||
new RespondWithHandler(mChannel, mServiceWorker, mRequest->Mode());
|
new RespondWithHandler(mChannel, mServiceWorker, mRequest->Mode(),
|
||||||
|
ir->IsClientRequest());
|
||||||
promise->AppendNativeHandler(handler);
|
promise->AppendNativeHandler(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "mozilla/dom/indexedDB/IDBFactory.h"
|
#include "mozilla/dom/indexedDB/IDBFactory.h"
|
||||||
#include "mozilla/dom/InternalHeaders.h"
|
#include "mozilla/dom/InternalHeaders.h"
|
||||||
#include "mozilla/dom/Navigator.h"
|
#include "mozilla/dom/Navigator.h"
|
||||||
|
#include "mozilla/dom/NotificationEvent.h"
|
||||||
#include "mozilla/dom/PromiseNativeHandler.h"
|
#include "mozilla/dom/PromiseNativeHandler.h"
|
||||||
#include "mozilla/dom/Request.h"
|
#include "mozilla/dom/Request.h"
|
||||||
#include "mozilla/dom/RootedDictionary.h"
|
#include "mozilla/dom/RootedDictionary.h"
|
||||||
|
@ -2282,6 +2283,133 @@ ServiceWorkerManager::SendPushSubscriptionChangeEvent(const nsACString& aOriginA
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SendNotificationClickEventRunnable final : public WorkerRunnable
|
||||||
|
{
|
||||||
|
nsMainThreadPtrHandle<ServiceWorker> mServiceWorker;
|
||||||
|
const nsString mID;
|
||||||
|
const nsString mTitle;
|
||||||
|
const nsString mDir;
|
||||||
|
const nsString mLang;
|
||||||
|
const nsString mBody;
|
||||||
|
const nsString mTag;
|
||||||
|
const nsString mIcon;
|
||||||
|
const nsString mData;
|
||||||
|
const nsString mBehavior;
|
||||||
|
const nsString mScope;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SendNotificationClickEventRunnable(
|
||||||
|
WorkerPrivate* aWorkerPrivate,
|
||||||
|
nsMainThreadPtrHandle<ServiceWorker>& aServiceWorker,
|
||||||
|
const nsAString& aID,
|
||||||
|
const nsAString& aTitle,
|
||||||
|
const nsAString& aDir,
|
||||||
|
const nsAString& aLang,
|
||||||
|
const nsAString& aBody,
|
||||||
|
const nsAString& aTag,
|
||||||
|
const nsAString& aIcon,
|
||||||
|
const nsAString& aData,
|
||||||
|
const nsAString& aBehavior,
|
||||||
|
const nsAString& aScope)
|
||||||
|
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
|
||||||
|
, mServiceWorker(aServiceWorker)
|
||||||
|
, mID(aID)
|
||||||
|
, mTitle(aTitle)
|
||||||
|
, mDir(aDir)
|
||||||
|
, mLang(aLang)
|
||||||
|
, mBody(aBody)
|
||||||
|
, mTag(aTag)
|
||||||
|
, mIcon(aIcon)
|
||||||
|
, mData(aData)
|
||||||
|
, mBehavior(aBehavior)
|
||||||
|
, mScope(aScope)
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(aWorkerPrivate);
|
||||||
|
MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aWorkerPrivate);
|
||||||
|
|
||||||
|
nsRefPtr<EventTarget> target = do_QueryObject(aWorkerPrivate->GlobalScope());
|
||||||
|
|
||||||
|
ErrorResult result;
|
||||||
|
nsRefPtr<Notification> notification =
|
||||||
|
Notification::ConstructFromFields(aWorkerPrivate->GlobalScope(), mID,
|
||||||
|
mTitle, mDir, mLang, mBody, mTag, mIcon,
|
||||||
|
mData, mScope, result);
|
||||||
|
if (NS_WARN_IF(result.Failed())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationEventInit nei;
|
||||||
|
nei.mNotification = notification;
|
||||||
|
nei.mBubbles = false;
|
||||||
|
nei.mCancelable = true;
|
||||||
|
|
||||||
|
nsRefPtr<NotificationEvent> event =
|
||||||
|
NotificationEvent::Constructor(target, NS_LITERAL_STRING("notificationclick"), nei, result);
|
||||||
|
if (NS_WARN_IF(result.Failed())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
event->SetTrusted(true);
|
||||||
|
nsRefPtr<Promise> waitUntilPromise =
|
||||||
|
DispatchExtendableEventOnWorkerScope(aCx, aWorkerPrivate->GlobalScope(), event);
|
||||||
|
|
||||||
|
if (waitUntilPromise) {
|
||||||
|
nsRefPtr<KeepAliveHandler> handler = new KeepAliveHandler(mServiceWorker);
|
||||||
|
waitUntilPromise->AppendNativeHandler(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
ServiceWorkerManager::SendNotificationClickEvent(const nsACString& aOriginSuffix,
|
||||||
|
const nsACString& aScope,
|
||||||
|
const nsAString& aID,
|
||||||
|
const nsAString& aTitle,
|
||||||
|
const nsAString& aDir,
|
||||||
|
const nsAString& aLang,
|
||||||
|
const nsAString& aBody,
|
||||||
|
const nsAString& aTag,
|
||||||
|
const nsAString& aIcon,
|
||||||
|
const nsAString& aData,
|
||||||
|
const nsAString& aBehavior)
|
||||||
|
{
|
||||||
|
OriginAttributes attrs;
|
||||||
|
if (!attrs.PopulateFromSuffix(aOriginSuffix)) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<ServiceWorker> serviceWorker = CreateServiceWorkerForScope(attrs, aScope);
|
||||||
|
if (!serviceWorker) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
nsMainThreadPtrHandle<ServiceWorker> serviceWorkerHandle(
|
||||||
|
new nsMainThreadPtrHolder<ServiceWorker>(serviceWorker));
|
||||||
|
|
||||||
|
nsRefPtr<SendNotificationClickEventRunnable> r =
|
||||||
|
new SendNotificationClickEventRunnable(serviceWorker->GetWorkerPrivate(),
|
||||||
|
serviceWorkerHandle, aID, aTitle,
|
||||||
|
aDir, aLang, aBody, aTag, aIcon,
|
||||||
|
aData, aBehavior,
|
||||||
|
NS_ConvertUTF8toUTF16(aScope));
|
||||||
|
|
||||||
|
AutoJSAPI jsapi;
|
||||||
|
jsapi.Init();
|
||||||
|
if (NS_WARN_IF(!r->Dispatch(jsapi.cx()))) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
ServiceWorkerManager::GetReadyPromise(nsIDOMWindow* aWindow,
|
ServiceWorkerManager::GetReadyPromise(nsIDOMWindow* aWindow,
|
||||||
nsISupports** aPromise)
|
nsISupports** aPromise)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "ServiceWorkerRegistration.h"
|
#include "ServiceWorkerRegistration.h"
|
||||||
|
|
||||||
|
#include "mozilla/dom/Notification.h"
|
||||||
#include "mozilla/dom/Promise.h"
|
#include "mozilla/dom/Promise.h"
|
||||||
#include "mozilla/dom/PromiseWorkerProxy.h"
|
#include "mozilla/dom/PromiseWorkerProxy.h"
|
||||||
#include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
|
#include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
|
||||||
|
@ -595,6 +596,52 @@ ServiceWorkerRegistrationMainThread::Unregister(ErrorResult& aRv)
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notification API extension.
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
ServiceWorkerRegistrationMainThread::ShowNotification(JSContext* aCx,
|
||||||
|
const nsAString& aTitle,
|
||||||
|
const NotificationOptions& aOptions,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(GetOwner());
|
||||||
|
nsCOMPtr<nsPIDOMWindow> window = GetOwner();
|
||||||
|
if (NS_WARN_IF(!window)) {
|
||||||
|
aRv.Throw(NS_ERROR_FAILURE);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
|
||||||
|
if (NS_WARN_IF(!doc)) {
|
||||||
|
aRv.Throw(NS_ERROR_FAILURE);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<workers::ServiceWorker> worker = GetActive();
|
||||||
|
if (!worker) {
|
||||||
|
aRv.ThrowTypeError(MSG_NO_ACTIVE_WORKER);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
|
||||||
|
nsRefPtr<Promise> p =
|
||||||
|
Notification::ShowPersistentNotification(global,
|
||||||
|
mScope, aTitle, aOptions, aRv);
|
||||||
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
ServiceWorkerRegistrationMainThread::GetNotifications(const GetNotificationOptions& aOptions, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
nsCOMPtr<nsPIDOMWindow> window = GetOwner();
|
||||||
|
return Notification::Get(window, aOptions, mScope, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<PushManager>
|
already_AddRefed<PushManager>
|
||||||
ServiceWorkerRegistrationMainThread::GetPushManager(ErrorResult& aRv)
|
ServiceWorkerRegistrationMainThread::GetPushManager(ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
|
@ -1001,5 +1048,32 @@ WorkerListener::UpdateFound()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dom
|
// Notification API extension.
|
||||||
} // namespace mozilla
|
already_AddRefed<Promise>
|
||||||
|
ServiceWorkerRegistrationWorkerThread::ShowNotification(JSContext* aCx,
|
||||||
|
const nsAString& aTitle,
|
||||||
|
const NotificationOptions& aOptions,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
// Until Bug 1131324 exposes ServiceWorkerContainer on workers,
|
||||||
|
// ShowPersistentNotification() checks for valid active worker while it is
|
||||||
|
// also verifying scope so that we block the worker on the main thread only
|
||||||
|
// once.
|
||||||
|
nsRefPtr<Promise> p =
|
||||||
|
Notification::ShowPersistentNotification(mWorkerPrivate->GlobalScope(),
|
||||||
|
mScope, aTitle, aOptions, aRv);
|
||||||
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
ServiceWorkerRegistrationWorkerThread::GetNotifications(const GetNotificationOptions& aOptions, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
return Notification::WorkerGet(mWorkerPrivate, aOptions, mScope, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // dom namespace
|
||||||
|
} // mozilla namespace
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
#include "mozilla/dom/ServiceWorkerCommon.h"
|
#include "mozilla/dom/ServiceWorkerCommon.h"
|
||||||
#include "mozilla/dom/workers/bindings/WorkerFeature.h"
|
#include "mozilla/dom/workers/bindings/WorkerFeature.h"
|
||||||
|
|
||||||
|
// Support for Notification API extension.
|
||||||
|
#include "mozilla/dom/NotificationBinding.h"
|
||||||
|
|
||||||
class nsPIDOMWindow;
|
class nsPIDOMWindow;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
@ -111,6 +114,16 @@ public:
|
||||||
JSObject*
|
JSObject*
|
||||||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
|
// Partial interface from Notification API.
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
ShowNotification(JSContext* aCx,
|
||||||
|
const nsAString& aTitle,
|
||||||
|
const NotificationOptions& aOptions,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
GetNotifications(const GetNotificationOptions& aOptions, ErrorResult& aRv);
|
||||||
|
|
||||||
already_AddRefed<workers::ServiceWorker>
|
already_AddRefed<workers::ServiceWorker>
|
||||||
GetInstalling() override;
|
GetInstalling() override;
|
||||||
|
|
||||||
|
@ -190,6 +203,16 @@ public:
|
||||||
JSObject*
|
JSObject*
|
||||||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
|
// Partial interface from Notification API.
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
ShowNotification(JSContext* aCx,
|
||||||
|
const nsAString& aTitle,
|
||||||
|
const NotificationOptions& aOptions,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
GetNotifications(const GetNotificationOptions& aOptions, ErrorResult& aRv);
|
||||||
|
|
||||||
already_AddRefed<workers::ServiceWorker>
|
already_AddRefed<workers::ServiceWorker>
|
||||||
GetInstalling() override;
|
GetInstalling() override;
|
||||||
|
|
||||||
|
|
|
@ -208,6 +208,7 @@ public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerGlobalScope,
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerGlobalScope,
|
||||||
WorkerGlobalScope)
|
WorkerGlobalScope)
|
||||||
|
IMPL_EVENT_HANDLER(notificationclick)
|
||||||
|
|
||||||
ServiceWorkerGlobalScope(WorkerPrivate* aWorkerPrivate, const nsACString& aScope);
|
ServiceWorkerGlobalScope(WorkerPrivate* aWorkerPrivate, const nsACString& aScope);
|
||||||
|
|
||||||
|
|
Двоичные данные
dom/workers/test/serviceworkers/app-protocol/application.zip
Двоичные данные
dom/workers/test/serviceworkers/app-protocol/application.zip
Двоичный файл не отображается.
|
@ -21,10 +21,12 @@ function runTests() {
|
||||||
return testFetchAppResource('test_custom_content_type',
|
return testFetchAppResource('test_custom_content_type',
|
||||||
'customContentType', 'text/html');
|
'customContentType', 'text/html');
|
||||||
})
|
})
|
||||||
.then(testRedirectedResponse)
|
// XXX: Cross-origin interceptions without CORS result in opaque responses
|
||||||
.then(testRedirectedHttpsResponse)
|
// which are illegal for navigations like iframes. (bug 1183313)
|
||||||
.then(testCachedRedirectedResponse)
|
//.then(testRedirectedResponse)
|
||||||
.then(testCachedRedirectedHttpsResponse)
|
//.then(testRedirectedHttpsResponse)
|
||||||
|
//.then(testCachedRedirectedResponse)
|
||||||
|
//.then(testCachedRedirectedHttpsResponse)
|
||||||
.then(done);
|
.then(done);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -93,6 +93,8 @@ support-files =
|
||||||
client_focus_worker.js
|
client_focus_worker.js
|
||||||
bug1151916_worker.js
|
bug1151916_worker.js
|
||||||
bug1151916_driver.html
|
bug1151916_driver.html
|
||||||
|
notificationclick.html
|
||||||
|
notificationclick.js
|
||||||
worker_updatefoundevent.js
|
worker_updatefoundevent.js
|
||||||
worker_updatefoundevent2.js
|
worker_updatefoundevent2.js
|
||||||
updatefoundevent.html
|
updatefoundevent.html
|
||||||
|
@ -103,6 +105,11 @@ support-files =
|
||||||
periodic/register.html
|
periodic/register.html
|
||||||
periodic/wait_for_update.html
|
periodic/wait_for_update.html
|
||||||
periodic/unregister.html
|
periodic/unregister.html
|
||||||
|
notification_constructor_error.js
|
||||||
|
notification_get_sw.js
|
||||||
|
notification/register.html
|
||||||
|
notification/listener.html
|
||||||
|
notification_alt/register.html
|
||||||
sanitize/frame.html
|
sanitize/frame.html
|
||||||
sanitize/register.html
|
sanitize/register.html
|
||||||
sanitize/example_check_and_unregister.html
|
sanitize/example_check_and_unregister.html
|
||||||
|
@ -217,6 +224,9 @@ skip-if = !debug
|
||||||
[test_request_context_xslt.html]
|
[test_request_context_xslt.html]
|
||||||
[test_scopes.html]
|
[test_scopes.html]
|
||||||
[test_sandbox_intercept.html]
|
[test_sandbox_intercept.html]
|
||||||
|
[test_notificationclick.html]
|
||||||
|
[test_notification_constructor_error.html]
|
||||||
|
[test_notification_get.html]
|
||||||
[test_sanitize.html]
|
[test_sanitize.html]
|
||||||
[test_sanitize_domain.html]
|
[test_sanitize_domain.html]
|
||||||
[test_service_worker_allowed.html]
|
[test_service_worker_allowed.html]
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
<!--
|
||||||
|
Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
-->
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Bug 1114554 - proxy to forward messages from SW to test</title>
|
||||||
|
<script class="testbody" type="text/javascript">
|
||||||
|
var testWindow = parent;
|
||||||
|
if (opener) {
|
||||||
|
testWindow = opener;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigator.serviceWorker.onmessage = function(msg) {
|
||||||
|
// worker message;
|
||||||
|
testWindow.postMessage(msg.data, "*");
|
||||||
|
if (msg.data.type == 'finish') {
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<script>
|
||||||
|
function done() {
|
||||||
|
parent.callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
navigator.serviceWorker.ready.then(done);
|
||||||
|
navigator.serviceWorker.register("../notification_get_sw.js", {scope: "."}).catch(function(e) {
|
||||||
|
dump("Registration failure " + e.message + "\n");
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<script>
|
||||||
|
function done() {
|
||||||
|
parent.callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
navigator.serviceWorker.ready.then(done);
|
||||||
|
navigator.serviceWorker.register("../notification_get_sw.js", {scope: "."}).catch(function(e) {
|
||||||
|
dump("Registration failure " + e.message + "\n");
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1 @@
|
||||||
|
new Notification("Hi there");
|
|
@ -0,0 +1,49 @@
|
||||||
|
function postAll(data) {
|
||||||
|
self.clients.matchAll().then(function(clients) {
|
||||||
|
if (clients.length == 0) {
|
||||||
|
dump("***************** NO CLIENTS FOUND! Test messages are being lost *******************\n");
|
||||||
|
}
|
||||||
|
clients.forEach(function(client) {
|
||||||
|
client.postMessage(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function ok(a, msg) {
|
||||||
|
postAll({type: 'status', status: !!a, msg: a + ": " + msg });
|
||||||
|
}
|
||||||
|
|
||||||
|
function is(a, b, msg) {
|
||||||
|
postAll({type: 'status', status: a === b, msg: a + " === " + b + ": " + msg });
|
||||||
|
}
|
||||||
|
|
||||||
|
function done() {
|
||||||
|
postAll({type: 'finish'});
|
||||||
|
}
|
||||||
|
|
||||||
|
onmessage = function(e) {
|
||||||
|
dump("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% MESSAGE " + e.data + "\n");
|
||||||
|
var start;
|
||||||
|
if (e.data == 'create') {
|
||||||
|
start = registration.showNotification("This is a title");
|
||||||
|
} else {
|
||||||
|
start = Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
start.then(function() {
|
||||||
|
dump("CALLING getNotification\n");
|
||||||
|
registration.getNotifications().then(function(notifications) {
|
||||||
|
dump("RECD getNotification\n");
|
||||||
|
is(notifications.length, 1, "There should be one stored notification");
|
||||||
|
var notification = notifications[0];
|
||||||
|
if (!notification) {
|
||||||
|
done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ok(notification instanceof Notification, "Should be a Notification");
|
||||||
|
is(notification.title, "This is a title", "Title should match");
|
||||||
|
notification.close();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
<!--
|
||||||
|
Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
-->
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Bug 1114554 - controlled page</title>
|
||||||
|
<script class="testbody" type="text/javascript">
|
||||||
|
var testWindow = parent;
|
||||||
|
if (opener) {
|
||||||
|
testWindow = opener;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigator.serviceWorker.ready.then(function(swr) {
|
||||||
|
swr.showNotification("Hi there. The ServiceWorker should receive a click event for this.");
|
||||||
|
});
|
||||||
|
|
||||||
|
navigator.serviceWorker.onmessage = function(msg) {
|
||||||
|
testWindow.callback();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Any copyright is dedicated to the Public Domain.
|
||||||
|
// http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
//
|
||||||
|
onnotificationclick = function(e) {
|
||||||
|
self.clients.matchAll().then(function(clients) {
|
||||||
|
if (clients.length === 0) {
|
||||||
|
dump("********************* CLIENTS LIST EMPTY! Test will timeout! ***********************\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.forEach(function(client) {
|
||||||
|
client.postMessage("done");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
<!--
|
||||||
|
Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
-->
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Bug XXXXXXX - Check that Notification constructor throws in ServiceWorkerGlobalScope</title>
|
||||||
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="text/javascript" src="/tests/dom/tests/mochitest/notification/MockServices.js"></script>
|
||||||
|
<script type="text/javascript" src="/tests/dom/tests/mochitest/notification/NotificationTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none"></div>
|
||||||
|
<pre id="test"></pre>
|
||||||
|
<script class="testbody" type="text/javascript">
|
||||||
|
|
||||||
|
function simpleRegister() {
|
||||||
|
return navigator.serviceWorker.register("notification_constructor_error.js", { scope: "notification_constructor_error/" }).then(function(swr) {
|
||||||
|
ok(false, "Registration should fail.");
|
||||||
|
}, function(e) {
|
||||||
|
ok(e.message.indexOf("Notification") != -1, "Registration should fail.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTest() {
|
||||||
|
MockServices.register();
|
||||||
|
simpleRegister()
|
||||||
|
.then(function() {
|
||||||
|
MockServices.unregister();
|
||||||
|
SimpleTest.finish();
|
||||||
|
}).catch(function(e) {
|
||||||
|
ok(false, "Some test failed with error " + e);
|
||||||
|
MockServices.unregister();
|
||||||
|
SimpleTest.finish();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
SpecialPowers.pushPrefEnv({"set": [
|
||||||
|
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||||
|
["dom.serviceWorkers.enabled", true],
|
||||||
|
["dom.serviceWorkers.testing.enabled", true],
|
||||||
|
["notification.prompt.testing", true],
|
||||||
|
]}, runTest);
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>ServiceWorkerRegistration.getNotifications() on main thread and worker thread.</title>
|
||||||
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="text/javascript" src="/tests/dom/tests/mochitest/notification/MockServices.js"></script>
|
||||||
|
<script type="text/javascript" src="/tests/dom/tests/mochitest/notification/NotificationTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none"></div>
|
||||||
|
<pre id="test"></pre>
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
SimpleTest.requestFlakyTimeout("untriaged");
|
||||||
|
|
||||||
|
function testFrame(src) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
var iframe = document.createElement("iframe");
|
||||||
|
iframe.src = src;
|
||||||
|
window.callback = function(result) {
|
||||||
|
iframe.src = "about:blank";
|
||||||
|
document.body.removeChild(iframe);
|
||||||
|
iframe = null;
|
||||||
|
SpecialPowers.exactGC(window, function() {
|
||||||
|
resolve(result);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerSW() {
|
||||||
|
return testFrame('notification/register.html').then(function() {
|
||||||
|
ok(true, "Registered service worker.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// To check that the scope is respected when retrieving notifications.
|
||||||
|
function registerAlternateSWAndAddNotification() {
|
||||||
|
return testFrame('notification_alt/register.html').then(function() {
|
||||||
|
ok(true, "Registered alternate service worker.");
|
||||||
|
return navigator.serviceWorker.getRegistration("./notification_alt/").then(function(reg) {
|
||||||
|
return reg.showNotification("This is a notification_alt");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGet() {
|
||||||
|
// Non persistent notifications will not show up in getNotification().
|
||||||
|
var n = new Notification("Scope does not match");
|
||||||
|
var options = NotificationTest.payload;
|
||||||
|
return navigator.serviceWorker.getRegistration("./notification/")
|
||||||
|
.then(function(reg) {
|
||||||
|
return reg.showNotification("This is a title", options)
|
||||||
|
.then(function() {
|
||||||
|
return reg;
|
||||||
|
});
|
||||||
|
}).then(function(reg) {
|
||||||
|
return registerAlternateSWAndAddNotification().then(function() {
|
||||||
|
return reg;
|
||||||
|
});
|
||||||
|
}).then(function(reg) {
|
||||||
|
return reg.getNotifications();
|
||||||
|
}).then(function(notifications) {
|
||||||
|
is(notifications.length, 1, "There should be one stored notification");
|
||||||
|
var notification = notifications[0];
|
||||||
|
ok(notification instanceof Notification, "Should be a Notification");
|
||||||
|
is(notification.title, "This is a title", "Title should match");
|
||||||
|
for (var key in options) {
|
||||||
|
if (key === "data") {
|
||||||
|
ok(NotificationTest.customDataMatches(notification.data),
|
||||||
|
"data property should match");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
is(notification[key], options[key], key + " property should match");
|
||||||
|
}
|
||||||
|
notification.close();
|
||||||
|
}).then(function() {
|
||||||
|
return navigator.serviceWorker.getRegistration("./notification/").then(function(reg) {
|
||||||
|
return reg.getNotifications();
|
||||||
|
});
|
||||||
|
}).then(function(notifications) {
|
||||||
|
// Make sure closed notifications are no longer retrieved.
|
||||||
|
is(notifications.length, 0, "There should be no more stored notifications");
|
||||||
|
}).catch(function(e) {
|
||||||
|
ok(false, "Something went wrong " + e.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetWorker() {
|
||||||
|
todo(false, "navigator.serviceWorker is not available on workers yet");
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
function waitForSWTests(reg, msg) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
var content = document.getElementById("content");
|
||||||
|
|
||||||
|
iframe = document.createElement("iframe");
|
||||||
|
|
||||||
|
content.appendChild(iframe);
|
||||||
|
iframe.setAttribute('src', "notification/listener.html");
|
||||||
|
|
||||||
|
window.onmessage = function(e) {
|
||||||
|
if (e.data.type == 'status') {
|
||||||
|
ok(e.data.status, "Service worker test: " + e.data.msg);
|
||||||
|
} else if (e.data.type == 'finish') {
|
||||||
|
content.removeChild(iframe);
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe.onload = function(e) {
|
||||||
|
iframe.onload = null;
|
||||||
|
reg.active.postMessage(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetServiceWorker() {
|
||||||
|
return navigator.serviceWorker.getRegistration("./notification/")
|
||||||
|
.then(function(reg) {
|
||||||
|
return waitForSWTests(reg, 'create');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a Notification here, make sure ServiceWorker sees it.
|
||||||
|
function testAcrossThreads() {
|
||||||
|
return navigator.serviceWorker.getRegistration("./notification/")
|
||||||
|
.then(function(reg) {
|
||||||
|
return reg.showNotification("This is a title")
|
||||||
|
.then(function() {
|
||||||
|
return reg;
|
||||||
|
});
|
||||||
|
}).then(function(reg) {
|
||||||
|
return waitForSWTests(reg, 'do-not-create');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
MockServices.register();
|
||||||
|
SpecialPowers.pushPrefEnv({"set": [
|
||||||
|
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||||
|
["dom.serviceWorkers.enabled", true],
|
||||||
|
["dom.serviceWorkers.testing.enabled", true],
|
||||||
|
["dom.webnotifications.workers.enabled", true],
|
||||||
|
["notification.prompt.testing", true],
|
||||||
|
]}, function() {
|
||||||
|
registerSW()
|
||||||
|
.then(testGet)
|
||||||
|
.then(testGetWorker)
|
||||||
|
.then(testGetServiceWorker)
|
||||||
|
.then(testAcrossThreads)
|
||||||
|
.then(function() {
|
||||||
|
MockServices.unregister();
|
||||||
|
SimpleTest.finish();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,56 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=916893
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<title>Bug 1114554 - Test ServiceWorkerGlobalScope.notificationclick event.</title>
|
||||||
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="text/javascript" src="/tests/dom/tests/mochitest/notification/MockServices.js"></script>
|
||||||
|
<script type="text/javascript" src="/tests/dom/tests/mochitest/notification/NotificationTest.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=1114554">Bug 1114554</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
</pre>
|
||||||
|
<script type="text/javascript">
|
||||||
|
SimpleTest.requestFlakyTimeout("Mock alert service dispatches show and click events.");
|
||||||
|
|
||||||
|
function testFrame(src) {
|
||||||
|
var iframe = document.createElement("iframe");
|
||||||
|
iframe.src = src;
|
||||||
|
window.callback = function() {
|
||||||
|
window.callback = null;
|
||||||
|
document.body.removeChild(iframe);
|
||||||
|
iframe = null;
|
||||||
|
ok(true, "Got notificationclick event.");
|
||||||
|
MockServices.unregister();
|
||||||
|
SimpleTest.finish();
|
||||||
|
};
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTest() {
|
||||||
|
MockServices.register();
|
||||||
|
testFrame('notificationclick.html');
|
||||||
|
navigator.serviceWorker.register("notificationclick.js", { scope: "notificationclick.html" }).then(function(reg) {
|
||||||
|
}, function(e) {
|
||||||
|
ok(false, "registration should have passed!");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
SpecialPowers.pushPrefEnv({"set": [
|
||||||
|
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||||
|
["dom.serviceWorkers.enabled", true],
|
||||||
|
["dom.serviceWorkers.testing.enabled", true],
|
||||||
|
["dom.webnotifications.workers.enabled", true],
|
||||||
|
["notification.prompt.testing", true],
|
||||||
|
]}, runTest);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -158,6 +158,8 @@ var interfaceNamesInGlobalScope =
|
||||||
"MessagePort",
|
"MessagePort",
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
"Notification",
|
"Notification",
|
||||||
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
|
"NotificationEvent",
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
"Performance",
|
"Performance",
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
|
|
|
@ -18,7 +18,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=916893
|
||||||
<pre id="test">
|
<pre id="test">
|
||||||
</pre>
|
</pre>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
SimpleTest.requestFlakyTimeout("Mock alert service dispatches show event.");
|
SimpleTest.requestFlakyTimeout("Mock alert service dispatches show and click events.");
|
||||||
|
|
||||||
function runTest() {
|
function runTest() {
|
||||||
MockServices.register();
|
MockServices.register();
|
||||||
|
|
|
@ -944,8 +944,6 @@ XULDocument::AttributeChanged(nsIDocument* aDocument,
|
||||||
AddElementToRefMap(aElement);
|
AddElementToRefMap(aElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
// Synchronize broadcast listeners
|
// Synchronize broadcast listeners
|
||||||
if (mBroadcasterMap &&
|
if (mBroadcasterMap &&
|
||||||
CanBroadcast(aNameSpaceID, aAttribute)) {
|
CanBroadcast(aNameSpaceID, aAttribute)) {
|
||||||
|
@ -1012,8 +1010,10 @@ XULDocument::AttributeChanged(nsIDocument* aDocument,
|
||||||
if (!persist.IsEmpty()) {
|
if (!persist.IsEmpty()) {
|
||||||
// XXXldb This should check that it's a token, not just a substring.
|
// XXXldb This should check that it's a token, not just a substring.
|
||||||
if (persist.Find(nsDependentAtomString(aAttribute)) >= 0) {
|
if (persist.Find(nsDependentAtomString(aAttribute)) >= 0) {
|
||||||
rv = Persist(aElement, kNameSpaceID_None, aAttribute);
|
nsContentUtils::AddScriptRunner(NS_NewRunnableMethodWithArgs
|
||||||
if (NS_FAILED(rv)) return;
|
<nsIContent*, int32_t, nsIAtom*>
|
||||||
|
(this, &XULDocument::DoPersist, aElement, kNameSpaceID_None,
|
||||||
|
aAttribute));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,6 +298,12 @@ protected:
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
Persist(nsIContent* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute);
|
Persist(nsIContent* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute);
|
||||||
|
// Just like Persist but ignores the return value so we can use it
|
||||||
|
// as a runnable method.
|
||||||
|
void DoPersist(nsIContent* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute)
|
||||||
|
{
|
||||||
|
Persist(aElement, aNameSpaceID, aAttribute);
|
||||||
|
}
|
||||||
|
|
||||||
virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
|
virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
|
|
|
@ -1883,6 +1883,11 @@ gfxWindowsPlatform::InitD3D11Devices()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool useWARP = false;
|
bool useWARP = false;
|
||||||
|
bool allowWARP = false;
|
||||||
|
|
||||||
|
if (IsWin8OrLater()) {
|
||||||
|
allowWARP = true;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
|
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
|
||||||
if (gfxInfo) {
|
if (gfxInfo) {
|
||||||
|
@ -1906,7 +1911,7 @@ gfxWindowsPlatform::InitD3D11Devices()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
useWARP = true;
|
useWARP = allowWARP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1942,7 +1947,7 @@ gfxWindowsPlatform::InitD3D11Devices()
|
||||||
if (!gfxPrefs::LayersD3D11DisableWARP()) {
|
if (!gfxPrefs::LayersD3D11DisableWARP()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
useWARP = true;
|
useWARP = allowWARP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1964,7 +1969,7 @@ gfxWindowsPlatform::InitD3D11Devices()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
useWARP = true;
|
useWARP = allowWARP;
|
||||||
adapter = nullptr;
|
adapter = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1974,7 +1979,7 @@ gfxWindowsPlatform::InitD3D11Devices()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
useWARP = true;
|
useWARP = allowWARP;
|
||||||
adapter = nullptr;
|
adapter = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8154,7 +8154,7 @@ IonBuilder::getElemTryDense(bool* emitted, MDefinition* obj, MDefinition* index)
|
||||||
|
|
||||||
// Don't generate a fast path if there have been bounds check failures
|
// Don't generate a fast path if there have been bounds check failures
|
||||||
// and this access might be on a sparse property.
|
// and this access might be on a sparse property.
|
||||||
if (ElementAccessHasExtraIndexedProperty(constraints(), obj) && failedBoundsCheck_) {
|
if (ElementAccessHasExtraIndexedProperty(this, obj) && failedBoundsCheck_) {
|
||||||
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -8188,7 +8188,7 @@ IonBuilder::getStaticTypedArrayObject(MDefinition* obj, MDefinition* index)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ElementAccessHasExtraIndexedProperty(constraints(), obj)) {
|
if (ElementAccessHasExtraIndexedProperty(this, obj)) {
|
||||||
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -8536,7 +8536,7 @@ IonBuilder::jsop_getelem_dense(MDefinition* obj, MDefinition* index, JSValueType
|
||||||
// cannot hit another indexed property on the object or its prototypes.
|
// cannot hit another indexed property on the object or its prototypes.
|
||||||
bool readOutOfBounds =
|
bool readOutOfBounds =
|
||||||
types->hasType(TypeSet::UndefinedType()) &&
|
types->hasType(TypeSet::UndefinedType()) &&
|
||||||
!ElementAccessHasExtraIndexedProperty(constraints(), obj);
|
!ElementAccessHasExtraIndexedProperty(this, obj);
|
||||||
|
|
||||||
MIRType knownType = MIRType_Value;
|
MIRType knownType = MIRType_Value;
|
||||||
if (unboxedType == JSVAL_TYPE_MAGIC && barrier == BarrierKind::NoBarrier)
|
if (unboxedType == JSVAL_TYPE_MAGIC && barrier == BarrierKind::NoBarrier)
|
||||||
|
@ -9097,7 +9097,7 @@ IonBuilder::setElemTryDense(bool* emitted, MDefinition* object,
|
||||||
|
|
||||||
// Don't generate a fast path if there have been bounds check failures
|
// Don't generate a fast path if there have been bounds check failures
|
||||||
// and this access might be on a sparse property.
|
// and this access might be on a sparse property.
|
||||||
if (ElementAccessHasExtraIndexedProperty(constraints(), object) && failedBoundsCheck_) {
|
if (ElementAccessHasExtraIndexedProperty(this, object) && failedBoundsCheck_) {
|
||||||
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -9163,7 +9163,7 @@ IonBuilder::setElemTryCache(bool* emitted, MDefinition* object,
|
||||||
// from them. If TI can guard that there are no indexed properties on the prototype
|
// from them. If TI can guard that there are no indexed properties on the prototype
|
||||||
// chain, we know that we anen't missing any setters by overwriting the hole with
|
// chain, we know that we anen't missing any setters by overwriting the hole with
|
||||||
// another value.
|
// another value.
|
||||||
bool guardHoles = ElementAccessHasExtraIndexedProperty(constraints(), object);
|
bool guardHoles = ElementAccessHasExtraIndexedProperty(this, object);
|
||||||
|
|
||||||
// Make sure the object being written to doesn't have copy on write elements.
|
// Make sure the object being written to doesn't have copy on write elements.
|
||||||
const Class* clasp = object->resultTypeSet() ? object->resultTypeSet()->getKnownClass(constraints()) : nullptr;
|
const Class* clasp = object->resultTypeSet() ? object->resultTypeSet()->getKnownClass(constraints()) : nullptr;
|
||||||
|
@ -9199,7 +9199,7 @@ IonBuilder::jsop_setelem_dense(TemporaryTypeSet::DoubleConversion conversion,
|
||||||
|
|
||||||
// Writes which are on holes in the object do not have to bail out if they
|
// Writes which are on holes in the object do not have to bail out if they
|
||||||
// cannot hit another indexed property on the object or its prototypes.
|
// cannot hit another indexed property on the object or its prototypes.
|
||||||
bool writeOutOfBounds = !ElementAccessHasExtraIndexedProperty(constraints(), obj);
|
bool writeOutOfBounds = !ElementAccessHasExtraIndexedProperty(this, obj);
|
||||||
|
|
||||||
if (NeedsPostBarrier(info(), value))
|
if (NeedsPostBarrier(info(), value))
|
||||||
current->add(MPostWriteBarrier::New(alloc(), obj, value));
|
current->add(MPostWriteBarrier::New(alloc(), obj, value));
|
||||||
|
@ -11068,7 +11068,7 @@ IonBuilder::getPropTryCache(bool* emitted, MDefinition* obj, PropertyName* name,
|
||||||
// reflect such possible values.
|
// reflect such possible values.
|
||||||
if (barrier != BarrierKind::TypeSet) {
|
if (barrier != BarrierKind::TypeSet) {
|
||||||
BarrierKind protoBarrier =
|
BarrierKind protoBarrier =
|
||||||
PropertyReadOnPrototypeNeedsTypeBarrier(this, constraints(), obj, name, types);
|
PropertyReadOnPrototypeNeedsTypeBarrier(this, obj, name, types);
|
||||||
if (protoBarrier != BarrierKind::NoBarrier) {
|
if (protoBarrier != BarrierKind::NoBarrier) {
|
||||||
MOZ_ASSERT(barrier <= protoBarrier);
|
MOZ_ASSERT(barrier <= protoBarrier);
|
||||||
barrier = protoBarrier;
|
barrier = protoBarrier;
|
||||||
|
@ -12373,7 +12373,7 @@ IonBuilder::jsop_in()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ElementAccessHasExtraIndexedProperty(constraints(), obj))
|
if (ElementAccessHasExtraIndexedProperty(this, obj))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
return jsop_in_dense(obj, id, unboxedType);
|
return jsop_in_dense(obj, id, unboxedType);
|
||||||
|
|
|
@ -649,7 +649,7 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode)
|
||||||
return InliningStatus_NotInlined;
|
return InliningStatus_NotInlined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ArrayPrototypeHasIndexedProperty(constraints(), script())) {
|
if (ArrayPrototypeHasIndexedProperty(this, script())) {
|
||||||
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
||||||
return InliningStatus_NotInlined;
|
return InliningStatus_NotInlined;
|
||||||
}
|
}
|
||||||
|
@ -791,7 +791,7 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo)
|
||||||
return InliningStatus_NotInlined;
|
return InliningStatus_NotInlined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ArrayPrototypeHasIndexedProperty(constraints(), script())) {
|
if (ArrayPrototypeHasIndexedProperty(this, script())) {
|
||||||
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
||||||
return InliningStatus_NotInlined;
|
return InliningStatus_NotInlined;
|
||||||
}
|
}
|
||||||
|
@ -890,7 +890,7 @@ IonBuilder::inlineArrayConcat(CallInfo& callInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watch out for indexed properties on the prototype.
|
// Watch out for indexed properties on the prototype.
|
||||||
if (ArrayPrototypeHasIndexedProperty(constraints(), script())) {
|
if (ArrayPrototypeHasIndexedProperty(this, script())) {
|
||||||
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
||||||
return InliningStatus_NotInlined;
|
return InliningStatus_NotInlined;
|
||||||
}
|
}
|
||||||
|
@ -1006,7 +1006,7 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watch out for indexed properties on the prototype.
|
// Watch out for indexed properties on the prototype.
|
||||||
if (ArrayPrototypeHasIndexedProperty(constraints(), script())) {
|
if (ArrayPrototypeHasIndexedProperty(this, script())) {
|
||||||
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
|
||||||
return InliningStatus_NotInlined;
|
return InliningStatus_NotInlined;
|
||||||
}
|
}
|
||||||
|
@ -2127,7 +2127,7 @@ IonBuilder::inlineDefineDataProperty(CallInfo& callInfo)
|
||||||
MDefinition* id = callInfo.getArg(1);
|
MDefinition* id = callInfo.getArg(1);
|
||||||
MDefinition* value = callInfo.getArg(2);
|
MDefinition* value = callInfo.getArg(2);
|
||||||
|
|
||||||
if (ElementAccessHasExtraIndexedProperty(constraints(), obj))
|
if (ElementAccessHasExtraIndexedProperty(this, obj))
|
||||||
return InliningStatus_NotInlined;
|
return InliningStatus_NotInlined;
|
||||||
|
|
||||||
// setElemTryDense will push the value as the result of the define instead
|
// setElemTryDense will push the value as the result of the define instead
|
||||||
|
|
|
@ -4884,15 +4884,14 @@ jit::ElementAccessMightBeCopyOnWrite(CompilerConstraintList* constraints, MDefin
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit::ElementAccessHasExtraIndexedProperty(CompilerConstraintList* constraints,
|
jit::ElementAccessHasExtraIndexedProperty(IonBuilder* builder, MDefinition* obj)
|
||||||
MDefinition* obj)
|
|
||||||
{
|
{
|
||||||
TemporaryTypeSet* types = obj->resultTypeSet();
|
TemporaryTypeSet* types = obj->resultTypeSet();
|
||||||
|
|
||||||
if (!types || types->hasObjectFlags(constraints, OBJECT_FLAG_LENGTH_OVERFLOW))
|
if (!types || types->hasObjectFlags(builder->constraints(), OBJECT_FLAG_LENGTH_OVERFLOW))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return TypeCanHaveExtraIndexedProperties(constraints, types);
|
return TypeCanHaveExtraIndexedProperties(builder, types);
|
||||||
}
|
}
|
||||||
|
|
||||||
MIRType
|
MIRType
|
||||||
|
@ -5056,7 +5055,6 @@ jit::PropertyReadNeedsTypeBarrier(JSContext* propertycx,
|
||||||
|
|
||||||
BarrierKind
|
BarrierKind
|
||||||
jit::PropertyReadOnPrototypeNeedsTypeBarrier(IonBuilder* builder,
|
jit::PropertyReadOnPrototypeNeedsTypeBarrier(IonBuilder* builder,
|
||||||
CompilerConstraintList* constraints,
|
|
||||||
MDefinition* obj, PropertyName* name,
|
MDefinition* obj, PropertyName* name,
|
||||||
TemporaryTypeSet* observed)
|
TemporaryTypeSet* observed)
|
||||||
{
|
{
|
||||||
|
@ -5074,13 +5072,14 @@ jit::PropertyReadOnPrototypeNeedsTypeBarrier(IonBuilder* builder,
|
||||||
if (!key)
|
if (!key)
|
||||||
continue;
|
continue;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!key->hasStableClassAndProto(constraints))
|
if (!key->hasStableClassAndProto(builder->constraints()))
|
||||||
return BarrierKind::TypeSet;
|
return BarrierKind::TypeSet;
|
||||||
if (!key->proto().isObject())
|
if (!key->proto().isObject())
|
||||||
break;
|
break;
|
||||||
JSObject* proto = builder->checkNurseryObject(key->proto().toObject());
|
JSObject* proto = builder->checkNurseryObject(key->proto().toObject());
|
||||||
key = TypeSet::ObjectKey::get(proto);
|
key = TypeSet::ObjectKey::get(proto);
|
||||||
BarrierKind kind = PropertyReadNeedsTypeBarrier(constraints, key, name, observed);
|
BarrierKind kind = PropertyReadNeedsTypeBarrier(builder->constraints(),
|
||||||
|
key, name, observed);
|
||||||
if (kind == BarrierKind::TypeSet)
|
if (kind == BarrierKind::TypeSet)
|
||||||
return BarrierKind::TypeSet;
|
return BarrierKind::TypeSet;
|
||||||
|
|
||||||
|
@ -5164,6 +5163,58 @@ jit::AddObjectsForPropertyRead(MDefinition* obj, PropertyName* name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
PrototypeHasIndexedProperty(IonBuilder* builder, JSObject* obj)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
TypeSet::ObjectKey* key = TypeSet::ObjectKey::get(builder->checkNurseryObject(obj));
|
||||||
|
if (ClassCanHaveExtraProperties(key->clasp()))
|
||||||
|
return true;
|
||||||
|
if (key->unknownProperties())
|
||||||
|
return true;
|
||||||
|
HeapTypeSetKey index = key->property(JSID_VOID);
|
||||||
|
if (index.nonData(builder->constraints()) || index.isOwnProperty(builder->constraints()))
|
||||||
|
return true;
|
||||||
|
obj = obj->getProto();
|
||||||
|
} while (obj);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Whether Array.prototype, or an object on its proto chain, has an indexed property.
|
||||||
|
bool
|
||||||
|
jit::ArrayPrototypeHasIndexedProperty(IonBuilder* builder, JSScript* script)
|
||||||
|
{
|
||||||
|
if (JSObject* proto = script->global().maybeGetArrayPrototype())
|
||||||
|
return PrototypeHasIndexedProperty(builder, proto);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Whether obj or any of its prototypes have an indexed property.
|
||||||
|
bool
|
||||||
|
jit::TypeCanHaveExtraIndexedProperties(IonBuilder* builder, TemporaryTypeSet* types)
|
||||||
|
{
|
||||||
|
const Class* clasp = types->getKnownClass(builder->constraints());
|
||||||
|
|
||||||
|
// Note: typed arrays have indexed properties not accounted for by type
|
||||||
|
// information, though these are all in bounds and will be accounted for
|
||||||
|
// by JIT paths.
|
||||||
|
if (!clasp || (ClassCanHaveExtraProperties(clasp) && !IsAnyTypedArrayClass(clasp)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (types->hasObjectFlags(builder->constraints(), OBJECT_FLAG_SPARSE_INDEXES))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
JSObject* proto;
|
||||||
|
if (!types->getCommonPrototype(builder->constraints(), &proto))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!proto)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return PrototypeHasIndexedProperty(builder, proto);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
PropertyTypeIncludes(TempAllocator& alloc, HeapTypeSetKey property,
|
PropertyTypeIncludes(TempAllocator& alloc, HeapTypeSetKey property,
|
||||||
MDefinition* value, MIRType implicitType)
|
MDefinition* value, MIRType implicitType)
|
||||||
|
|
|
@ -13719,8 +13719,7 @@ bool ElementAccessIsAnyTypedArray(CompilerConstraintList* constraints,
|
||||||
Scalar::Type* arrayType);
|
Scalar::Type* arrayType);
|
||||||
bool ElementAccessIsPacked(CompilerConstraintList* constraints, MDefinition* obj);
|
bool ElementAccessIsPacked(CompilerConstraintList* constraints, MDefinition* obj);
|
||||||
bool ElementAccessMightBeCopyOnWrite(CompilerConstraintList* constraints, MDefinition* obj);
|
bool ElementAccessMightBeCopyOnWrite(CompilerConstraintList* constraints, MDefinition* obj);
|
||||||
bool ElementAccessHasExtraIndexedProperty(CompilerConstraintList* constraints,
|
bool ElementAccessHasExtraIndexedProperty(IonBuilder* builder, MDefinition* obj);
|
||||||
MDefinition* obj);
|
|
||||||
MIRType DenseNativeElementType(CompilerConstraintList* constraints, MDefinition* obj);
|
MIRType DenseNativeElementType(CompilerConstraintList* constraints, MDefinition* obj);
|
||||||
BarrierKind PropertyReadNeedsTypeBarrier(JSContext* propertycx,
|
BarrierKind PropertyReadNeedsTypeBarrier(JSContext* propertycx,
|
||||||
CompilerConstraintList* constraints,
|
CompilerConstraintList* constraints,
|
||||||
|
@ -13731,7 +13730,6 @@ BarrierKind PropertyReadNeedsTypeBarrier(JSContext* propertycx,
|
||||||
MDefinition* obj, PropertyName* name,
|
MDefinition* obj, PropertyName* name,
|
||||||
TemporaryTypeSet* observed);
|
TemporaryTypeSet* observed);
|
||||||
BarrierKind PropertyReadOnPrototypeNeedsTypeBarrier(IonBuilder* builder,
|
BarrierKind PropertyReadOnPrototypeNeedsTypeBarrier(IonBuilder* builder,
|
||||||
CompilerConstraintList* constraints,
|
|
||||||
MDefinition* obj, PropertyName* name,
|
MDefinition* obj, PropertyName* name,
|
||||||
TemporaryTypeSet* observed);
|
TemporaryTypeSet* observed);
|
||||||
bool PropertyReadIsIdempotent(CompilerConstraintList* constraints,
|
bool PropertyReadIsIdempotent(CompilerConstraintList* constraints,
|
||||||
|
@ -13745,6 +13743,8 @@ bool PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList*
|
||||||
MBasicBlock* current, MDefinition** pobj,
|
MBasicBlock* current, MDefinition** pobj,
|
||||||
PropertyName* name, MDefinition** pvalue,
|
PropertyName* name, MDefinition** pvalue,
|
||||||
bool canModify, MIRType implicitType = MIRType_None);
|
bool canModify, MIRType implicitType = MIRType_None);
|
||||||
|
bool ArrayPrototypeHasIndexedProperty(IonBuilder* builder, JSScript* script);
|
||||||
|
bool TypeCanHaveExtraIndexedProperties(IonBuilder* builder, TemporaryTypeSet* types);
|
||||||
|
|
||||||
} // namespace jit
|
} // namespace jit
|
||||||
} // namespace js
|
} // namespace js
|
||||||
|
|
|
@ -2829,6 +2829,19 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
||||||
void compareExchange32(const T& mem, Register oldval, Register newval, Register output) {
|
void compareExchange32(const T& mem, Register oldval, Register newval, Register output) {
|
||||||
compareExchange(4, false, mem, oldval, newval, output);
|
compareExchange(4, false, mem, oldval, newval, output);
|
||||||
}
|
}
|
||||||
|
template <typename T>
|
||||||
|
void atomicExchange32(const T& mem, Register value, Register output) {
|
||||||
|
MOZ_CRASH("atomicExchang32");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void atomicExchange8ZeroExtend(const T& mem, Register value, Register output) {
|
||||||
|
MOZ_CRASH("atomicExchange8ZeroExtend");
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
void atomicExchange8SignExtend(const T& mem, Register value, Register output) {
|
||||||
|
MOZ_CRASH("atomicExchange8SignExtend");
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, typename S>
|
template <typename T, typename S>
|
||||||
void atomicFetchAdd8SignExtend(const S& value, const T& mem, Register temp, Register output) {
|
void atomicFetchAdd8SignExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||||
|
@ -2864,6 +2877,15 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
||||||
atomicEffectOp(4, AtomicFetchAddOp, value, mem);
|
atomicEffectOp(4, AtomicFetchAddOp, value, mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void atomicExchange16ZeroExtend(const T& mem, Register value, Register output) {
|
||||||
|
MOZ_CRASH("atomicExchange16ZeroExtend");
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
void atomicExchange16SignExtend(const T& mem, Register value, Register output) {
|
||||||
|
MOZ_CRASH("atomicExchange16SignExtend");
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, typename S>
|
template <typename T, typename S>
|
||||||
void atomicFetchSub8SignExtend(const S& value, const T& mem, Register temp, Register output) {
|
void atomicFetchSub8SignExtend(const S& value, const T& mem, Register temp, Register output) {
|
||||||
atomicFetchOp(1, true, AtomicFetchSubOp, value, mem, temp, output);
|
atomicFetchOp(1, true, AtomicFetchSubOp, value, mem, temp, output);
|
||||||
|
@ -3003,6 +3025,10 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
||||||
// Emit a BLR or NOP instruction. ToggleCall can be used to patch
|
// Emit a BLR or NOP instruction. ToggleCall can be used to patch
|
||||||
// this instruction.
|
// this instruction.
|
||||||
CodeOffsetLabel toggledCall(JitCode* target, bool enabled) {
|
CodeOffsetLabel toggledCall(JitCode* target, bool enabled) {
|
||||||
|
// The returned offset must be to the first instruction generated,
|
||||||
|
// for the debugger to match offset with Baseline's pcMappingEntries_.
|
||||||
|
BufferOffset offset = nextOffset();
|
||||||
|
|
||||||
// TODO: Random pool insertion between instructions below is terrible.
|
// TODO: Random pool insertion between instructions below is terrible.
|
||||||
// Unfortunately, we can't forbid pool prevention, because we're trying
|
// Unfortunately, we can't forbid pool prevention, because we're trying
|
||||||
// to add an entry to a pool. So as a temporary fix, just flush the pool
|
// to add an entry to a pool. So as a temporary fix, just flush the pool
|
||||||
|
@ -3012,7 +3038,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
||||||
|
|
||||||
syncStackPtr();
|
syncStackPtr();
|
||||||
|
|
||||||
BufferOffset offset = nextOffset();
|
|
||||||
BufferOffset loadOffset;
|
BufferOffset loadOffset;
|
||||||
{
|
{
|
||||||
vixl::UseScratchRegisterScope temps(this);
|
vixl::UseScratchRegisterScope temps(this);
|
||||||
|
|
|
@ -2449,57 +2449,6 @@ js::ClassCanHaveExtraProperties(const Class* clasp)
|
||||||
|| IsAnyTypedArrayClass(clasp);
|
|| IsAnyTypedArrayClass(clasp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
PrototypeHasIndexedProperty(CompilerConstraintList* constraints, JSObject* obj)
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
TypeSet::ObjectKey* key = TypeSet::ObjectKey::get(obj);
|
|
||||||
if (ClassCanHaveExtraProperties(key->clasp()))
|
|
||||||
return true;
|
|
||||||
if (key->unknownProperties())
|
|
||||||
return true;
|
|
||||||
HeapTypeSetKey index = key->property(JSID_VOID);
|
|
||||||
if (index.nonData(constraints) || index.isOwnProperty(constraints))
|
|
||||||
return true;
|
|
||||||
obj = obj->getProto();
|
|
||||||
} while (obj);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
js::ArrayPrototypeHasIndexedProperty(CompilerConstraintList* constraints, JSScript* script)
|
|
||||||
{
|
|
||||||
if (JSObject* proto = script->global().maybeGetArrayPrototype())
|
|
||||||
return PrototypeHasIndexedProperty(constraints, proto);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
js::TypeCanHaveExtraIndexedProperties(CompilerConstraintList* constraints,
|
|
||||||
TemporaryTypeSet* types)
|
|
||||||
{
|
|
||||||
const Class* clasp = types->getKnownClass(constraints);
|
|
||||||
|
|
||||||
// Note: typed arrays have indexed properties not accounted for by type
|
|
||||||
// information, though these are all in bounds and will be accounted for
|
|
||||||
// by JIT paths.
|
|
||||||
if (!clasp || (ClassCanHaveExtraProperties(clasp) && !IsAnyTypedArrayClass(clasp)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (types->hasObjectFlags(constraints, OBJECT_FLAG_SPARSE_INDEXES))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
JSObject* proto;
|
|
||||||
if (!types->getCommonPrototype(constraints, &proto))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (!proto)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return PrototypeHasIndexedProperty(constraints, proto);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TypeZone::processPendingRecompiles(FreeOp* fop, RecompileInfoVector& recompiles)
|
TypeZone::processPendingRecompiles(FreeOp* fop, RecompileInfoVector& recompiles)
|
||||||
{
|
{
|
||||||
|
|
|
@ -974,17 +974,6 @@ inline bool isInlinableCall(jsbytecode* pc);
|
||||||
bool
|
bool
|
||||||
ClassCanHaveExtraProperties(const Class* clasp);
|
ClassCanHaveExtraProperties(const Class* clasp);
|
||||||
|
|
||||||
/*
|
|
||||||
* Whether Array.prototype, or an object on its proto chain, has an
|
|
||||||
* indexed property.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
ArrayPrototypeHasIndexedProperty(CompilerConstraintList* constraints, JSScript* script);
|
|
||||||
|
|
||||||
/* Whether obj or any of its prototypes have an indexed property. */
|
|
||||||
bool
|
|
||||||
TypeCanHaveExtraIndexedProperties(CompilerConstraintList* constraints, TemporaryTypeSet* types);
|
|
||||||
|
|
||||||
/* Persistent type information for a script, retained across GCs. */
|
/* Persistent type information for a script, retained across GCs. */
|
||||||
class TypeScript
|
class TypeScript
|
||||||
{
|
{
|
||||||
|
|
|
@ -1939,6 +1939,15 @@ js::TryConvertToUnboxedLayout(ExclusiveContext* cx, Shape* templateShape,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure that all properties on the template shape are property
|
||||||
|
// names, and not indexes.
|
||||||
|
for (Shape::Range<NoGC> r(templateShape); !r.empty(); r.popFront()) {
|
||||||
|
jsid id = r.front().propid();
|
||||||
|
uint32_t dummy;
|
||||||
|
if (!JSID_IS_ATOM(id) || JSID_TO_ATOM(id)->isIndex(&dummy))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
layoutSize = ComputePlainObjectLayout(cx, templateShape, properties);
|
layoutSize = ComputePlainObjectLayout(cx, templateShape, properties);
|
||||||
|
|
||||||
// The entire object must be allocatable inline.
|
// The entire object must be allocatable inline.
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
if (report) {
|
if (report) {
|
||||||
opener.postMessage("callbackHappened", "*");
|
opener.postMessage("callbackHappened", "*");
|
||||||
}
|
}
|
||||||
window.mozRequestAnimationFrame(g);
|
window.requestAnimationFrame(g);
|
||||||
}
|
}
|
||||||
g();
|
g();
|
||||||
|
|
||||||
|
|
|
@ -21,24 +21,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=569520
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SimpleTest.requestFlakyTimeout("untriaged");
|
SimpleTest.requestFlakyTimeout("untriaged");
|
||||||
|
|
||||||
var startNow = Date.now();
|
var start = window.performance.now();
|
||||||
var start = window.mozAnimationStartTime;
|
|
||||||
var firstListenerArg;
|
var firstListenerArg;
|
||||||
var secondListenerArg;
|
var secondListenerArg;
|
||||||
var thirdListenerTime;
|
var thirdListenerTime;
|
||||||
|
|
||||||
// callback arg is wallclock from mozRequestAnimationFrame
|
// callback arg is in the same timeline as performance.now()
|
||||||
function thirdListener(t) {
|
function thirdListener(t) {
|
||||||
thirdListenerTime = t;
|
thirdListenerTime = t;
|
||||||
|
|
||||||
// They really shouldn't be more than 100ms apart, but we can get weird
|
ok(secondListenerArg >= firstListenerArg, // callback args from consecutive requestAnimationFrame
|
||||||
// effects on slow machines. 5 minutes is our test timeout, though.
|
|
||||||
ok(Math.abs(startNow - start) <= 5 * 60 * 1000, "Bogus animation start time");
|
|
||||||
|
|
||||||
ok(secondListenerArg >= firstListenerArg, // callback args from consecutive unprefixed requestAnimationFrame
|
|
||||||
"Second listener should fire after first listener");
|
"Second listener should fire after first listener");
|
||||||
|
|
||||||
ok(thirdListenerTime >= start, "Third listener should fire after start");
|
ok(thirdListenerTime >= secondListenerArg,
|
||||||
|
"Third listener should fire after second listener");
|
||||||
|
|
||||||
|
ok(firstListenerArg >= start, "First listener should fire after start");
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
@ -46,7 +44,7 @@ function thirdListener(t) {
|
||||||
// callback arg is from requestAnimationFrame and comparable to performance.now()
|
// callback arg is from requestAnimationFrame and comparable to performance.now()
|
||||||
function secondListener(t) {
|
function secondListener(t) {
|
||||||
secondListenerArg = t;
|
secondListenerArg = t;
|
||||||
mozRequestAnimationFrame(thirdListener);
|
requestAnimationFrame(thirdListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
function firstListener(t) {
|
function firstListener(t) {
|
||||||
|
|
|
@ -21,24 +21,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=569520
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SimpleTest.requestFlakyTimeout("untriaged");
|
SimpleTest.requestFlakyTimeout("untriaged");
|
||||||
|
|
||||||
var startNow = Date.now();
|
var start = window.performance.now();
|
||||||
var start = window.mozAnimationStartTime;
|
|
||||||
var firstListenerArg;
|
var firstListenerArg;
|
||||||
var secondListenerArg;
|
var secondListenerArg;
|
||||||
var thirdListenerTime;
|
var thirdListenerTime;
|
||||||
|
|
||||||
// callback arg is wallclock from mozRequestAnimationFrame
|
// callback arg is in the same timeline as performance.now()
|
||||||
function thirdListener(t) {
|
function thirdListener(t) {
|
||||||
thirdListenerTime = t;
|
thirdListenerTime = t;
|
||||||
|
|
||||||
// They really shouldn't be more than 100ms apart, but we can get weird
|
ok(secondListenerArg >= firstListenerArg, // callback args from consecutive requestAnimationFrame
|
||||||
// effects on slow machines. 5 minutes is our test timeout, though.
|
|
||||||
ok(Math.abs(startNow - start) <= 5 * 60 * 1000, "Bogus animation start time");
|
|
||||||
|
|
||||||
ok(secondListenerArg >= firstListenerArg, // callback args from consecutive unprefixed requestAnimationFrame
|
|
||||||
"Second listener should fire after first listener");
|
"Second listener should fire after first listener");
|
||||||
|
|
||||||
ok(thirdListenerTime >= start, "Third listener should fire after start");
|
ok(thirdListenerTime >= secondListenerArg,
|
||||||
|
"Third listener should fire after second listener");
|
||||||
|
|
||||||
|
ok(firstListenerArg >= start, "First listener should fire after start");
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
@ -46,7 +44,7 @@ function thirdListener(t) {
|
||||||
// callback arg is from requestAnimationFrame and comparable to performance.now()
|
// callback arg is from requestAnimationFrame and comparable to performance.now()
|
||||||
function secondListener(t) {
|
function secondListener(t) {
|
||||||
secondListenerArg = t;
|
secondListenerArg = t;
|
||||||
mozRequestAnimationFrame(thirdListener);
|
requestAnimationFrame(thirdListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
function firstListener(t) {
|
function firstListener(t) {
|
||||||
|
|
|
@ -19,7 +19,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=607529
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
/* General idea: Open a new window (needed because we don't bfcache
|
/* General idea: Open a new window (needed because we don't bfcache
|
||||||
subframes) that uses mozRequestAnimationFrame, navigate it, navigate it
|
subframes) that uses requestAnimationFrame, navigate it, navigate it
|
||||||
back, and verify that the animations are still running. */
|
back, and verify that the animations are still running. */
|
||||||
|
|
||||||
var doneOneLoad = false;
|
var doneOneLoad = false;
|
||||||
|
|
|
@ -42,7 +42,7 @@ function onScroll() {
|
||||||
|
|
||||||
function doTest() {
|
function doTest() {
|
||||||
window.getSelection().collapse(inner.firstChild, 0);
|
window.getSelection().collapse(inner.firstChild, 0);
|
||||||
window.mozRequestAnimationFrame(onFrame);
|
window.requestAnimationFrame(onFrame);
|
||||||
d.onscroll = onScroll;
|
d.onscroll = onScroll;
|
||||||
sendKey("DOWN");
|
sendKey("DOWN");
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ function doTest() {
|
||||||
function prepareTest() {
|
function prepareTest() {
|
||||||
// Start the test after we've gotten at least one rAF callback, to make sure
|
// Start the test after we've gotten at least one rAF callback, to make sure
|
||||||
// that rAF is no longer throttled. (See bug 1145439.)
|
// that rAF is no longer throttled. (See bug 1145439.)
|
||||||
window.mozRequestAnimationFrame(function() {
|
window.requestAnimationFrame(function() {
|
||||||
SpecialPowers.pushPrefEnv({"set":[[smoothScrollPref, false]]}, doTest);
|
SpecialPowers.pushPrefEnv({"set":[[smoothScrollPref, false]]}, doTest);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ function runTest() {
|
||||||
// Delay until next repaint in case stuff is asynchronous. Also
|
// Delay until next repaint in case stuff is asynchronous. Also
|
||||||
// take a trip through the event loop.
|
// take a trip through the event loop.
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
window.mozRequestAnimationFrame(function() {
|
window.requestAnimationFrame(function() {
|
||||||
is(sel.anchorNode, target.firstChild, "Should have selected 'target' text node");
|
is(sel.anchorNode, target.firstChild, "Should have selected 'target' text node");
|
||||||
is(sel.anchorOffset, 1, "Selection should have moved left one character");
|
is(sel.anchorOffset, 1, "Selection should have moved left one character");
|
||||||
// We should not have needed to scroll the caret into view
|
// We should not have needed to scroll the caret into view
|
||||||
|
|
|
@ -5,8 +5,6 @@ var property = "left";
|
||||||
var rfa = null;
|
var rfa = null;
|
||||||
if (window.requestAnimationFrame) {
|
if (window.requestAnimationFrame) {
|
||||||
rfa = requestAnimationFrame;
|
rfa = requestAnimationFrame;
|
||||||
} else if (window.mozRequestAnimationFrame) {
|
|
||||||
rfa = mozRequestAnimationFrame;
|
|
||||||
} else if (window.webkitRequestAnimationFrame) {
|
} else if (window.webkitRequestAnimationFrame) {
|
||||||
rfa = webkitRequestAnimationFrame;
|
rfa = webkitRequestAnimationFrame;
|
||||||
} else if (window.msRequestAnimationFrame) {
|
} else if (window.msRequestAnimationFrame) {
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
var rfa = null;
|
var rfa = null;
|
||||||
if (window.requestAnimationFrame) {
|
if (window.requestAnimationFrame) {
|
||||||
rfa = requestAnimationFrame;
|
rfa = requestAnimationFrame;
|
||||||
} else if (window.mozRequestAnimationFrame) {
|
|
||||||
rfa = mozRequestAnimationFrame;
|
|
||||||
} else if (window.webkitRequestAnimationFrame) {
|
} else if (window.webkitRequestAnimationFrame) {
|
||||||
rfa = webkitRequestAnimationFrame;
|
rfa = webkitRequestAnimationFrame;
|
||||||
} else if (window.msRequestAnimationFrame) {
|
} else if (window.msRequestAnimationFrame) {
|
||||||
|
|
|
@ -5,8 +5,6 @@ var property = "top";
|
||||||
var rfa = null;
|
var rfa = null;
|
||||||
if (window.requestAnimationFrame) {
|
if (window.requestAnimationFrame) {
|
||||||
rfa = requestAnimationFrame;
|
rfa = requestAnimationFrame;
|
||||||
} else if (window.mozRequestAnimationFrame) {
|
|
||||||
rfa = mozRequestAnimationFrame;
|
|
||||||
} else if (window.webkitRequestAnimationFrame) {
|
} else if (window.webkitRequestAnimationFrame) {
|
||||||
rfa = webkitRequestAnimationFrame;
|
rfa = webkitRequestAnimationFrame;
|
||||||
} else if (window.msRequestAnimationFrame) {
|
} else if (window.msRequestAnimationFrame) {
|
||||||
|
|
|
@ -89,13 +89,15 @@ InterceptedJARChannel::FinishSynthesizedResponse()
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
InterceptedJARChannel::Cancel()
|
InterceptedJARChannel::Cancel(nsresult aStatus)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(NS_FAILED(aStatus));
|
||||||
|
|
||||||
if (!mChannel) {
|
if (!mChannel) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = mChannel->Cancel(NS_BINDING_ABORTED);
|
nsresult rv = mChannel->Cancel(aStatus);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
mResponseBody = nullptr;
|
mResponseBody = nullptr;
|
||||||
mChannel = nullptr;
|
mChannel = nullptr;
|
||||||
|
|
|
@ -1022,7 +1022,7 @@ pref("dom.allow_scripts_to_close_windows", false);
|
||||||
|
|
||||||
pref("dom.disable_open_during_load", false);
|
pref("dom.disable_open_during_load", false);
|
||||||
pref("dom.popup_maximum", 20);
|
pref("dom.popup_maximum", 20);
|
||||||
pref("dom.popup_allowed_events", "change click dblclick mouseup reset submit touchend");
|
pref("dom.popup_allowed_events", "change click dblclick mouseup notificationclick reset submit touchend");
|
||||||
pref("dom.disable_open_click_delay", 1000);
|
pref("dom.disable_open_click_delay", 1000);
|
||||||
|
|
||||||
pref("dom.storage.enabled", true);
|
pref("dom.storage.enabled", true);
|
||||||
|
|
|
@ -26,7 +26,7 @@ class ChannelInfo;
|
||||||
* which do not implement nsIChannel.
|
* which do not implement nsIChannel.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
[scriptable, uuid(f2c07a6b-366d-4ef4-85ab-a77f4bcb1646)]
|
[scriptable, uuid(1062c96a-d73c-4ad5-beb7-6e803e414973)]
|
||||||
interface nsIInterceptedChannel : nsISupports
|
interface nsIInterceptedChannel : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -59,7 +59,7 @@ interface nsIInterceptedChannel : nsISupports
|
||||||
* @return NS_ERROR_FAILURE if the response has already been synthesized or
|
* @return NS_ERROR_FAILURE if the response has already been synthesized or
|
||||||
* the original request has been instructed to continue.
|
* the original request has been instructed to continue.
|
||||||
*/
|
*/
|
||||||
void cancel();
|
void cancel(in nsresult status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The synthesized response body to be produced.
|
* The synthesized response body to be produced.
|
||||||
|
|
|
@ -98,7 +98,7 @@ HttpChannelParent::ActorDestroy(ActorDestroyReason why)
|
||||||
// If this is an intercepted channel, we need to make sure that any resources are
|
// If this is an intercepted channel, we need to make sure that any resources are
|
||||||
// cleaned up to avoid leaks.
|
// cleaned up to avoid leaks.
|
||||||
if (mInterceptedChannel) {
|
if (mInterceptedChannel) {
|
||||||
mInterceptedChannel->Cancel();
|
mInterceptedChannel->Cancel(NS_ERROR_INTERCEPTION_FAILED);
|
||||||
mInterceptedChannel = nullptr;
|
mInterceptedChannel = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,15 +230,17 @@ InterceptedChannelChrome::FinishSynthesizedResponse()
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
InterceptedChannelChrome::Cancel()
|
InterceptedChannelChrome::Cancel(nsresult aStatus)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(NS_FAILED(aStatus));
|
||||||
|
|
||||||
if (!mChannel) {
|
if (!mChannel) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we need to use AsyncAbort instead of Cancel since there's no active pump
|
// we need to use AsyncAbort instead of Cancel since there's no active pump
|
||||||
// to cancel which will provide OnStart/OnStopRequest to the channel.
|
// to cancel which will provide OnStart/OnStopRequest to the channel.
|
||||||
nsresult rv = mChannel->AsyncAbort(NS_BINDING_ABORTED);
|
nsresult rv = mChannel->AsyncAbort(aStatus);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -335,15 +337,17 @@ InterceptedChannelContent::FinishSynthesizedResponse()
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
InterceptedChannelContent::Cancel()
|
InterceptedChannelContent::Cancel(nsresult aStatus)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(NS_FAILED(aStatus));
|
||||||
|
|
||||||
if (!mChannel) {
|
if (!mChannel) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we need to use AsyncAbort instead of Cancel since there's no active pump
|
// we need to use AsyncAbort instead of Cancel since there's no active pump
|
||||||
// to cancel which will provide OnStart/OnStopRequest to the channel.
|
// to cancel which will provide OnStart/OnStopRequest to the channel.
|
||||||
nsresult rv = mChannel->AsyncAbort(NS_BINDING_ABORTED);
|
nsresult rv = mChannel->AsyncAbort(aStatus);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
mChannel = nullptr;
|
mChannel = nullptr;
|
||||||
mStreamListener = nullptr;
|
mStreamListener = nullptr;
|
||||||
|
|
|
@ -81,7 +81,7 @@ public:
|
||||||
NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
|
NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
|
||||||
NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override;
|
NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override;
|
||||||
NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override;
|
NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override;
|
||||||
NS_IMETHOD Cancel() override;
|
NS_IMETHOD Cancel(nsresult aStatus) override;
|
||||||
NS_IMETHOD SetChannelInfo(mozilla::dom::ChannelInfo* aChannelInfo) override;
|
NS_IMETHOD SetChannelInfo(mozilla::dom::ChannelInfo* aChannelInfo) override;
|
||||||
|
|
||||||
virtual void NotifyController() override;
|
virtual void NotifyController() override;
|
||||||
|
@ -108,7 +108,7 @@ public:
|
||||||
NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
|
NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
|
||||||
NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override;
|
NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override;
|
||||||
NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override;
|
NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override;
|
||||||
NS_IMETHOD Cancel() override;
|
NS_IMETHOD Cancel(nsresult aStatus) override;
|
||||||
NS_IMETHOD SetChannelInfo(mozilla::dom::ChannelInfo* aChannelInfo) override;
|
NS_IMETHOD SetChannelInfo(mozilla::dom::ChannelInfo* aChannelInfo) override;
|
||||||
|
|
||||||
virtual void NotifyController() override;
|
virtual void NotifyController() override;
|
||||||
|
|
|
@ -188,7 +188,7 @@ add_test(function() {
|
||||||
// ensure that the intercepted channel can be cancelled
|
// ensure that the intercepted channel can be cancelled
|
||||||
add_test(function() {
|
add_test(function() {
|
||||||
var chan = make_channel(URL + '/body', null, function(intercepted) {
|
var chan = make_channel(URL + '/body', null, function(intercepted) {
|
||||||
intercepted.cancel();
|
intercepted.cancel(Cr.NS_BINDING_ABORTED);
|
||||||
});
|
});
|
||||||
chan.asyncOpen(new ChannelListener(run_next_test, null,
|
chan.asyncOpen(new ChannelListener(run_next_test, null,
|
||||||
CL_EXPECT_FAILURE), null);
|
CL_EXPECT_FAILURE), null);
|
||||||
|
|
|
@ -1082,7 +1082,7 @@
|
||||||
<p>Euro sign: €</p>
|
<p>Euro sign: €</p>
|
||||||
<script>
|
<script>
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
window.mozRequestAnimationFrame(function() {
|
window.requestAnimationFrame(function() {
|
||||||
parent.document.documentElement.removeAttribute("class");
|
parent.document.documentElement.removeAttribute("class");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче