merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2016-06-01 15:07:48 +02:00
commit c2494b5883
359 changed files with 10072 additions and 2909 deletions

View File

@ -43,6 +43,7 @@ _OPT\.OBJ/
^js/src/autom4te.cache$
# SpiderMonkey test result logs
^js/src/tests/results-.*\.(html|txt)$
^js/src/devtools/rootAnalysis/t/out
# Java HTML5 parser classes
^parser/html/java/(html|java)parser/

View File

@ -92,6 +92,17 @@ HTMLLIAccessible::Bounds() const
return rect;
}
bool
HTMLLIAccessible::InsertChildAt(uint32_t aIndex, Accessible* aChild)
{
// Adjust index if there's a bullet.
if (mBullet && aIndex == 0 && aChild != mBullet) {
return HyperTextAccessible::InsertChildAt(aIndex + 1, aChild);
}
return HyperTextAccessible::InsertChildAt(aIndex, aChild);
}
////////////////////////////////////////////////////////////////////////////////
// HTMLLIAccessible: public

View File

@ -53,6 +53,8 @@ public:
virtual a11y::role NativeRole() override;
virtual uint64_t NativeState() override;
virtual bool InsertChildAt(uint32_t aIndex, Accessible* aChild) override;
// HTMLLIAccessible
HTMLListBulletAccessible* Bullet() const { return mBullet; }
void UpdateBullet(bool aHasBullet);

View File

@ -157,7 +157,7 @@ public:
virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() override;
virtual Relation RelationByType(RelationType aRelationType) override;
bool InsertChildAt(uint32_t aIndex, Accessible* aChild) override;
virtual bool InsertChildAt(uint32_t aIndex, Accessible* aChild) override;
protected:
virtual ~HTMLTableAccessible() {}

View File

@ -82,6 +82,28 @@
this.onProcessed = function showProcessor_onProcessed()
{
testLiAccessibleTree();
gSequence.processNext();
}
};
function textReplaceProcessor()
{
this.liNode = getNode("li");
this.process = function textReplaceProcessor_process()
{
this.liNode.textContent = "hey";
}
this.onProcessed = function textReplaceProcessor_onProcessed()
{
var tree = {
LISTITEM: [
{ STATICTEXT: [] },
{ TEXT_LEAF: [] }
]
};
testAccessibleTree(this.liNode, tree);
SimpleTest.finish();
}
};
@ -89,8 +111,9 @@
////////////////////////////////////////////////////////////////////////////
// Test
var gSequence = null;
//gA11yEventDumpToConsole = true;
var gSequence = null;
function doTest()
{
testLiAccessibleTree();
@ -101,6 +124,8 @@
"hide HTML li");
gSequence.append(new showProcessor(), EVENT_SHOW, getNode("li"),
"show HTML li");
gSequence.append(new textReplaceProcessor(), EVENT_REORDER, getNode("li"),
"change text of HTML li");
gSequence.processNext(); // SimpleTest.finish() will be called in the end
}

View File

@ -1087,6 +1087,8 @@ pref("dom.performance.enable_notify_performance_timing", true);
pref("b2g.multiscreen.chrome_remote_url", "chrome://b2g/content/shell_remote.html");
pref("b2g.multiscreen.system_remote_url", "index_remote.html");
// Audio competing between tabs
pref("dom.audiochannel.audioCompeting", false);
// Because we can't have nice things.
#ifdef MOZ_GRAPHENE

View File

@ -1,47 +1,47 @@
[
{
"version": "gcc 4.9.3",
"size": 102421980,
"digest": "f25292aa93dc449e0472eee511c0ac15b5f1a4272ab76cf53ce5d20dc57f29e83da49ae1a9d9e994192647f75e13ae60f75ba2ac3cb9d26d5f5d6cabf88de921",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": true
"size" : 102421980,
"digest" : "f25292aa93dc449e0472eee511c0ac15b5f1a4272ab76cf53ce5d20dc57f29e83da49ae1a9d9e994192647f75e13ae60f75ba2ac3cb9d26d5f5d6cabf88de921",
"version" : "gcc 4.9.3",
"unpack" : true,
"filename" : "gcc.tar.xz",
"algorithm" : "sha512"
},
{
"hg_id" : "cd93f15a30ce",
"unpack" : true,
"algorithm" : "sha512",
"digest" : "541eb3842ab6b91bd87223cad7a5e4387ef3e496e5b580c8047b8b586bc7eb69fecf3c9eb8c45a1e0deebb53554f0e8acedfe1b4ca64d93b6d008f3f2eb11389",
"filename" : "sixgill.tar.xz",
"size" : 2626640,
"hg_id" : "8cb9c3fb039a+ tip",
"digest" : "36dc644e24c0aa824975ad8f5c15714445d5cb064d823000c3cb637e885199414d7df551e6b99233f0656dcf5760918192ef04113c486af37f3c489bb93ad029",
"size" : 2631908
},
{
"algorithm" : "sha512",
"filename" : "gtk3.tar.xz",
"setup" : "setup.sh",
"unpack" : true,
"digest" : "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
"size" : 12072532
},
{
"size" : 89319524,
"digest" : "5383d843c9f28abf0a6d254e9d975d96972d2c86d627ca836fa8e272a5d53230603b387d7d1499c49df7f84b1bb946946e800a85c88d968bdbe81c755fcb02e1",
"algorithm" : "sha512",
"filename" : "rustc.tar.xz",
"unpack" : true
},
{
"size": 12072532,
"digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"setup": "setup.sh",
"unpack": true
"algorithm" : "sha512",
"filename" : "sccache.tar.bz2",
"unpack" : true,
"digest" : "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"size" : 167175
},
{
"size": 89319524,
"digest": "5383d843c9f28abf0a6d254e9d975d96972d2c86d627ca836fa8e272a5d53230603b387d7d1499c49df7f84b1bb946946e800a85c88d968bdbe81c755fcb02e1",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true
},
{
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
"filename": "sccache.tar.bz2",
"unpack": true
},
{
"size": 31078810,
"digest": "2dffe4e5419a0c0c9908dc52b01cc07379a42e2aa8481be7a26bb8750b586b95bbac3fe57e64f5d37b43e206516ea70ad938a2e45858fdcf1e28258e70ae8d8c",
"algorithm": "sha512",
"filename": "moz-tt.tar.bz2",
"unpack": true
"filename" : "moz-tt.tar.bz2",
"algorithm" : "sha512",
"unpack" : true,
"digest" : "2dffe4e5419a0c0c9908dc52b01cc07379a42e2aa8481be7a26bb8750b586b95bbac3fe57e64f5d37b43e206516ea70ad938a2e45858fdcf1e28258e70ae8d8c",
"size" : 31078810
}
]

View File

@ -4069,11 +4069,11 @@ function updateUserContextUIVisibility()
/**
* Updates the User Context UI indicators if the browser is in a non-default context
*/
function updateUserContextUIIndicator(browser)
function updateUserContextUIIndicator()
{
let hbox = document.getElementById("userContext-icons");
let userContextId = browser.getAttribute("usercontextid");
let userContextId = gBrowser.selectedBrowser.getAttribute("usercontextid");
if (!userContextId) {
hbox.hidden = true;
return;
@ -6420,8 +6420,16 @@ function checkEmptyPageOrigin(browser = gBrowser.selectedBrowser,
let contentPrincipal = browser.contentPrincipal;
// Not all principals have URIs...
if (contentPrincipal.URI) {
// A manually entered about:blank URI is slightly magical:
if (uri.spec == "about:blank" && contentPrincipal.isNullPrincipal) {
// There are two specialcases involving about:blank. One is where
// the user has manually loaded it and it got created with a null
// principal. The other involves the case where we load
// some other empty page in a browser and the current page is the
// initial about:blank page (which has that as its principal, not
// just URI in which case it could be web-based). Especially in
// e10s, we need to tackle that case specifically to avoid race
// conditions when updating the URL bar.
if ((uri.spec == "about:blank" && contentPrincipal.isNullPrincipal) ||
contentPrincipal.URI.spec == "about:blank") {
return true;
}
return contentPrincipal.URI.equals(uri);

View File

@ -637,15 +637,22 @@
// pointing to their resolved jar: or file: URIs.
if (!(originalLocation && gInitialPages.includes(originalLocation.spec) &&
originalLocation != "about:blank" &&
this.mBrowser.initialPageLoadedFromURLBar != originalLocation.spec &&
this.mBrowser.currentURI && this.mBrowser.currentURI.spec == "about:blank")) {
// This will trigger clearing the location bar. Don't do it if
// we loaded off a blank browser and this is an initial page load
// (e.g. about:privatebrowsing, about:newtab, etc.) so we avoid
// clearing the location bar in case the user is typing in it.
// loading about:blank shouldn't trigger this, either, because its
// loads are "special".
// Indicating that we started a load will allow the location
// bar to be cleared when the load finishes.
// In order to not overwrite user-typed content, we avoid it
// (see if condition above) in a very specific case:
// If the load is of an 'initial' page (e.g. about:privatebrowsing,
// about:newtab, etc.), was not explicitly typed in the location
// bar by the user, is not about:blank (because about:blank can be
// loaded by websites under their principal), and the current
// page in the browser is about:blank (indicating it is a newly
// created or re-created browser, e.g. because it just switched
// remoteness or is a new tab/window).
this.mBrowser.urlbarChangeTracker.startedLoad();
}
delete this.mBrowser.initialPageLoadedFromURLBar;
// If the browser is loading it must not be crashed anymore
this.mTab.removeAttribute("crashed");
}
@ -1217,7 +1224,7 @@
this._adjustFocusAfterTabSwitch(this.mCurrentTab);
}
updateUserContextUIIndicator(gBrowser.selectedBrowser);
updateUserContextUIIndicator();
this.tabContainer._setPositionalAttributes();
@ -4328,7 +4335,12 @@
tab.setUserContextId(data.userContextId);
}
updateUserContextUIIndicator(browser);
// We don't want to update the container icon and identifier if
// this is not the selected browser.
if (browser == gBrowser.selectedBrowser) {
updateUserContextUIIndicator();
}
break;
}
case "Findbar:Keypress": {

View File

@ -4,7 +4,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "Feeds",
function test() {
var exampleUri = makeURI("http://example.com/");
var secman = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
var principal = secman.getSimpleCodebasePrincipal(exampleUri);
var principal = secman.createCodebasePrincipal(exampleUri, {});
function testIsFeed(aTitle, aHref, aType, aKnown) {
var link = { title: aTitle, href: aHref, type: aType };

View File

@ -1,39 +1,36 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
"use strict";
/**
* Tests that the identity-box shows the chromeUI styling
* when viewing about:home in a new window.
*/
function test() {
waitForExplicitFinish();
registerCleanupFunction(function() {
Services.prefs.clearUserPref("browser.startup.homepage");
Services.prefs.clearUserPref("browser.startup.page");
win.close();
});
add_task(function*(){
let homepage = "about:home";
Services.prefs.setCharPref("browser.startup.homepage", homepage);
Services.prefs.setIntPref("browser.startup.page", 1);
let win = OpenBrowserWindow();
whenDelayedStartupFinished(win, function() {
let browser = win.gBrowser.selectedBrowser;
if (browser.contentDocument.readyState == "complete" &&
browser.currentURI.spec == homepage) {
checkIdentityMode(win);
return;
}
browser.addEventListener("load", function onLoad() {
if (browser.currentURI.spec != homepage)
return;
browser.removeEventListener("load", onLoad, true);
checkIdentityMode(win);
}, true);
yield SpecialPowers.pushPrefEnv({
"set": [
["browser.startup.homepage", homepage],
["browser.startup.page", 1],
]
});
}
let win = OpenBrowserWindow();
yield BrowserTestUtils.waitForEvent(win, "load");
let browser = win.gBrowser.selectedBrowser;
// If we've finished loading about:home already, we can check
// right away - otherwise, we need to wait.
if (browser.contentDocument.readyState == "complete" &&
browser.currentURI.spec == homepage) {
checkIdentityMode(win);
} else {
yield BrowserTestUtils.browserLoaded(browser, false, homepage);
checkIdentityMode(win);
}
yield BrowserTestUtils.closeWindow(win);
});
function checkIdentityMode(win) {
let identityMode = win.document.getElementById("identity-box").className;
is(identityMode, "chromeUI", "Identity state should be chromeUI for about:home in a new window");
finish();
}

View File

@ -43,6 +43,7 @@ support-files =
moz.png
[browser_tabMatchesInAwesomebar_perwindowpb.js]
skip-if = os == 'linux' # Bug 1104755
[browser_urlbarAboutHomeLoading.js]
[browser_urlbarAutoFillTrimURLs.js]
[browser_urlbarCopying.js]
subsuite = clipboard

View File

@ -0,0 +1,104 @@
"use strict";
const {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
/**
* Test what happens if loading a URL that should clear the
* location bar after a parent process URL.
*/
add_task(function* clearURLBarAfterParentProcessURL() {
let tab = yield new Promise(resolve => {
gBrowser.selectedTab = gBrowser.addTab("about:preferences");
let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
newTabBrowser.addEventListener("Initialized", function onInit() {
newTabBrowser.removeEventListener("Initialized", onInit, true);
resolve(gBrowser.selectedTab);
}, true);
});
document.getElementById("home-button").click();
yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
is(gURLBar.value, "", "URL bar should be empty");
is(tab.linkedBrowser.userTypedValue, null, "The browser should have no recorded userTypedValue");
yield BrowserTestUtils.removeTab(tab);
});
/**
* Same as above, but open the tab without passing the URL immediately
* which changes behaviour in tabbrowser.xml.
*/
add_task(function* clearURLBarAfterParentProcessURLInExistingTab() {
let tab = yield new Promise(resolve => {
gBrowser.selectedTab = gBrowser.addTab();
let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
newTabBrowser.addEventListener("Initialized", function onInit() {
newTabBrowser.removeEventListener("Initialized", onInit, true);
resolve(gBrowser.selectedTab);
}, true);
newTabBrowser.loadURI("about:preferences");
});
document.getElementById("home-button").click();
yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
is(gURLBar.value, "", "URL bar should be empty");
is(tab.linkedBrowser.userTypedValue, null, "The browser should have no recorded userTypedValue");
yield BrowserTestUtils.removeTab(tab);
});
/**
* Load about:home directly from an about:newtab page. Because it is an
* 'initial' page, we need to treat this specially if the user actually
* loads a page like this from the URL bar.
*/
add_task(function* clearURLBarAfterManuallyLoadingAboutHome() {
let promiseTabOpenedAndSwitchedTo = BrowserTestUtils.switchTab(gBrowser, () => {});
// This opens about:newtab:
BrowserOpenTab();
let tab = yield promiseTabOpenedAndSwitchedTo;
is(gURLBar.value, "", "URL bar should be empty");
is(tab.linkedBrowser.userTypedValue, null, "userTypedValue should be null");
gURLBar.value = "about:home";
gURLBar.select();
let aboutHomeLoaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, "about:home");
EventUtils.sendKey("return");
yield aboutHomeLoaded;
is(gURLBar.value, "", "URL bar should be empty");
is(tab.linkedBrowser.userTypedValue, null, "userTypedValue should be null");
yield BrowserTestUtils.removeTab(tab);
});
/**
* Ensure we don't show 'about:home' in the URL bar temporarily in new tabs
* while we're switching remoteness (when the URL we're loading and the
* default content principal are different).
*/
add_task(function* dontTemporarilyShowAboutHome() {
yield SpecialPowers.pushPrefEnv({set: [["browser.startup.page", 1]]});
let windowOpenedPromise = BrowserTestUtils.waitForNewWindow();
let win = OpenBrowserWindow();
yield windowOpenedPromise;
let promiseTabSwitch = BrowserTestUtils.switchTab(win.gBrowser, () => {});
win.BrowserOpenTab();
yield promiseTabSwitch;
yield TabStateFlusher.flush(win.gBrowser.selectedBrowser);
yield BrowserTestUtils.closeWindow(win);
ok(SessionStore.getClosedWindowCount(), "Should have a closed window");
windowOpenedPromise = BrowserTestUtils.waitForNewWindow();
win = SessionStore.undoCloseWindow(0);
yield windowOpenedPromise;
let wpl = {
onLocationChange(wpl, request, location, flags) {
is(win.gURLBar.value, "", "URL bar value should stay empty.");
},
};
win.gBrowser.addProgressListener(wpl);
let otherTab = win.gBrowser.selectedTab.previousSibling;
let tabLoaded = BrowserTestUtils.browserLoaded(otherTab.linkedBrowser, false, "about:home");
yield BrowserTestUtils.switchTab(win.gBrowser, otherTab);
yield tabLoaded;
win.gBrowser.removeProgressListener(wpl);
is(win.gURLBar.value, "", "URL bar value should be empty.");
yield BrowserTestUtils.closeWindow(win);
});

View File

@ -382,6 +382,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
{
this.value = url;
gBrowser.userTypedValue = url;
if (gInitialPages.includes(url)) {
gBrowser.selectedBrowser.initialPageLoadedFromURLBar = url;
}
try {
addToUrlbarHistory(url);
} catch (ex) {

View File

@ -924,7 +924,7 @@ FeedWriter.prototype = {
let secman = Cc["@mozilla.org/scriptsecuritymanager;1"].
getService(Ci.nsIScriptSecurityManager);
this._feedPrincipal = secman.getSimpleCodebasePrincipal(this._feedURI);
this._feedPrincipal = secman.createCodebasePrincipal(this._feedURI, {});
LOG("Subscribe Preview: feed uri = " + this._window.location.href);

View File

@ -784,7 +784,10 @@ var SessionStoreInternal = {
// clear user input instead), so we shouldn't set them here either.
// They also don't fall under the issues in bug 439675 where user input
// needs to be preserved if the load doesn't succeed.
if (!browser.userTypedValue && uri && !win.gInitialPages.includes(uri)) {
// We also don't do this for remoteness updates, where it should not
// be necessary.
if (!browser.userTypedValue && uri && !data.isRemotenessUpdate &&
!win.gInitialPages.includes(uri)) {
browser.userTypedValue = uri;
}
@ -3335,7 +3338,8 @@ var SessionStoreInternal = {
browser.messageManager.sendAsyncMessage("SessionStore:restoreHistory", {
tabData: tabData,
epoch: epoch,
loadArguments: aLoadArguments
loadArguments: aLoadArguments,
isRemotenessUpdate,
});
}

View File

@ -154,7 +154,7 @@ var MessageListener = {
}
},
restoreHistory({epoch, tabData, loadArguments}) {
restoreHistory({epoch, tabData, loadArguments, isRemotenessUpdate}) {
gContentRestore.restoreHistory(tabData, loadArguments, {
// Note: The callbacks passed here will only be used when a load starts
// that was not initiated by sessionstore itself. This can happen when
@ -179,7 +179,7 @@ var MessageListener = {
// sync about the state of the restore (particularly regarding
// docShell.currentURI). Using a synchronous message is the easiest way
// to temporarily synchronize them.
sendSyncMessage("SessionStore:restoreHistoryComplete", {epoch});
sendSyncMessage("SessionStore:restoreHistoryComplete", {epoch, isRemotenessUpdate});
},
restoreTabContent({loadArguments, isRemotenessUpdate}) {

View File

@ -1,51 +1,47 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
function test() {
/** Test for Bug 480893 **/
/**
* Tests that we get sent to the right page when the user clicks
* the "Close" button in about:sessionrestore
*/
add_task(function*() {
yield SpecialPowers.pushPrefEnv({
"set": [
["browser.startup.page", 0],
]
});
waitForExplicitFinish();
// Test that starting a new session loads a blank page if Firefox is
// configured to display a blank page at startup (browser.startup.page = 0)
gPrefService.setIntPref("browser.startup.page", 0);
let tab = gBrowser.addTab("about:sessionrestore");
gBrowser.selectedTab = tab;
let browser = tab.linkedBrowser;
promiseBrowserLoaded(browser).then(() => {
let doc = browser.contentDocument;
yield BrowserTestUtils.browserLoaded(browser, false, "about:sessionrestore");
// click on the "Start New Session" button after about:sessionrestore is loaded
doc.getElementById("errorCancel").click();
promiseBrowserLoaded(browser).then(() => {
let doc = browser.contentDocument;
let doc = browser.contentDocument;
is(doc.URL, "about:blank", "loaded page is about:blank");
// Click on the "Close" button after about:sessionrestore is loaded.
doc.getElementById("errorCancel").click();
// Test that starting a new session loads the homepage (set to http://mochi.test:8888)
// if Firefox is configured to display a homepage at startup (browser.startup.page = 1)
let homepage = "http://mochi.test:8888/";
gPrefService.setCharPref("browser.startup.homepage", homepage);
gPrefService.setIntPref("browser.startup.page", 1);
gBrowser.loadURI("about:sessionrestore");
promiseBrowserLoaded(browser).then(() => {
let doc = browser.contentDocument;
yield BrowserTestUtils.browserLoaded(browser, false, "about:blank");
// click on the "Start New Session" button after about:sessionrestore is loaded
doc.getElementById("errorCancel").click();
promiseBrowserLoaded(browser).then(() => {
let doc = browser.contentDocument;
is(doc.URL, homepage, "loaded page is the homepage");
// close tab, restore default values and finish the test
gBrowser.removeTab(tab);
gPrefService.clearUserPref("browser.startup.page");
gPrefService.clearUserPref("browser.startup.homepage");
finish();
});
});
});
// Test that starting a new session loads the homepage (set to http://mochi.test:8888)
// if Firefox is configured to display a homepage at startup (browser.startup.page = 1)
let homepage = "http://mochi.test:8888/";
yield SpecialPowers.pushPrefEnv({
"set": [
["browser.startup.homepage", homepage],
["browser.startup.page", 1],
]
});
}
browser.loadURI("about:sessionrestore");
yield BrowserTestUtils.browserLoaded(browser, false, "about:sessionrestore");
doc = browser.contentDocument;
// Click on the "Close" button after about:sessionrestore is loaded.
doc.getElementById("errorCancel").click();
yield BrowserTestUtils.browserLoaded(browser);
is(browser.currentURI.spec, homepage, "loaded page is the homepage");
yield BrowserTestUtils.removeTab(tab);
});

View File

@ -1,40 +1,40 @@
[
{
"version": "gcc 4.9.3",
"size": 102421980,
"digest": "f25292aa93dc449e0472eee511c0ac15b5f1a4272ab76cf53ce5d20dc57f29e83da49ae1a9d9e994192647f75e13ae60f75ba2ac3cb9d26d5f5d6cabf88de921",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": true
},
{
"hg_id" : "cd93f15a30ce",
"size" : 102421980,
"version" : "gcc 4.9.3",
"filename" : "gcc.tar.xz",
"algorithm" : "sha512",
"digest" : "541eb3842ab6b91bd87223cad7a5e4387ef3e496e5b580c8047b8b586bc7eb69fecf3c9eb8c45a1e0deebb53554f0e8acedfe1b4ca64d93b6d008f3f2eb11389",
"filename" : "sixgill.tar.xz",
"size" : 2626640,
"digest" : "f25292aa93dc449e0472eee511c0ac15b5f1a4272ab76cf53ce5d20dc57f29e83da49ae1a9d9e994192647f75e13ae60f75ba2ac3cb9d26d5f5d6cabf88de921",
"unpack" : true
},
{
"size": 12072532,
"digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"setup": "setup.sh",
"unpack": true
"digest" : "36dc644e24c0aa824975ad8f5c15714445d5cb064d823000c3cb637e885199414d7df551e6b99233f0656dcf5760918192ef04113c486af37f3c489bb93ad029",
"unpack" : true,
"algorithm" : "sha512",
"filename" : "sixgill.tar.xz",
"size" : 2631908,
"hg_id" : "8cb9c3fb039a+ tip"
},
{
"size": 89319524,
"digest": "5383d843c9f28abf0a6d254e9d975d96972d2c86d627ca836fa8e272a5d53230603b387d7d1499c49df7f84b1bb946946e800a85c88d968bdbe81c755fcb02e1",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true
"digest" : "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
"unpack" : true,
"setup" : "setup.sh",
"algorithm" : "sha512",
"filename" : "gtk3.tar.xz",
"size" : 12072532
},
{
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
"filename": "sccache.tar.bz2",
"unpack": true
"unpack" : true,
"digest" : "5383d843c9f28abf0a6d254e9d975d96972d2c86d627ca836fa8e272a5d53230603b387d7d1499c49df7f84b1bb946946e800a85c88d968bdbe81c755fcb02e1",
"filename" : "rustc.tar.xz",
"algorithm" : "sha512",
"size" : 89319524
},
{
"filename" : "sccache.tar.bz2",
"algorithm" : "sha512",
"digest" : "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"unpack" : true,
"size" : 167175
}
]

View File

@ -6,9 +6,9 @@
"filename": "mozmake.exe"
},
{
"version": "rustc 1.8.0 (db2939409 2016-04-11)",
"size": 78733276,
"digest": "96ab09cd667ed854efeeca41881a92c9fdc5f3cdeff9b02b12c514183c0b54a21dee8574367abe532429e04660681a1f6c37f6d22cc877d63fbcca7b986d3495",
"version": "rustc 1.9.0 (e4e8b6668 2016-05-18)",
"size": 82463178,
"digest": "a3c54c6792e75d53ec79caf958db25b651fcf968a37b00949fb327c54a54cad6305a4af302f267082d86d70fcf837ed0f273f85b97706c20b957ff3690889b40",
"algorithm": "sha512",
"filename": "rustc.tar.bz2",
"unpack": true

View File

@ -6,9 +6,9 @@
"filename": "mozmake.exe"
},
{
"version": "rustc 1.8.0 (db2939409 2016-04-11)",
"size": 85285866,
"digest": "f3862036781df9f699a18a5449d51a4f8880e7d890500b314d1f16f394da77c2c496fa537a691d9d99f3248ec2067beaf20b4361babe0dd449d4f7b4f539acac",
"version": "rustc 1.9.0 (e4e8b6668 2016-05-18)",
"size": 88486080,
"digest": "a4fb99cd637b236a9c30e111757ca560bc8df1b143324c1d9ab58c32470b9b9a0598e3e0d220278ee157959dcd88421496388e2ed856e6261d9c81f18e6310e9",
"algorithm": "sha512",
"visibility": "public",
"filename": "rustc.tar.bz2",

View File

@ -18,6 +18,7 @@ support-files =
[browser_panel_privateBrowsing.js]
[browser_mozLoop_sharingListeners.js]
[browser_mozLoop_telemetry.js]
skip-if = os == win && !debug # Bug 1267562 zombiecheck | child process 1228 still alive after shutdown (on win7-vm specifically)
[browser_sharingTitleListeners.js]
[browser_throttler.js]
[browser_toolbarbutton.js]

View File

@ -53,6 +53,8 @@ PluginContent.prototype = {
global.addMessageListener("BrowserPlugins:NPAPIPluginProcessCrashed", this);
global.addMessageListener("BrowserPlugins:CrashReportSubmitted", this);
global.addMessageListener("BrowserPlugins:Test:ClearCrashData", this);
Services.obs.addObserver(this, "Plugin::HiddenPluginTouched", false);
},
uninit: function() {
@ -75,6 +77,8 @@ PluginContent.prototype = {
global.removeMessageListener("BrowserPlugins:Test:ClearCrashData", this);
delete this.global;
delete this.content;
Services.obs.removeObserver(this, "Plugin::HiddenPluginTouched");
},
receiveMessage: function (msg) {
@ -116,6 +120,15 @@ PluginContent.prototype = {
}
},
observe: function observe(aSubject, aTopic, aData) {
let pluginTag = aSubject;
if (aTopic == "Plugin::HiddenPluginTouched") {
this._showClickToPlayNotification(pluginTag, false);
} else {
Cu.reportError("unknown topic observed: " + aTopic);
}
},
onPageShow: function (event) {
// Ignore events that aren't from the main document.
if (!this.content || event.target != this.content.document) {
@ -194,6 +207,45 @@ PluginContent.prototype = {
};
},
_getPluginInfoForTag: function (pluginTag, tagMimetype, fallbackType) {
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let pluginName = gNavigatorBundle.GetStringFromName("pluginInfo.unknownPlugin");
let permissionString = null;
let blocklistState = null;
if (pluginTag) {
pluginName = BrowserUtils.makeNicePluginName(pluginTag.name);
permissionString = pluginHost.getPermissionStringForTag(pluginTag);
blocklistState = pluginTag.blocklistState;
// Convert this from nsIPluginTag so it can be serialized.
let properties = ["name", "description", "filename", "version", "enabledState", "niceName"];
let pluginTagCopy = {};
for (let prop of properties) {
pluginTagCopy[prop] = pluginTag[prop];
}
pluginTag = pluginTagCopy;
// Make state-softblocked == state-notblocked for our purposes,
// they have the same UI. STATE_OUTDATED should not exist for plugin
// items, but let's alias it anyway, just in case.
if (blocklistState == Ci.nsIBlocklistService.STATE_SOFTBLOCKED ||
blocklistState == Ci.nsIBlocklistService.STATE_OUTDATED) {
blocklistState = Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
}
}
return { mimetype: tagMimetype,
pluginName: pluginName,
pluginTag: pluginTag,
permissionString: permissionString,
fallbackType: fallbackType,
blocklistState: blocklistState,
};
},
/**
* Update the visibility of the plugin overlay.
*/

View File

@ -207,12 +207,6 @@ AC_DEFUN([MOZ_ANDROID_AAR],[
MOZ_ANDROID_AAR_COMPONENT(concat(local_aar_var, _ASSETS), concat(root, assets), $6)
])
ANDROID_SUPPORT_LIBRARY_VERSION="23.0.1"
AC_SUBST(ANDROID_SUPPORT_LIBRARY_VERSION)
ANDROID_GOOGLE_PLAY_SERVICES_VERSION="8.4.0"
AC_SUBST(ANDROID_GOOGLE_PLAY_SERVICES_VERSION)
AC_DEFUN([MOZ_ANDROID_GOOGLE_PLAY_SERVICES],
[

View File

@ -55,7 +55,8 @@ if __name__ == '__main__':
"name": "compiler_metrics",
"subtests": [{
"name": "num_constructors",
"value": count_ctors(f)
"value": count_ctors(f),
"alertThreshold": 0.25
}]}
]
}

View File

@ -133,13 +133,6 @@ interface nsIScriptSecurityManager : nsISupports
*/
nsIPrincipal getSystemPrincipal();
/**
* Return a principal that has the same origin as aURI.
* This principals should not be used for any data/permission check, it will
* have appId = UNKNOWN_APP_ID.
*/
nsIPrincipal getSimpleCodebasePrincipal(in nsIURI aURI);
/**
* Returns a principal that has the given information.
* @param appId is the app id of the principal. It can't be UNKNOWN_APP_ID.

View File

@ -1108,16 +1108,6 @@ nsScriptSecurityManager::GetSystemPrincipal(nsIPrincipal **result)
return NS_OK;
}
NS_IMETHODIMP
nsScriptSecurityManager::GetSimpleCodebasePrincipal(nsIURI* aURI,
nsIPrincipal** aPrincipal)
{
PrincipalOriginAttributes attrs(UNKNOWN_APP_ID, false);
nsCOMPtr<nsIPrincipal> prin = BasePrincipal::CreateCodebasePrincipal(aURI, attrs);
prin.forget(aPrincipal);
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsScriptSecurityManager::GetNoAppCodebasePrincipal(nsIURI* aURI,
nsIPrincipal** aPrincipal)

View File

@ -22,6 +22,7 @@
#include "nsThreadUtils.h"
#include "nsHashPropertyBag.h"
#include "nsComponentManagerUtils.h"
#include "nsGlobalWindow.h"
#include "nsPIDOMWindow.h"
#include "nsServiceManagerUtils.h"
#include "mozilla/dom/SettingChangeNotificationBinding.h"
@ -41,6 +42,7 @@ namespace {
// If true, any new AudioChannelAgent will be muted when created.
bool sAudioChannelMutedByDefault = false;
bool sAudioChannelCompeting = false;
bool sXPCOMShuttingDown = false;
class NotifyChannelActiveRunnable final : public Runnable
@ -210,6 +212,13 @@ AudioChannelService::Shutdown()
}
}
/* static */ bool
AudioChannelService::IsEnableAudioCompeting()
{
CreateServiceIfNeeded();
return sAudioChannelCompeting;
}
NS_INTERFACE_MAP_BEGIN(AudioChannelService)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAudioChannelService)
NS_INTERFACE_MAP_ENTRY(nsIAudioChannelService)
@ -241,6 +250,8 @@ AudioChannelService::AudioChannelService()
Preferences::AddBoolVarCache(&sAudioChannelMutedByDefault,
"dom.audiochannel.mutedByDefault");
Preferences::AddBoolVarCache(&sAudioChannelCompeting,
"dom.audiochannel.audioCompeting");
}
AudioChannelService::~AudioChannelService()
@ -336,14 +347,15 @@ AudioChannelService::GetMediaConfig(nsPIDOMWindowOuter* aWindow,
if (winData) {
config.mVolume *= winData->mChannels[aAudioChannel].mVolume;
config.mMuted = config.mMuted || winData->mChannels[aAudioChannel].mMuted;
config.mSuspend = winData->mOwningAudioFocus ?
config.mSuspend : nsISuspendedTypes::SUSPENDED_STOP_DISPOSABLE;
}
config.mVolume *= window->GetAudioVolume();
config.mMuted = config.mMuted || window->GetAudioMuted();
// If the mSuspend is already suspended, we don't need to set it again.
config.mSuspend = (config.mSuspend == nsISuspendedTypes::NONE_SUSPENDED) ?
window->GetMediaSuspend() : config.mSuspend;
if (window->GetMediaSuspend() != nsISuspendedTypes::NONE_SUSPENDED) {
config.mSuspend = window->GetMediaSuspend();
}
nsCOMPtr<nsPIDOMWindowOuter> win = window->GetScriptableParentOrNull();
if (!win) {
@ -994,6 +1006,176 @@ AudioChannelService::ChildStatusReceived(uint64_t aChildID,
data->mActiveContentOrNormalChannel = aContentOrNormalChannel;
}
void
AudioChannelService::RefreshAgentsAudioFocusChanged(AudioChannelAgent* aAgent,
bool aActive)
{
MOZ_ASSERT(aAgent);
nsTObserverArray<nsAutoPtr<AudioChannelWindow>>::ForwardIterator
iter(mWindows);
while (iter.HasMore()) {
AudioChannelWindow* winData = iter.GetNext();
if (winData->mOwningAudioFocus) {
winData->AudioFocusChanged(aAgent, aActive);
}
}
}
void
AudioChannelService::AudioChannelWindow::RequestAudioFocus(AudioChannelAgent* aAgent)
{
MOZ_ASSERT(aAgent);
// We already have the audio focus. No operation is needed.
if (mOwningAudioFocus) {
return;
}
// Only foreground window can request audio focus, but it would still own the
// audio focus even it goes to background. Audio focus would be abandoned
// only when other foreground window starts audio competing.
mOwningAudioFocus = !(aAgent->Window()->IsBackground());
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("AudioChannelWindow, RequestAudioFocus, this = %p, "
"agent = %p, owning audio focus = %d\n",
this, aAgent, mOwningAudioFocus));
}
void
AudioChannelService::AudioChannelWindow::NotifyAudioCompetingChanged(AudioChannelAgent* aAgent,
bool aActive)
{
// This function may be called after RemoveAgentAndReduceAgentsNum(), so the
// agent may be not contained in mAgent. In addition, the agent would still
// be alive because we have kungFuDeathGrip in UnregisterAudioChannelAgent().
MOZ_ASSERT(aAgent);
RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
MOZ_ASSERT(service);
if (!service->IsEnableAudioCompeting()) {
return;
}
if (!IsAgentInvolvingInAudioCompeting(aAgent)) {
return;
}
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("AudioChannelWindow, NotifyAudioCompetingChanged, this = %p, "
"agent = %p, active = %d\n",
this, aAgent, aActive));
service->RefreshAgentsAudioFocusChanged(aAgent, aActive);
}
bool
AudioChannelService::AudioChannelWindow::IsAgentInvolvingInAudioCompeting(AudioChannelAgent* aAgent) const
{
MOZ_ASSERT(aAgent);
if(!mOwningAudioFocus) {
return false;
}
if (IsAudioCompetingInSameTab()) {
return false;
}
// TODO : add MediaSession::ambient kind, because it doens't interact with
// other kinds.
return true;
}
bool
AudioChannelService::AudioChannelWindow::IsAudioCompetingInSameTab() const
{
return (mOwningAudioFocus && mAudibleAgents.Length() > 1);
}
void
AudioChannelService::AudioChannelWindow::AudioFocusChanged(AudioChannelAgent* aNewPlayingAgent,
bool aActive)
{
// This agent isn't always known for the current window, because it can comes
// from other window.
MOZ_ASSERT(aNewPlayingAgent);
if (mAudibleAgents.IsEmpty()) {
// These would happen in two situations,
// (1) Audio in page A was ended, and another page B want to play audio.
// Page A should abandon its focus.
// (2) Audio was paused by remote-control, page should still own the focus.
mOwningAudioFocus = IsContainingPlayingAgent(aNewPlayingAgent);
} else {
nsTObserverArray<AudioChannelAgent*>::ForwardIterator iter(mAudibleAgents);
while (iter.HasMore()) {
AudioChannelAgent* agent = iter.GetNext();
MOZ_ASSERT(agent);
// Don't need to update the playing state of new playing agent.
if (agent == aNewPlayingAgent) {
continue;
}
uint32_t type = GetCompetingBehavior(agent,
aNewPlayingAgent->AudioChannelType(),
aActive);
// If window will be suspended, it needs to abandon the audio focus
// because only one window can own audio focus at a time. However, we
// would support multiple audio focus at the same time in the future.
mOwningAudioFocus = (type == nsISuspendedTypes::NONE_SUSPENDED);
// TODO : support other behaviors which are definded in MediaSession API.
switch (type) {
case nsISuspendedTypes::NONE_SUSPENDED:
case nsISuspendedTypes::SUSPENDED_STOP_DISPOSABLE:
agent->WindowSuspendChanged(type);
break;
}
}
}
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("AudioChannelWindow, AudioFocusChanged, this = %p, "
"OwningAudioFocus = %d\n", this, mOwningAudioFocus));
}
bool
AudioChannelService::AudioChannelWindow::IsContainingPlayingAgent(AudioChannelAgent* aAgent) const
{
return (aAgent->WindowID() == mWindowID);
}
uint32_t
AudioChannelService::AudioChannelWindow::GetCompetingBehavior(AudioChannelAgent* aAgent,
int32_t aIncomingChannelType,
bool aIncomingChannelActive) const
{
MOZ_ASSERT(aAgent);
MOZ_ASSERT(mAudibleAgents.Contains(aAgent));
uint32_t competingBehavior = nsISuspendedTypes::NONE_SUSPENDED;
int32_t presentChannelType = aAgent->AudioChannelType();
// TODO : add other competing cases for MediaSession API
if (presentChannelType == int32_t(AudioChannel::Normal) &&
aIncomingChannelType == int32_t(AudioChannel::Normal) &&
aIncomingChannelActive) {
competingBehavior = nsISuspendedTypes::SUSPENDED_STOP_DISPOSABLE;
}
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("AudioChannelWindow, GetCompetingBehavior, this = %p, "
"present type = %d, incoming channel = %d, behavior = %d\n",
this, presentChannelType, aIncomingChannelType, competingBehavior));
return competingBehavior;
}
/* static */ bool
AudioChannelService::IsAudioChannelMutedByDefault()
{
@ -1007,9 +1189,12 @@ AudioChannelService::AudioChannelWindow::AppendAgent(AudioChannelAgent* aAgent,
{
MOZ_ASSERT(aAgent);
RequestAudioFocus(aAgent);
AppendAgentAndIncreaseAgentsNum(aAgent);
AudioCapturedChanged(aAgent, AudioCaptureState::eCapturing);
AudioAudibleChanged(aAgent, aAudible);
if (aAudible) {
AudioAudibleChanged(aAgent, AudibleState::eAudible);
}
}
void
@ -1082,6 +1267,8 @@ AudioChannelService::AudioChannelWindow::AudioAudibleChanged(AudioChannelAgent*
} else {
RemoveAudibleAgentIfContained(aAgent);
}
NotifyAudioCompetingChanged(aAgent, aAudible);
}
void

View File

@ -89,6 +89,8 @@ public:
static PRLogModuleInfo* GetAudioChannelLog();
static bool IsEnableAudioCompeting();
/**
* Any audio channel agent that starts playing should register itself to
* this service, sharing the AudioChannel.
@ -220,6 +222,9 @@ private:
void SetDefaultVolumeControlChannelInternal(int32_t aChannel,
bool aVisible, uint64_t aChildID);
void RefreshAgentsAudioFocusChanged(AudioChannelAgent* aAgent,
bool aActive);
class AudioChannelConfig final : public AudioPlaybackConfig
{
public:
@ -236,13 +241,15 @@ private:
{
public:
explicit AudioChannelWindow(uint64_t aWindowID)
: mWindowID(aWindowID),
mIsAudioCaptured(false)
: mWindowID(aWindowID)
, mIsAudioCaptured(false)
, mOwningAudioFocus(!AudioChannelService::IsEnableAudioCompeting())
{
// Workaround for bug1183033, system channel type can always playback.
mChannels[(int16_t)AudioChannel::System].mMuted = false;
}
void AudioFocusChanged(AudioChannelAgent* aNewPlayingAgent, bool aActive);
void AudioAudibleChanged(AudioChannelAgent* aAgent, AudibleState aAudible);
void AppendAgent(AudioChannelAgent* aAgent, AudibleState aAudible);
@ -256,6 +263,10 @@ private:
nsTObserverArray<AudioChannelAgent*> mAgents;
nsTObserverArray<AudioChannelAgent*> mAudibleAgents;
// Owning audio focus when the window starts playing audible sound, and
// lose audio focus when other windows starts playing.
bool mOwningAudioFocus;
private:
void AudioCapturedChanged(AudioChannelAgent* aAgent,
AudioCaptureState aCapture);
@ -273,6 +284,16 @@ private:
AudibleState aAudible);
void NotifyChannelActive(uint64_t aWindowID, AudioChannel aChannel,
bool aActive);
void RequestAudioFocus(AudioChannelAgent* aAgent);
void NotifyAudioCompetingChanged(AudioChannelAgent* aAgent, bool aActive);
uint32_t GetCompetingBehavior(AudioChannelAgent* aAgent,
int32_t aIncomingChannelType,
bool aIncomingChannelActive) const;
bool IsAgentInvolvingInAudioCompeting(AudioChannelAgent* aAgent) const;
bool IsAudioCompetingInSameTab() const;
bool IsContainingPlayingAgent(AudioChannelAgent* aAgent) const;
};
AudioChannelWindow*

View File

@ -21,6 +21,10 @@ UNIFIED_SOURCES += [
'AudioChannelService.cpp',
]
LOCAL_INCLUDES += [
'/dom/base/',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'

View File

@ -339,12 +339,9 @@ DOMParser::Init(nsIPrincipal* principal, nsIURI* documentURI,
mPrincipal = principal;
nsresult rv;
if (!mPrincipal) {
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
NS_ENSURE_TRUE(secMan, NS_ERROR_NOT_AVAILABLE);
rv =
secMan->GetSimpleCodebasePrincipal(mDocumentURI,
getter_AddRefs(mPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
PrincipalOriginAttributes attrs;
mPrincipal = BasePrincipal::CreateCodebasePrincipal(mDocumentURI, attrs);
NS_ENSURE_TRUE(mPrincipal, NS_ERROR_FAILURE);
mOriginalPrincipal = mPrincipal;
} else {
mOriginalPrincipal = mPrincipal;

View File

@ -1181,17 +1181,11 @@ Element::SetAttribute(const nsAString& aName,
if (aError.Failed()) {
return;
}
const nsAttrName* name = InternalGetExistingAttrNameFromQName(aName);
nsAutoString nameToUse;
const nsAttrName* name = InternalGetAttrNameFromQName(aName, &nameToUse);
if (!name) {
nsCOMPtr<nsIAtom> nameAtom;
if (IsHTMLElement() && IsInHTMLDocument()) {
nsAutoString lower;
nsContentUtils::ASCIIToLower(aName, lower);
nameAtom = NS_Atomize(lower);
}
else {
nameAtom = NS_Atomize(aName);
}
nsCOMPtr<nsIAtom> nameAtom = NS_Atomize(nameToUse);
if (!nameAtom) {
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
@ -1208,7 +1202,7 @@ Element::SetAttribute(const nsAString& aName,
void
Element::RemoveAttribute(const nsAString& aName, ErrorResult& aError)
{
const nsAttrName* name = InternalGetExistingAttrNameFromQName(aName);
const nsAttrName* name = InternalGetAttrNameFromQName(aName);
if (!name) {
// If there is no canonical nsAttrName for this attribute name, then the
@ -1991,7 +1985,7 @@ Element::FindAttributeDependence(const nsIAtom* aAttribute,
already_AddRefed<mozilla::dom::NodeInfo>
Element::GetExistingAttrNameFromQName(const nsAString& aStr) const
{
const nsAttrName* name = InternalGetExistingAttrNameFromQName(aStr);
const nsAttrName* name = InternalGetAttrNameFromQName(aStr);
if (!name) {
return nullptr;
}
@ -2167,9 +2161,27 @@ Element::SetEventHandler(nsIAtom* aEventName,
//----------------------------------------------------------------------
const nsAttrName*
Element::InternalGetExistingAttrNameFromQName(const nsAString& aStr) const
Element::InternalGetAttrNameFromQName(const nsAString& aStr,
nsAutoString* aNameToUse) const
{
return mAttrsAndChildren.GetExistingAttrNameFromQName(aStr);
MOZ_ASSERT(!aNameToUse || aNameToUse->IsEmpty());
const nsAttrName* val = nullptr;
if (IsHTMLElement() && IsInHTMLDocument()) {
nsAutoString lower;
nsAutoString& outStr = aNameToUse ? *aNameToUse : lower;
nsContentUtils::ASCIIToLower(aStr, outStr);
val = mAttrsAndChildren.GetExistingAttrNameFromQName(outStr);
if (val) {
outStr.Truncate();
}
} else {
val = mAttrsAndChildren.GetExistingAttrNameFromQName(aStr);
if (!val && aNameToUse) {
*aNameToUse = aStr;
}
}
return val;
}
bool

View File

@ -660,7 +660,7 @@ public:
ErrorResult& aError);
bool HasAttribute(const nsAString& aName) const
{
return InternalGetExistingAttrNameFromQName(aName) != nullptr;
return InternalGetAttrNameFromQName(aName) != nullptr;
}
bool HasAttributeNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName) const;
@ -1273,9 +1273,13 @@ protected:
GetEventListenerManagerForAttr(nsIAtom* aAttrName, bool* aDefer);
/**
* Internal hook for converting an attribute name-string to an atomized name
* Internal hook for converting an attribute name-string to nsAttrName in
* case there is such existing attribute. aNameToUse can be passed to get
* name which was used for looking for the attribute (lowercase in HTML).
*/
virtual const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const;
const nsAttrName*
InternalGetAttrNameFromQName(const nsAString& aStr,
nsAutoString* aNameToUse = nullptr) const;
nsIFrame* GetStyledFrame();

View File

@ -2719,10 +2719,10 @@ class WorkerRunnableDispatcher final : public WorkerRunnable
public:
WorkerRunnableDispatcher(WebSocketImpl* aImpl, WorkerPrivate* aWorkerPrivate,
already_AddRefed<nsIRunnable>&& aEvent)
already_AddRefed<nsIRunnable> aEvent)
: WorkerRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
, mWebSocketImpl(aImpl)
, mEvent(aEvent)
, mEvent(Move(aEvent))
{
}
@ -2779,7 +2779,7 @@ WebSocketImpl::DispatchFromScript(nsIRunnable* aEvent, uint32_t aFlags)
}
NS_IMETHODIMP
WebSocketImpl::Dispatch(already_AddRefed<nsIRunnable>&& aEvent, uint32_t aFlags)
WebSocketImpl::Dispatch(already_AddRefed<nsIRunnable> aEvent, uint32_t aFlags)
{
nsCOMPtr<nsIRunnable> event_ref(aEvent);
// If the target is the main-thread we can just dispatch the runnable.
@ -2811,7 +2811,7 @@ WebSocketImpl::Dispatch(already_AddRefed<nsIRunnable>&& aEvent, uint32_t aFlags)
}
NS_IMETHODIMP
WebSocketImpl::DelayedDispatch(already_AddRefed<nsIRunnable>&&, uint32_t)
WebSocketImpl::DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -47,3 +47,4 @@ DEPRECATED_OPERATION(AppCache)
DEPRECATED_OPERATION(PrefixedFullscreenAPI)
DEPRECATED_OPERATION(LenientSetter)
DEPRECATED_OPERATION(NavigatorBattery)
DEPRECATED_OPERATION(FileLastModifiedDate)

View File

@ -856,6 +856,7 @@ GK_ATOM(onmapsendmessagereq, "onmapsendmessagereq")
GK_ATOM(onmapmessageupdatereq, "onmapmessageupdatereq")
GK_ATOM(onnewrdsgroup, "onnewrdsgroup")
GK_ATOM(onnotificationclick, "onnotificationclick")
GK_ATOM(onnotificationclose, "onnotificationclose")
GK_ATOM(onnoupdate, "onnoupdate")
GK_ATOM(onobexpasswordreq, "onobexpasswordreq")
GK_ATOM(onobsolete, "onobsolete")

View File

@ -134,25 +134,6 @@ private:
void **aOffThreadToken);
};
class MOZ_STACK_CLASS AutoDontReportUncaught {
JSContext* mContext;
bool mWasSet;
public:
explicit AutoDontReportUncaught(JSContext* aContext) : mContext(aContext) {
MOZ_ASSERT(aContext);
mWasSet = JS::ContextOptionsRef(mContext).dontReportUncaught();
if (!mWasSet) {
JS::ContextOptionsRef(mContext).setDontReportUncaught(true);
}
}
~AutoDontReportUncaught() {
if (!mWasSet) {
JS::ContextOptionsRef(mContext).setDontReportUncaught(false);
}
}
};
template<typename T>
inline bool
AssignJSString(JSContext *cx, T &dest, JSString *s)

View File

@ -19,6 +19,8 @@
#include "nsIWeakReference.h"
#include "mozilla/Services.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIPermissionManager.h"
#include "nsIDocument.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -66,7 +68,8 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsPluginArray,
mWindow,
mPlugins)
mPlugins,
mCTPPlugins)
static void
GetPluginMimeTypes(const nsTArray<RefPtr<nsPluginElement> >& aPlugins,
@ -146,6 +149,7 @@ nsPluginArray::Refresh(bool aReloadDocuments)
}
mPlugins.Clear();
mCTPPlugins.Clear();
nsCOMPtr<nsIDOMNavigator> navigator = mWindow->GetNavigator();
@ -221,6 +225,13 @@ nsPluginArray::NamedGetter(const nsAString& aName, bool &aFound)
nsPluginElement* plugin = FindPlugin(mPlugins, aName);
aFound = (plugin != nullptr);
if (!aFound) {
nsPluginElement* hiddenPlugin = FindPlugin(mCTPPlugins, aName);
if (hiddenPlugin) {
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
obs->NotifyObservers(hiddenPlugin->PluginTag(), "Plugin::HiddenPluginTouched", nsString(aName).get());
}
}
return plugin;
}
@ -282,7 +293,7 @@ operator<(const RefPtr<nsPluginElement>& lhs,
void
nsPluginArray::EnsurePlugins()
{
if (!mPlugins.IsEmpty()) {
if (!mPlugins.IsEmpty() || !mCTPPlugins.IsEmpty()) {
// We already have an array of plugin elements.
return;
}
@ -299,7 +310,31 @@ nsPluginArray::EnsurePlugins()
// need to wrap each of these with a nsPluginElement, which is
// scriptable.
for (uint32_t i = 0; i < pluginTags.Length(); ++i) {
mPlugins.AppendElement(new nsPluginElement(mWindow, pluginTags[i]));
nsCOMPtr<nsPluginTag> pluginTag = do_QueryInterface(pluginTags[i]);
if (!pluginTag) {
mPlugins.AppendElement(new nsPluginElement(mWindow, pluginTags[i]));
} else if (pluginTag->IsActive()) {
uint32_t permission = nsIPermissionManager::ALLOW_ACTION;
if (pluginTag->IsClicktoplay()) {
nsCString name;
pluginTag->GetName(name);
if (NS_LITERAL_CSTRING("Shockwave Flash").Equals(name)) {
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
nsCString permString;
nsresult rv = pluginHost->GetPermissionStringForTag(pluginTag, 0, permString);
if (rv == NS_OK) {
nsIPrincipal* principal = mWindow->GetExtantDoc()->NodePrincipal();
nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
permMgr->TestPermissionFromPrincipal(principal, permString.get(), &permission);
}
}
}
if (permission == nsIPermissionManager::ALLOW_ACTION) {
mPlugins.AppendElement(new nsPluginElement(mWindow, pluginTags[i]));
} else {
mCTPPlugins.AppendElement(new nsPluginElement(mWindow, pluginTags[i]));
}
}
}
// Alphabetize the enumeration order of non-hidden plugins to reduce

View File

@ -60,6 +60,10 @@ private:
nsCOMPtr<nsPIDOMWindowInner> mWindow;
nsTArray<RefPtr<nsPluginElement> > mPlugins;
/* A separate list of click-to-play plugins that we don't tell content
* about but keep track of so we can still prompt the user to click to play.
*/
nsTArray<RefPtr<nsPluginElement> > mCTPPlugins;
};
class nsPluginElement final : public nsISupports,

View File

@ -13656,7 +13656,9 @@ class CGNativeMember(ClassMethod):
def __init__(self, descriptorProvider, member, name, signature, extendedAttrs,
breakAfter=True, passJSBitsAsNeeded=True, visibility="public",
typedArraysAreStructs=True, variadicIsSequence=False,
resultNotAddRefed=False):
resultNotAddRefed=False,
virtual=False,
override=False):
"""
If typedArraysAreStructs is false, typed arrays will be passed as
JS::Handle<JSObject*>. If it's true they will be passed as one of the
@ -13684,7 +13686,9 @@ class CGNativeMember(ClassMethod):
not signature[0].isVoid()),
breakAfterReturnDecl=" ",
breakAfterSelf=breakAfterSelf,
visibility=visibility)
visibility=visibility,
virtual=virtual,
override=override)
def getReturnType(self, type, isMember):
return self.getRetvalInfo(type, isMember)[0]
@ -14448,12 +14452,15 @@ class CGJSImplMember(CGNativeMember):
"""
def __init__(self, descriptorProvider, member, name, signature,
extendedAttrs, breakAfter=True, passJSBitsAsNeeded=True,
visibility="public", variadicIsSequence=False):
visibility="public", variadicIsSequence=False,
virtual=False, override=False):
CGNativeMember.__init__(self, descriptorProvider, member, name,
signature, extendedAttrs, breakAfter=breakAfter,
passJSBitsAsNeeded=passJSBitsAsNeeded,
visibility=visibility,
variadicIsSequence=variadicIsSequence)
variadicIsSequence=variadicIsSequence,
virtual=virtual,
override=override)
self.body = self.getImpl()
def getArgs(self, returnType, argList):
@ -14468,6 +14475,13 @@ class CGJSImplMethod(CGJSImplMember):
interface.
"""
def __init__(self, descriptor, method, signature, isConstructor, breakAfter=True):
virtual = False
override = False
if (method.identifier.name == "eventListenerWasAdded" or
method.identifier.name == "eventListenerWasRemoved"):
virtual = True
override = True
self.signature = signature
self.descriptor = descriptor
self.isConstructor = isConstructor
@ -14478,7 +14492,9 @@ class CGJSImplMethod(CGJSImplMember):
descriptor.getExtendedAttributes(method),
breakAfter=breakAfter,
variadicIsSequence=True,
passJSBitsAsNeeded=False)
passJSBitsAsNeeded=False,
virtual=virtual,
override=override)
def getArgs(self, returnType, argList):
if self.isConstructor:

View File

@ -218,10 +218,11 @@ TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec, const char* fun
// And go!:
MOZ_ASSERT(srcOrigin != dstOrigin || srcPremultiplied != dstPremultiplied);
bool unused_wasTrivial;
if (!ConvertImage(mWidth, mHeight,
mBytes, rowStride, srcOrigin, texelFormat, srcPremultiplied,
tempBuffer.get(), rowStride, dstOrigin, texelFormat,
dstPremultiplied))
dstPremultiplied, &unused_wasTrivial))
{
MOZ_ASSERT(false, "ConvertImage failed unexpectedly.");
*out_glError = LOCAL_GL_OUT_OF_MEMORY;
@ -311,6 +312,10 @@ TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec, const char* fun
return; // Blitting was successful, so we're done!
} while (false);
webgl->GenerateWarning("%s: Failed to hit GPU-copy fast-path. Falling back to CPU"
" upload.",
funcName);
RefPtr<SourceSurface> surface = mImage->GetAsSourceSurface();
if (!surface) {
*out_glError = LOCAL_GL_OUT_OF_MEMORY;
@ -662,7 +667,7 @@ TexUnpackSurface::ConvertSurface(WebGLContext* webgl, const webgl::DriverUnpackI
gfx::DataSourceSurface* surf, bool isSurfAlphaPremult,
UniqueBuffer* const out_convertedBuffer,
uint8_t* const out_convertedAlignment,
bool* const out_outOfMemory)
bool* const out_wasTrivial, bool* const out_outOfMemory)
{
*out_outOfMemory = false;
@ -719,9 +724,11 @@ TexUnpackSurface::ConvertSurface(WebGLContext* webgl, const webgl::DriverUnpackI
const bool dstPremultiplied = webgl->mPixelStore_PremultiplyAlpha;
// And go!:
bool wasTrivial;
if (!ConvertImage(width, height,
srcBegin, srcStride, srcOrigin, srcFormat, srcPremultiplied,
dstBegin, dstStride, dstOrigin, dstFormat, dstPremultiplied))
dstBegin, dstStride, dstOrigin, dstFormat, dstPremultiplied,
&wasTrivial))
{
MOZ_ASSERT(false, "ConvertImage failed unexpectedly.");
NS_ERROR("ConvertImage failed unexpectedly.");
@ -731,6 +738,7 @@ TexUnpackSurface::ConvertSurface(WebGLContext* webgl, const webgl::DriverUnpackI
*out_convertedBuffer = Move(dstBuffer);
*out_convertedAlignment = dstAlignment;
*out_wasTrivial = wasTrivial;
return true;
}
@ -785,9 +793,10 @@ TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec, const char* f
UniqueBuffer convertedBuffer;
uint8_t convertedAlignment;
bool wasTrivial;
bool outOfMemory;
if (!ConvertSurface(webgl, dui, dataSurf, mIsAlphaPremult, &convertedBuffer,
&convertedAlignment, &outOfMemory))
&convertedAlignment, &wasTrivial, &outOfMemory))
{
if (outOfMemory) {
*out_glError = LOCAL_GL_OUT_OF_MEMORY;
@ -798,6 +807,12 @@ TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec, const char* f
return;
}
if (!wasTrivial) {
webgl->GenerateWarning("%s: Chosen format/type incured an expensive reformat:"
" 0x%04x/0x%04x",
funcName, dui->unpackFormat, dui->unpackType);
}
MOZ_ALWAYS_TRUE( webgl->gl->MakeCurrent() );
ScopedUnpackReset scopedReset(webgl);
webgl->gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, convertedAlignment);

View File

@ -147,7 +147,7 @@ protected:
gfx::DataSourceSurface* surf, bool isSurfAlphaPremult,
UniqueBuffer* const out_convertedBuffer,
uint8_t* const out_convertedAlignment,
bool* const out_outOfMemory);
bool* const out_wasTrivial, bool* const out_outOfMemory);
static bool UploadDataSurface(bool isSubImage, WebGLContext* webgl,
TexImageTarget target, GLint level,
const webgl::DriverUnpackInfo* dui, GLint xOffset,

View File

@ -43,11 +43,8 @@ WebGL2Context::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
/* GLenum */
case LOCAL_GL_READ_BUFFER: {
if (mBoundReadFramebuffer) {
GLint val = LOCAL_GL_NONE;
gl->fGetIntegerv(pname, &val);
return JS::Int32Value(val);
}
if (mBoundReadFramebuffer)
return JS::Int32Value(mBoundReadFramebuffer->ReadBufferMode());
return JS::Int32Value(LOCAL_GL_BACK);
}

View File

@ -984,6 +984,9 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
mOptions.antialias = gl->Caps().antialias;
//////
// Initial setup.
MakeContextCurrent();
gl->fViewport(0, 0, mWidth, mHeight);
@ -991,20 +994,13 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
mViewportHeight = mHeight;
gl->fScissor(0, 0, mWidth, mHeight);
// Make sure that we clear this out, otherwise
// we'll end up displaying random memory
gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
//////
// Check everything
AssertCachedBindings();
AssertCachedState();
// Clear immediately, because we need to present the cleared initial
// buffer.
mBackbufferNeedsClear = true;
ClearBackbufferIfNeeded();
mShouldPresent = true;
AssertCachedGlobalState();
MOZ_ASSERT(gl->Caps().color);
@ -1020,8 +1016,14 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
MOZ_ASSERT(gl->Caps().antialias == mOptions.antialias);
MOZ_ASSERT(gl->Caps().preserve == mOptions.preserveDrawingBuffer);
AssertCachedBindings();
AssertCachedState();
//////
// Clear immediately, because we need to present the cleared initial buffer
mBackbufferNeedsClear = true;
ClearBackbufferIfNeeded();
mShouldPresent = true;
//////
reporter.SetSuccessful();
@ -1416,8 +1418,7 @@ WebGLContext::ForceClearFramebufferWithDefaultValues(GLbitfield clearBits,
// Fun GL fact: No need to worry about the viewport here, glViewport is just
// setting up a coordinates transformation, it doesn't affect glClear at all.
AssertCachedState(); // Can't check cached bindings, as we could
// have a different FB bound temporarily.
AssertCachedGlobalState();
// Prepare GL state for clearing.
gl->fDisable(LOCAL_GL_SCISSOR_TEST);
@ -1881,6 +1882,14 @@ WebGLContext::ValidateCurFBForRead(const char* funcName,
GLenum* const out_mode)
{
if (!mBoundReadFramebuffer) {
const GLenum readBufferMode = gl->Screen()->GetReadBufferMode();
if (readBufferMode == LOCAL_GL_NONE) {
ErrorInvalidOperation("%s: Can't read from backbuffer when readBuffer mode is"
" NONE.",
funcName);
return false;
}
ClearBackbufferIfNeeded();
// FIXME - here we're assuming that the default framebuffer is backed by

View File

@ -376,7 +376,7 @@ public:
bool TryToRestoreContext();
void AssertCachedBindings();
void AssertCachedState();
void AssertCachedGlobalState();
dom::HTMLCanvasElement* GetCanvas() const { return mCanvasElement; }

View File

@ -72,7 +72,8 @@ WebGLContext::ClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
MakeContextCurrent();
const bool supportsFloatColorBuffers = (IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_half_float) ||
const bool supportsFloatColorBuffers = (IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_float) ||
IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_half_float) ||
IsExtensionEnabled(WebGLExtensionID::WEBGL_color_buffer_float));
if (!supportsFloatColorBuffers) {
r = GLClampFloat(r);

View File

@ -68,7 +68,7 @@ ContextLossWorkerEventTarget::DispatchFromScript(nsIRunnable* aEvent, uint32_t a
}
NS_IMETHODIMP
ContextLossWorkerEventTarget::Dispatch(already_AddRefed<nsIRunnable>&& aEvent,
ContextLossWorkerEventTarget::Dispatch(already_AddRefed<nsIRunnable> aEvent,
uint32_t aFlags)
{
nsCOMPtr<nsIRunnable> eventRef(aEvent);
@ -78,7 +78,7 @@ ContextLossWorkerEventTarget::Dispatch(already_AddRefed<nsIRunnable>&& aEvent,
}
NS_IMETHODIMP
ContextLossWorkerEventTarget::DelayedDispatch(already_AddRefed<nsIRunnable>&&,
ContextLossWorkerEventTarget::DelayedDispatch(already_AddRefed<nsIRunnable>,
uint32_t)
{
return NS_ERROR_NOT_IMPLEMENTED;

View File

@ -380,16 +380,11 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
return JS::NumberValue(uint32_t(i));
}
case LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE: {
if (mBoundReadFramebuffer) {
nsCString fbStatusInfoIgnored;
const auto status = mBoundReadFramebuffer->CheckFramebufferStatus(&fbStatusInfoIgnored);
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
ErrorInvalidOperation("getParameter: Read framebuffer must be"
" complete before querying"
" IMPLEMENTATION_COLOR_READ_TYPE.");
return JS::NullValue();
}
}
const webgl::FormatUsageInfo* usage;
uint32_t width, height;
GLenum mode;
if (!ValidateCurFBForRead(funcName, &usage, &width, &height, &mode))
return JS::NullValue();
GLint i = 0;
if (gl->IsSupported(gl::GLFeature::ES2_compatibility)) {
@ -401,16 +396,11 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
return JS::NumberValue(uint32_t(i));
}
case LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT: {
if (mBoundReadFramebuffer) {
nsCString fbStatusInfoIgnored;
const auto status = mBoundReadFramebuffer->CheckFramebufferStatus(&fbStatusInfoIgnored);
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
ErrorInvalidOperation("getParameter: Read framebuffer must be"
" complete before querying"
" IMPLEMENTATION_COLOR_READ_FORMAT.");
return JS::NullValue();
}
}
const webgl::FormatUsageInfo* usage;
uint32_t width, height;
GLenum mode;
if (!ValidateCurFBForRead(funcName, &usage, &width, &height, &mode))
return JS::NullValue();
GLint i = 0;
if (gl->IsSupported(gl::GLFeature::ES2_compatibility)) {

View File

@ -684,7 +684,7 @@ WebGLContext::AssertCachedBindings()
AssertUintParamCorrect(gl, LOCAL_GL_VERTEX_ARRAY_BINDING, bound);
}
// Bound object state
// Framebuffers
if (IsWebGL2()) {
GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->mGLName
: 0;
@ -699,6 +699,15 @@ WebGLContext::AssertCachedBindings()
AssertUintParamCorrect(gl, LOCAL_GL_FRAMEBUFFER_BINDING, bound);
}
GLint stencilBits = 0;
if (GetStencilBits(&stencilBits)) { // Depends on current draw framebuffer.
const GLuint stencilRefMask = (1 << stencilBits) - 1;
AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_REF, stencilRefMask, mStencilRefFront);
AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, stencilRefMask, mStencilRefBack);
}
// Program
GLuint bound = mCurrentProgram ? mCurrentProgram->mGLName : 0;
AssertUintParamCorrect(gl, LOCAL_GL_CURRENT_PROGRAM, bound);
@ -730,7 +739,7 @@ WebGLContext::AssertCachedBindings()
}
void
WebGLContext::AssertCachedState()
WebGLContext::AssertCachedGlobalState()
{
#ifdef DEBUG
MakeContextCurrent();
@ -771,14 +780,6 @@ WebGLContext::AssertCachedState()
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_CLEAR_VALUE, mStencilClearValue);
GLint stencilBits = 0;
if (GetStencilBits(&stencilBits)) {
const GLuint stencilRefMask = (1 << stencilBits) - 1;
AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_REF, stencilRefMask, mStencilRefFront);
AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, stencilRefMask, mStencilRefBack);
}
// GLES 3.0.4, $4.1.4, p177:
// [...] the front and back stencil mask are both set to the value `2^s - 1`, where
// `s` is greater than or equal to the number of bits in the deepest stencil buffer

View File

@ -257,6 +257,8 @@ public:
mReadBufferMode = readBufferMode;
}
GLenum ReadBufferMode() const { return mReadBufferMode; }
protected:
WebGLFBAttachPoint* GetAttachPoint(GLenum attachment); // Fallible

View File

@ -349,8 +349,11 @@ ConvertImage(size_t width, size_t height,
const void* srcBegin, size_t srcStride, gl::OriginPos srcOrigin,
WebGLTexelFormat srcFormat, bool srcPremultiplied,
void* dstBegin, size_t dstStride, gl::OriginPos dstOrigin,
WebGLTexelFormat dstFormat, bool dstPremultiplied)
WebGLTexelFormat dstFormat, bool dstPremultiplied,
bool* const out_wasTrivial)
{
*out_wasTrivial = true;
if (srcFormat == WebGLTexelFormat::FormatNotSupportingAnyConversion ||
dstFormat == WebGLTexelFormat::FormatNotSupportingAnyConversion)
{
@ -410,6 +413,8 @@ ConvertImage(size_t width, size_t height,
return true;
}
*out_wasTrivial = false;
WebGLImageConverter converter(width, height, srcItr, dstItr, srcStride, dstItrStride);
converter.run(srcFormat, dstFormat, premultOp);

View File

@ -43,7 +43,8 @@ bool ConvertImage(size_t width, size_t height,
const void* srcBegin, size_t srcStride, gl::OriginPos srcOrigin,
WebGLTexelFormat srcFormat, bool srcPremultiplied,
void* dstBegin, size_t dstStride, gl::OriginPos dstOrigin,
WebGLTexelFormat dstFormat, bool dstPremultiplied);
WebGLTexelFormat dstFormat, bool dstPremultiplied,
bool* out_wasTrivial);
//////////////////////////////////////////////////////////////////////////////////////////

View File

@ -1338,6 +1338,19 @@ EventListenerManager::Disconnect()
RemoveAllListeners();
}
static EventListenerFlags
GetEventListenerFlagsFromOptions(const EventListenerOptions& aOptions)
{
EventListenerFlags flags;
flags.mCapture = aOptions.mCapture;
if (aOptions.mMozSystemGroup) {
JSContext* cx = nsContentUtils::GetCurrentJSContext();
MOZ_ASSERT(cx, "Not being called from JS?");
flags.mInSystemGroup = IsChromeOrXBL(cx, nullptr);
}
return flags;
}
void
EventListenerManager::AddEventListener(
const nsAString& aType,
@ -1362,8 +1375,9 @@ EventListenerManager::AddEventListener(
if (aOptions.IsBoolean()) {
flags.mCapture = aOptions.GetAsBoolean();
} else {
flags.mCapture = aOptions.GetAsAddEventListenerOptions().mCapture;
flags.mPassive = aOptions.GetAsAddEventListenerOptions().mPassive;
const auto& options = aOptions.GetAsAddEventListenerOptions();
flags = GetEventListenerFlagsFromOptions(options);
flags.mPassive = options.mPassive;
}
flags.mAllowUntrustedEvents = aWantsUntrusted;
return AddEventListenerByType(aListenerHolder, aType, flags);
@ -1387,9 +1401,12 @@ EventListenerManager::RemoveEventListener(
const dom::EventListenerOptionsOrBoolean& aOptions)
{
EventListenerFlags flags;
flags.mCapture =
aOptions.IsBoolean() ? aOptions.GetAsBoolean()
: aOptions.GetAsEventListenerOptions().mCapture;
if (aOptions.IsBoolean()) {
flags.mCapture = aOptions.GetAsBoolean();
} else {
const auto& options = aOptions.GetAsEventListenerOptions();
flags = GetEventListenerFlagsFromOptions(options);
}
RemoveEventListenerByType(aListenerHolder, aType, flags);
}

View File

@ -77,6 +77,55 @@ function test_duplicateGetFilesAndDirectories() {
script.sendAsyncMessage("dir.open", { path: 'test' });
}
function test_inputGetFiles() {
var url = SimpleTest.getTestFileURL("script_fileList.js");
var script = SpecialPowers.loadChromeScript(url);
function onOpened(message) {
var fileList = document.getElementById('fileList');
SpecialPowers.wrap(fileList).mozSetDirectory(message.dir);
fileList.getFilesAndDirectories()
.then(function(result) {
is(result.length, 1, "getFilesAndDirectories should return 1 element");
ok(result[0] instanceof Directory, "getFilesAndDirectories should return 1 directory");
return fileList.getFiles(false);
})
.then(function(result) {
is(result.length, 1, "getFiles should return 1 element");
ok(result[0] instanceof File, "getFile should return 1 file");
is(result[0].name, 'foo.txt', "getFiles()[0].name should be 'foo.txt'");
is(result[0].webkitRelativePath, '/foo.txt', "getFiles()[0].webkitRelativePath should be '/foo.txt'");
return fileList.getFiles(true);
})
.then(function(result) {
is(result.length, 2, "getFiles should return 2 elements");
function checkFile(file) {
ok(file instanceof File, "getFile[x] should return a file");
if (file.name == 'foo.txt') {
is(file.webkitRelativePath, '/foo.txt', "getFiles()[x].webkitRelativePath should be '/foo.txt'");
} else {
is(file.name, 'bar.txt', "getFiles()[x].name should be 'bar.txt'");
is(file.webkitRelativePath, '/subdir/bar.txt', "getFiles()[x].webkitRelativePath should be '/subdir/bar.txt'");
}
}
checkFile(result[0]);
checkFile(result[1]);
})
.then(function() {
script.destroy();
next();
});
}
script.addMessageListener("dir.opened", onOpened);
script.sendAsyncMessage("dir.open", { path: 'test' });
}
var tests = [
function() { setup_tests(next); },
@ -95,6 +144,7 @@ var tests = [
function() { test_getFiles(directory, false, next); },
test_duplicateGetFilesAndDirectories,
test_inputGetFiles,
test_simpleFilePicker
];

View File

@ -218,6 +218,321 @@ const Decimal HTMLInputElement::kStepAny = Decimal(0);
#define PROGRESS_STR "progress"
static const uint32_t kProgressEventInterval = 50; // ms
// Retrieving the list of files can be very time/IO consuming. We use this
// helper class to do it just once.
class GetFilesHelper final : public Runnable
{
public:
static already_AddRefed<GetFilesHelper>
Create(nsIGlobalObject* aGlobal,
const nsTArray<OwningFileOrDirectory>& aFilesOrDirectory,
bool aRecursiveFlag, ErrorResult& aRv)
{
MOZ_ASSERT(aGlobal);
RefPtr<GetFilesHelper> helper = new GetFilesHelper(aGlobal, aRecursiveFlag);
nsAutoString directoryPath;
for (uint32_t i = 0; i < aFilesOrDirectory.Length(); ++i) {
const OwningFileOrDirectory& data = aFilesOrDirectory[i];
if (data.IsFile()) {
if (!helper->mFiles.AppendElement(data.GetAsFile(), fallible)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
} else {
MOZ_ASSERT(data.IsDirectory());
// We support the upload of only 1 top-level directory from our
// directory picker. This means that we cannot have more than 1
// Directory object in aFilesOrDirectory array.
MOZ_ASSERT(directoryPath.IsEmpty());
RefPtr<Directory> directory = data.GetAsDirectory();
MOZ_ASSERT(directory);
aRv = directory->GetFullRealPath(directoryPath);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
}
}
// No directories to explore.
if (directoryPath.IsEmpty()) {
helper->mListingCompleted = true;
return helper.forget();
}
MOZ_ASSERT(helper->mFiles.IsEmpty());
helper->SetDirectoryPath(directoryPath);
nsCOMPtr<nsIEventTarget> target =
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(target);
aRv = target->Dispatch(helper, NS_DISPATCH_NORMAL);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return helper.forget();
}
void
AddPromise(Promise* aPromise)
{
MOZ_ASSERT(aPromise);
// Still working.
if (!mListingCompleted) {
mPromises.AppendElement(aPromise);
return;
}
MOZ_ASSERT(mPromises.IsEmpty());
ResolveOrRejectPromise(aPromise);
}
// CC methods
void Unlink()
{
mGlobal = nullptr;
mFiles.Clear();
mPromises.Clear();
}
void Traverse(nsCycleCollectionTraversalCallback &cb)
{
GetFilesHelper* tmp = this;
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFiles);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPromises);
}
private:
GetFilesHelper(nsIGlobalObject* aGlobal, bool aRecursiveFlag)
: mGlobal(aGlobal)
, mRecursiveFlag(aRecursiveFlag)
, mListingCompleted(false)
, mErrorResult(NS_OK)
{
MOZ_ASSERT(aGlobal);
}
void
SetDirectoryPath(const nsAString& aDirectoryPath)
{
mDirectoryPath = aDirectoryPath;
}
NS_IMETHOD
Run() override
{
MOZ_ASSERT(!mDirectoryPath.IsEmpty());
MOZ_ASSERT(!mListingCompleted);
// First step is to retrieve the list of file paths.
// This happens in the I/O thread.
if (!NS_IsMainThread()) {
RunIO();
return NS_DispatchToMainThread(this);
}
RunMainThread();
// We mark the operation as completed here.
mListingCompleted = true;
// Let's process the pending promises.
nsTArray<RefPtr<Promise>> promises;
promises.SwapElements(mPromises);
for (uint32_t i = 0; i < promises.Length(); ++i) {
ResolveOrRejectPromise(promises[i]);
}
return NS_OK;
}
void
RunIO()
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(!mDirectoryPath.IsEmpty());
MOZ_ASSERT(!mListingCompleted);
nsCOMPtr<nsIFile> file;
mErrorResult = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(mDirectoryPath), true,
getter_AddRefs(file));
if (NS_WARN_IF(NS_FAILED(mErrorResult))) {
return;
}
nsAutoString path;
path.AssignLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
mErrorResult = ExploreDirectory(path, file);
}
void
RunMainThread()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mDirectoryPath.IsEmpty());
MOZ_ASSERT(!mListingCompleted);
// If there is an error, do nothing.
if (NS_FAILED(mErrorResult)) {
return;
}
// Create the sequence of Files.
for (uint32_t i = 0; i < mTargetPathArray.Length(); ++i) {
nsCOMPtr<nsIFile> file;
mErrorResult =
NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(mTargetPathArray[i].mRealPath),
true, getter_AddRefs(file));
if (NS_WARN_IF(NS_FAILED(mErrorResult))) {
mFiles.Clear();
return;
}
RefPtr<File> domFile =
File::CreateFromFile(mGlobal, file);
MOZ_ASSERT(domFile);
domFile->SetPath(mTargetPathArray[i].mDomPath);
if (!mFiles.AppendElement(domFile, fallible)) {
mErrorResult = NS_ERROR_OUT_OF_MEMORY;
mFiles.Clear();
return;
}
}
}
nsresult
ExploreDirectory(const nsAString& aDOMPath, nsIFile* aFile)
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aFile);
nsCOMPtr<nsISimpleEnumerator> entries;
nsresult rv = aFile->GetDirectoryEntries(getter_AddRefs(entries));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
for (;;) {
bool hasMore = false;
if (NS_WARN_IF(NS_FAILED(entries->HasMoreElements(&hasMore))) || !hasMore) {
break;
}
nsCOMPtr<nsISupports> supp;
if (NS_WARN_IF(NS_FAILED(entries->GetNext(getter_AddRefs(supp))))) {
break;
}
nsCOMPtr<nsIFile> currFile = do_QueryInterface(supp);
MOZ_ASSERT(currFile);
bool isLink, isSpecial, isFile, isDir;
if (NS_WARN_IF(NS_FAILED(currFile->IsSymlink(&isLink)) ||
NS_FAILED(currFile->IsSpecial(&isSpecial))) ||
isLink || isSpecial) {
continue;
}
if (NS_WARN_IF(NS_FAILED(currFile->IsFile(&isFile)) ||
NS_FAILED(currFile->IsDirectory(&isDir))) ||
!(isFile || isDir)) {
continue;
}
// The new domPath
nsAutoString domPath;
domPath.Assign(aDOMPath);
if (!aDOMPath.EqualsLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL)) {
domPath.AppendLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
}
nsAutoString leafName;
if (NS_WARN_IF(NS_FAILED(currFile->GetLeafName(leafName)))) {
continue;
}
domPath.Append(leafName);
if (isFile) {
FileData* data = mTargetPathArray.AppendElement(fallible);
if (!data) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (NS_WARN_IF(NS_FAILED(currFile->GetPath(data->mRealPath)))) {
continue;
}
data->mDomPath = domPath;
continue;
}
MOZ_ASSERT(isDir);
if (!mRecursiveFlag) {
continue;
}
// Recursive.
rv = ExploreDirectory(domPath, currFile);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return NS_OK;
}
void
ResolveOrRejectPromise(Promise* aPromise)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mListingCompleted);
MOZ_ASSERT(aPromise);
// Error propagation.
if (NS_FAILED(mErrorResult)) {
aPromise->MaybeReject(mErrorResult);
return;
}
aPromise->MaybeResolve(mFiles);
}
nsCOMPtr<nsIGlobalObject> mGlobal;
bool mRecursiveFlag;
bool mListingCompleted;
nsString mDirectoryPath;
// We populate this array in the I/O thread with the paths of the Files that
// we want to send as result to the promise objects.
struct FileData {
nsString mDomPath;
nsString mRealPath;
};
FallibleTArray<FileData> mTargetPathArray;
// This is the real File sequence that we expose via Promises.
Sequence<RefPtr<File>> mFiles;
// Error code to propagate.
nsresult mErrorResult;
nsTArray<RefPtr<Promise>> mPromises;
};
class HTMLInputElementState final : public nsISupports
{
public:
@ -1052,6 +1367,15 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLInputElement,
tmp->mInputData.mState->Traverse(cb);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFilesOrDirectories)
if (tmp->mGetFilesRecursiveHelper) {
tmp->mGetFilesRecursiveHelper->Traverse(cb);
}
if (tmp->mGetFilesNonRecursiveHelper) {
tmp->mGetFilesNonRecursiveHelper->Traverse(cb);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFileList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -1064,6 +1388,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLInputElement,
if (tmp->IsSingleLineTextControl(false)) {
tmp->mInputData.mState->Unlink();
}
tmp->ClearGetFilesHelpers();
//XXX should unlink more?
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -1117,6 +1444,7 @@ HTMLInputElement::Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) co
// we can just grab the pretty string and use it as wallpaper
GetDisplayFileName(it->mStaticDocFileList);
} else {
it->ClearGetFilesHelpers();
it->mFilesOrDirectories.Clear();
it->mFilesOrDirectories.AppendElements(mFilesOrDirectories);
}
@ -2562,6 +2890,8 @@ void
HTMLInputElement::SetFilesOrDirectories(const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories,
bool aSetValueChanged)
{
ClearGetFilesHelpers();
mFilesOrDirectories.Clear();
mFilesOrDirectories.AppendElements(aFilesOrDirectories);
@ -2574,6 +2904,7 @@ HTMLInputElement::SetFiles(nsIDOMFileList* aFiles,
{
RefPtr<FileList> files = static_cast<FileList*>(aFiles);
mFilesOrDirectories.Clear();
ClearGetFilesHelpers();
if (aFiles) {
uint32_t listLength;
@ -5081,6 +5412,58 @@ HTMLInputElement::GetFilesAndDirectories(ErrorResult& aRv)
return p.forget();
}
already_AddRefed<Promise>
HTMLInputElement::GetFiles(bool aRecursiveFlag, ErrorResult& aRv)
{
if (mType != NS_FORM_INPUT_FILE) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
nsCOMPtr<nsIGlobalObject> global = OwnerDoc()->GetScopeObject();
MOZ_ASSERT(global);
if (!global) {
return nullptr;
}
RefPtr<GetFilesHelper> helper;
if (aRecursiveFlag) {
if (!mGetFilesRecursiveHelper) {
mGetFilesRecursiveHelper =
GetFilesHelper::Create(global,
GetFilesOrDirectoriesInternal(),
aRecursiveFlag, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
}
helper = mGetFilesRecursiveHelper;
} else {
if (!mGetFilesNonRecursiveHelper) {
mGetFilesNonRecursiveHelper =
GetFilesHelper::Create(global,
GetFilesOrDirectoriesInternal(),
aRecursiveFlag, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
}
helper = mGetFilesNonRecursiveHelper;
}
MOZ_ASSERT(helper);
RefPtr<Promise> p = Promise::Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
helper->AddPromise(p);
return p.forget();
}
// Controllers Methods
@ -7578,6 +7961,20 @@ HTMLInputElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return HTMLInputElementBinding::Wrap(aCx, this, aGivenProto);
}
void
HTMLInputElement::ClearGetFilesHelpers()
{
if (mGetFilesRecursiveHelper) {
mGetFilesRecursiveHelper->Unlink();
mGetFilesRecursiveHelper = nullptr;
}
if (mGetFilesNonRecursiveHelper) {
mGetFilesNonRecursiveHelper->Unlink();
mGetFilesNonRecursiveHelper = nullptr;
}
}
} // namespace dom
} // namespace mozilla

View File

@ -40,6 +40,7 @@ namespace dom {
class Date;
class File;
class FileList;
class GetFilesHelper;
/**
* A class we use to create a singleton object that is used to keep track of
@ -703,6 +704,8 @@ public:
already_AddRefed<Promise> GetFilesAndDirectories(ErrorResult& aRv);
already_AddRefed<Promise> GetFiles(bool aRecursiveFlag, ErrorResult& aRv);
void ChooseDirectory(ErrorResult& aRv);
// XPCOM GetAlign() is OK
@ -1253,6 +1256,8 @@ protected:
*/
bool IsPopupBlocked() const;
void ClearGetFilesHelpers();
nsCOMPtr<nsIControllers> mControllers;
/*
@ -1286,6 +1291,9 @@ protected:
*/
nsTArray<OwningFileOrDirectory> mFilesOrDirectories;
RefPtr<GetFilesHelper> mGetFilesRecursiveHelper;
RefPtr<GetFilesHelper> mGetFilesNonRecursiveHelper;
#ifndef MOZ_CHILD_PERMISSIONS
/**
* Hack for bug 1086684: Stash the .value when we're a file picker.

View File

@ -2802,18 +2802,6 @@ nsGenericHTMLElement::DispatchSimulatedClick(nsGenericHTMLElement* aElement,
return EventDispatcher::Dispatch(ToSupports(aElement), aPresContext, &event);
}
const nsAttrName*
nsGenericHTMLElement::InternalGetExistingAttrNameFromQName(const nsAString& aStr) const
{
if (IsInHTMLDocument()) {
nsAutoString lower;
nsContentUtils::ASCIIToLower(aStr, lower);
return mAttrsAndChildren.GetExistingAttrNameFromQName(lower);
}
return mAttrsAndChildren.GetExistingAttrNameFromQName(aStr);
}
nsresult
nsGenericHTMLElement::GetEditor(nsIEditor** aEditor)
{

View File

@ -937,8 +937,6 @@ protected:
GetEventListenerManagerForAttr(nsIAtom* aAttrName,
bool* aDefer) override;
virtual const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const override;
/**
* Dispatch a simulated mouse click by keyboard to the given element.
*/

View File

@ -185,6 +185,19 @@ interface nsIServiceWorkerManager : nsISupports
in AString aIcon,
in AString aData,
in AString aBehavior);
void sendNotificationCloseEvent(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);
[optional_argc] void sendPushEvent(in ACString aOriginAttributes,
in ACString aScope,
[optional] in uint32_t aDataLength,

View File

@ -5539,10 +5539,13 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
nsCOMPtr<mozIDOMWindowProxy> window;
TabParent::AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
const char* name = aName.IsVoid() ? nullptr : NS_ConvertUTF16toUTF8(aName).get();
const char* features = aFeatures.IsVoid() ? nullptr : aFeatures.get();
*aResult = pwwatch->OpenWindow2(parent, nullptr, name, features, aCalledFromJS,
*aResult = pwwatch->OpenWindow2(parent, nullptr,
aName.IsVoid() ?
nullptr :
NS_ConvertUTF16toUTF8(aName).get(),
features, aCalledFromJS,
false, false, thisTabParent, nullptr,
aFullZoom, 1, getter_AddRefs(window));

View File

@ -229,3 +229,4 @@ PushMessageDecryptionFailure=The ServiceWorker for scope %1$S encountered
# LOCALIZATION NOTE: %1$S is the type of a DOM event. 'passive' is a literal parameter from the DOM spec.
PreventDefaultFromPassiveListenerWarning=Ignoring preventDefault() call on event of type %1$S from a listener registered as passive.
NavigatorBatteryWarning=navigator.battery is deprecated. Use navigator.getBattery() instead.
FileLastModifiedDateWarning=File.lastModifiedDate is deprecated. Use File.lastModified instead.

View File

@ -315,16 +315,19 @@ struct ToCubebFormat<AUDIO_FORMAT_S16> {
static const cubeb_sample_format value = CUBEB_SAMPLE_S16NE;
};
template <typename Function, typename... Args>
int AudioStream::InvokeCubeb(Function aFunction, Args&&... aArgs)
{
MonitorAutoUnlock mon(mMonitor);
return aFunction(mCubebStream.get(), Forward<Args>(aArgs)...);
}
nsresult
AudioStream::Init(uint32_t aNumChannels, uint32_t aRate,
const dom::AudioChannel aAudioChannel)
{
auto startTime = TimeStamp::Now();
mIsFirst = CubebUtils::GetFirstStream();
if (!CubebUtils::GetCubebContext()) {
return NS_ERROR_FAILURE;
}
auto isFirst = CubebUtils::GetFirstStream();
LOG("%s channels: %d, rate: %d", __FUNCTION__, aNumChannels, aRate);
mInRate = mOutRate = aRate;
@ -351,49 +354,34 @@ AudioStream::Init(uint32_t aNumChannels, uint32_t aRate,
params.format = ToCubebFormat<AUDIO_OUTPUT_FORMAT>::value;
mAudioClock.Init();
return OpenCubeb(params, startTime);
return OpenCubeb(params, startTime, isFirst);
}
// This code used to live inside AudioStream::Init(), but on Mac (others?)
// it has been known to take 300-800 (or even 8500) ms to execute(!)
nsresult
AudioStream::OpenCubeb(cubeb_stream_params &aParams, TimeStamp aStartTime)
AudioStream::OpenCubeb(cubeb_stream_params& aParams,
TimeStamp aStartTime, bool aIsFirst)
{
cubeb* cubebContext = CubebUtils::GetCubebContext();
if (!cubebContext) {
NS_WARNING("Can't get cubeb context!");
MonitorAutoLock mon(mMonitor);
mState = AudioStream::ERRORED;
return NS_ERROR_FAILURE;
}
// If the latency pref is set, use it. Otherwise, if this stream is intended
// for low latency playback, try to get the lowest latency possible.
// Otherwise, for normal streams, use 100ms.
uint32_t latency = CubebUtils::GetCubebLatency();
{
cubeb_stream* stream;
if (cubeb_stream_init(cubebContext, &stream, "AudioStream",
nullptr, nullptr, nullptr, &aParams,
latency, DataCallback_S, StateCallback_S, this) == CUBEB_OK) {
MonitorAutoLock mon(mMonitor);
MOZ_ASSERT(mState != SHUTDOWN);
mCubebStream.reset(stream);
} else {
MonitorAutoLock mon(mMonitor);
mState = ERRORED;
NS_WARNING(nsPrintfCString("AudioStream::OpenCubeb() %p failed to init cubeb", this).get());
return NS_ERROR_FAILURE;
}
cubeb_stream* stream = nullptr;
if (cubeb_stream_init(cubebContext, &stream, "AudioStream",
nullptr, nullptr, nullptr, &aParams,
CubebUtils::GetCubebLatency(),
DataCallback_S, StateCallback_S, this) == CUBEB_OK) {
mCubebStream.reset(stream);
} else {
NS_WARNING(nsPrintfCString("AudioStream::OpenCubeb() %p failed to init cubeb", this).get());
return NS_ERROR_FAILURE;
}
mState = INITIALIZED;
TimeDuration timeDelta = TimeStamp::Now() - aStartTime;
LOG("creation time %sfirst: %u ms", mIsFirst ? "" : "not ",
LOG("creation time %sfirst: %u ms", aIsFirst ? "" : "not ",
(uint32_t) timeDelta.ToMilliseconds());
Telemetry::Accumulate(mIsFirst ? Telemetry::AUDIOSTREAM_FIRST_OPEN_MS :
Telemetry::Accumulate(aIsFirst ? Telemetry::AUDIOSTREAM_FIRST_OPEN_MS :
Telemetry::AUDIOSTREAM_LATER_OPEN_MS, timeDelta.ToMilliseconds());
return NS_OK;
@ -413,21 +401,10 @@ void
AudioStream::Start()
{
MonitorAutoLock mon(mMonitor);
if (mState == INITIALIZED) {
mState = STARTED;
int r;
{
MonitorAutoUnlock mon(mMonitor);
r = cubeb_stream_start(mCubebStream.get());
// DataCallback might be called before we exit this scope
// if cubeb_stream_start() succeeds. mState must be set to STARTED
// beforehand.
}
if (r != CUBEB_OK) {
mState = ERRORED;
}
LOG("started, state %s", mState == STARTED ? "STARTED" : "ERRORED");
}
MOZ_ASSERT(mState == INITIALIZED);
auto r = InvokeCubeb(cubeb_stream_start);
mState = r == CUBEB_OK ? STARTED : ERRORED;
LOG("started, state %s", mState == STARTED ? "STARTED" : "ERRORED");
}
void
@ -439,16 +416,12 @@ AudioStream::Pause()
return;
}
if (mState != STARTED && mState != RUNNING) {
if (mState != STARTED) {
mState = STOPPED; // which also tells async OpenCubeb not to start, just init
return;
}
int r;
{
MonitorAutoUnlock mon(mMonitor);
r = cubeb_stream_stop(mCubebStream.get());
}
int r = InvokeCubeb(cubeb_stream_stop);
if (mState != ERRORED && r == CUBEB_OK) {
mState = STOPPED;
}
@ -462,11 +435,7 @@ AudioStream::Resume()
return;
}
int r;
{
MonitorAutoUnlock mon(mMonitor);
r = cubeb_stream_start(mCubebStream.get());
}
int r = InvokeCubeb(cubeb_stream_start);
if (mState != ERRORED && r == CUBEB_OK) {
mState = STARTED;
}
@ -514,13 +483,9 @@ AudioStream::GetPositionInFramesUnlocked()
}
uint64_t position = 0;
{
MonitorAutoUnlock mon(mMonitor);
if (cubeb_stream_get_position(mCubebStream.get(), &position) != CUBEB_OK) {
return -1;
}
if (InvokeCubeb(cubeb_stream_get_position, &position) != CUBEB_OK) {
return -1;
}
return std::min<uint64_t>(position, INT64_MAX);
}
@ -636,11 +601,6 @@ AudioStream::DataCallback(void* aBuffer, long aFrames)
// NOTE: wasapi (others?) can call us back *after* stop()/Shutdown() (mState == SHUTDOWN)
// Bug 996162
// callback tells us cubeb succeeded initializing
if (mState == STARTED) {
mState = RUNNING;
}
if (mInRate == mOutRate) {
GetUnprocessed(writer);
} else {

View File

@ -313,7 +313,8 @@ protected:
int64_t GetPositionInFramesUnlocked();
private:
nsresult OpenCubeb(cubeb_stream_params &aParams, TimeStamp aStartTime);
nsresult OpenCubeb(cubeb_stream_params& aParams,
TimeStamp aStartTime, bool aIsFirst);
static long DataCallback_S(cubeb_stream*, void* aThis,
const void* /* aInputBuffer */, void* aOutputBuffer,
@ -340,6 +341,9 @@ private:
void GetUnprocessed(AudioBufferWriter& aWriter);
void GetTimeStretched(AudioBufferWriter& aWriter);
template <typename Function, typename... Args>
int InvokeCubeb(Function aFunction, Args&&... aArgs);
// The monitor is held to protect all access to member variables.
Monitor mMonitor;
@ -360,8 +364,7 @@ private:
enum StreamState {
INITIALIZED, // Initialized, playback has not begun.
STARTED, // cubeb started, but callbacks haven't started
RUNNING, // DataCallbacks have started after STARTED, or after Resume().
STARTED, // cubeb started.
STOPPED, // Stopped by a call to Pause().
DRAINED, // StateCallback has indicated that the drain is complete.
ERRORED, // Stream disabled due to an internal error.
@ -369,7 +372,6 @@ private:
};
StreamState mState;
bool mIsFirst;
DataSource& mDataSource;
};

View File

@ -153,46 +153,47 @@ WMFVideoMFTManager::GetMediaSubtypeGUID()
};
}
struct D3D11BlacklistingCache
struct D3DDLLBlacklistingCache
{
// D3D11-blacklist pref last seen.
// Blacklist pref value last seen.
nsCString mBlacklistPref;
// Non-empty if a D3D11-blacklisted DLL was found.
// Non-empty if a blacklisted DLL was found.
nsCString mBlacklistedDLL;
};
StaticAutoPtr<D3D11BlacklistingCache> sD3D11BlacklistingCache;
StaticAutoPtr<D3DDLLBlacklistingCache> sD3D11BlacklistingCache;
StaticAutoPtr<D3DDLLBlacklistingCache> sD3D9BlacklistingCache;
// If a blacklisted DLL is found, return its information, otherwise "".
static const nsACString&
FindD3D11BlacklistedDLL()
FindDXVABlacklistedDLL(StaticAutoPtr<D3DDLLBlacklistingCache>& aDLLBlacklistingCache,
const char* aDLLBlacklistPrefName)
{
NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
if (!sD3D11BlacklistingCache) {
if (!aDLLBlacklistingCache) {
// First time here, create persistent data that will be reused in all
// D3D11-blacklisting checks.
sD3D11BlacklistingCache = new D3D11BlacklistingCache();
ClearOnShutdown(&sD3D11BlacklistingCache);
aDLLBlacklistingCache = new D3DDLLBlacklistingCache();
ClearOnShutdown(&aDLLBlacklistingCache);
}
nsAdoptingCString blacklist =
Preferences::GetCString("media.wmf.disable-d3d11-for-dlls");
nsAdoptingCString blacklist = Preferences::GetCString(aDLLBlacklistPrefName);
if (blacklist.IsEmpty()) {
// Empty blacklist -> No blacklisting.
sD3D11BlacklistingCache->mBlacklistPref.SetLength(0);
sD3D11BlacklistingCache->mBlacklistedDLL.SetLength(0);
return sD3D11BlacklistingCache->mBlacklistedDLL;
aDLLBlacklistingCache->mBlacklistPref.SetLength(0);
aDLLBlacklistingCache->mBlacklistedDLL.SetLength(0);
return aDLLBlacklistingCache->mBlacklistedDLL;
}
// Detect changes in pref.
if (sD3D11BlacklistingCache->mBlacklistPref.Equals(blacklist)) {
if (aDLLBlacklistingCache->mBlacklistPref.Equals(blacklist)) {
// Same blacklist -> Return same result (i.e., don't check DLLs again).
return sD3D11BlacklistingCache->mBlacklistedDLL;
return aDLLBlacklistingCache->mBlacklistedDLL;
}
// Adopt new pref now, so we don't work on it again.
sD3D11BlacklistingCache->mBlacklistPref = blacklist;
aDLLBlacklistingCache->mBlacklistPref = blacklist;
// media.wmf.disable-d3d11-for-dlls format: (whitespace is trimmed)
// media.wmf.disable-d3d*-for-dlls format: (whitespace is trimmed)
// "dll1.dll: 1.2.3.4[, more versions...][; more dlls...]"
nsTArray<nsCString> dlls;
SplitAt(";", blacklist, dlls);
@ -200,7 +201,8 @@ FindD3D11BlacklistedDLL()
nsTArray<nsCString> nameAndVersions;
SplitAt(":", dll, nameAndVersions);
if (nameAndVersions.Length() != 2) {
NS_WARNING("Skipping incorrect 'media.wmf.disable-d3d11-for-dlls' dll:versions format");
NS_WARNING(nsPrintfCString("Skipping incorrect '%s' dll:versions format",
aDLLBlacklistPrefName).get());
continue;
}
@ -235,7 +237,8 @@ FindD3D11BlacklistedDLL()
nsTArray<nsCString> numberStrings;
SplitAt(".", version, numberStrings);
if (numberStrings.Length() != 4) {
NS_WARNING("Skipping incorrect 'media.wmf.disable-d3d11-for-dlls' a.b.c.d version format");
NS_WARNING(nsPrintfCString("Skipping incorrect '%s' a.b.c.d version format",
aDLLBlacklistPrefName).get());
continue;
}
DWORD numbers[4];
@ -253,25 +256,38 @@ FindD3D11BlacklistedDLL()
}
if (NS_FAILED(errorCode)) {
NS_WARNING("Skipping incorrect 'media.wmf.disable-d3d11-for-dlls' a.b.c.d version format");
NS_WARNING(nsPrintfCString("Skipping incorrect '%s' a.b.c.d version format",
aDLLBlacklistPrefName).get());
continue;
}
if (vInfo->dwFileVersionMS == ((numbers[0] << 16) | numbers[1])
&& vInfo->dwFileVersionLS == ((numbers[2] << 16) | numbers[3])) {
// Blacklisted! Record bad DLL.
sD3D11BlacklistingCache->mBlacklistedDLL.SetLength(0);
sD3D11BlacklistingCache->mBlacklistedDLL.AppendPrintf(
aDLLBlacklistingCache->mBlacklistedDLL.SetLength(0);
aDLLBlacklistingCache->mBlacklistedDLL.AppendPrintf(
"%s (%lu.%lu.%lu.%lu)",
nameAndVersions[0].get(), numbers[0], numbers[1], numbers[2], numbers[3]);
return sD3D11BlacklistingCache->mBlacklistedDLL;
return aDLLBlacklistingCache->mBlacklistedDLL;
}
}
}
// No blacklisted DLL.
sD3D11BlacklistingCache->mBlacklistedDLL.SetLength(0);
return sD3D11BlacklistingCache->mBlacklistedDLL;
aDLLBlacklistingCache->mBlacklistedDLL.SetLength(0);
return aDLLBlacklistingCache->mBlacklistedDLL;
}
static const nsACString&
FindD3D11BlacklistedDLL() {
return FindDXVABlacklistedDLL(sD3D11BlacklistingCache,
"media.wmf.disable-d3d11-for-dlls");
}
static const nsACString&
FindD3D9BlacklistedDLL() {
return FindDXVABlacklistedDLL(sD3D9BlacklistingCache,
"media.wmf.disable-d3d9-for-dlls");
}
class CreateDXVAManagerEvent : public Runnable {
@ -302,9 +318,16 @@ public:
failureReason = &secondFailureReason;
mFailureReason.Append(NS_LITERAL_CSTRING("; "));
}
mDXVA2Manager = DXVA2Manager::CreateD3D9DXVA(*failureReason);
// Make sure we include the messages from both attempts (if applicable).
mFailureReason.Append(secondFailureReason);
const nsACString& blacklistedDLL = FindD3D9BlacklistedDLL();
if (!blacklistedDLL.IsEmpty()) {
mFailureReason.AppendPrintf("D3D9 blacklisted with DLL %s",
blacklistedDLL);
} else {
mDXVA2Manager = DXVA2Manager::CreateD3D9DXVA(*failureReason);
// Make sure we include the messages from both attempts (if applicable).
mFailureReason.Append(secondFailureReason);
}
return NS_OK;
}
nsAutoPtr<DXVA2Manager> mDXVA2Manager;

View File

@ -1590,29 +1590,31 @@ ServiceWorkerNotificationObserver::Observe(nsISupports* aSubject,
{
AssertIsOnMainThread();
nsAutoCString originSuffix;
nsresult rv = mPrincipal->GetOriginSuffix(originSuffix);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsIServiceWorkerManager> swm =
mozilla::services::GetServiceWorkerManager();
if (NS_WARN_IF(!swm)) {
return NS_ERROR_FAILURE;
}
if (!strcmp("alertclickcallback", aTopic)) {
nsAutoCString originSuffix;
nsresult rv = mPrincipal->GetOriginSuffix(originSuffix);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsIServiceWorkerManager> swm =
mozilla::services::GetServiceWorkerManager();
if (swm) {
swm->SendNotificationClickEvent(originSuffix,
NS_ConvertUTF16toUTF8(mScope),
mID,
mTitle,
mDir,
mLang,
mBody,
mTag,
mIcon,
mData,
mBehavior);
}
rv = swm->SendNotificationClickEvent(originSuffix,
NS_ConvertUTF16toUTF8(mScope),
mID,
mTitle,
mDir,
mLang,
mBody,
mTag,
mIcon,
mData,
mBehavior);
Unused << NS_WARN_IF(NS_FAILED(rv));
return NS_OK;
}
@ -1629,6 +1631,20 @@ ServiceWorkerNotificationObserver::Observe(nsISupports* aSubject,
if (notificationStorage) {
notificationStorage->Delete(origin, mID);
}
rv = swm->SendNotificationCloseEvent(originSuffix,
NS_ConvertUTF16toUTF8(mScope),
mID,
mTitle,
mDir,
mLang,
mBody,
mTag,
mIcon,
mData,
mBehavior);
Unused << NS_WARN_IF(NS_FAILED(rv));
return NS_OK;
}
return NS_OK;

View File

@ -99,6 +99,18 @@ interface nsIPluginHost : nsISupports
ACString getPermissionStringForType(in AUTF8String mimeType,
[optional] in uint32_t excludeFlags);
/**
* Get the "permission string" for the plugin. This is a string that can be
* passed to the permission manager to see whether the plugin is allowed to
* run, for example. This will typically be based on the plugin's "nice name"
* and its blocklist state.
*
* @tag The tage we're interested in
* @excludeFlags Set of the EXCLUDE_* flags above, defaulting to EXCLUDE_NONE.
*/
ACString getPermissionStringForTag(in nsIPluginTag tag,
[optional] in uint32_t excludeFlags);
/**
* Get the nsIPluginTag for this MIME type. This method works with both
* enabled and disabled/blocklisted plugins, but an enabled plugin will

View File

@ -1110,11 +1110,19 @@ nsPluginHost::GetPermissionStringForType(const nsACString &aMimeType,
nsresult rv = GetPluginTagForType(aMimeType, aExcludeFlags,
getter_AddRefs(tag));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(tag, NS_ERROR_FAILURE);
return GetPermissionStringForTag(tag, aExcludeFlags, aPermissionString);
}
NS_IMETHODIMP
nsPluginHost::GetPermissionStringForTag(nsIPluginTag* aTag,
uint32_t aExcludeFlags,
nsACString &aPermissionString)
{
NS_ENSURE_TRUE(aTag, NS_ERROR_FAILURE);
aPermissionString.Truncate();
uint32_t blocklistState;
rv = tag->GetBlocklistState(&blocklistState);
nsresult rv = aTag->GetBlocklistState(&blocklistState);
NS_ENSURE_SUCCESS(rv, rv);
if (blocklistState == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE ||
@ -1126,7 +1134,7 @@ nsPluginHost::GetPermissionStringForType(const nsACString &aMimeType,
}
nsCString niceName;
rv = tag->GetNiceName(niceName);
rv = aTag->GetNiceName(niceName);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(!niceName.IsEmpty(), NS_ERROR_FAILURE);

View File

@ -323,7 +323,7 @@ nsPluginTag::~nsPluginTag()
NS_ASSERTION(!mNext, "Risk of exhausting the stack space, bug 486349");
}
NS_IMPL_ISUPPORTS(nsPluginTag, nsIPluginTag, nsIInternalPluginTag)
NS_IMPL_ISUPPORTS(nsPluginTag, nsPluginTag, nsIInternalPluginTag, nsIPluginTag)
void nsPluginTag::InitMime(const char* const* aMimeTypes,
const char* const* aMimeDescriptions,

View File

@ -31,6 +31,9 @@ struct FakePluginTagInit;
{ 0xe8fdd227, 0x27da, 0x46ee, \
{ 0xbe, 0xf3, 0x1a, 0xef, 0x5a, 0x8f, 0xc5, 0xb4 } }
#define NS_PLUGINTAG_IID \
{ 0xcce2e8b9, 0x9702, 0x4d4b, \
{ 0xbe, 0xa4, 0x7c, 0x1e, 0x13, 0x1f, 0xaf, 0x78 } }
class nsIInternalPluginTag : public nsIPluginTag
{
public:
@ -91,6 +94,8 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIInternalPluginTag, NS_IINTERNALPLUGINTAG_IID)
class nsPluginTag final : public nsIInternalPluginTag
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_PLUGINTAG_IID)
NS_DECL_ISUPPORTS
NS_DECL_NSIPLUGINTAG
@ -193,6 +198,7 @@ private:
static uint32_t sNextId;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsPluginTag, NS_PLUGINTAG_IID)
// A class representing "fake" plugin tags; that is plugin tags not
// corresponding to actual NPAPI plugins. In practice these are all

View File

@ -145,7 +145,7 @@ MulticastDNSDeviceProvider::Init()
Preferences::AddStrongObservers(this, kObservedPrefs);
mDiscoveryEnabled = Preferences::GetBool(PREF_PRESENTATION_DISCOVERY);
mDiscveryTimeoutMs = Preferences::GetUint(PREF_PRESENTATION_DISCOVERY_TIMEOUT_MS);
mDiscoveryTimeoutMs = Preferences::GetUint(PREF_PRESENTATION_DISCOVERY_TIMEOUT_MS);
mDiscoverable = Preferences::GetBool(PREF_PRESENTATION_DISCOVERABLE);
mServiceName = Preferences::GetCString(PREF_PRESENTATION_DEVICE_NAME);
@ -534,7 +534,7 @@ MulticastDNSDeviceProvider::ForceDiscovery()
Unused << mDiscoveryTimer->Cancel();
if (NS_WARN_IF(NS_FAILED( rv = mDiscoveryTimer->Init(this,
mDiscveryTimeoutMs,
mDiscoveryTimeoutMs,
nsITimer::TYPE_ONE_SHOT)))) {
return rv;
}
@ -565,7 +565,7 @@ MulticastDNSDeviceProvider::OnDiscoveryStarted(const nsACString& aServiceType)
nsresult rv;
if (NS_WARN_IF(NS_FAILED(rv = mDiscoveryTimer->Init(this,
mDiscveryTimeoutMs,
mDiscoveryTimeoutMs,
nsITimer::TYPE_ONE_SHOT)))) {
return rv;
}
@ -924,7 +924,7 @@ MulticastDNSDeviceProvider::OnDiscoveryTimeoutChanged(uint32_t aTimeoutMs)
LOG_I("OnDiscoveryTimeoutChanged = %d\n", aTimeoutMs);
MOZ_ASSERT(NS_IsMainThread());
mDiscveryTimeoutMs = aTimeoutMs;
mDiscoveryTimeoutMs = aTimeoutMs;
return NS_OK;
}

View File

@ -186,7 +186,7 @@ private:
bool mDiscoveryEnabled = false;
bool mIsDiscovering = false;
uint32_t mDiscveryTimeoutMs;
uint32_t mDiscoveryTimeoutMs;
nsCOMPtr<nsITimer> mDiscoveryTimer;
bool mDiscoverable = false;

View File

@ -2623,7 +2623,7 @@ Promise::ResolveInternal(JSContext* aCx,
mResolvePending = true;
if (aValue.isObject()) {
AutoDontReportUncaught silenceReporting(aCx);
MOZ_ASSERT(JS::ContextOptionsRef(aCx).autoJSAPIOwnsErrorReporting());
JS::Rooted<JSObject*> valueObj(aCx, &aValue.toObject());
// Thenables.

View File

@ -208,9 +208,15 @@ this.PushServiceAndroidGCM = {
register: function(record) {
console.debug("register:", record);
let ctime = Date.now();
let appServerKey = record.appServerKey ?
ChromeUtils.base64URLEncode(record.appServerKey, {
// The Push server requires padding.
pad: true,
}) : null;
// Caller handles errors.
return Messaging.sendRequestForResult({
type: "PushServiceAndroidGCM:SubscribeChannel",
appServerKey: appServerKey,
}).then(data => {
console.debug("Got data:", data);
return PushCrypto.generateKeys()
@ -227,6 +233,7 @@ this.PushServiceAndroidGCM = {
p256dhPublicKey: exportedKeys[0],
p256dhPrivateKey: exportedKeys[1],
authenticationSecret: PushCrypto.generateAuthenticationSecret(),
appServerKey: record.appServerKey,
})
);
});

View File

@ -477,8 +477,10 @@ this.PushServiceWebSocket = {
console.warn("makeWebSocket: Network is offline.");
return null;
}
let socket = Cc["@mozilla.org/network/protocol;1?name=wss"]
.createInstance(Ci.nsIWebSocketChannel);
let contractId = uri.scheme == "ws" ?
"@mozilla.org/network/protocol;1?name=ws" :
"@mozilla.org/network/protocol;1?name=wss";
let socket = Cc[contractId].createInstance(Ci.nsIWebSocketChannel);
socket.initLoadInfo(null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),

View File

@ -101,7 +101,9 @@ nsresult runTest(uint32_t aExpectedPolicyCount, // this should be 0 for policies
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> selfURIPrincipal;
rv = secman->GetSimpleCodebasePrincipal(selfURI, getter_AddRefs(selfURIPrincipal));
// Can't use BasePrincipal::CreateCodebasePrincipal here
// because the symbol is not visible here
rv = secman->GetCodebasePrincipal(selfURI, getter_AddRefs(selfURIPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
// create a CSP object

View File

@ -41,7 +41,7 @@
var secMan = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(SpecialPowers.Ci.nsIScriptSecurityManager);
var manifestURI = SpecialPowers.Services.io.newURI(gManifestURL, null, null);
principal = secMan.getSimpleCodebasePrincipal(manifestURI);
principal = secMan.createCodebasePrincipal(manifestURI, {});
csp.setRequestContext(null, principal);
ok(true, "setRequestContext hasn't thown");
} catch(e) {

View File

@ -87,7 +87,7 @@ function makeTest(id, expectedJSON, useReportOnlyPolicy, callback) {
let ssm = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager);
principal = ssm.getSimpleCodebasePrincipal(selfuri);
principal = ssm.createCodebasePrincipal(selfuri, {});
csp.setRequestContext(null, principal);
// Load up the policy

View File

@ -32,11 +32,9 @@ interface Blob {
// void close(); TODO bug 1048325
};
enum EndingTypes{"transparent", "native"};
enum EndingTypes { "transparent", "native" };
dictionary BlobPropertyBag {
DOMString type = "";
EndingTypes endings = "transparent";
};

View File

@ -13,6 +13,9 @@
dictionary EventListenerOptions {
boolean capture = false;
/* This is a Mozilla extension only available in Chrome and XBL.
Setting to true make the listener be added to the system group. */
boolean mozSystemGroup = false;
};
dictionary AddEventListenerOptions : EventListenerOptions {

View File

@ -2,6 +2,9 @@
/* 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
* https://w3c.github.io/FileAPI/#file
*/
interface nsIFile;
@ -16,32 +19,25 @@ interface nsIFile;
Exposed=(Window,Worker)]
interface File : Blob {
readonly attribute DOMString name;
[GetterThrows]
readonly attribute long long lastModified;
};
dictionary FilePropertyBag {
DOMString type = "";
long long lastModified;
DOMString type = "";
long long lastModified;
};
dictionary ChromeFilePropertyBag : FilePropertyBag {
DOMString name = "";
boolean temporary = false;
DOMString name = "";
boolean temporary = false;
};
// Mozilla extensions
partial interface File {
[GetterThrows]
[GetterThrows, Deprecated="FileLastModifiedDate"]
readonly attribute Date lastModifiedDate;
[BinaryName="path", Func="mozilla::dom::Directory::WebkitBlinkDirectoryPickerEnabled"]

View File

@ -204,6 +204,9 @@ partial interface HTMLInputElement {
[Throws, Pref="dom.input.dirpicker"]
Promise<sequence<(File or Directory)>> getFilesAndDirectories();
[Throws, Pref="dom.input.dirpicker"]
Promise<sequence<File>> getFiles(optional boolean recursiveFlag = false);
[Throws, Pref="dom.input.dirpicker"]
void chooseDirectory();
};

View File

@ -23,4 +23,5 @@ dictionary NotificationEventInit : ExtendableEventInit {
partial interface ServiceWorkerGlobalScope {
attribute EventHandler onnotificationclick;
attribute EventHandler onnotificationclose;
};

View File

@ -147,9 +147,6 @@ namespace {
const uint32_t kNoIndex = uint32_t(-1);
const JS::ContextOptions kRequiredContextOptions =
JS::ContextOptions().setDontReportUncaught(true);
uint32_t gMaxWorkersPerDomain = MAX_WORKERS_PER_DOMAIN;
// Does not hold an owning reference.
@ -807,8 +804,6 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
js::SetCTypesActivityCallback(aRuntime, CTypesActivityCallback);
JS::ContextOptionsRef(workerCx) = kRequiredContextOptions;
#ifdef JS_GC_ZEAL
JS_SetGCZeal(workerCx, settings.gcZeal, settings.gcZealFrequency);
#endif

View File

@ -959,6 +959,37 @@ ServiceWorkerManager::SendPushSubscriptionChangeEvent(const nsACString& aOriginA
#endif
}
nsresult
ServiceWorkerManager::SendNotificationEvent(const nsAString& aEventName,
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)
{
PrincipalOriginAttributes attrs;
if (!attrs.PopulateFromSuffix(aOriginSuffix)) {
return NS_ERROR_INVALID_ARG;
}
ServiceWorkerInfo* info = GetActiveWorkerInfoForScope(attrs, aScope);
if (!info) {
return NS_ERROR_FAILURE;
}
ServiceWorkerPrivate* workerPrivate = info->WorkerPrivate();
return workerPrivate->SendNotificationEvent(aEventName, aID, aTitle, aDir,
aLang, aBody, aTag,
aIcon, aData, aBehavior,
NS_ConvertUTF8toUTF16(aScope));
}
NS_IMETHODIMP
ServiceWorkerManager::SendNotificationClickEvent(const nsACString& aOriginSuffix,
const nsACString& aScope,
@ -972,21 +1003,27 @@ ServiceWorkerManager::SendNotificationClickEvent(const nsACString& aOriginSuffix
const nsAString& aData,
const nsAString& aBehavior)
{
PrincipalOriginAttributes attrs;
if (!attrs.PopulateFromSuffix(aOriginSuffix)) {
return NS_ERROR_INVALID_ARG;
}
return SendNotificationEvent(NS_LITERAL_STRING(NOTIFICATION_CLICK_EVENT_NAME),
aOriginSuffix, aScope, aID, aTitle, aDir, aLang,
aBody, aTag, aIcon, aData, aBehavior);
}
ServiceWorkerInfo* info = GetActiveWorkerInfoForScope(attrs, aScope);
if (!info) {
return NS_ERROR_FAILURE;
}
ServiceWorkerPrivate* workerPrivate = info->WorkerPrivate();
return workerPrivate->SendNotificationClickEvent(aID, aTitle, aDir,
aLang, aBody, aTag,
aIcon, aData, aBehavior,
NS_ConvertUTF8toUTF16(aScope));
NS_IMETHODIMP
ServiceWorkerManager::SendNotificationCloseEvent(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)
{
return SendNotificationEvent(NS_LITERAL_STRING(NOTIFICATION_CLOSE_EVENT_NAME),
aOriginSuffix, aScope, aID, aTitle, aDir, aLang,
aBody, aTag, aIcon, aData, aBehavior);
}
NS_IMETHODIMP

View File

@ -431,6 +431,20 @@ private:
void
MaybeSendUnregister(nsIPrincipal* aPrincipal, const nsACString& aScope);
nsresult
SendNotificationEvent(const nsAString& aEventName,
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);
};
} // namespace workers

View File

@ -1079,8 +1079,9 @@ ClearWindowAllowedRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPriv
return true;
}
class SendNotificationClickEventRunnable final : public ExtendableEventWorkerRunnable
class SendNotificationEventRunnable final : public ExtendableEventWorkerRunnable
{
const nsString mEventName;
const nsString mID;
const nsString mTitle;
const nsString mDir;
@ -1093,19 +1094,21 @@ class SendNotificationClickEventRunnable final : public ExtendableEventWorkerRun
const nsString mScope;
public:
SendNotificationClickEventRunnable(WorkerPrivate* aWorkerPrivate,
KeepAliveToken* aKeepAliveToken,
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)
SendNotificationEventRunnable(WorkerPrivate* aWorkerPrivate,
KeepAliveToken* aKeepAliveToken,
const nsAString& aEventName,
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)
: ExtendableEventWorkerRunnable(aWorkerPrivate, aKeepAliveToken)
, mEventName(aEventName)
, mID(aID)
, mTitle(aTitle)
, mDir(aDir)
@ -1144,8 +1147,7 @@ public:
nei.mCancelable = false;
RefPtr<NotificationEvent> event =
NotificationEvent::Constructor(target,
NS_LITERAL_STRING("notificationclick"),
NotificationEvent::Constructor(target, mEventName,
nei, result);
if (NS_WARN_IF(result.Failed())) {
return false;
@ -1170,27 +1172,37 @@ public:
} // namespace anonymous
nsresult
ServiceWorkerPrivate::SendNotificationClickEvent(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)
ServiceWorkerPrivate::SendNotificationEvent(const nsAString& aEventName,
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)
{
nsresult rv = SpawnWorkerIfNeeded(NotificationClickEvent, nullptr);
WakeUpReason why;
if (aEventName.EqualsLiteral(NOTIFICATION_CLICK_EVENT_NAME)) {
why = NotificationClickEvent;
gDOMDisableOpenClickDelay = Preferences::GetInt("dom.disable_open_click_delay");
} else if (aEventName.EqualsLiteral(NOTIFICATION_CLOSE_EVENT_NAME)) {
why = NotificationCloseEvent;
} else {
MOZ_ASSERT_UNREACHABLE("Invalid notification event name");
return NS_ERROR_FAILURE;
}
nsresult rv = SpawnWorkerIfNeeded(why, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
gDOMDisableOpenClickDelay = Preferences::GetInt("dom.disable_open_click_delay");
RefPtr<WorkerRunnable> r =
new SendNotificationClickEventRunnable(mWorkerPrivate, mKeepAliveToken,
aID, aTitle, aDir, aLang,
aBody, aTag, aIcon, aData,
aBehavior, aScope);
new SendNotificationEventRunnable(mWorkerPrivate, mKeepAliveToken,
aEventName, aID, aTitle, aDir, aLang,
aBody, aTag, aIcon, aData, aBehavior,
aScope);
if (NS_WARN_IF(!r->Dispatch())) {
return NS_ERROR_FAILURE;
}

View File

@ -11,6 +11,9 @@
#include "WorkerPrivate.h"
#define NOTIFICATION_CLICK_EVENT_NAME "notificationclick"
#define NOTIFICATION_CLOSE_EVENT_NAME "notificationclose"
class nsIInterceptedChannel;
namespace mozilla {
@ -93,16 +96,17 @@ public:
SendPushSubscriptionChangeEvent();
nsresult
SendNotificationClickEvent(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);
SendNotificationEvent(const nsAString& aEventName,
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);
nsresult
SendFetchEvent(nsIInterceptedChannel* aChannel,
@ -149,6 +153,7 @@ private:
PushSubscriptionChangeEvent,
MessageEvent,
NotificationClickEvent,
NotificationCloseEvent,
LifeCycleEvent,
AttachEvent
};

View File

@ -1828,7 +1828,7 @@ TimerThreadEventTarget::DispatchFromScript(nsIRunnable* aRunnable, uint32_t aFla
}
NS_IMETHODIMP
TimerThreadEventTarget::Dispatch(already_AddRefed<nsIRunnable>&& aRunnable, uint32_t aFlags)
TimerThreadEventTarget::Dispatch(already_AddRefed<nsIRunnable> aRunnable, uint32_t aFlags)
{
// This should only happen on the timer thread.
MOZ_ASSERT(!NS_IsMainThread());
@ -1850,7 +1850,7 @@ TimerThreadEventTarget::Dispatch(already_AddRefed<nsIRunnable>&& aRunnable, uint
}
NS_IMETHODIMP
TimerThreadEventTarget::DelayedDispatch(already_AddRefed<nsIRunnable>&&, uint32_t)
TimerThreadEventTarget::DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
@ -2402,7 +2402,7 @@ WorkerPrivateParent<Derived>::WrapObject(JSContext* aCx, JS::Handle<JSObject*> a
template <class Derived>
nsresult
WorkerPrivateParent<Derived>::DispatchPrivate(already_AddRefed<WorkerRunnable>&& aRunnable,
WorkerPrivateParent<Derived>::DispatchPrivate(already_AddRefed<WorkerRunnable> aRunnable,
nsIEventTarget* aSyncLoopTarget)
{
// May be called on any thread!
@ -2480,7 +2480,7 @@ WorkerPrivateParent<Derived>::DisableDebugger()
template <class Derived>
nsresult
WorkerPrivateParent<Derived>::DispatchControlRunnable(
already_AddRefed<WorkerControlRunnable>&& aWorkerControlRunnable)
already_AddRefed<WorkerControlRunnable> aWorkerControlRunnable)
{
// May be called on any thread!
RefPtr<WorkerControlRunnable> runnable(aWorkerControlRunnable);
@ -2518,7 +2518,7 @@ WorkerPrivateParent<Derived>::DispatchControlRunnable(
template <class Derived>
nsresult
WorkerPrivateParent<Derived>::DispatchDebuggerRunnable(
already_AddRefed<WorkerRunnable>&& aDebuggerRunnable)
already_AddRefed<WorkerRunnable> aDebuggerRunnable)
{
// May be called on any thread!
@ -2548,7 +2548,7 @@ WorkerPrivateParent<Derived>::DispatchDebuggerRunnable(
template <class Derived>
already_AddRefed<WorkerRunnable>
WorkerPrivateParent<Derived>::MaybeWrapAsWorkerRunnable(already_AddRefed<nsIRunnable>&& aRunnable)
WorkerPrivateParent<Derived>::MaybeWrapAsWorkerRunnable(already_AddRefed<nsIRunnable> aRunnable)
{
// May be called on any thread!
@ -6738,7 +6738,7 @@ EventTarget::DispatchFromScript(nsIRunnable* aRunnable, uint32_t aFlags)
template <class Derived>
NS_IMETHODIMP
WorkerPrivateParent<Derived>::
EventTarget::Dispatch(already_AddRefed<nsIRunnable>&& aRunnable, uint32_t aFlags)
EventTarget::Dispatch(already_AddRefed<nsIRunnable> aRunnable, uint32_t aFlags)
{
// May be called on any thread!
nsCOMPtr<nsIRunnable> event(aRunnable);
@ -6774,7 +6774,7 @@ EventTarget::Dispatch(already_AddRefed<nsIRunnable>&& aRunnable, uint32_t aFlags
template <class Derived>
NS_IMETHODIMP
WorkerPrivateParent<Derived>::
EventTarget::DelayedDispatch(already_AddRefed<nsIRunnable>&&, uint32_t)
EventTarget::DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -238,7 +238,7 @@ private:
ErrorResult& aRv);
nsresult
DispatchPrivate(already_AddRefed<WorkerRunnable>&& aRunnable, nsIEventTarget* aSyncLoopTarget);
DispatchPrivate(already_AddRefed<WorkerRunnable> aRunnable, nsIEventTarget* aSyncLoopTarget);
public:
virtual JSObject*
@ -263,19 +263,19 @@ public:
}
nsresult
Dispatch(already_AddRefed<WorkerRunnable>&& aRunnable)
Dispatch(already_AddRefed<WorkerRunnable> aRunnable)
{
return DispatchPrivate(Move(aRunnable), nullptr);
}
nsresult
DispatchControlRunnable(already_AddRefed<WorkerControlRunnable>&& aWorkerControlRunnable);
DispatchControlRunnable(already_AddRefed<WorkerControlRunnable> aWorkerControlRunnable);
nsresult
DispatchDebuggerRunnable(already_AddRefed<WorkerRunnable>&& aDebuggerRunnable);
DispatchDebuggerRunnable(already_AddRefed<WorkerRunnable> aDebuggerRunnable);
already_AddRefed<WorkerRunnable>
MaybeWrapAsWorkerRunnable(already_AddRefed<nsIRunnable>&& aRunnable);
MaybeWrapAsWorkerRunnable(already_AddRefed<nsIRunnable> aRunnable);
already_AddRefed<nsIEventTarget>
GetEventTarget();
@ -1538,10 +1538,10 @@ protected:
NS_IMETHOD
Dispatch(already_AddRefed<nsIRunnable>&& aRunnable, uint32_t aFlags) override;
Dispatch(already_AddRefed<nsIRunnable> aRunnable, uint32_t aFlags) override;
NS_IMETHOD
DelayedDispatch(already_AddRefed<nsIRunnable>&&, uint32_t) override;
DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t) override;
NS_IMETHOD
IsOnCurrentThread(bool* aIsOnCurrentThread) override;

View File

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

View File

@ -145,7 +145,7 @@ WorkerThread::SetWorker(const WorkerThreadFriendKey& /* aKey */,
nsresult
WorkerThread::DispatchPrimaryRunnable(const WorkerThreadFriendKey& /* aKey */,
already_AddRefed<nsIRunnable>&& aRunnable)
already_AddRefed<nsIRunnable> aRunnable)
{
nsCOMPtr<nsIRunnable> runnable(aRunnable);
@ -170,7 +170,7 @@ WorkerThread::DispatchPrimaryRunnable(const WorkerThreadFriendKey& /* aKey */,
nsresult
WorkerThread::DispatchAnyThread(const WorkerThreadFriendKey& /* aKey */,
already_AddRefed<WorkerRunnable>&& aWorkerRunnable)
already_AddRefed<WorkerRunnable> aWorkerRunnable)
{
// May be called on any thread!
@ -213,7 +213,7 @@ WorkerThread::DispatchFromScript(nsIRunnable* aRunnable, uint32_t aFlags)
}
NS_IMETHODIMP
WorkerThread::Dispatch(already_AddRefed<nsIRunnable>&& aRunnable, uint32_t aFlags)
WorkerThread::Dispatch(already_AddRefed<nsIRunnable> aRunnable, uint32_t aFlags)
{
// May be called on any thread!
nsCOMPtr<nsIRunnable> runnable(aRunnable); // in case we exit early
@ -299,7 +299,7 @@ WorkerThread::Dispatch(already_AddRefed<nsIRunnable>&& aRunnable, uint32_t aFlag
}
NS_IMETHODIMP
WorkerThread::DelayedDispatch(already_AddRefed<nsIRunnable>&&, uint32_t)
WorkerThread::DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -68,11 +68,11 @@ public:
nsresult
DispatchPrimaryRunnable(const WorkerThreadFriendKey& aKey,
already_AddRefed<nsIRunnable>&& aRunnable);
already_AddRefed<nsIRunnable> aRunnable);
nsresult
DispatchAnyThread(const WorkerThreadFriendKey& aKey,
already_AddRefed<WorkerRunnable>&& aWorkerRunnable);
already_AddRefed<WorkerRunnable> aWorkerRunnable);
uint32_t
RecursionDepth(const WorkerThreadFriendKey& aKey) const;
@ -86,13 +86,13 @@ private:
// This should only be called by consumers that have an
// nsIEventTarget/nsIThread pointer.
NS_IMETHOD
Dispatch(already_AddRefed<nsIRunnable>&& aRunnable, uint32_t aFlags) override;
Dispatch(already_AddRefed<nsIRunnable> aRunnable, uint32_t aFlags) override;
NS_IMETHOD
DispatchFromScript(nsIRunnable* aRunnable, uint32_t aFlags) override;
NS_IMETHOD
DelayedDispatch(already_AddRefed<nsIRunnable>&&, uint32_t) override;
DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t) override;
};
} // namespace workers

View File

@ -133,6 +133,8 @@ support-files =
notificationclick.js
notificationclick_focus.html
notificationclick_focus.js
notificationclose.html
notificationclose.js
worker_updatefoundevent.js
worker_updatefoundevent2.js
updatefoundevent.html
@ -249,6 +251,7 @@ tags = mcb
[test_notificationclick.html]
[test_notificationclick_focus.html]
[test_notificationclick-otherwindow.html]
[test_notificationclose.html]
[test_opaque_intercept.html]
[test_openWindow.html]
[test_origin_after_redirect.html]

View File

@ -0,0 +1,37 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1265841 - controlled page</title>
<script class="testbody" type="text/javascript">
var testWindow = parent;
if (opener) {
testWindow = opener;
}
navigator.serviceWorker.ready.then(function(swr) {
return swr.showNotification(
"Hi there. The ServiceWorker should receive a close event for this.",
{ data: { complex: ["jsval", 5] }}).then(function() {
return swr;
});
}).then(function(swr) {
return swr.getNotifications();
}).then(function(notifications) {
notifications.forEach(function(notification) {
notification.close();
});
});
navigator.serviceWorker.onmessage = function(msg) {
testWindow.callback(msg.data.result);
};
</script>
</head>
<body>
</body>
</html>

View File

@ -0,0 +1,19 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/
//
onnotificationclose = 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({ result: e.notification.data &&
e.notification.data['complex'] &&
e.notification.data['complex'][0] == "jsval" &&
e.notification.data['complex'][1] == 5 });
});
});
}

View File

@ -0,0 +1,62 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1265841
-->
<head>
<title>Bug 1265841 - Test ServiceWorkerGlobalScope.notificationclose 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=1265841">Bug 1265841</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, click, and close events.");
function testFrame(src) {
var iframe = document.createElement("iframe");
iframe.src = src;
window.callback = function(result) {
window.callback = null;
document.body.removeChild(iframe);
iframe = null;
ok(result, "Got notificationclose event with correct data.");
MockServices.unregister();
registration.unregister().then(function() {
SimpleTest.finish();
});
};
document.body.appendChild(iframe);
}
var registration;
function runTest() {
MockServices.register();
testFrame('notificationclose.html');
navigator.serviceWorker.register("notificationclose.js", { scope: "notificationclose.html" }).then(function(reg) {
registration = 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],
["dom.webnotifications.serviceworker.enabled", true],
["notification.prompt.testing", true],
]}, runTest);
</script>
</body>
</html>

View File

@ -417,11 +417,10 @@ txCompileObserver::loadURI(const nsAString& aUri,
rv = NS_NewURI(getter_AddRefs(referrerUri), aReferrerUri);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> referrerPrincipal;
rv = nsContentUtils::GetSecurityManager()->
GetSimpleCodebasePrincipal(referrerUri,
getter_AddRefs(referrerPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
PrincipalOriginAttributes attrs;
nsCOMPtr<nsIPrincipal> referrerPrincipal =
BasePrincipal::CreateCodebasePrincipal(referrerUri, attrs);
NS_ENSURE_TRUE(referrerPrincipal, NS_ERROR_FAILURE);
return startLoad(uri, aCompiler, referrerPrincipal, aReferrerPolicy);
}
@ -622,11 +621,9 @@ txSyncCompileObserver::loadURI(const nsAString& aUri,
rv = NS_NewURI(getter_AddRefs(referrerUri), aReferrerUri);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> referrerPrincipal;
rv = nsContentUtils::GetSecurityManager()->
GetSimpleCodebasePrincipal(referrerUri,
getter_AddRefs(referrerPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> referrerPrincipal =
BasePrincipal::CreateCodebasePrincipal(referrerUri, PrincipalOriginAttributes());
NS_ENSURE_TRUE(referrerPrincipal, NS_ERROR_FAILURE);
// This is probably called by js, a loadGroup for the channel doesn't
// make sense.

View File

@ -259,7 +259,7 @@ FlattenBezierCurveSegment(const BezierControlPoints &aControlPoints,
double t = 0;
while (t < 1.0) {
PointD cp21 = currentCP.mCP2 - currentCP.mCP3;
PointD cp21 = currentCP.mCP2 - currentCP.mCP1;
PointD cp31 = currentCP.mCP3 - currentCP.mCP1;
/* To remove divisions and check for divide-by-zero, this is optimized from:

View File

@ -69,6 +69,9 @@ const std::string &Framebuffer::Data::getLabel()
const FramebufferAttachment *Framebuffer::Data::getReadAttachment() const
{
if (mReadBufferState == GL_NONE)
return nullptr;
ASSERT(mReadBufferState == GL_BACK || (mReadBufferState >= GL_COLOR_ATTACHMENT0 && mReadBufferState <= GL_COLOR_ATTACHMENT15));
size_t readIndex = (mReadBufferState == GL_BACK ? 0 : static_cast<size_t>(mReadBufferState - GL_COLOR_ATTACHMENT0));
ASSERT(readIndex < mColorAttachments.size());

View File

@ -365,6 +365,12 @@ typedef GenericFlingAnimation FlingAnimation;
* \li\b apz.zoom_animation_duration_ms
* This controls how long the zoom-to-rect animation takes.\n
* Units: ms
*
* \li\b apz.scale_repaint_delay_ms
* How long to delay between repaint requests during a scale.
* A negative number prevents repaint requests during a scale.\n
* Units: ms
*
*/
/**
@ -703,6 +709,7 @@ AsyncPanZoomController::AsyncPanZoomController(uint64_t aLayersId,
mState(NOTHING),
mNotificationBlockers(0),
mInputQueue(aInputQueue),
mPinchPaintTimerSet(false),
mAPZCId(sAsyncPanZoomControllerCount++),
mSharedLock(nullptr),
mAsyncTransformAppliedToContent(false),
@ -1281,6 +1288,7 @@ nsEventStatus AsyncPanZoomController::OnTouchCancel(const MultiTouchInput& aEven
nsEventStatus AsyncPanZoomController::OnScaleBegin(const PinchGestureInput& aEvent) {
APZC_LOG("%p got a scale-begin in state %d\n", this, mState);
mPinchPaintTimerSet = false;
// Note that there may not be a touch block at this point, if we received the
// PinchGestureEvent directly from widget code without any touch events.
if (HasReadyTouchBlock() && !CurrentTouchBlock()->TouchActionAllowsPinchZoom()) {
@ -1375,8 +1383,21 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
}
ScheduleComposite();
// We don't want to redraw on every scale, so don't use
// RequestContentRepaint()
// We don't want to redraw on every scale, so throttle it.
if (!mPinchPaintTimerSet) {
const int delay = gfxPrefs::APZScaleRepaintDelay();
if (delay >= 0) {
if (RefPtr<GeckoContentController> controller = GetGeckoContentController()) {
mPinchPaintTimerSet = true;
controller->PostDelayedTask(
NewRunnableMethod(this,
&AsyncPanZoomController::DoDelayedRequestContentRepaint),
delay);
}
}
}
UpdateSharedCompositorFrameMetrics();
}
@ -1389,6 +1410,8 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
nsEventStatus AsyncPanZoomController::OnScaleEnd(const PinchGestureInput& aEvent) {
APZC_LOG("%p got a scale-end in state %d\n", this, mState);
mPinchPaintTimerSet = false;
if (HasReadyTouchBlock() && !CurrentTouchBlock()->TouchActionAllowsPinchZoom()) {
return nsEventStatus_eIgnore;
}
@ -1613,6 +1636,15 @@ AsyncPanZoomController::AllowScrollHandoffInCurrentBlock() const
return result;
}
void AsyncPanZoomController::DoDelayedRequestContentRepaint()
{
if (!IsDestroyed() && mPinchPaintTimerSet) {
ReentrantMonitorAutoEnter lock(mMonitor);
RequestContentRepaint();
}
mPinchPaintTimerSet = false;
}
static ScrollInputMethod
ScrollInputMethodForWheelDeltaType(ScrollWheelInput::ScrollDeltaType aDeltaType)
{

Some files were not shown because too many files have changed in this diff Show More