This commit is contained in:
Ryan VanderMeulen 2015-07-14 23:40:10 -04:00
Родитель 201d63d360 b8ca505d1b
Коммит efd6d32c77
111 изменённых файлов: 2519 добавлений и 541 удалений

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

@ -102,19 +102,28 @@ HTMLLIAccessible::UpdateBullet(bool aHasBullet)
return;
}
nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this);
AutoTreeMutation mut(this);
DocAccessible* document = Document();
if (aHasBullet) {
mBullet = new HTMLListBulletAccessible(mContent, mDoc);
document->BindToDocument(mBullet, nullptr);
InsertChildAt(0, mBullet);
nsRefPtr<AccShowEvent> event = new AccShowEvent(mBullet, mBullet->GetContent());
mDoc->FireDelayedEvent(event);
reorderEvent->AddSubMutationEvent(event);
} else {
nsRefPtr<AccHideEvent> event = new AccHideEvent(mBullet, mBullet->GetContent());
mDoc->FireDelayedEvent(event);
reorderEvent->AddSubMutationEvent(event);
RemoveChild(mBullet);
document->UnbindFromDocument(mBullet);
mBullet = nullptr;
}
// XXXtodo: fire show/hide and reorder events. That's hard to make it
// right now because coalescence happens by DOM node.
mDoc->FireDelayedEvent(reorderEvent);
}
////////////////////////////////////////////////////////////////////////////////

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

@ -6,6 +6,7 @@
[test_bug884251.xhtml]
[test_bug895082.html]
[test_bug1040735.html]
[test_bug1100602.html]
[test_canvas.html]
[test_colorpicker.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">
<copyfile dest="Makefile" src="core/root.mk"/>
</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="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<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/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="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="init_sh" path="external/init_sh" remote="b2g" revision="3bdd26e092db9c47c5beb04b4809a35f8f767b8a"/>
<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">
<copyfile dest="Makefile" src="core/root.mk"/>
</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="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<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="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<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="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cfa80d0c1c13a13a64b049173ea3a1d605f2cffd"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</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="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</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="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<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="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<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">
<copyfile dest="Makefile" src="core/root.mk"/>
</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="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "803d04e3829fd4fe9261211aa0ddca6b79d4e328",
"git_revision": "c6ef08964711f461a8e6326eae911789d1ec220c",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "ad35f158cbd79823e9449f30df5d693613eef17f",
"revision": "422a64c4639a399fda83fb6ba9af46254a659421",
"repo_path": "integration/gaia-central"
}

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<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="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cfa80d0c1c13a13a64b049173ea3a1d605f2cffd"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</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="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<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.
error.AssignLiteral("corruptedContentError");
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:
break;
}
@ -7825,6 +7836,12 @@ nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
aStatus == NS_ERROR_UNSAFE_CONTENT_TYPE ||
aStatus == NS_ERROR_REMOTE_XUL ||
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) {
// Errors to be shown for any frame
DisplayLoadError(aStatus, url, nullptr, aChannel);
@ -14091,7 +14108,7 @@ nsDocShell::ChannelIntercepted(nsIInterceptedChannel* aChannel)
{
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
if (!swm) {
aChannel->Cancel();
aChannel->Cancel(NS_ERROR_INTERCEPTION_FAILED);
return NS_OK;
}

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

@ -23,22 +23,13 @@
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_CLASS(URL)
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_COLLECTION_WRAPPERCACHE(URL, mParent, mSearchParams)
NS_IMPL_CYCLE_COLLECTING_ADDREF(URL)
NS_IMPL_CYCLE_COLLECTING_RELEASE(URL)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END

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

@ -39,7 +39,7 @@ class URL final : public URLSearchParamsObserver
public:
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);

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

@ -1,6 +1,6 @@
<!DOCTYPE html>
<script>
window.mozRequestAnimationFrame(null);
window.requestAnimationFrame(null);
</script>

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

@ -1,5 +1,5 @@
<!DOCTYPE html>
<script>
mozCancelRequestAnimationFrame(mozRequestAnimationFrame(function() {}));
mozRequestAnimationFrame(function() {});
cancelRequestAnimationFrame(requestAnimationFrame(function() {}));
requestAnimationFrame(function() {});
</script>

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

@ -3417,6 +3417,36 @@ nsContentUtils::ReportToConsole(uint32_t aErrorFlags,
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
nsContentUtils::ReportToConsoleNonLocalized(const nsAString& aErrorText,

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

@ -842,6 +842,9 @@ public:
uint32_t aLineNumber = 0,
uint32_t aColumnNumber = 0);
static nsresult
MaybeReportInterceptionErrorToConsole(nsIDocument* aDocument, nsresult aError);
static void LogMessageToConsole(const char* aMsg, ...);
/**

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

@ -1761,10 +1761,10 @@ private:
void EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
bool aUpdateCSSLoader);
// Revoke any pending notifications due to mozRequestAnimationFrame calls
// Revoke any pending notifications due to requestAnimationFrame calls
void RevokeAnimationFrameNotifications();
// 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();
// These are not implemented and not supported.

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

@ -823,6 +823,7 @@ GK_ATOM(onMozScrolledAreaChanged, "onMozScrolledAreaChanged")
GK_ATOM(onmoznetworkupload, "onmoznetworkupload")
GK_ATOM(onmoznetworkdownload, "onmoznetworkdownload")
GK_ATOM(onnewrdsgroup, "onnewrdsgroup")
GK_ATOM(onnotificationclick, "onnotificationclick")
GK_ATOM(onnoupdate, "onnoupdate")
GK_ATOM(onobsolete, "onobsolete")
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
// up with the outer. See bug 969156.
if (createdInnerWindow) {
// AutoEntryScript required to invoke debugger hook, which is a
// Gecko-specific concept at present.
AutoEntryScript aes(newInnerWindow, "nsGlobalWindow report new global");
JS::Rooted<JSObject*> global(aes.cx(), newInnerWindow->GetWrapper());
JS_FireOnNewGlobalObject(aes.cx(), global);
nsContentUtils::AddScriptRunner(
NS_NewRunnableMethod(newInnerWindow,
&nsGlobalWindow::FireOnNewGlobalObject));
}
if (newInnerWindow && !newInnerWindow->mHasNotifiedGlobalCreated && mDoc) {
@ -14167,6 +14165,18 @@ nsGlobalWindow::SetReplaceableWindowCoord(JSContext* aCx,
(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_
#error "Never include windows.h in this file!"
#endif

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

@ -1538,6 +1538,11 @@ protected:
// show, in that case we show a separate dialog to ask this question.
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
// through JavaScript. If there is any chance that a member variable
// could own objects that are implemented in JavaScript, then those

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

@ -22,7 +22,7 @@ SimpleTest.waitForExplicitFinish();
var counter = 3;
var called = false;
var handle1 = window.mozRequestAnimationFrame(function() {
var handle1 = window.requestAnimationFrame(function() {
called = true;
});
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");
SimpleTest.finish();
} else {
window.mozRequestAnimationFrame(checker);
window.requestAnimationFrame(checker);
}
}
window.mozRequestAnimationFrame(checker);
window.mozCancelAnimationFrame(handle1);
window.requestAnimationFrame(checker);
window.cancelAnimationFrame(handle1);
</script>
</pre>

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

@ -27,7 +27,7 @@ function f() {
}
}
window.mozRequestAnimationFrame(f);
window.requestAnimationFrame(f);
var xhr = new XMLHttpRequest();
xhr.open("GET", "file_bug675121.sjs", false);
xhrInProgress = true;

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

@ -12,34 +12,34 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=
/** Test for Bug **/
SimpleTest.waitForExplicitFinish();
var unprefixedRan = false;
var prefixedRan = false;
function unprefixed(time) {
is(prefixedRan, true, "We were called second");
unprefixedRan = true;
var firstRan = false;
var secondRan = false;
function second(time) {
is(firstRan, true, "We were called second");
secondRan = true;
ok(Math.abs(time - performance.now()) < 3600000,
"An hour really shouldn't have passed here");
ok(Math.abs(time - Date.now()) > 3600000,
"More than an hour should have passed since 1970");
}
function prefixed(time) {
is(unprefixedRan, false, "Prefixed was called first");
prefixedRan = true;
ok(Math.abs(time - Date.now()) < 3600000,
"Our time should be comparable to Date.now()");
ok(Math.abs(time - performance.now()) > 3600000,
"Our time should not be comparable to performance.now()");
function first(time) {
is(secondRan, false, "second() was called first");
firstRan = true;
ok(Math.abs(time - performance.now()) < 3600000,
"An hour really shouldn't have passed here either");
ok(Math.abs(time - Date.now()) > 3600000,
"More than an hour should have passed since 1970 here either");
}
function prefixed2() {
ok(prefixedRan, "We should be after the other prefixed call");
ok(unprefixedRan, "We should be after the unprefixed call");
function third() {
ok(firstRan, "We should be after the first call");
ok(secondRan, "We should be after the second call");
SimpleTest.finish();
}
window.onload = function() {
window.mozRequestAnimationFrame(prefixed);
window.requestAnimationFrame(unprefixed);
window.mozRequestAnimationFrame(prefixed2);
window.requestAnimationFrame(first);
window.requestAnimationFrame(second);
window.requestAnimationFrame(third);
}
</script>

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

@ -869,6 +869,14 @@ DOMInterfaces = {
'nativeType': 'nsINodeList',
},
'NotificationEvent': {
'headerFile': 'mozilla/dom/NotificationEvent.h',
'nativeType': 'mozilla::dom::workers::NotificationEvent',
'binaryNames': {
'notification': 'notification_'
}
},
'OfflineAudioContext': {
'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_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_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);
}
let startTime = content.mozAnimationStartTime;
let startTime = content.performance.now();
let elapsedTime = 0, targetedTime = 0, averageTime = 0;
let velocity = this._velocity;
@ -667,9 +667,9 @@ const KineticPanning = {
return;
}
content.mozRequestAnimationFrame(callback);
content.requestAnimationFrame(callback);
}).bind(this);
content.mozRequestAnimationFrame(callback);
content.requestAnimationFrame(callback);
}
};

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

@ -62,7 +62,7 @@ function initGL(canvas) {
}
function rAF(func) {
var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame;
var raf = window.requestAnimationFrame;
raf(func);
}

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

@ -55,10 +55,10 @@ function runTest() {
scrollDown15PxWithPixelScrolling(scrollbox);
// wait for the next refresh driver run
win.mozRequestAnimationFrame(function() {
win.requestAnimationFrame(function() {
// actually, wait for the next one before checking results, since
// scrolling might not be flushed until after this code has run
win.mozRequestAnimationFrame(function() {
win.requestAnimationFrame(function() {
is(scrollbox.scrollTop, scrollTopBefore + 15,
"Pixel scrolling should have finished after one refresh driver iteration. " +
"We shouldn't be scrolling smoothly, even though the pref is set.");

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

@ -195,5 +195,44 @@ InternalRequest::MapContentPolicyTypeToRequestContext(nsContentPolicyType aConte
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 mozilla

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

@ -356,6 +356,16 @@ public:
mCreatedByFetchEvent = false;
}
bool
IsNavigationRequest() const;
bool
IsWorkerRequest() const;
bool
IsClientRequest() const;
private:
// Does not copy mBodyStream. Use fallible Clone() for complete copy.
explicit InternalRequest(const InternalRequest& aOther);

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

@ -33,7 +33,7 @@ interface nsIServiceWorkerInfo : nsISupports
readonly attribute DOMString waitingCacheName;
};
[scriptable, builtinclass, uuid(e9abb123-0099-4d9e-85db-c8cd0aff19e6)]
[scriptable, builtinclass, uuid(ed1cbbf2-0400-4caa-8eb2-b09d21a94e20)]
interface nsIServiceWorkerManager : nsISupports
{
/**
@ -126,6 +126,17 @@ interface nsIServiceWorkerManager : nsISupports
in nsIServiceWorkerUnregisterCallback aCallback,
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,
in ACString aScope,
in DOMString aData);

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

@ -4,7 +4,7 @@
#include "domstubs.idl"
[scriptable, uuid(9f1c43b9-f01b-4c87-ad3d-1a86520c2159)]
[scriptable, uuid(c1622232-259c-43b0-b52e-89c39dcd9796)]
interface nsINotificationStorageCallback : nsISupports
{
/**
@ -28,7 +28,8 @@ interface nsINotificationStorageCallback : nsISupports
in DOMString tag,
in DOMString icon,
in DOMString data,
in DOMString behavior);
in DOMString behavior,
in DOMString serviceWorkerRegistrationID);
/**
* Callback function used to notify C++ the we have returned
@ -41,7 +42,7 @@ interface nsINotificationStorageCallback : nsISupports
/**
* Interface for notification persistence layer.
*/
[scriptable, uuid(cac01fb0-c2eb-4252-b2f4-5b1fac933bd4)]
[scriptable, uuid(17f85e52-fe57-440e-9ba1-5c312ca02b95)]
interface nsINotificationStorage : nsISupports
{
@ -61,6 +62,10 @@ interface nsINotificationStorage : nsISupports
* Stored in the database to avoid re-computing
* it. Built from origin and tag or id depending
* 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,
in DOMString id,
@ -72,7 +77,8 @@ interface nsINotificationStorage : nsISupports
in DOMString icon,
in DOMString alertName,
in DOMString data,
in DOMString behavior);
in DOMString behavior,
in DOMString serviceWorkerRegistrationID);
/**
* Retrieve a list of notifications.
@ -86,6 +92,20 @@ interface nsINotificationStorage : nsISupports
in DOMString tag,
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.
*

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

@ -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
# LOCALIZATION NOTE: Do not translate "Worker".
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 NotificationObserver;
friend class NotificationStorageCallback;
friend class ServiceWorkerNotificationObserver;
friend class WorkerGetRunnable;
friend class WorkerNotificationObserver;
public:
@ -134,6 +136,31 @@ public:
const nsAString& aTitle,
const NotificationOptions& aOption,
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) {
aRetval = mID;
}
@ -189,10 +216,30 @@ public:
static NotificationPermission GetPermission(const GlobalObject& aGlobal,
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,
const GetNotificationOptions& aFilter,
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();
nsPIDOMWindow* GetParentObject()
@ -233,15 +280,20 @@ public:
bool AddRefObject();
void ReleaseObject();
static NotificationPermission GetPermission(nsIGlobalObject* aGlobal,
ErrorResult& aRv);
static NotificationPermission GetPermissionInternal(nsIPrincipal* aPrincipal,
ErrorResult& rv);
bool DispatchClickEvent();
bool DispatchNotificationClickEvent();
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,
const nsAString& aTag, const nsAString& aIconUrl,
const NotificationBehavior& aBehavior, nsIGlobalObject* aGlobal);
const NotificationBehavior& aBehavior);
static already_AddRefed<Notification> CreateInternal(nsIGlobalObject* aGlobal,
const nsAString& aID,
@ -277,14 +329,29 @@ protected:
return NotificationDirection::Auto;
}
static nsresult GetOrigin(nsPIDOMWindow* aWindow, nsString& aOrigin);
nsresult GetOriginWorker(nsString& aOrigin);
static nsresult GetOrigin(nsIPrincipal* aPrincipal, nsString& aOrigin);
void GetAlertName(nsAString& aRetval)
{
workers::AssertIsOnMainThread();
if (mAlertName.IsEmpty()) {
SetAlertName();
}
aRetval = mAlertName;
}
void GetScope(nsAString& aScope)
{
aScope = mScope;
}
void
SetScope(const nsAString& aScope)
{
MOZ_ASSERT(mScope.IsEmpty());
mScope = aScope;
}
const nsString mID;
const nsString mTitle;
const nsString mBody;
@ -299,6 +366,7 @@ protected:
nsCOMPtr<nsIVariant> mData;
nsString mAlertName;
nsString mScope;
// Main thread only.
bool mIsClosed;
@ -314,11 +382,25 @@ protected:
private:
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();
nsresult PersistNotification();
void UnpersistNotification();
void
SetAlertName();
bool IsTargetThread() const
{
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";
const DEBUG = false;
const DEBUG = true;
function debug(s) { dump("-*- NotificationStorage.js: " + s + "\n"); }
const Cc = Components.classes;
@ -84,8 +84,8 @@ NotificationStorage.prototype = {
},
put: function(origin, id, title, dir, lang, body, tag, icon, alertName,
data, behavior) {
if (DEBUG) { debug("PUT: " + id + ": " + title); }
data, behavior, serviceWorkerRegistrationID) {
if (DEBUG) { debug("PUT: " + origin + " " + id + ": " + title); }
var notification = {
id: id,
title: title,
@ -98,7 +98,8 @@ NotificationStorage.prototype = {
timestamp: new Date().getTime(),
origin: origin,
data: data,
mozbehavior: behavior
mozbehavior: behavior,
serviceWorkerRegistrationID: serviceWorkerRegistrationID,
};
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) {
if (DEBUG) { debug("DELETE: " + id); }
var notification = this._notifications[id];
@ -211,23 +231,30 @@ NotificationStorage.prototype = {
}
// Pass each notification back separately.
// The callback is called asynchronously to match the behaviour when
// fetching from the database.
notifications.forEach(function(notification) {
try {
callback.handle(notification.id,
notification.title,
notification.dir,
notification.lang,
notification.body,
notification.tag,
notification.icon,
notification.data,
notification.mozbehavior);
Services.tm.currentThread.dispatch(
callback.handle.bind(callback,
notification.id,
notification.title,
notification.dir,
notification.lang,
notification.body,
notification.tag,
notification.icon,
notification.data,
notification.mozbehavior,
notification.serviceWorkerRegistrationID),
Ci.nsIThread.DISPATCH_NORMAL);
} catch (e) {
if (DEBUG) { debug("Error calling callback handle: " + e); }
}
});
try {
callback.done();
Services.tm.currentThread.dispatch(callback.done,
Ci.nsIThread.DISPATCH_NORMAL);
} catch (e) {
if (DEBUG) { debug("Error calling callback done: " + e); }
}

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

@ -18,11 +18,13 @@ EXTRA_JS_MODULES += [
EXPORTS.mozilla.dom += [
'DesktopNotification.h',
'Notification.h',
'NotificationEvent.h',
]
UNIFIED_SOURCES += [
'DesktopNotification.cpp',
'Notification.cpp',
'NotificationEvent.cpp',
]
FAIL_ON_WARNINGS = True

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

@ -35,7 +35,7 @@ function start() {
canvas = document.getElementById("two");
paintCanvas();
mozRequestAnimationFrame(moveSomething);
requestAnimationFrame(moveSomething);
}
function paintCanvas() {
@ -52,7 +52,7 @@ function moveSomething() {
return finish();
}
mozRequestAnimationFrame(moveSomething);
requestAnimationFrame(moveSomething);
}
function finish() {

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

@ -1619,9 +1619,9 @@ PromiseWorkerProxy::RunCallback(JSContext* aCx,
{
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 (mCleanedUp) {
if (IsClean()) {
return;
}

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

@ -43,9 +43,10 @@ var MockServices = (function () {
setTimeout(function () {
listener.observe(null, "alertshow", cookie);
}, 100);
setTimeout(function () {
listener.observe(null, "alertclickcallback", cookie);
}, 100);
}
// ?? SpecialPowers.wrap(alertListener).observe(null, "alertclickcallback", cookie);
},
showAppNotification: function(aImageUrl, aTitle, aText, aAlertListener, aDetails) {

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

@ -68,7 +68,7 @@ dictionary NotificationOptions {
};
dictionary GetNotificationOptions {
DOMString tag;
DOMString tag = "";
};
dictionary NotificationBehavior {
@ -93,3 +93,9 @@ enum NotificationDirection {
"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
[Func="mozilla::dom::workers::ServiceWorkerVisible",
// 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 {
readonly attribute USVString scriptURL;
readonly attribute ServiceWorkerState state;

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

@ -335,6 +335,7 @@ WEBIDL_FILES = [
'NodeIterator.webidl',
'NodeList.webidl',
'Notification.webidl',
'NotificationEvent.webidl',
'NotifyPaintEvent.webidl',
'OfflineAudioCompletionEvent.webidl',
'OfflineAudioContext.webidl',

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

@ -66,7 +66,6 @@ using mozilla::dom::cache::Cache;
using mozilla::dom::cache::CacheStorage;
using mozilla::dom::Promise;
using mozilla::dom::PromiseNativeHandler;
using mozilla::dom::workers::exceptions::ThrowDOMExceptionForNSResult;
using mozilla::ErrorResult;
using mozilla::ipc::PrincipalInfo;
using mozilla::UniquePtr;
@ -151,13 +150,6 @@ ChannelFromScriptURL(nsIPrincipal* principal,
return NS_ERROR_DOM_SECURITY_ERR;
}
} 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.
// This allows workers in sandboxed documents to load data URLs
// (and other URLs that inherit their principal from their
@ -283,6 +275,8 @@ struct ScriptLoadInfo
CacheStatus mCacheStatus;
Maybe<bool> mMutedErrorFlag;
bool Finished() const
{
return mLoadingFinished && !mCachePromise && !mChannel;
@ -955,12 +949,33 @@ private:
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;
nsresult rv = aLoader->GetRequest(getter_AddRefs(request));
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);
if (httpChannel) {
bool requestSucceeded;
@ -996,9 +1011,6 @@ private:
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
NS_ASSERTION(channel, "This should never fail!");
// Figure out what we actually loaded.
nsCOMPtr<nsIURI> finalURI;
rv = NS_GetFinalChannelURI(channel, getter_AddRefs(finalURI));
@ -1104,6 +1116,18 @@ private:
ScriptLoadInfo& loadInfo = mLoadInfos[aIndex];
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.
nsIDocument* parentDoc = mWorkerPrivate->GetDocument();
@ -1126,8 +1150,6 @@ private:
nsILoadGroup* loadGroup = mWorkerPrivate->GetLoadGroup();
MOZ_ASSERT(loadGroup);
nsCOMPtr<nsIPrincipal> responsePrincipal =
PrincipalInfoToPrincipal(*aPrincipalInfo);
mozilla::DebugOnly<bool> equal = false;
MOZ_ASSERT(responsePrincipal && NS_SUCCEEDED(responsePrincipal->Equals(principal, &equal)));
MOZ_ASSERT(equal);
@ -1567,7 +1589,7 @@ CacheScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aCont
return NS_OK;
}
class ChannelGetterRunnable final : public nsRunnable
class ChannelGetterRunnable final : public nsRunnable
{
WorkerPrivate* mParentWorker;
nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
@ -1720,6 +1742,9 @@ ScriptExecutorRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
options.setVersion(JSVERSION_LATEST);
}
MOZ_ASSERT(loadInfo.mMutedErrorFlag.isSome());
options.setMutedErrors(loadInfo.mMutedErrorFlag.valueOr(true));
JS::SourceBufferHolder srcBuf(loadInfo.mScriptTextBuf,
loadInfo.mScriptTextLength,
JS::SourceBufferHolder::GiveOwnership);

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

@ -79,16 +79,19 @@ namespace {
class CancelChannelRunnable final : public nsRunnable
{
nsMainThreadPtrHandle<nsIInterceptedChannel> mChannel;
const nsresult mStatus;
public:
explicit CancelChannelRunnable(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel)
CancelChannelRunnable(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
nsresult aStatus)
: mChannel(aChannel)
, mStatus(aStatus)
{
}
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
nsresult rv = mChannel->Cancel();
nsresult rv = mChannel->Cancel(mStatus);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
@ -146,15 +149,17 @@ class RespondWithHandler final : public PromiseNativeHandler
nsMainThreadPtrHandle<nsIInterceptedChannel> mInterceptedChannel;
nsMainThreadPtrHandle<ServiceWorker> mServiceWorker;
RequestMode mRequestMode;
bool mIsClientRequest;
public:
NS_DECL_ISUPPORTS
RespondWithHandler(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
nsMainThreadPtrHandle<ServiceWorker>& aServiceWorker,
RequestMode aRequestMode)
RequestMode aRequestMode, bool aIsClientRequest)
: mInterceptedChannel(aChannel)
, mServiceWorker(aServiceWorker)
, mRequestMode(aRequestMode)
, mIsClientRequest(aIsClientRequest)
{
}
@ -162,7 +167,7 @@ public:
void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
void CancelRequest();
void CancelRequest(nsresult aStatus);
private:
~RespondWithHandler() {}
};
@ -192,7 +197,8 @@ void RespondWithCopyComplete(void* aClosure, nsresult aStatus)
data->mInternalResponse,
data->mWorkerChannelInfo);
} else {
event = new CancelChannelRunnable(data->mInterceptedChannel);
event = new CancelChannelRunnable(data->mInterceptedChannel,
NS_ERROR_INTERCEPTION_FAILED);
}
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(event)));
}
@ -200,20 +206,28 @@ void RespondWithCopyComplete(void* aClosure, nsresult aStatus)
class MOZ_STACK_CLASS AutoCancel
{
nsRefPtr<RespondWithHandler> mOwner;
nsresult mStatus;
public:
explicit AutoCancel(RespondWithHandler* aOwner)
: mOwner(aOwner)
, mStatus(NS_ERROR_INTERCEPTION_FAILED)
{
}
~AutoCancel()
{
if (mOwner) {
mOwner->CancelRequest();
mOwner->CancelRequest(mStatus);
}
}
void SetCancelStatus(nsresult aStatus)
{
MOZ_ASSERT(NS_FAILED(aStatus));
mStatus = aStatus;
}
void Reset()
{
mOwner = nullptr;
@ -246,17 +260,35 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
// security implications are not a complete disaster.
if (response->Type() == ResponseType::Opaque &&
!worker->OpaqueInterceptionEnabled()) {
autoCancel.SetCancelStatus(NS_ERROR_OPAQUE_INTERCEPTION_DISABLED);
return;
}
// Section 4.2, step 2.2 "If either response's type is "opaque" and request's
// mode is not "no-cors" or response's type is error, return a network error."
if (((response->Type() == ResponseType::Opaque) && (mRequestMode != RequestMode::No_cors)) ||
response->Type() == ResponseType::Error) {
// Section 4.2, step 2.2:
// If one of the following conditions is true, return a network error:
// * response's type is "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;
}
if (NS_WARN_IF(response->BodyUsed())) {
autoCancel.SetCancelStatus(NS_ERROR_INTERCEPTED_USED_RESPONSE);
return;
}
@ -302,13 +334,14 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
void
RespondWithHandler::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
{
CancelRequest();
CancelRequest(NS_ERROR_INTERCEPTION_FAILED);
}
void
RespondWithHandler::CancelRequest()
RespondWithHandler::CancelRequest(nsresult aStatus)
{
nsCOMPtr<nsIRunnable> runnable = new CancelChannelRunnable(mInterceptedChannel);
nsCOMPtr<nsIRunnable> runnable =
new CancelChannelRunnable(mInterceptedChannel, aStatus);
NS_DispatchToMainThread(runnable);
}
@ -337,9 +370,11 @@ FetchEvent::RespondWith(const ResponseOrPromise& aArg, ErrorResult& aRv)
} else if (aArg.IsPromise()) {
promise = &aArg.GetAsPromise();
}
nsRefPtr<InternalRequest> ir = mRequest->GetInternalRequest();
mWaitToRespond = true;
nsRefPtr<RespondWithHandler> handler =
new RespondWithHandler(mChannel, mServiceWorker, mRequest->Mode());
new RespondWithHandler(mChannel, mServiceWorker, mRequest->Mode(),
ir->IsClientRequest());
promise->AppendNativeHandler(handler);
}

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

@ -39,6 +39,7 @@
#include "mozilla/dom/indexedDB/IDBFactory.h"
#include "mozilla/dom/InternalHeaders.h"
#include "mozilla/dom/Navigator.h"
#include "mozilla/dom/NotificationEvent.h"
#include "mozilla/dom/PromiseNativeHandler.h"
#include "mozilla/dom/Request.h"
#include "mozilla/dom/RootedDictionary.h"
@ -2282,6 +2283,133 @@ ServiceWorkerManager::SendPushSubscriptionChangeEvent(const nsACString& aOriginA
#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
ServiceWorkerManager::GetReadyPromise(nsIDOMWindow* aWindow,
nsISupports** aPromise)

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

@ -6,6 +6,7 @@
#include "ServiceWorkerRegistration.h"
#include "mozilla/dom/Notification.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseWorkerProxy.h"
#include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
@ -595,6 +596,52 @@ ServiceWorkerRegistrationMainThread::Unregister(ErrorResult& aRv)
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>
ServiceWorkerRegistrationMainThread::GetPushManager(ErrorResult& aRv)
{
@ -1001,5 +1048,32 @@ WorkerListener::UpdateFound()
}
}
} // namespace dom
} // namespace mozilla
// Notification API extension.
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/workers/bindings/WorkerFeature.h"
// Support for Notification API extension.
#include "mozilla/dom/NotificationBinding.h"
class nsPIDOMWindow;
namespace mozilla {
@ -111,6 +114,16 @@ public:
JSObject*
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>
GetInstalling() override;
@ -190,6 +203,16 @@ public:
JSObject*
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>
GetInstalling() override;

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

@ -208,6 +208,7 @@ public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerGlobalScope,
WorkerGlobalScope)
IMPL_EVENT_HANDLER(notificationclick)
ServiceWorkerGlobalScope(WorkerPrivate* aWorkerPrivate, const nsACString& aScope);

Двоичный файл не отображается.

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

@ -21,10 +21,12 @@ function runTests() {
return testFetchAppResource('test_custom_content_type',
'customContentType', 'text/html');
})
.then(testRedirectedResponse)
.then(testRedirectedHttpsResponse)
.then(testCachedRedirectedResponse)
.then(testCachedRedirectedHttpsResponse)
// XXX: Cross-origin interceptions without CORS result in opaque responses
// which are illegal for navigations like iframes. (bug 1183313)
//.then(testRedirectedResponse)
//.then(testRedirectedHttpsResponse)
//.then(testCachedRedirectedResponse)
//.then(testCachedRedirectedHttpsResponse)
.then(done);
}
</script>

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

@ -93,6 +93,8 @@ support-files =
client_focus_worker.js
bug1151916_worker.js
bug1151916_driver.html
notificationclick.html
notificationclick.js
worker_updatefoundevent.js
worker_updatefoundevent2.js
updatefoundevent.html
@ -103,6 +105,11 @@ support-files =
periodic/register.html
periodic/wait_for_update.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/register.html
sanitize/example_check_and_unregister.html
@ -217,6 +224,9 @@ skip-if = !debug
[test_request_context_xslt.html]
[test_scopes.html]
[test_sandbox_intercept.html]
[test_notificationclick.html]
[test_notification_constructor_error.html]
[test_notification_get.html]
[test_sanitize.html]
[test_sanitize_domain.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",
// IMPORTANT: Do not change this list without review from a DOM peer!
"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!
"Performance",
// 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>
<script type="text/javascript">
SimpleTest.requestFlakyTimeout("Mock alert service dispatches show event.");
SimpleTest.requestFlakyTimeout("Mock alert service dispatches show and click events.");
function runTest() {
MockServices.register();

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

@ -944,8 +944,6 @@ XULDocument::AttributeChanged(nsIDocument* aDocument,
AddElementToRefMap(aElement);
}
nsresult rv;
// Synchronize broadcast listeners
if (mBroadcasterMap &&
CanBroadcast(aNameSpaceID, aAttribute)) {
@ -1012,8 +1010,10 @@ XULDocument::AttributeChanged(nsIDocument* aDocument,
if (!persist.IsEmpty()) {
// XXXldb This should check that it's a token, not just a substring.
if (persist.Find(nsDependentAtomString(aAttribute)) >= 0) {
rv = Persist(aElement, kNameSpaceID_None, aAttribute);
if (NS_FAILED(rv)) return;
nsContentUtils::AddScriptRunner(NS_NewRunnableMethodWithArgs
<nsIContent*, int32_t, nsIAtom*>
(this, &XULDocument::DoPersist, aElement, kNameSpaceID_None,
aAttribute));
}
}
}

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

@ -298,6 +298,12 @@ protected:
nsresult
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;

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

@ -1883,6 +1883,11 @@ gfxWindowsPlatform::InitD3D11Devices()
}
bool useWARP = false;
bool allowWARP = false;
if (IsWin8OrLater()) {
allowWARP = true;
}
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
if (gfxInfo) {
@ -1906,7 +1911,7 @@ gfxWindowsPlatform::InitD3D11Devices()
}
}
useWARP = true;
useWARP = allowWARP;
}
}
}
@ -1942,7 +1947,7 @@ gfxWindowsPlatform::InitD3D11Devices()
if (!gfxPrefs::LayersD3D11DisableWARP()) {
return;
}
useWARP = true;
useWARP = allowWARP;
}
}
@ -1964,7 +1969,7 @@ gfxWindowsPlatform::InitD3D11Devices()
return;
}
useWARP = true;
useWARP = allowWARP;
adapter = nullptr;
}
@ -1974,7 +1979,7 @@ gfxWindowsPlatform::InitD3D11Devices()
return;
}
useWARP = true;
useWARP = allowWARP;
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
// and this access might be on a sparse property.
if (ElementAccessHasExtraIndexedProperty(constraints(), obj) && failedBoundsCheck_) {
if (ElementAccessHasExtraIndexedProperty(this, obj) && failedBoundsCheck_) {
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
return true;
}
@ -8188,7 +8188,7 @@ IonBuilder::getStaticTypedArrayObject(MDefinition* obj, MDefinition* index)
return nullptr;
}
if (ElementAccessHasExtraIndexedProperty(constraints(), obj)) {
if (ElementAccessHasExtraIndexedProperty(this, obj)) {
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
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.
bool readOutOfBounds =
types->hasType(TypeSet::UndefinedType()) &&
!ElementAccessHasExtraIndexedProperty(constraints(), obj);
!ElementAccessHasExtraIndexedProperty(this, obj);
MIRType knownType = MIRType_Value;
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
// and this access might be on a sparse property.
if (ElementAccessHasExtraIndexedProperty(constraints(), object) && failedBoundsCheck_) {
if (ElementAccessHasExtraIndexedProperty(this, object) && failedBoundsCheck_) {
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
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
// chain, we know that we anen't missing any setters by overwriting the hole with
// 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.
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
// 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))
current->add(MPostWriteBarrier::New(alloc(), obj, value));
@ -11068,7 +11068,7 @@ IonBuilder::getPropTryCache(bool* emitted, MDefinition* obj, PropertyName* name,
// reflect such possible values.
if (barrier != BarrierKind::TypeSet) {
BarrierKind protoBarrier =
PropertyReadOnPrototypeNeedsTypeBarrier(this, constraints(), obj, name, types);
PropertyReadOnPrototypeNeedsTypeBarrier(this, obj, name, types);
if (protoBarrier != BarrierKind::NoBarrier) {
MOZ_ASSERT(barrier <= protoBarrier);
barrier = protoBarrier;
@ -12373,7 +12373,7 @@ IonBuilder::jsop_in()
break;
}
if (ElementAccessHasExtraIndexedProperty(constraints(), obj))
if (ElementAccessHasExtraIndexedProperty(this, obj))
break;
return jsop_in_dense(obj, id, unboxedType);

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

@ -649,7 +649,7 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode)
return InliningStatus_NotInlined;
}
if (ArrayPrototypeHasIndexedProperty(constraints(), script())) {
if (ArrayPrototypeHasIndexedProperty(this, script())) {
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
return InliningStatus_NotInlined;
}
@ -791,7 +791,7 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo)
return InliningStatus_NotInlined;
}
if (ArrayPrototypeHasIndexedProperty(constraints(), script())) {
if (ArrayPrototypeHasIndexedProperty(this, script())) {
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
return InliningStatus_NotInlined;
}
@ -890,7 +890,7 @@ IonBuilder::inlineArrayConcat(CallInfo& callInfo)
}
// Watch out for indexed properties on the prototype.
if (ArrayPrototypeHasIndexedProperty(constraints(), script())) {
if (ArrayPrototypeHasIndexedProperty(this, script())) {
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
return InliningStatus_NotInlined;
}
@ -1006,7 +1006,7 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo)
}
// Watch out for indexed properties on the prototype.
if (ArrayPrototypeHasIndexedProperty(constraints(), script())) {
if (ArrayPrototypeHasIndexedProperty(this, script())) {
trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps);
return InliningStatus_NotInlined;
}
@ -2127,7 +2127,7 @@ IonBuilder::inlineDefineDataProperty(CallInfo& callInfo)
MDefinition* id = callInfo.getArg(1);
MDefinition* value = callInfo.getArg(2);
if (ElementAccessHasExtraIndexedProperty(constraints(), obj))
if (ElementAccessHasExtraIndexedProperty(this, obj))
return InliningStatus_NotInlined;
// setElemTryDense will push the value as the result of the define instead

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

@ -4884,15 +4884,14 @@ jit::ElementAccessMightBeCopyOnWrite(CompilerConstraintList* constraints, MDefin
}
bool
jit::ElementAccessHasExtraIndexedProperty(CompilerConstraintList* constraints,
MDefinition* obj)
jit::ElementAccessHasExtraIndexedProperty(IonBuilder* builder, MDefinition* obj)
{
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 TypeCanHaveExtraIndexedProperties(constraints, types);
return TypeCanHaveExtraIndexedProperties(builder, types);
}
MIRType
@ -5056,7 +5055,6 @@ jit::PropertyReadNeedsTypeBarrier(JSContext* propertycx,
BarrierKind
jit::PropertyReadOnPrototypeNeedsTypeBarrier(IonBuilder* builder,
CompilerConstraintList* constraints,
MDefinition* obj, PropertyName* name,
TemporaryTypeSet* observed)
{
@ -5074,13 +5072,14 @@ jit::PropertyReadOnPrototypeNeedsTypeBarrier(IonBuilder* builder,
if (!key)
continue;
while (true) {
if (!key->hasStableClassAndProto(constraints))
if (!key->hasStableClassAndProto(builder->constraints()))
return BarrierKind::TypeSet;
if (!key->proto().isObject())
break;
JSObject* proto = builder->checkNurseryObject(key->proto().toObject());
key = TypeSet::ObjectKey::get(proto);
BarrierKind kind = PropertyReadNeedsTypeBarrier(constraints, key, name, observed);
BarrierKind kind = PropertyReadNeedsTypeBarrier(builder->constraints(),
key, name, observed);
if (kind == 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
PropertyTypeIncludes(TempAllocator& alloc, HeapTypeSetKey property,
MDefinition* value, MIRType implicitType)

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

@ -13719,8 +13719,7 @@ bool ElementAccessIsAnyTypedArray(CompilerConstraintList* constraints,
Scalar::Type* arrayType);
bool ElementAccessIsPacked(CompilerConstraintList* constraints, MDefinition* obj);
bool ElementAccessMightBeCopyOnWrite(CompilerConstraintList* constraints, MDefinition* obj);
bool ElementAccessHasExtraIndexedProperty(CompilerConstraintList* constraints,
MDefinition* obj);
bool ElementAccessHasExtraIndexedProperty(IonBuilder* builder, MDefinition* obj);
MIRType DenseNativeElementType(CompilerConstraintList* constraints, MDefinition* obj);
BarrierKind PropertyReadNeedsTypeBarrier(JSContext* propertycx,
CompilerConstraintList* constraints,
@ -13731,7 +13730,6 @@ BarrierKind PropertyReadNeedsTypeBarrier(JSContext* propertycx,
MDefinition* obj, PropertyName* name,
TemporaryTypeSet* observed);
BarrierKind PropertyReadOnPrototypeNeedsTypeBarrier(IonBuilder* builder,
CompilerConstraintList* constraints,
MDefinition* obj, PropertyName* name,
TemporaryTypeSet* observed);
bool PropertyReadIsIdempotent(CompilerConstraintList* constraints,
@ -13745,6 +13743,8 @@ bool PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList*
MBasicBlock* current, MDefinition** pobj,
PropertyName* name, MDefinition** pvalue,
bool canModify, MIRType implicitType = MIRType_None);
bool ArrayPrototypeHasIndexedProperty(IonBuilder* builder, JSScript* script);
bool TypeCanHaveExtraIndexedProperties(IonBuilder* builder, TemporaryTypeSet* types);
} // namespace jit
} // namespace js

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

@ -2829,6 +2829,19 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
void compareExchange32(const T& mem, Register oldval, Register newval, Register 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>
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);
}
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>
void atomicFetchSub8SignExtend(const S& value, const T& mem, Register temp, Register 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
// this instruction.
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.
// 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
@ -3012,7 +3038,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
syncStackPtr();
BufferOffset offset = nextOffset();
BufferOffset loadOffset;
{
vixl::UseScratchRegisterScope temps(this);

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

@ -2449,57 +2449,6 @@ js::ClassCanHaveExtraProperties(const Class* 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
TypeZone::processPendingRecompiles(FreeOp* fop, RecompileInfoVector& recompiles)
{

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

@ -974,17 +974,6 @@ inline bool isInlinableCall(jsbytecode* pc);
bool
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. */
class TypeScript
{

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

@ -1939,6 +1939,15 @@ js::TryConvertToUnboxedLayout(ExclusiveContext* cx, Shape* templateShape,
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);
// The entire object must be allocatable inline.

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

@ -11,7 +11,7 @@
if (report) {
opener.postMessage("callbackHappened", "*");
}
window.mozRequestAnimationFrame(g);
window.requestAnimationFrame(g);
}
g();

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

@ -21,24 +21,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=569520
SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("untriaged");
var startNow = Date.now();
var start = window.mozAnimationStartTime;
var start = window.performance.now();
var firstListenerArg;
var secondListenerArg;
var thirdListenerTime;
// callback arg is wallclock from mozRequestAnimationFrame
// callback arg is in the same timeline as performance.now()
function thirdListener(t) {
thirdListenerTime = t;
// They really shouldn't be more than 100ms apart, but we can get weird
// 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
ok(secondListenerArg >= firstListenerArg, // callback args from consecutive requestAnimationFrame
"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();
}
@ -46,7 +44,7 @@ function thirdListener(t) {
// callback arg is from requestAnimationFrame and comparable to performance.now()
function secondListener(t) {
secondListenerArg = t;
mozRequestAnimationFrame(thirdListener);
requestAnimationFrame(thirdListener);
}
function firstListener(t) {

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

@ -21,24 +21,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=569520
SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("untriaged");
var startNow = Date.now();
var start = window.mozAnimationStartTime;
var start = window.performance.now();
var firstListenerArg;
var secondListenerArg;
var thirdListenerTime;
// callback arg is wallclock from mozRequestAnimationFrame
// callback arg is in the same timeline as performance.now()
function thirdListener(t) {
thirdListenerTime = t;
// They really shouldn't be more than 100ms apart, but we can get weird
// 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
ok(secondListenerArg >= firstListenerArg, // callback args from consecutive requestAnimationFrame
"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();
}
@ -46,7 +44,7 @@ function thirdListener(t) {
// callback arg is from requestAnimationFrame and comparable to performance.now()
function secondListener(t) {
secondListenerArg = t;
mozRequestAnimationFrame(thirdListener);
requestAnimationFrame(thirdListener);
}
function firstListener(t) {

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

@ -19,7 +19,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=607529
SimpleTest.waitForExplicitFinish();
/* 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. */
var doneOneLoad = false;

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

@ -42,7 +42,7 @@ function onScroll() {
function doTest() {
window.getSelection().collapse(inner.firstChild, 0);
window.mozRequestAnimationFrame(onFrame);
window.requestAnimationFrame(onFrame);
d.onscroll = onScroll;
sendKey("DOWN");
}
@ -50,7 +50,7 @@ function doTest() {
function prepareTest() {
// Start the test after we've gotten at least one rAF callback, to make sure
// that rAF is no longer throttled. (See bug 1145439.)
window.mozRequestAnimationFrame(function() {
window.requestAnimationFrame(function() {
SpecialPowers.pushPrefEnv({"set":[[smoothScrollPref, false]]}, doTest);
});
}

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

@ -48,7 +48,7 @@ function runTest() {
// Delay until next repaint in case stuff is asynchronous. Also
// take a trip through the event loop.
setTimeout(function() {
window.mozRequestAnimationFrame(function() {
window.requestAnimationFrame(function() {
is(sel.anchorNode, target.firstChild, "Should have selected 'target' text node");
is(sel.anchorOffset, 1, "Selection should have moved left one character");
// We should not have needed to scroll the caret into view

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

@ -5,8 +5,6 @@ var property = "left";
var rfa = null;
if (window.requestAnimationFrame) {
rfa = requestAnimationFrame;
} else if (window.mozRequestAnimationFrame) {
rfa = mozRequestAnimationFrame;
} else if (window.webkitRequestAnimationFrame) {
rfa = webkitRequestAnimationFrame;
} else if (window.msRequestAnimationFrame) {

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

@ -1,8 +1,6 @@
var rfa = null;
if (window.requestAnimationFrame) {
rfa = requestAnimationFrame;
} else if (window.mozRequestAnimationFrame) {
rfa = mozRequestAnimationFrame;
} else if (window.webkitRequestAnimationFrame) {
rfa = webkitRequestAnimationFrame;
} else if (window.msRequestAnimationFrame) {

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

@ -5,8 +5,6 @@ var property = "top";
var rfa = null;
if (window.requestAnimationFrame) {
rfa = requestAnimationFrame;
} else if (window.mozRequestAnimationFrame) {
rfa = mozRequestAnimationFrame;
} else if (window.webkitRequestAnimationFrame) {
rfa = webkitRequestAnimationFrame;
} else if (window.msRequestAnimationFrame) {

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

@ -89,13 +89,15 @@ InterceptedJARChannel::FinishSynthesizedResponse()
}
NS_IMETHODIMP
InterceptedJARChannel::Cancel()
InterceptedJARChannel::Cancel(nsresult aStatus)
{
MOZ_ASSERT(NS_FAILED(aStatus));
if (!mChannel) {
return NS_ERROR_FAILURE;
}
nsresult rv = mChannel->Cancel(NS_BINDING_ABORTED);
nsresult rv = mChannel->Cancel(aStatus);
NS_ENSURE_SUCCESS(rv, rv);
mResponseBody = nullptr;
mChannel = nullptr;

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

@ -1022,7 +1022,7 @@ pref("dom.allow_scripts_to_close_windows", false);
pref("dom.disable_open_during_load", false);
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.storage.enabled", true);

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

@ -26,7 +26,7 @@ class ChannelInfo;
* which do not implement nsIChannel.
*/
[scriptable, uuid(f2c07a6b-366d-4ef4-85ab-a77f4bcb1646)]
[scriptable, uuid(1062c96a-d73c-4ad5-beb7-6e803e414973)]
interface nsIInterceptedChannel : nsISupports
{
/**
@ -59,7 +59,7 @@ interface nsIInterceptedChannel : nsISupports
* @return NS_ERROR_FAILURE if the response has already been synthesized or
* the original request has been instructed to continue.
*/
void cancel();
void cancel(in nsresult status);
/**
* 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
// cleaned up to avoid leaks.
if (mInterceptedChannel) {
mInterceptedChannel->Cancel();
mInterceptedChannel->Cancel(NS_ERROR_INTERCEPTION_FAILED);
mInterceptedChannel = nullptr;
}
}

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

@ -230,15 +230,17 @@ InterceptedChannelChrome::FinishSynthesizedResponse()
}
NS_IMETHODIMP
InterceptedChannelChrome::Cancel()
InterceptedChannelChrome::Cancel(nsresult aStatus)
{
MOZ_ASSERT(NS_FAILED(aStatus));
if (!mChannel) {
return NS_ERROR_FAILURE;
}
// we need to use AsyncAbort instead of Cancel since there's no active pump
// 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);
return NS_OK;
}
@ -335,15 +337,17 @@ InterceptedChannelContent::FinishSynthesizedResponse()
}
NS_IMETHODIMP
InterceptedChannelContent::Cancel()
InterceptedChannelContent::Cancel(nsresult aStatus)
{
MOZ_ASSERT(NS_FAILED(aStatus));
if (!mChannel) {
return NS_ERROR_FAILURE;
}
// we need to use AsyncAbort instead of Cancel since there's no active pump
// 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);
mChannel = nullptr;
mStreamListener = nullptr;

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

@ -81,7 +81,7 @@ public:
NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) 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;
virtual void NotifyController() override;
@ -108,7 +108,7 @@ public:
NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) 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;
virtual void NotifyController() override;

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

@ -188,7 +188,7 @@ add_test(function() {
// ensure that the intercepted channel can be cancelled
add_test(function() {
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,
CL_EXPECT_FAILURE), null);

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

@ -1082,7 +1082,7 @@
<p>Euro sign: €</p>
<script>
window.onload = function() {
window.mozRequestAnimationFrame(function() {
window.requestAnimationFrame(function() {
parent.document.documentElement.removeAttribute("class");
});
}

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