diff --git a/dom/permission/PermissionStatus.cpp b/dom/permission/PermissionStatus.cpp index f9662ac814f..e966b18c835 100644 --- a/dom/permission/PermissionStatus.cpp +++ b/dom/permission/PermissionStatus.cpp @@ -6,6 +6,7 @@ #include "mozilla/dom/PermissionStatus.h" +#include "mozilla/AsyncEventDispatcher.h" #include "mozilla/Services.h" #include "mozilla/UniquePtr.h" #include "nsIPermissionManager.h" @@ -113,5 +114,17 @@ PermissionStatus::GetPrincipal() const return doc->NodePrincipal(); } +void +PermissionStatus::PermissionChanged() +{ + auto oldState = mState; + UpdateState(); + if (mState != oldState) { + nsRefPtr eventDispatcher = + new AsyncEventDispatcher(this, NS_LITERAL_STRING("change"), false); + eventDispatcher->PostDOMEvent(); + } +} + } // namespace dom } // namespace mozilla diff --git a/dom/permission/PermissionStatus.h b/dom/permission/PermissionStatus.h index 605d99d6505..61e3df73980 100644 --- a/dom/permission/PermissionStatus.h +++ b/dom/permission/PermissionStatus.h @@ -44,7 +44,7 @@ private: nsIPrincipal* GetPrincipal() const; - void PermissionChanged() {} + void PermissionChanged(); PermissionName mName; PermissionState mState; diff --git a/dom/permission/tests/test_permissions_api.html b/dom/permission/tests/test_permissions_api.html index bf122631e5e..1f45150d1b9 100644 --- a/dom/permission/tests/test_permissions_api.html +++ b/dom/permission/tests/test_permissions_api.html @@ -68,6 +68,38 @@ function checkUserVisiblePushPermission() { error => ok(true, `query should have rejected for userVisible push`)); } +function promiseStateChanged(state) { + return Promise.all(PERMISSIONS.map(x => { + return navigator.permissions.query({ name: x.name }).then( + result => { + return new Promise((resolve, reject) => { + result.onchange = () => { + result.onchange = null; + is(result.state, state, `state correctly changed for '${x.name}'`); + resolve(); + }; + }); + }, + error => ok(false, `query should not have rejected for '${x.name}'`)); + })); +} + +function testStatusOnChange() { + return new Promise((resolve, reject) => { + SpecialPowers.popPermissions(() => { + let permMgr = SpecialPowers.Ci.nsIPermissionManager; + + let promiseGranted = promiseStateChanged('granted'); + setPermissions(permMgr.ALLOW_ACTION); + promiseGranted.then(() => { + let promisePrompt = promiseStateChanged('prompt'); + SpecialPowers.popPermissions(); + return promisePrompt; + }).then(resolve); + }); + }); +} + function runTests() { let permMgr = SpecialPowers.Ci.nsIPermissionManager; @@ -82,6 +114,7 @@ function runTests() { .then(() => checkPermissions('granted')) .then(() => setPermissions(permMgr.DENY_ACTION)) .then(() => checkPermissions('denied')) + .then(testStatusOnChange) .then(SimpleTest.finish) .catch ((e) => { ok(false, 'Unexpected error ' + e);