Merge m-c to fx-team, a=merge

This commit is contained in:
Wes Kocher 2015-09-03 14:12:23 -07:00
commit 5c6ab9fcda
148 changed files with 3009 additions and 1755 deletions

View File

@ -587,6 +587,7 @@ let settingsToObserve = {
'layers.effect.invert': false,
'layers.effect.grayscale': false,
'layers.effect.contrast': '0.0',
'layout.display-list.dump': false,
'mms.debugging.enabled': false,
'network.debugging.enabled': false,
'privacy.donottrackheader.enabled': false,

View File

@ -4,6 +4,10 @@
"use strict"
function debug(aMsg) {
//dump("-*- PresentationRequestUIGlue: " + aMsg + "\n");
}
const { interfaces: Ci, utils: Cu, classes: Cc } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -30,9 +34,10 @@ function PresentationRequestUIGlue() {
return;
}
let sessionId = detail.sessionId;
let sessionId = detail.id;
let resolver = this._resolvers[sessionId];
if (!resolver) {
debug("No correspondent resolver for session ID: " + sessionId);
return;
}
@ -44,13 +49,13 @@ function PresentationRequestUIGlue() {
PresentationRequestUIGlue.prototype = {
sendRequest: function(aUrl, aSessionId) {
SystemAppProxy._sendCustomEvent("mozPresentationChromeEvent",
{ type: "presentation-launch-receiver",
url: aUrl,
id: aSessionId });
return new Promise(function(aResolve, aReject) {
this._resolvers[aSessionId] = aResolve;
SystemAppProxy._sendCustomEvent("mozPresentationChromeEvent",
{ type: "presentation-launch-receiver",
url: aUrl,
id: aSessionId });
}.bind(this));
},

View File

@ -28,7 +28,7 @@ addMessageListener('trigger-ui-glue', function(aData) {
addMessageListener('trigger-presentation-content-event', function(aData) {
var detail = {
type: 'presentation-receiver-launched',
sessionId: aData.sessionId,
id: aData.sessionId,
frame: aData.frame
};
SystemAppProxy._sendCustomEvent('mozPresentationContentEvent', detail);

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="a55d3d512a765bd483bd595b0c8f80c5f1d61b65"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d7385b79e68d4ad662cacf810506e9ee53345d23"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="a55d3d512a765bd483bd595b0c8f80c5f1d61b65"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d7385b79e68d4ad662cacf810506e9ee53345d23"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a55d3d512a765bd483bd595b0c8f80c5f1d61b65"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d7385b79e68d4ad662cacf810506e9ee53345d23"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="2d58f4b9206b50b8fda0d5036da6f0c62608db7c"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="a55d3d512a765bd483bd595b0c8f80c5f1d61b65"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d7385b79e68d4ad662cacf810506e9ee53345d23"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="51ebaf824cc634665c5efcae95b8301ad1758c5e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e1a50a20b3383e3b0959e5b32ef429425fd6be5b"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="a55d3d512a765bd483bd595b0c8f80c5f1d61b65"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d7385b79e68d4ad662cacf810506e9ee53345d23"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="05a36844c1046a1eb07d5b1325f85ed741f961ea">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="a55d3d512a765bd483bd595b0c8f80c5f1d61b65"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d7385b79e68d4ad662cacf810506e9ee53345d23"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a55d3d512a765bd483bd595b0c8f80c5f1d61b65"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d7385b79e68d4ad662cacf810506e9ee53345d23"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="2d58f4b9206b50b8fda0d5036da6f0c62608db7c"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="a55d3d512a765bd483bd595b0c8f80c5f1d61b65"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d7385b79e68d4ad662cacf810506e9ee53345d23"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "a55d3d512a765bd483bd595b0c8f80c5f1d61b65",
"git_revision": "d7385b79e68d4ad662cacf810506e9ee53345d23",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "66b32b3f26ec1ed81ddfb799aaeec3e9cf0a758d",
"revision": "c379332cd161e9675eedc580725f101a18be38f6",
"repo_path": "integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="a55d3d512a765bd483bd595b0c8f80c5f1d61b65"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d7385b79e68d4ad662cacf810506e9ee53345d23"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="51ebaf824cc634665c5efcae95b8301ad1758c5e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e1a50a20b3383e3b0959e5b32ef429425fd6be5b"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="05a36844c1046a1eb07d5b1325f85ed741f961ea">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="a55d3d512a765bd483bd595b0c8f80c5f1d61b65"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d7385b79e68d4ad662cacf810506e9ee53345d23"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1437165748000">
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1441146756000">
<emItems>
<emItem blockID="i58" id="webmaster@buzzzzvideos.info">
<versionRange minVersion="0" maxVersion="*">
@ -30,6 +30,12 @@
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i994" id="addonhack@mozilla.kewis.ch">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i400" id="{dd6b651f-dfb9-4142-b0bd-09912ad22674}">
<versionRange minVersion="0" maxVersion="*" severity="1">
@ -267,6 +273,12 @@
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i972" id="831778-poidjao88DASfsAnindsd@jetpack">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i352" id="vpyekkifgv@vpyekkifgv.org">
<versionRange minVersion="0" maxVersion="*" severity="3">
@ -312,6 +324,12 @@
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i988" id="{b12785f5-d8d0-4530-a3ea-5c4263b85bef}">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i856" id="/^({94d62e35-4b43-494c-bf52-ba5935df36ef}|firefox@advanceelite\.com|{bb7b7a60-f574-47c2-8a0b-4c56f2da9802})$/">
<versionRange minVersion="0" maxVersion="*" severity="3">
@ -460,8 +478,10 @@
<prefs>
</prefs>
</emItem>
<emItem blockID="i644" id="youtubeunblocker@unblocker.yt">
<emItem blockID="i990" id="youtubeunblocker@unblocker.yt">
<versionRange minVersion="43.4.1" maxVersion="77.5.1" severity="3">
</versionRange>
<versionRange minVersion="0" maxVersion="0.6.16" severity="1">
</versionRange>
<prefs>
</prefs>
@ -817,6 +837,12 @@
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i980" id="wHO@W9.net">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i99" id="pfzPXmnzQRXX6@2iABkVe.com">
<versionRange minVersion="0" maxVersion="*">
@ -1149,8 +1175,8 @@
<prefs>
</prefs>
</emItem>
<emItem blockID="i306" id="{ADFA33FD-16F5-4355-8504-DF4D664CFE10}">
<versionRange minVersion="0" maxVersion="*" severity="1">
<emItem blockID="i437" id="{4933189D-C7F7-4C6E-834B-A29F087BFD23}">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
<prefs>
</prefs>
@ -1328,6 +1354,12 @@
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i968" id="{184AA5E6-741D-464a-820E-94B3ABC2F3B4}">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i754" id="{bb7b7a60-f574-47c2-8a0b-4c56f2da9802}">
<versionRange minVersion="0" maxVersion="*" severity="1">
@ -1760,6 +1792,12 @@
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i982" id="odtffplugin@ibm.com">
<versionRange minVersion="9.0.1.1" maxVersion="9.0.1.100" severity="1">
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i564" id="/^(firefox@vebergreat\.net|EFGLQA@78ETGYN-0W7FN789T87\.COM)$/">
<versionRange minVersion="0" maxVersion="*" severity="1">
@ -2056,8 +2094,8 @@
<prefs>
</prefs>
</emItem>
<emItem blockID="i437" id="{4933189D-C7F7-4C6E-834B-A29F087BFD23}">
<versionRange minVersion="0" maxVersion="*" severity="3">
<emItem blockID="i306" id="{ADFA33FD-16F5-4355-8504-DF4D664CFE10}">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
<prefs>
</prefs>
@ -2343,6 +2381,12 @@
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i970" id="hha8771ui3-Fo9j9h7aH98jsdfa8sda@jetpack">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i342" id="lbmsrvfvxcblvpane@lpaezhjez.org">
<versionRange minVersion="0" maxVersion="*" severity="1">
@ -3163,6 +3207,43 @@
</devices>
<feature>DIRECT3D_9_LAYERS</feature> <featureStatus>BLOCKED_DEVICE</featureStatus> </gfxBlacklistEntry>
<gfxBlacklistEntry blockID="g511"> <os>WINNT 5.1</os> <vendor>0x8086</vendor> <feature>DIRECT3D_9_LAYERS, WEBGL_ANGLE</feature> <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus> <driverVersion>6.14.10.5218</driverVersion> <driverVersionComparator>LESS_THAN</driverVersionComparator> </gfxBlacklistEntry>
<gfxBlacklistEntry blockID="g974"> <os>WINNT 10.0</os> <vendor>0x1002</vendor> <devices>
<device>0x6920</device>
<device>0x6921</device>
<device>0x6928</device>
<device>0x6929</device>
<device>0x692b</device>
<device>0x692f</device>
<device>0x6930</device>
<device>0x6938</device>
<device>0x6939</device>
<device>0x6900</device>
<device>0x6901</device>
<device>0x6902</device>
<device>0x6903</device>
<device>0x6907</device>
<device>0x7300</device>
</devices>
<feature>DIRECT2D</feature> <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus> <driverVersion>15.201.1151.0</driverVersion> <driverVersionComparator>LESS_THAN</driverVersionComparator> </gfxBlacklistEntry>
<gfxBlacklistEntry blockID="g984"> <os>All</os> <vendor>0x8086</vendor> <feature>DIRECT2D</feature> <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus> <driverVersion>8.15.10.2413</driverVersion> <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator> </gfxBlacklistEntry>
<gfxBlacklistEntry blockID="g992"> <os>WINNT 8.1</os> <vendor>0x1002</vendor> <devices>
<device>0x6920</device>
<device>0x6921</device>
<device>0x6928</device>
<device>0x6929</device>
<device>0x692b</device>
<device>0x692f</device>
<device>0x6930</device>
<device>0x6938</device>
<device>0x6939</device>
<device>0x6900</device>
<device>0x6901</device>
<device>0x6902</device>
<device>0x6903</device>
<device>0x6907</device>
<device>0x7300</device>
</devices>
<feature>DIRECT2D</feature> <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus> <driverVersion>15.201.1151.0</driverVersion> <driverVersionComparator>LESS_THAN</driverVersionComparator> </gfxBlacklistEntry>
</gfxItems>
<certItems>

View File

@ -68,7 +68,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
this._mayTrimURLs = this._prefs.getBoolPref("trimURLs");
this._userMadeSearchSuggestionsChoice =
this._prefs.getBoolPref("userMadeSearchSuggestionsChoice");
this._ignoreNextSelect = false;
this.inputField.controllers.insertControllerAt(0, this._copyCutController);
this.inputField.addEventListener("paste", this, false);
@ -854,15 +853,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
]]></body>
</method>
<method name="selectTextRange">
<parameter name="aStartIndex"/>
<parameter name="aEndIndex"/>
<body><![CDATA[
this._ignoreNextSelect = true;
this.inputField.setSelectionRange(aStartIndex, aEndIndex);
]]></body>
</method>
<method name="onInput">
<parameter name="aEvent"/>
<body><![CDATA[
@ -1015,20 +1005,16 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<handler event="dragover" phase="capturing" action="this.onDragOver(event, this);"/>
<handler event="drop" phase="capturing" action="this.onDrop(event, this);"/>
<handler event="select"><![CDATA[
if (this._ignoreNextSelect) {
// If this select event is coming from autocomplete's selectTextRange,
// then we don't need to adjust what's on the selection keyboard here,
// but make sure to reset the flag since this should be a one-time
// suppression.
this._ignoreNextSelect = false;
return;
}
if (!Cc["@mozilla.org/widget/clipboard;1"]
.getService(Ci.nsIClipboard)
.supportsSelectionClipboard())
return;
if (!window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.isHandlingUserInput)
return;
var val = this._getSelectedValueForClipboard();
if (!val)
return;

View File

@ -38,33 +38,14 @@ leak:nr_reg_local_init
leak:r_log_register
leak:nr_reg_set
# Additional WebRTC leak suppressions added for Mochitest 3.
leak:mozilla::TransportLayerDtls::Setup
# Bug 1187424 - DesktopApplication does not free any of its string members.
leak:webrtc::DesktopApplication::
# Bug 1187518 - SCTP leaks in child process while running WebRTC tests.
leak:recv_function_udp
# Bug 1074310 - Very large e10s vp8 leaks, maybe in WebRTC tests.
leak:set_noise_sensitivity
leak:vp8_alloc_compressor_data
leak:vp8_change_config
leak:vp8_lookahead_init
leak:vpx_codec_enc_init_ver
###
### Many leaks only affect some test suites. The suite annotations are not checked.
###
# Bug 981195 - Small leak in the parser. m4
leak:ObjectGroup::fixPlainObjectGroup
# Bug 982111 - WebM is leaking. m1
leak:nestegg_read_packet
# Bug 987385 - Various plugin leaks. m3
leak:mozilla::plugins::PPluginInstanceParent::CallNPP_HandleEvent
leak:mozilla::plugins::PPluginModuleParent::OnCallReceived
@ -89,7 +70,7 @@ leak:_render_glyph_outline
# Bug 1023548 - Small leak under SECITEM_AllocItem_Util. bc1, bc3
leak:SECITEM_AllocItem_Util
# This is a one-time leak, so it is probably okay to ignore. bc1, oth
# This is a one-time leak, so it is probably okay to ignore. bc3, oth
leak:GlobalPrinters::InitializeGlobalPrinters
leak:nsPSPrinterList::GetPrinterList

View File

@ -23,10 +23,22 @@ using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::dom::workers;
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PerformanceObserver,
mOwner,
mPerformance,
mCallback)
NS_IMPL_CYCLE_COLLECTION_CLASS(PerformanceObserver)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(PerformanceObserver)
tmp->Disconnect();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPerformance)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(PerformanceObserver)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPerformance)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(PerformanceObserver)
NS_IMPL_CYCLE_COLLECTING_ADDREF(PerformanceObserver)
NS_IMPL_CYCLE_COLLECTING_RELEASE(PerformanceObserver)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PerformanceObserver)
@ -95,7 +107,22 @@ PerformanceObserver::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProt
}
void
PerformanceObserver::Notify(PerformanceEntry* aEntry)
PerformanceObserver::Notify()
{
if (mQueuedEntries.IsEmpty()) {
return;
}
nsRefPtr<PerformanceObserverEntryList> list =
new PerformanceObserverEntryList(this, mQueuedEntries);
ErrorResult rv;
mCallback->Call(this, *list, *this, rv);
NS_WARN_IF(rv.Failed());
mQueuedEntries.Clear();
}
void
PerformanceObserver::QueueEntry(PerformanceEntry* aEntry)
{
MOZ_ASSERT(aEntry);
@ -105,12 +132,7 @@ PerformanceObserver::Notify(PerformanceEntry* aEntry)
return;
}
nsRefPtr<PerformanceObserverEntryList> list = new PerformanceObserverEntryList(this);
list->AppendEntry(aEntry);
ErrorResult rv;
mCallback->Call(this, *list, *this, rv);
NS_WARN_IF(rv.Failed());
mQueuedEntries.AppendElement(aEntry);
}
static nsString sValidTypeNames[7] = {

View File

@ -59,7 +59,8 @@ public:
void Disconnect();
void Notify(PerformanceEntry* entry);
void Notify();
void QueueEntry(PerformanceEntry* aEntry);
private:
~PerformanceObserver();
@ -69,6 +70,7 @@ private:
nsRefPtr<PerformanceBase> mPerformance;
nsTArray<nsString> mEntryTypes;
bool mConnected;
nsTArray<nsRefPtr<PerformanceEntry>> mQueuedEntries;
};
} // namespace dom

View File

@ -94,10 +94,3 @@ PerformanceObserverEntryList::GetEntriesByName(
}
}
}
void
PerformanceObserverEntryList::AppendEntry(PerformanceEntry* aEntry)
{
mEntries.AppendElement(aEntry);
}

View File

@ -26,8 +26,11 @@ class PerformanceObserverEntryList final : public nsISupports,
~PerformanceObserverEntryList();
public:
explicit PerformanceObserverEntryList(nsISupports* aOwner)
PerformanceObserverEntryList(nsISupports* aOwner,
nsTArray<nsRefPtr<PerformanceEntry>>&
aEntries)
: mOwner(aOwner)
, mEntries(aEntries)
{
}
@ -50,8 +53,6 @@ public:
const Optional<nsAString>& aEntryType,
nsTArray<nsRefPtr<PerformanceEntry>>& aRetval);
void AppendEntry(PerformanceEntry* aEntry);
private:
nsCOMPtr<nsISupports> mOwner;
nsTArray<nsRefPtr<PerformanceEntry>> mEntries;

View File

@ -4409,8 +4409,7 @@ FindSheet(const nsCOMArray<nsIStyleSheet>& aSheets, nsIURI* aSheetURI)
}
nsresult
nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType,
nsIURI* aSheetURI)
nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI)
{
NS_PRECONDITION(aSheetURI, "null arg");
@ -4419,29 +4418,11 @@ nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType,
return NS_ERROR_INVALID_ARG;
// Loading the sheet sync.
nsRefPtr<css::Loader> loader = new css::Loader();
css::SheetParsingMode parsingMode;
switch (aType) {
case nsIDocument::eAgentSheet:
parsingMode = css::eAgentSheetFeatures;
break;
case nsIDocument::eUserSheet:
parsingMode = css::eUserSheetFeatures;
break;
case nsIDocument::eAuthorSheet:
parsingMode = css::eAuthorSheetFeatures;
break;
default:
MOZ_CRASH("impossible value for aType");
}
nsRefPtr<mozilla::css::Loader> loader = new mozilla::css::Loader();
nsRefPtr<CSSStyleSheet> sheet;
nsresult rv = loader->LoadSheetSync(aSheetURI, parsingMode, true,
getter_AddRefs(sheet));
nsresult rv = loader->LoadSheetSync(aSheetURI, aType == eAgentSheet,
true, getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv);
sheet->SetOwningDocument(this);
@ -7934,15 +7915,13 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
ScreenSize viewportSize(viewportWidth, viewportWidth * aspectRatio);
return nsViewportInfo(RoundedToInt(viewportSize),
CSSToScreenScale(scaleToFit),
/*allowZoom*/false,
/*allowDoubleTapZoom*/ false);
/*allowZoom*/ true);
}
if (!gfxPrefs::MetaViewportEnabled()) {
return nsViewportInfo(aDisplaySize,
defaultScale,
/*allowZoom*/ false,
/*allowDoubleTapZoom*/ false);
/*allowZoom*/ false);
}
// In cases where the width of the CSS viewport is less than or equal to the width
@ -7953,13 +7932,7 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
case DisplayWidthHeight:
return nsViewportInfo(aDisplaySize,
defaultScale,
/*allowZoom*/ true,
/*allowDoubleTapZoom*/ true);
case DisplayWidthHeightNoZoom:
return nsViewportInfo(aDisplaySize,
defaultScale,
/*allowZoom*/ false,
/*allowDoubleTapZoom*/ false);
/*allowZoom*/ true);
case Unknown:
{
nsAutoString viewport;
@ -7981,8 +7954,7 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
mViewportType = DisplayWidthHeight;
return nsViewportInfo(aDisplaySize,
defaultScale,
/*allowZoom*/true,
/*allowDoubleTapZoom*/false);
/*allowZoom*/true);
}
}
}
@ -7993,8 +7965,7 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
mViewportType = DisplayWidthHeight;
return nsViewportInfo(aDisplaySize,
defaultScale,
/*allowZoom*/true,
/*allowDoubleTapZoom*/false);
/*allowZoom*/true);
}
}
@ -8068,7 +8039,6 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
(userScalable.EqualsLiteral("false"))) {
mAllowZoom = false;
}
mAllowDoubleTapZoom = mAllowZoom;
mScaleStrEmpty = scaleStr.IsEmpty();
mWidthStrEmpty = widthStr.IsEmpty();
@ -8079,6 +8049,24 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
}
case Specified:
default:
LayoutDeviceToScreenScale effectiveMinScale = mScaleMinFloat;
LayoutDeviceToScreenScale effectiveMaxScale = mScaleMaxFloat;
bool effectiveValidMaxScale = mValidMaxScale;
bool effectiveAllowZoom = mAllowZoom;
if (gfxPrefs::ForceUserScalable()) {
// If the pref to force user-scalable is enabled, we ignore the values
// from the meta-viewport tag for these properties and just assume they
// allow the page to be scalable. Note in particular that this code is
// in the "Specified" branch of the enclosing switch statement, so that
// calls to GetViewportInfo always use the latest value of the
// ForceUserScalable pref. Other codepaths that return nsViewportInfo
// instances are all consistent with ForceUserScalable() already.
effectiveMinScale = kViewportMinScale;
effectiveMaxScale = kViewportMaxScale;
effectiveValidMaxScale = true;
effectiveAllowZoom = true;
}
CSSSize size = mViewportSize;
if (!mValidWidth) {
@ -8101,8 +8089,8 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
}
CSSToScreenScale scaleFloat = mScaleFloat * layoutDeviceScale;
CSSToScreenScale scaleMinFloat = mScaleMinFloat * layoutDeviceScale;
CSSToScreenScale scaleMaxFloat = mScaleMaxFloat * layoutDeviceScale;
CSSToScreenScale scaleMinFloat = effectiveMinScale * layoutDeviceScale;
CSSToScreenScale scaleMaxFloat = effectiveMaxScale * layoutDeviceScale;
if (mAutoSize) {
// aDisplaySize is in screen pixels; convert them to CSS pixels for the viewport size.
@ -8127,14 +8115,14 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
CSSSize displaySize = ScreenSize(aDisplaySize) / scaleFloat;
size.width = std::max(size.width, displaySize.width);
size.height = std::max(size.height, displaySize.height);
} else if (mValidMaxScale) {
} else if (effectiveValidMaxScale) {
CSSSize displaySize = ScreenSize(aDisplaySize) / scaleMaxFloat;
size.width = std::max(size.width, displaySize.width);
size.height = std::max(size.height, displaySize.height);
}
return nsViewportInfo(scaleFloat, scaleMinFloat, scaleMaxFloat, size,
mAutoSize, mAllowZoom, mAllowDoubleTapZoom);
mAutoSize, effectiveAllowZoom);
}
}
@ -9954,10 +9942,7 @@ nsresult
nsDocument::LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
CSSStyleSheet** sheet)
{
css::SheetParsingMode mode =
isAgentSheet ? css::eAgentSheetFeatures
: css::eAuthorSheetFeatures;
return CSSLoader()->LoadSheetSync(uri, mode, isAgentSheet, sheet);
return CSSLoader()->LoadSheetSync(uri, isAgentSheet, isAgentSheet, sheet);
}
class nsDelayedEventDispatcher : public nsRunnable

View File

@ -1850,7 +1850,6 @@ private:
enum ViewportType {
DisplayWidthHeight,
DisplayWidthHeightNoZoom,
Specified,
Unknown
};

View File

@ -812,6 +812,7 @@ NS_IMPL_RELEASE_INHERITED(PerformanceBase, DOMEventTargetHelper)
PerformanceBase::PerformanceBase()
: mResourceTimingBufferSize(kDefaultResourceTimingBufferSize)
, mPendingNotificationObserversTask(false)
{
MOZ_ASSERT(!NS_IsMainThread());
}
@ -819,6 +820,7 @@ PerformanceBase::PerformanceBase()
PerformanceBase::PerformanceBase(nsPIDOMWindow* aWindow)
: DOMEventTargetHelper(aWindow)
, mResourceTimingBufferSize(kDefaultResourceTimingBufferSize)
, mPendingNotificationObserversTask(false)
{
MOZ_ASSERT(NS_IsMainThread());
}
@ -1050,9 +1052,7 @@ PerformanceBase::InsertUserEntry(PerformanceEntry* aEntry)
mUserEntries.InsertElementSorted(aEntry,
PerformanceEntryComparator());
NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers,
PerformanceObserver,
Notify, (aEntry));
QueueEntry(aEntry);
}
void
@ -1076,9 +1076,7 @@ PerformanceBase::InsertResourceEntry(PerformanceEntry* aEntry)
// call onresourcetimingbufferfull
DispatchBufferFullEvent();
}
NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers,
PerformanceObserver,
Notify, (aEntry));
QueueEntry(aEntry);
}
void
@ -1092,3 +1090,75 @@ PerformanceBase::RemoveObserver(PerformanceObserver* aObserver)
{
mObservers.RemoveElement(aObserver);
}
void
PerformanceBase::NotifyObservers()
{
mPendingNotificationObserversTask = false;
NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers,
PerformanceObserver,
Notify, ());
}
void
PerformanceBase::CancelNotificationObservers()
{
mPendingNotificationObserversTask = false;
}
class NotifyObserversTask final : public nsCancelableRunnable
{
public:
explicit NotifyObserversTask(PerformanceBase* aPerformance)
: mPerformance(aPerformance)
{
MOZ_ASSERT(mPerformance);
}
NS_IMETHOD Run() override
{
MOZ_ASSERT(mPerformance);
mPerformance->NotifyObservers();
return NS_OK;
}
NS_IMETHOD Cancel() override
{
mPerformance->CancelNotificationObservers();
mPerformance = nullptr;
return NS_OK;
}
private:
~NotifyObserversTask()
{
}
nsRefPtr<PerformanceBase> mPerformance;
};
void
PerformanceBase::RunNotificationObserversTask()
{
mPendingNotificationObserversTask = true;
nsCOMPtr<nsIRunnable> task = new NotifyObserversTask(this);
nsresult rv = NS_DispatchToCurrentThread(task);
if (NS_WARN_IF(NS_FAILED(rv))) {
mPendingNotificationObserversTask = false;
}
}
void
PerformanceBase::QueueEntry(PerformanceEntry* aEntry)
{
if (mObservers.IsEmpty()) {
return;
}
NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers,
PerformanceObserver,
QueueEntry, (aEntry));
if (!mPendingNotificationObserversTask) {
RunNotificationObserversTask();
}
}

View File

@ -325,6 +325,8 @@ public:
void AddObserver(PerformanceObserver* aObserver);
void RemoveObserver(PerformanceObserver* aObserver);
void NotifyObservers();
void CancelNotificationObservers();
protected:
virtual ~PerformanceBase();
@ -358,6 +360,9 @@ protected:
void LogEntry(PerformanceEntry* aEntry, const nsACString& aOwner) const;
void TimingNotification(PerformanceEntry* aEntry, const nsACString& aOwner, uint64_t epoch);
void RunNotificationObserversTask();
void QueueEntry(PerformanceEntry* aEntry);
nsTObserverArray<PerformanceObserver*> mObservers;
private:
@ -366,6 +371,7 @@ private:
uint64_t mResourceTimingBufferSize;
static const uint64_t kDefaultResourceTimingBufferSize = 150;
bool mPendingNotificationObserversTask;
};
// Script "performance" object

View File

@ -1103,8 +1103,7 @@ nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal,
// Create the CSS parser, and parse the CSS text.
nsCSSParser parser(nullptr, sheet);
rv = parser.ParseSheet(aOriginal, aDocument->GetDocumentURI(), aBaseURI,
aDocument->NodePrincipal(), 0,
mozilla::css::eAuthorSheetFeatures);
aDocument->NodePrincipal(), 0, false);
NS_ENSURE_SUCCESS(rv, true);
// Mark the sheet as complete.
MOZ_ASSERT(!sheet->IsModified(),

View File

@ -26,16 +26,11 @@ class MOZ_STACK_CLASS nsViewportInfo
public:
nsViewportInfo(const mozilla::ScreenIntSize& aDisplaySize,
const mozilla::CSSToScreenScale& aDefaultZoom,
bool aAllowZoom,
bool aAllowDoubleTapZoom) :
bool aAllowZoom) :
mDefaultZoom(aDefaultZoom),
mAutoSize(true),
mAllowZoom(aAllowZoom),
mAllowDoubleTapZoom(aAllowDoubleTapZoom)
mAllowZoom(aAllowZoom)
{
// Don't allow double-tap zooming unless zooming is also allowed
MOZ_ASSERT(mAllowZoom || !mAllowDoubleTapZoom);
mSize = mozilla::ScreenSize(aDisplaySize) / mDefaultZoom;
mozilla::CSSToLayoutDeviceScale pixelRatio(1.0f);
mMinZoom = pixelRatio * kViewportMinScale;
@ -48,19 +43,14 @@ class MOZ_STACK_CLASS nsViewportInfo
const mozilla::CSSToScreenScale& aMaxZoom,
const mozilla::CSSSize& aSize,
bool aAutoSize,
bool aAllowZoom,
bool aAllowDoubleTapZoom) :
bool aAllowZoom) :
mDefaultZoom(aDefaultZoom),
mMinZoom(aMinZoom),
mMaxZoom(aMaxZoom),
mSize(aSize),
mAutoSize(aAutoSize),
mAllowZoom(aAllowZoom),
mAllowDoubleTapZoom(aAllowDoubleTapZoom)
mAllowZoom(aAllowZoom)
{
// Don't allow double-tap zooming unless zooming is also allowed
MOZ_ASSERT(mAllowZoom || !mAllowDoubleTapZoom);
ConstrainViewportValues();
}
@ -73,9 +63,6 @@ class MOZ_STACK_CLASS nsViewportInfo
bool IsAutoSizeEnabled() const { return mAutoSize; }
bool IsZoomAllowed() const { return mAllowZoom; }
bool IsDoubleTapZoomAllowed() const { return mAllowDoubleTapZoom; }
void SetAllowDoubleTapZoom(bool aAllowDoubleTapZoom) { mAllowDoubleTapZoom = aAllowDoubleTapZoom; }
private:
@ -107,11 +94,6 @@ class MOZ_STACK_CLASS nsViewportInfo
// Whether or not the user can zoom in and out on the page. Default is true.
bool mAllowZoom;
// Whether or not the user can double-tap to zoom in. When this is disabled
// we can dispatch click events faster on a single tap because we don't have
// to wait to detect the double-tap
bool mAllowDoubleTapZoom;
};
#endif

View File

@ -10,9 +10,9 @@
<script>
'use strict';
[
"async_test", "test", "setup",
"promise_test", "test", "setup",
"assert_true", "assert_equals", "assert_array_equals",
"assert_throws"
"assert_throws", "assert_unreached"
].forEach(func => {
window[func] = opener[func].bind(opener);
});
@ -29,49 +29,43 @@ function done() {
<body>
<div id="log"></div>
<script>
function promiseXHR(aUrl) {
return new Promise(resolve => {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onload = resolve;
xmlhttp.open("get", aUrl, true);
xmlhttp.send();
});
function makeXHR(aUrl) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("get", aUrl, true);
xmlhttp.send();
}
async_test(t => {
performance.clearResourceTimings();
promise_test(t => {
var promise = new Promise(resolve => {
performance.clearResourceTimings();
var observedEntryList;
var observedEntries = [];
var observer = new PerformanceObserver(list => {
list.getEntries().forEach(entry => observedEntries.push(entry));
observedEntryList = list;
var observer = new PerformanceObserver(list => resolve(list));
observer.observe({entryTypes: ['resource']});
t.add_cleanup(() => observer.disconnect());
});
observer.observe({entryTypes: ['resource']});
t.add_cleanup(() => observer.disconnect());
assert_equals(observedEntries.length, 0);
makeXHR("test-data.json");
promiseXHR("test-data.json").then(t.step_func_done(() => {
assert_equals(observedEntries.length, 1);
assert_array_equals(observedEntries,
return promise.then(list => {
assert_equals(list.getEntries().length, 1);
assert_array_equals(list.getEntries(),
performance.getEntriesByType("resource"),
"Observed 'resource' entries should equal to entries obtained by getEntriesByType.");
// getEntries filtering tests
assert_array_equals(observedEntryList.getEntries({name: "http://mochi.test:8888/tests/dom/base/test/test-data.json"}),
assert_array_equals(list.getEntries({name: "http://mochi.test:8888/tests/dom/base/test/test-data.json"}),
performance.getEntriesByName("http://mochi.test:8888/tests/dom/base/test/test-data.json"),
"getEntries with name filter should return correct results.");
assert_array_equals(observedEntryList.getEntries({entryType: "resource"}),
assert_array_equals(list.getEntries({entryType: "resource"}),
performance.getEntriesByType("resource"),
"getEntries with entryType filter should return correct results.");
assert_array_equals(observedEntryList.getEntries({initiatorType: "xmlhttprequest"}),
assert_array_equals(list.getEntries({initiatorType: "xmlhttprequest"}),
performance.getEntriesByType("resource"),
"getEntries with initiatorType filter should return correct results.");
assert_array_equals(observedEntryList.getEntries({initiatorType: "link"}),
assert_array_equals(list.getEntries({initiatorType: "link"}),
[],
"getEntries with non-existent initiatorType filter should return an empty array.");
}));
});
}, "resource-timing test");
done();

View File

@ -35,213 +35,192 @@ test(t => {
}, "obsrve() should throw TypeError exception if 'entryTypes' attribute value is invalid.");
}, "Test that PerformanceObserver.observe throws exception");
test(t => {
performance.clearMarks();
performance.clearMeasures();
function promiseObserve(test, options) {
return new Promise(resolve => {
performance.clearMarks();
performance.clearMeasures();
var observedEntries = [];
var observer = new PerformanceObserver(list => {
list.getEntries().forEach(entry => observedEntries.push(entry));
var observer = new PerformanceObserver(list => resolve(list));
observer.observe(options);
test.add_cleanup(() => observer.disconnect());
});
observer.observe({entryTypes: ['mark', 'measure']});
t.add_cleanup(() => observer.disconnect());
}
assert_equals(observedEntries.length, 0,
"User timing entries should never be observed.");
assert_equals(performance.getEntriesByType("mark").length, 0,
"There should be no 'mark' entries.");
assert_equals(performance.getEntriesByType("measure").length, 0,
"There should be no 'measure' entries.");
promise_test(t => {
var promise = promiseObserve(t, {entryTypes: ['mark', 'measure']});
performance.mark("test-start");
performance.mark("test-end");
performance.measure("test-measure", "test-start", "test-end");
assert_equals(observedEntries.length, 3,
"There should be three observed entries.");
return promise.then(list => {
assert_equals(list.getEntries().length, 3,
"There should be three observed entries.");
var markEntries = observedEntries.filter(entry => {
return entry.entryType == "mark";
});
assert_array_equals(markEntries, performance.getEntriesByType("mark"),
"Observed 'mark' entries should equal to entries obtained by getEntriesByType.");
var markEntries = list.getEntries().filter(entry => {
return entry.entryType == "mark";
});
assert_array_equals(markEntries, performance.getEntriesByType("mark"),
"Observed 'mark' entries should equal to entries obtained by getEntriesByType.");
var measureEntries = observedEntries.filter(entry => {
return entry.entryType == "measure";
var measureEntries = list.getEntries().filter(entry => {
return entry.entryType == "measure";
});
assert_array_equals(measureEntries, performance.getEntriesByType("measure"),
"Observed 'measure' entries should equal to entries obtained by getEntriesByType.");
});
assert_array_equals(measureEntries, performance.getEntriesByType("measure"),
"Observed 'measure' entries should equal to entries obtained by getEntriesByType.");
}, "Test for user-timing with PerformanceObserver");
test(t => {
performance.clearMarks();
performance.clearMeasures();
promise_test(t => {
var promise = new Promise((resolve, reject) => {
performance.clearMarks();
performance.clearMeasures();
var observedEntries = [];
var observer = new PerformanceObserver(list => {
list.getEntries().forEach(entry => observedEntries.push(entry));
var observer = new PerformanceObserver(list => reject(list));
observer.observe({entryTypes: ['mark', 'measure']});
observer.disconnect();
t.step_timeout(resolve, 100);
});
observer.observe({entryTypes: ['mark', 'measure']});
observer.disconnect();
assert_equals(observedEntries.length, 0,
"User timing entries should be never observed.");
performance.mark("test-start");
performance.mark("test-end");
performance.measure("test-measure", "test-start", "test-end");
assert_equals(performance.getEntriesByType("mark").length, 2);
assert_equals(performance.getEntriesByType("measure").length, 1);
return promise.then(() => {
assert_equals(performance.getEntriesByType("mark").length, 2);
assert_equals(performance.getEntriesByType("measure").length, 1);
}, list => {
assert_unreached("Observer callback should never be called.");
});
assert_equals(observedEntries.length, 0,
"User timing entries should be never observed after disconnecting observer.");
}, "Nothing should be notified after disconnecting observer");
test(t => {
performance.clearMarks();
performance.clearMeasures();
var observedEntryList;
var observer = new PerformanceObserver(list => {
observedEntryList = list;
});
observer.observe({entryTypes: ['mark']});
t.add_cleanup(() => observer.disconnect());
promise_test(t => {
var promise = promiseObserve(t, {entryTypes: ['mark']});
performance.mark("test");
assert_array_equals(observedEntryList.getEntries({"entryType": "mark"}),
performance.getEntriesByType("mark"),
"getEntries with entryType filter should return correct results.");
assert_array_equals(observedEntryList.getEntries({"name": "test"}),
performance.getEntriesByName("test"),
"getEntries with name filter should return correct results.");
return promise.then(list => {
assert_array_equals(list.getEntries({"entryType": "mark"}),
performance.getEntriesByType("mark"),
"getEntries with entryType filter should return correct results.");
assert_array_equals(observedEntryList.getEntries({"name": "test",
"entryType": "mark"}),
performance.getEntriesByName("test"),
"getEntries with name and entryType filter should return correct results.");
assert_array_equals(list.getEntries({"name": "test"}),
performance.getEntriesByName("test"),
"getEntries with name filter should return correct results.");
assert_array_equals(observedEntryList.getEntries({"name": "invalid"}),
[],
"getEntries with non-existent name filter should return an empty array.");
assert_array_equals(list.getEntries({"name": "test",
"entryType": "mark"}),
performance.getEntriesByName("test"),
"getEntries with name and entryType filter should return correct results.");
assert_array_equals(observedEntryList.getEntries({"name": "test",
"entryType": "measure"}),
[],
"getEntries with name filter and non-existent entryType should return an empty array.");
assert_array_equals(list.getEntries({"name": "invalid"}),
[],
"getEntries with non-existent name filter should return an empty array.");
assert_array_equals(observedEntryList.getEntries({"name": "invalid",
"entryType": "mark"}),
[],
"getEntries with non-existent name and entryType filter should return an empty array.");
assert_array_equals(list.getEntries({"name": "test",
"entryType": "measure"}),
[],
"getEntries with name filter and non-existent entryType should return an empty array.");
assert_array_equals(observedEntryList.getEntries({initiatorType: "xmlhttprequest"}),
[],
"getEntries with initiatorType filter should return an empty array.");
assert_array_equals(list.getEntries({"name": "invalid",
"entryType": "mark"}),
[],
"getEntries with non-existent name and entryType filter should return an empty array.");
assert_array_equals(list.getEntries({initiatorType: "xmlhttprequest"}),
[],
"getEntries with initiatorType filter should return an empty array.");
});
}, "Test for PerformanceObserverEntryList.getEntries");
test(t => {
performance.clearMarks();
performance.clearMeasures();
var observedEntryList;
var observer = new PerformanceObserver(list => {
observedEntryList = list;
});
observer.observe({entryTypes: ['mark', 'measure']});
t.add_cleanup(() => observer.disconnect());
promise_test(t => {
var promise = promiseObserve(t, {entryTypes: ['mark', 'measure']});
performance.mark("test");
assert_array_equals(observedEntryList.getEntriesByType("mark"),
performance.getEntriesByType("mark"));
performance.measure("test-measure", "test", "test");
assert_array_equals(observedEntryList.getEntriesByType("measure"),
performance.getEntriesByType("measure"));
return promise.then(list => {
assert_array_equals(list.getEntriesByType("mark"),
performance.getEntriesByType("mark"));
assert_array_equals(list.getEntriesByType("measure"),
performance.getEntriesByType("measure"));
});
}, "Test for PerformanceObserverEntryList.getEntriesByType");
test(t => {
performance.clearMarks();
performance.clearMeasures();
var observedEntryList;
var observer = new PerformanceObserver(list => {
observedEntryList = list;
});
observer.observe({entryTypes: ['mark', 'measure']});
t.add_cleanup(() => observer.disconnect());
promise_test(t => {
var promise = promiseObserve(t, {entryTypes: ['mark', 'measure']});
performance.mark("test");
assert_array_equals(observedEntryList.getEntriesByName("test"),
performance.getEntriesByName("test"));
performance.measure("test-measure", "test", "test");
assert_array_equals(observedEntryList.getEntriesByName("test-measure"),
performance.getEntriesByName("test-measure"));
return promise.then(list => {
assert_array_equals(list.getEntriesByName("test"),
performance.getEntriesByName("test"));
assert_array_equals(list.getEntriesByName("test-measure"),
performance.getEntriesByName("test-measure"));
});
}, "Test for PerformanceObserverEntryList.getEntriesByName");
test(t => {
performance.clearMarks();
performance.clearMeasures();
promise_test(t => {
var promise = new Promise(resolve => {
performance.clearMarks();
performance.clearMeasures();
var observedEntries = [];
var observer = new PerformanceObserver(list => {
list.getEntries().forEach(entry => observedEntries.push(entry));
var observer = new PerformanceObserver(list => resolve(list));
observer.observe({entryTypes: ['mark', 'measure']});
observer.observe({entryTypes: ['mark', 'measure']});
t.add_cleanup(() => observer.disconnect());
});
observer.observe({entryTypes: ['mark', 'measure']});
observer.observe({entryTypes: ['mark', 'measure']});
t.add_cleanup(() => observer.disconnect());
performance.mark("test-start");
performance.mark("test-end");
performance.measure("test-measure", "test-start", "test-end");
assert_equals(observedEntries.length, 3,
"Observed user timing entries should have only three entries.");
return promise.then(list => {
assert_equals(list.getEntries().length, 3,
"Observed user timing entries should have only three entries.");
});
}, "Test that invoking observe method twice affects nothing");
test(t => {
performance.clearMarks();
performance.clearMeasures();
promise_test(t => {
var promise = new Promise(resolve => {
performance.clearMarks();
performance.clearMeasures();
var observedEntries = [];
var observer = new PerformanceObserver(list => {
list.getEntries().forEach(entry => observedEntries.push(entry));
var observer = new PerformanceObserver(list => resolve(list));
observer.observe({entryTypes: ['mark', 'measure']});
observer.observe({entryTypes: ['mark']});
t.add_cleanup(() => observer.disconnect());
});
observer.observe({entryTypes: ['mark', 'measure']});
observer.observe({entryTypes: ['mark']});
t.add_cleanup(() => observer.disconnect());
performance.mark("test-start");
performance.mark("test-end");
performance.measure("test-measure", "test-start", "test-end");
assert_equals(observedEntries.length, 2,
"Observed user timing entries should have only two entries.");
return promise.then(list => {
assert_equals(list.getEntries().length, 2,
"Observed user timing entries should have only two entries.");
});
}, "Test that observing filter is replaced by a new filter");
test(t => {
performance.clearMarks();
performance.clearMeasures();
promise_test(t => {
var promise = new Promise(resolve => {
performance.clearMarks();
performance.clearMeasures();
var observedEntries = [];
var observer = new PerformanceObserver(list => {
list.getEntries().forEach(entry => observedEntries.push(entry));
var observer = new PerformanceObserver(list => resolve(list));
observer.observe({entryTypes: ['mark']});
observer.observe({entryTypes: ['measure']});
t.add_cleanup(() => observer.disconnect());
});
observer.observe({entryTypes: ['mark']});
observer.observe({entryTypes: ['measure']});
t.add_cleanup(() => observer.disconnect());
performance.mark("test-start");
performance.mark("test-end");
performance.measure("test-measure", "test-start", "test-end");
assert_equals(observedEntries.length, 1,
"Observed user timing entries should have only 1 entries.");
return promise.then(list => {
assert_equals(list.getEntries().length, 1,
"Observed user timing entries should have only 1 entries.");
});
}, "Test that observing filter is replaced by a new filter");

View File

@ -2175,10 +2175,7 @@ bool
ContentChild::RecvFlushMemory(const nsString& reason)
{
#ifdef MOZ_NUWA_PROCESS
if (IsNuwaProcess()) {
// Don't flush memory in the nuwa process: the GC thread could be frozen.
return true;
}
MOZ_ASSERT(!IsNuwaProcess() || !IsNuwaReady());
#endif
nsCOMPtr<nsIObserverService> os =
mozilla::services::GetObserverService();
@ -2417,11 +2414,7 @@ bool
ContentChild::RecvMinimizeMemoryUsage()
{
#ifdef MOZ_NUWA_PROCESS
if (IsNuwaProcess()) {
// Don't minimize memory in the nuwa process: it will perform GC, but the
// GC thread could be frozen.
return true;
}
MOZ_ASSERT(!IsNuwaProcess() || !IsNuwaReady());
#endif
nsCOMPtr<nsIMemoryReporterManager> mgr =
do_GetService("@mozilla.org/memory-reporter-manager;1");

View File

@ -682,6 +682,22 @@ static const char* sObserverTopics[] = {
#endif
};
#ifdef MOZ_NUWA_PROCESS
// Contains the observer topics that can be sent to the Nuwa process after it
// becomes ready. The ContentParent instance will unregister sObserverTopics
// if not listed in sNuwaSafeObserverTopics.
static const char* sNuwaSafeObserverTopics[] = {
"xpcom-shutdown",
"profile-before-change",
#ifdef MOZ_WIDGET_GONK
"phone-state-changed",
#endif
#ifdef ACCESSIBILITY
"a11y-init-or-shutdown",
#endif
"nsPref:Changed"
};
#endif
/* static */ already_AddRefed<ContentParent>
ContentParent::RunNuwaProcess()
{
@ -2923,6 +2939,41 @@ ContentParent::ForkNewProcess(bool aBlocking)
#endif
}
#ifdef MOZ_NUWA_PROCESS
// Keep only observer topics listed in sNuwaSafeObserverTopics and unregister
// all the other registered topics.
static void
KeepNuwaSafeObserverTopics(ContentParent* aNuwaContentParent)
{
MOZ_ASSERT(aNuwaContentParent && aNuwaContentParent->IsNuwaProcess());
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (!obs) {
return;
}
size_t topicLength = ArrayLength(sObserverTopics);
for (size_t i = 0; i < topicLength; ++i) {
bool nuwaSafe = false;
size_t safeTopicLength = ArrayLength(sNuwaSafeObserverTopics);
for (size_t j = 0; j < safeTopicLength; j++) {
if (!nsCRT::strcmp(sObserverTopics[i],
sNuwaSafeObserverTopics[j])) {
// In the whitelist: don't need to unregister.
nuwaSafe = true;
break;
}
}
if (!nuwaSafe) {
obs->RemoveObserver(aNuwaContentParent, sObserverTopics[i]);
}
}
}
#endif
void
ContentParent::OnNuwaReady()
{
@ -2932,6 +2983,8 @@ ContentParent::OnNuwaReady()
MOZ_ASSERT(IsNuwaProcess());
sNuwaReady = true;
KeepNuwaSafeObserverTopics(this);
PreallocatedProcessManager::OnNuwaReady();
return;
#else
@ -3025,6 +3078,16 @@ ContentParent::Observe(nsISupports* aSubject,
if (!mIsAlive || !mSubprocess)
return NS_OK;
// The Nuwa process unregisters the topics after it becomes ready except for
// the ones listed in sNuwaSafeObserverTopics. If the topic needs to be
// observed by the Nuwa process, either for:
// 1. The topic is safe for the Nuwa process, either:
// 1.1 The state can safely happen (only run on the main thread) in the Nuwa
// process (e.g. "a11y-init-or-shutdown"), or
// 1.2 The topic doesn't send an IPC message (e.g. "xpcom-shutdown").
// 2. The topic needs special handling (e.g. nsPref:Changed),
// add the topic to sNuwaSafeObserverTopics and then handle it if necessary.
// listening for memory pressure event
if (!strcmp(aTopic, "memory-pressure") &&
!StringEndsWith(nsDependentString(aData),
@ -3039,7 +3102,7 @@ ContentParent::Observe(nsISupports* aSubject,
PrefSetting pref(strData, null_t(), null_t());
Preferences::GetPreference(&pref);
#ifdef MOZ_NUWA_PROCESS
if (IsNuwaProcess() && PreallocatedProcessManager::IsNuwaReady()) {
if (IsReadyNuwaProcess()) {
// Don't send the pref update to the Nuwa process. Save the update
// to send to the forked child.
if (!sNuwaPrefUpdates) {
@ -3056,28 +3119,16 @@ ContentParent::Observe(nsISupports* aSubject,
#endif
}
else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC)) {
NS_ConvertUTF16toUTF8 dataStr(aData);
const char *offline = dataStr.get();
#ifdef MOZ_NUWA_PROCESS
if (!(IsNuwaReady() && IsNuwaProcess())) {
#endif
if (!SendSetOffline(!strcmp(offline, "true") ? true : false)) {
return NS_ERROR_NOT_AVAILABLE;
}
#ifdef MOZ_NUWA_PROCESS
}
#endif
NS_ConvertUTF16toUTF8 dataStr(aData);
const char *offline = dataStr.get();
if (!SendSetOffline(!strcmp(offline, "true") ? true : false)) {
return NS_ERROR_NOT_AVAILABLE;
}
}
else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC)) {
#ifdef MOZ_NUWA_PROCESS
if (!(IsNuwaReady() && IsNuwaProcess())) {
#endif
if (!SendSetConnectivity(NS_LITERAL_STRING("true").Equals(aData))) {
return NS_ERROR_NOT_AVAILABLE;
}
#ifdef MOZ_NUWA_PROCESS
if (!SendSetConnectivity(NS_LITERAL_STRING("true").Equals(aData))) {
return NS_ERROR_NOT_AVAILABLE;
}
#endif
}
// listening for alert notifications
else if (!strcmp(aTopic, "alertfinished") ||
@ -3103,13 +3154,7 @@ ContentParent::Observe(nsISupports* aSubject,
nsCString creason;
CopyUTF16toUTF8(aData, creason);
DeviceStorageFile* file = static_cast<DeviceStorageFile*>(aSubject);
#ifdef MOZ_NUWA_PROCESS
if (!(IsNuwaReady() && IsNuwaProcess()))
#endif
{
unused << SendFilePathUpdate(file->mStorageType, file->mStorageName, file->mPath, creason);
}
unused << SendFilePathUpdate(file->mStorageType, file->mStorageName, file->mPath, creason);
}
#ifdef MOZ_WIDGET_GONK
else if(!strcmp(aTopic, NS_VOLUME_STATE_CHANGED)) {
@ -3142,27 +3187,17 @@ ContentParent::Observe(nsISupports* aSubject,
vol->GetIsRemovable(&isRemovable);
vol->GetIsHotSwappable(&isHotSwappable);
#ifdef MOZ_NUWA_PROCESS
if (!(IsNuwaReady() && IsNuwaProcess()))
#endif
{
unused << SendFileSystemUpdate(volName, mountPoint, state,
mountGeneration, isMediaPresent,
isSharing, isFormatting, isFake,
isUnmounting, isRemovable, isHotSwappable);
}
unused << SendFileSystemUpdate(volName, mountPoint, state,
mountGeneration, isMediaPresent,
isSharing, isFormatting, isFake,
isUnmounting, isRemovable, isHotSwappable);
} else if (!strcmp(aTopic, "phone-state-changed")) {
nsString state(aData);
unused << SendNotifyPhoneStateChange(state);
}
else if(!strcmp(aTopic, NS_VOLUME_REMOVED)) {
#ifdef MOZ_NUWA_PROCESS
if (!(IsNuwaReady() && IsNuwaProcess()))
#endif
{
nsString volName(aData);
unused << SendVolumeRemoved(volName);
}
nsString volName(aData);
unused << SendVolumeRemoved(volName);
}
#endif
#ifdef ACCESSIBILITY
@ -4468,12 +4503,10 @@ ContentParent::DoSendAsyncMessage(JSContext* aCx,
if (aCpows && (!mgr || !mgr->Wrap(aCx, aCpows, &cpows))) {
return false;
}
#ifdef MOZ_NUWA_PROCESS
if (IsNuwaProcess() && IsNuwaReady()) {
if (IsReadyNuwaProcess()) {
// Nuwa won't receive frame messages after it is frozen.
return true;
}
#endif
return SendAsyncMessage(nsString(aMessage), data, cpows, Principal(aPrincipal));
}

View File

@ -260,6 +260,15 @@ public:
bool IsNuwaProcess();
#endif
// A shorthand for checking if the Nuwa process is ready.
bool IsReadyNuwaProcess() {
#ifdef MOZ_NUWA_PROCESS
return IsNuwaProcess() && IsNuwaReady();
#else
return false;
#endif
}
GeckoChildProcessHost* Process() {
return mSubprocess;
}

View File

@ -169,4 +169,3 @@ PEExpectedVariableNameEOF=identifier for variable name
PEExpectedVariableName=Expected identifier for variable name but found '%1$S'.
PEExpectedVariableFallback=Expected variable reference fallback after ','.
PEExpectedVariableCommaOrCloseParen=Expected ',' or ')' after variable name in variable reference but found '%1$S'.
PEMozDocumentRuleNotAllowed=@-moz-document rules may only be used in user style sheets.

View File

@ -367,7 +367,7 @@ public:
: mRecorder(aRecorder)
, mTimeSlice(aTimeSlice)
, mStopIssued(false)
, mCanRetrieveData(false)
, mIsStartEventFired(false)
, mIsRegisterProfiler(false)
, mNeedSessionEndTask(true)
{
@ -494,10 +494,10 @@ private:
if (!encodedBuf[i].IsEmpty()) {
mEncodedBufferCache->AppendBuffer(encodedBuf[i]);
// Fire the start event when encoded data is available.
if (!mCanRetrieveData) {
if (!mIsStartEventFired) {
NS_DispatchToMainThread(
new DispatchStartEventRunnable(this, NS_LITERAL_STRING("start")));
mCanRetrieveData = true;
mIsStartEventFired = true;
}
}
}
@ -510,6 +510,12 @@ private:
pushBlob = true;
}
if (pushBlob || aForceFlush) {
// Fire the start event before the blob.
if (!mIsStartEventFired) {
NS_DispatchToMainThread(
new DispatchStartEventRunnable(this, NS_LITERAL_STRING("start")));
mIsStartEventFired = true;
}
if (NS_FAILED(NS_DispatchToMainThread(new EncoderErrorNotifierRunnable(this)))) {
MOZ_ASSERT(false, "NS_DispatchToMainThread EncoderErrorNotifierRunnable failed");
}
@ -639,6 +645,9 @@ private:
{
MOZ_ASSERT(NS_IsMainThread());
CleanupStreams();
NS_DispatchToMainThread(
new DispatchStartEventRunnable(this, NS_LITERAL_STRING("start")));
if (NS_FAILED(rv)) {
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableMethodWithArg<nsresult>(mRecorder,
@ -724,8 +733,8 @@ private:
const int32_t mTimeSlice;
// Indicate this session's stop has been called.
bool mStopIssued;
// Indicate session has encoded data. This can be changed in recording thread.
bool mCanRetrieveData;
// Indicate the session had fire start event. Encoding thread only.
bool mIsStartEventFired;
// The register flag for "Media_Encoder" thread to profiler
bool mIsRegisterProfiler;
// False if the InitEncoder called successfully, ensure the

View File

@ -1321,14 +1321,6 @@ MediaStreamGraphImpl::ProduceDataForStreamsBlockByBlock(uint32_t aStreamIndex,
ps->ProcessInput(t, next, (next == aTo) ? ProcessedMediaStream::ALLOW_FINISH : 0);
}
}
// Remove references to shared AudioChunk buffers from downstream nodes
// first so that upstream nodes can re-use next iteration.
for (uint32_t i = mStreams.Length(); i--; ) {
AudioNodeStream* ns = mStreams[i]->AsAudioNodeStream();
if (ns) {
ns->ReleaseSharedBuffers();
}
}
t = next;
}
NS_ASSERTION(t == aTo, "Something went wrong with rounding to block boundaries");

View File

@ -134,11 +134,8 @@ OmxVideoTrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
layers::Image* img = (!mLastFrame.GetImage() || mLastFrame.GetForceBlack())
? nullptr : mLastFrame.GetImage();
rv = mEncoder->Encode(img, mFrameWidth, mFrameHeight, totalDurationUs,
OMXCodecWrapper::BUFFER_EOS);
OMXCodecWrapper::BUFFER_EOS, &mEosSetInEncoder);
NS_ENSURE_SUCCESS(rv, rv);
// Keep sending EOS signal until OMXVideoEncoder gets it.
mEosSetInEncoder = true;
}
// Dequeue an encoded frame from the output buffers of OMXCodecWrapper.
@ -219,6 +216,7 @@ OmxAudioTrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
PROFILER_LABEL("OmxAACAudioTrackEncoder", "GetEncodedTrack",
js::ProfileEntry::Category::OTHER);
AudioSegment segment;
bool EOS;
// Move all the samples from mRawSegment to segment. We only hold
// the monitor in this block.
{
@ -234,14 +232,15 @@ OmxAudioTrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
}
segment.AppendFrom(&mRawSegment);
EOS = mEndOfStream;
}
nsresult rv;
if (segment.GetDuration() == 0) {
// Notify EOS at least once, even if segment is empty.
if (mEndOfStream && !mEosSetInEncoder) {
mEosSetInEncoder = true;
rv = mEncoder->Encode(segment, OMXCodecWrapper::BUFFER_EOS);
if (EOS && !mEosSetInEncoder) {
rv = mEncoder->Encode(segment, OMXCodecWrapper::BUFFER_EOS,
&mEosSetInEncoder);
NS_ENSURE_SUCCESS(rv, rv);
}
// Nothing to encode but encoder could still have encoded data for earlier
@ -252,8 +251,7 @@ OmxAudioTrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
// OMX encoder has limited input buffers only so we have to feed input and get
// output more than once if there are too many samples pending in segment.
while (segment.GetDuration() > 0) {
rv = mEncoder->Encode(segment,
mEndOfStream ? OMXCodecWrapper::BUFFER_EOS : 0);
rv = mEncoder->Encode(segment, 0);
NS_ENSURE_SUCCESS(rv, rv);
rv = AppendEncodedFrames(aData);

View File

@ -446,6 +446,7 @@ VP8TrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
{
PROFILER_LABEL("VP8TrackEncoder", "GetEncodedTrack",
js::ProfileEntry::Category::OTHER);
bool EOS;
{
// Move all the samples from mRawSegment to mSourceSegment. We only hold
// the monitor in this block.
@ -461,6 +462,7 @@ VP8TrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
return NS_ERROR_FAILURE;
}
mSourceSegment.AppendFrom(&mRawSegment);
EOS = mEndOfStream;
}
VideoSegment::ChunkIterator iter(mSourceSegment);
@ -534,7 +536,7 @@ VP8TrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
VP8LOG("RemoveLeading %lld\n",totalProcessedDuration);
// End of stream, pull the rest frames in encoder.
if (mEndOfStream) {
if (EOS) {
VP8LOG("mEndOfStream is true\n");
mEncodingComplete = true;
if (vpx_codec_encode(mVPXContext, nullptr, mEncodedTimestamp,

View File

@ -382,7 +382,7 @@ ConvertGrallocImageToNV12(GrallocImage* aSource, uint8_t* aDestination)
nsresult
OMXVideoEncoder::Encode(const Image* aImage, int aWidth, int aHeight,
int64_t aTimestamp, int aInputFlags)
int64_t aTimestamp, int aInputFlags, bool* aSendEOS)
{
MOZ_ASSERT(mStarted, "Configure() should be called before Encode().");
@ -456,6 +456,9 @@ OMXVideoEncoder::Encode(const Image* aImage, int aWidth, int aHeight,
// Queue this input buffer.
result = mCodec->queueInputBuffer(index, 0, dstSize, aTimestamp, aInputFlags);
if (aSendEOS && (aInputFlags & BUFFER_EOS) && result == OK) {
*aSendEOS = true;
}
return result == OK ? NS_OK : NS_ERROR_FAILURE;
}
@ -822,7 +825,8 @@ OMXAudioEncoder::~OMXAudioEncoder()
}
nsresult
OMXAudioEncoder::Encode(AudioSegment& aSegment, int aInputFlags)
OMXAudioEncoder::Encode(AudioSegment& aSegment, int aInputFlags,
bool* aSendEOS)
{
#ifndef MOZ_SAMPLE_TYPE_S16
#error MediaCodec accepts only 16-bit PCM data.
@ -877,7 +881,9 @@ OMXAudioEncoder::Encode(AudioSegment& aSegment, int aInputFlags)
}
result = buffer.Enqueue(mTimestamp, flags);
NS_ENSURE_TRUE(result == OK, NS_ERROR_FAILURE);
if (aSendEOS && (aInputFlags & BUFFER_EOS)) {
*aSendEOS = true;
}
return NS_OK;
}

View File

@ -224,8 +224,13 @@ public:
* stream, set aInputFlags to BUFFER_EOS. Since encoder has limited buffers,
* this function might not be able to encode all chunks in one call, however
* it will remove chunks it consumes from aSegment.
* aSendEOS is the output to tell the caller EOS signal sent into MediaCodec
* because the signal might not be sent due to the dequeueInputBuffer timeout.
* And the value of aSendEOS won't be set to any default value, only set to
* true when EOS signal sent into MediaCodec.
*/
nsresult Encode(mozilla::AudioSegment& aSegment, int aInputFlags = 0);
nsresult Encode(mozilla::AudioSegment& aSegment, int aInputFlags = 0,
bool* aSendEOS = nullptr);
~OMXAudioEncoder();
protected:
@ -298,9 +303,14 @@ public:
* semi-planar YUV420 format stored in the buffer of aImage. aTimestamp gives
* the frame timestamp/presentation time (in microseconds). To notify end of
* stream, set aInputFlags to BUFFER_EOS.
* aSendEOS is the output to tell the caller EOS signal sent into MediaCodec
* because the signal might not be sent due to the dequeueInputBuffer timeout.
* And the value of aSendEOS won't be set to any default value, only set to
* true when EOS signal sent into MediaCodec.
*/
nsresult Encode(const mozilla::layers::Image* aImage, int aWidth, int aHeight,
int64_t aTimestamp, int aInputFlags = 0);
int64_t aTimestamp, int aInputFlags = 0,
bool* aSendEOS = nullptr);
#if ANDROID_VERSION >= 18
/** Set encoding bitrate (in kbps). */

View File

@ -678,7 +678,6 @@ tags=msg
tags=msg
[test_mediarecorder_record_gum_video_timeslice.html]
tags=msg
skip-if = buildapp == 'b2g' || toolkit == 'android' # mimetype check, bug 969289
[test_mediarecorder_record_immediate_stop.html]
tags=msg capturestream
[test_mediarecorder_record_no_timeslice.html]

View File

@ -40,12 +40,10 @@ function startTest() {
is(evt.type, 'dataavailable',
'Event type should dataavailable');
ok(evt.data.size >= 0,
'Blob data size received is greater than or equal to zero');
is(evt.data.type, 'video/webm',
'Blob data received should have type = ' + 'video/webm');
is(mediaRecorder.mimeType, 'video/webm',
'Mime type in ondataavailable = ' + mediaRecorder.mimeType);
'Blob data size ' + evt.data.size + ' received is greater than or equal to zero');
is(mediaRecorder.mimeType, evt.data.type,
'Mime type in MediaRecorder and ondataavailable : '
+ mediaRecorder.mimeType + ' == ' + evt.data.type);
// We'll stop recording upon the 1st blob being received
if (dataAvailableCount === 1) {

View File

@ -957,8 +957,11 @@ AudioContext::UpdateNodeCount(int32_t aDelta)
bool firstNode = mNodeCount == 0;
mNodeCount += aDelta;
MOZ_ASSERT(mNodeCount >= 0);
// mDestinationNode may be null when we're destroying nodes unlinked by CC
if (!firstNode && mDestination) {
// mDestinationNode may be null when we're destroying nodes unlinked by CC.
// Skipping unnecessary calls after shutdown avoids RunInStableState events
// getting stuck in CycleCollectedJSRuntime during final cycle collection
// (bug 1200514).
if (!firstNode && mDestination && !mIsShutDown) {
mDestination->SetIsOnlyNodeForContext(mNodeCount == 1);
}
}

View File

@ -538,6 +538,12 @@ AudioNodeStream::ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags)
mEngine->ProcessBlocksOnPorts(this, mInputChunks, mLastChunks, &finished);
}
}
for (auto& chunk : mInputChunks) {
// If the buffer is shared then it won't be reused, so release the
// reference now. Keep the channel data array to save a free/alloc
// pair.
chunk.ReleaseBufferIfShared();
}
for (uint16_t i = 0; i < outputCount; ++i) {
NS_ASSERTION(mLastChunks[i].GetDuration() == WEBAUDIO_BLOCK_SIZE,
"Invalid WebAudio chunk size");
@ -613,22 +619,6 @@ AudioNodeStream::AdvanceOutputSegment()
}
}
void
AudioNodeStream::ReleaseSharedBuffers()
{
// A shared buffer can't be reused, so release the reference now. Keep
// the channel data arrays to save unnecessary free/alloc.
// Release shared output buffers first, as they may be shared with input
// buffers which can be re-used if there are no other references.
for (auto& chunk : mLastChunks) {
chunk.ReleaseBufferIfShared();
}
for (auto& chunk : mInputChunks) {
chunk.ReleaseBufferIfShared();
}
}
StreamTime
AudioNodeStream::GetCurrentPosition()
{

View File

@ -117,14 +117,6 @@ public:
* the output. This is used only for DelayNodeEngine in a feedback loop.
*/
void ProduceOutputBeforeInput(GraphTime aFrom);
/**
* Remove references to shared AudioChunk buffers. Called on downstream
* nodes first after an iteration has called ProcessInput() on the entire
* graph, so that upstream nodes can re-use their buffers on the next
* iteration.
*/
void ReleaseSharedBuffers();
StreamTime GetCurrentPosition();
bool IsAudioParamStream() const
{
@ -192,7 +184,7 @@ protected:
// The engine that will generate output for this node.
nsAutoPtr<AudioNodeEngine> mEngine;
// The mixed input blocks are kept from iteration to iteration to avoid
// reallocating channel data arrays and any buffers for mixing.
// reallocating channel data arrays.
OutputChunks mInputChunks;
// The last block produced by this node.
OutputChunks mLastChunks;

View File

@ -114,9 +114,6 @@ public:
// ProduceBlockBeforeInput() when in a cycle.
if (!mHaveProducedBeforeInput) {
UpdateOutputBlock(aOutput, 0.0);
// Not in cycle, so no need for additional buffer reference.
// See ProduceBlockBeforeInput().
mLastOutput.SetNull(0);
}
mHaveProducedBeforeInput = false;
mBuffer.NextBlock();
@ -159,13 +156,7 @@ public:
if (mLeftOverData <= 0) {
aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
} else {
// AudioNodeStream::ReleaseSharedBuffers() is called on delay nodes in
// cycles first and so may release the buffer reference in aOutput
// because downstream nodes may still be sharing when called. Therefore
// keep a separate reference to the output buffer for re-use next
// iteration.
UpdateOutputBlock(&mLastOutput, WEBAUDIO_BLOCK_SIZE);
*aOutput = mLastOutput;
UpdateOutputBlock(aOutput, WEBAUDIO_BLOCK_SIZE);
}
mHaveProducedBeforeInput = true;
}
@ -186,7 +177,6 @@ public:
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
AudioChunk mLastOutput; // Used only when in a cycle.
AudioNodeStream* mSource;
AudioNodeStream* mDestination;
AudioParamTimeline mDelay;

View File

@ -148,9 +148,7 @@ SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded()
NS_NewURI(getter_AddRefs(uri), spec);
if (uri) {
nsRefPtr<CSSStyleSheet> cssSheet;
cssLoader->LoadSheetSync(uri,
mozilla::css::eAgentSheetFeatures,
true, getter_AddRefs(cssSheet));
cssLoader->LoadSheetSync(uri, true, true, getter_AddRefs(cssSheet));
if (cssSheet) {
EnsureOnDemandBuiltInUASheet(cssSheet);
}

View File

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<textarea id="textarea" lang="en"></textarea>
</body>
</html>

View File

@ -5,3 +5,4 @@ skip-if = buildapp == 'b2g' || os == 'android'
[test_bug338427.html]
[test_bug434998.xul]
[test_bug678842.html]
[test_bug717433.html]

View File

@ -0,0 +1,2 @@
# Affix file for British English dictionary
# Fake file, nothing here.

View File

@ -0,0 +1,4 @@
3
Mary
Paul
Peter

View File

@ -1,6 +1,10 @@
[DEFAULT]
skip-if = buildapp == 'b2g' || buildapp == 'mulet'
support-files = bug678842_subframe.html
support-files =
bug678842_subframe.html
bug717433_subframe.html
en-GB/en_GB.dic
en-GB/en_GB.aff
[test_bug348497.html]
[test_bug384147.html]

View File

@ -0,0 +1,98 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=717433
-->
<head>
<title>Test for Bug 717433</title>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717433">Mozilla Bug 717433</a>
<p id="display"></p>
<iframe id="content"></iframe>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 717433 **/
SimpleTest.waitForExplicitFinish();
var content = document.getElementById('content');
// Load a subframe containing an editor with language "en". At first
// load, it will set the dictionary to en-GB or en-US. We set the other one.
// At second load, it will return the current dictionary. We can check that the
// dictionary is correctly remembered between loads.
var firstLoad = true;
var expected = "";
var en_GB;
var hunspell;
var loadListener = function(evt) {
Components.utils.import("resource://gre/modules/AsyncSpellCheckTestHelper.jsm");
if (firstLoad) {
var dir = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("CurWorkD", Components.interfaces.nsIFile);
dir.append("tests");
dir.append("editor");
dir.append("composer");
dir.append("test");
hunspell = Components.classes["@mozilla.org/spellchecker/engine;1"]
.getService(Components.interfaces.mozISpellCheckingEngine);
// Install en-GB dictionary.
en_GB = dir.clone();
en_GB.append("en-GB");
is(en_GB.exists(), true, "true expected (en-GB directory should exist)");
hunspell.addDirectory(en_GB);
}
var doc = evt.target.contentDocument;
var elem = doc.getElementById('textarea');
var editor = elem.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor;
editor.setSpellcheckUserOverride(true);
var inlineSpellChecker = editor.getInlineSpellChecker(true);
onSpellCheck(elem, function () {
var spellchecker = inlineSpellChecker.spellChecker;
try {
var currentDictonary = spellchecker.GetCurrentDictionary();
} catch(e) {}
if (firstLoad) {
firstLoad = false;
// First time around, we get a random dictionary based on the language "en".
if (currentDictonary == "en-GB") {
spellchecker.SetCurrentDictionary("en-US");
expected = "en-US";
} else if (currentDictonary == "en-US") {
spellchecker.SetCurrentDictionary("en-GB");
expected = "en-GB";
} else {
is(true, false, "Neither en-US nor en-GB are current");
}
content.src = 'http://mochi.test:8888/tests/editor/composer/test/bug717433_subframe.html?firstload=false';
} else {
is(currentDictonary, expected, expected + " expected");
content.removeEventListener('load', loadListener, false);
// Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
hunspell.removeDirectory(en_GB);
SimpleTest.finish();
}
});
}
content.addEventListener('load', loadListener, false);
content.src = 'http://mochi.test:8888/tests/editor/composer/test/bug717433_subframe.html?firstload=true';
</script>
</pre>
</body>
</html>

View File

@ -2840,8 +2840,7 @@ nsHTMLEditor::AddOverrideStyleSheet(const nsAString& aURL)
nsRefPtr<CSSStyleSheet> sheet;
// Editor override style sheets may want to style Gecko anonymous boxes
rv = ps->GetDocument()->CSSLoader()->
LoadSheetSync(uaURI, mozilla::css::eAgentSheetFeatures, true,
getter_AddRefs(sheet));
LoadSheetSync(uaURI, true, true, getter_AddRefs(sheet));
// Synchronous loads should ALWAYS return completed
NS_ENSURE_TRUE(sheet, NS_ERROR_NULL_POINTER);

View File

@ -1,10 +1,10 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=520189
https://bugzilla.mozilla.org/show_bug.cgi?id=520182
-->
<head>
<title>Test for Bug 520189</title>
<title>Test for Bug 520182</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
@ -79,7 +79,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=520189
<pre id="test">
<script type="application/javascript">
/** Test for Bug 520189 **/
/** Test for Bug 520182 **/
const dataPayload = "foo<iframe src=\"data:text/html,bar\"></iframe>baz";
const jsPayload = "foo<iframe src=\"javascript:void('bar');\"></iframe>baz";
@ -421,21 +421,13 @@ var tests = [
isIFrame: true,
payload: invalidStyle8Payload,
rootElement() { return document.getElementById("ss").contentDocument.documentElement; },
// The sanitizer currently doesn't discard unrecognized rules when
// that would make the sheet completely empty (see bug 1177546).
// This is harmless, since @-moz-document is inoperative in author
// style sheets (see bug 1035091).
checkResult(html) { todo_is(html.indexOf("@-moz-document"), -1, "Should not have retained the @-moz-document rule"); },
checkResult(html) { is(html.indexOf("@-moz-document"), -1, "Should not have retained the @-moz-document rule"); },
},
{
id: "tt",
payload: invalidStyle8Payload,
rootElement() { return document.getElementById("tt"); },
// The sanitizer currently doesn't discard unrecognized rules when
// that would make the sheet completely empty (see bug 1177546).
// This is harmless, since @-moz-document is inoperative in author
// style sheets (see bug 1035091).
checkResult(html) { todo_is(html.indexOf("@-moz-document"), -1, "Should not have retained the @-moz-document rule"); },
checkResult(html) { is(html.indexOf("@-moz-document"), -1, "Should not have retained the @-moz-document rule"); },
},
{
id: "uu",

View File

@ -1234,7 +1234,7 @@ public:
#if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
static already_AddRefed<GlyphRenderingOptions>
CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting);
CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting, AntialiasMode aAntialiasMode = AntialiasMode::DEFAULT);
#endif
static already_AddRefed<DrawTarget>
CreateDualDrawTarget(DrawTarget *targetA, DrawTarget *targetB);

View File

@ -10,6 +10,7 @@
#include "ScaledFontCairo.h"
#include "skia/include/core/SkBitmapDevice.h"
#include "FilterNodeSoftware.h"
#include "HelpersSkia.h"
#ifdef USE_SKIA_GPU
#include "skia/include/gpu/SkGpuDevice.h"
@ -571,23 +572,17 @@ DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
paint.mPaint.setLCDRenderText(shouldLCDRenderText);
if (aRenderingOptions && aRenderingOptions->GetType() == FontType::CAIRO) {
switch (static_cast<const GlyphRenderingOptionsCairo*>(aRenderingOptions)->GetHinting()) {
case FontHinting::NONE:
paint.mPaint.setHinting(SkPaint::kNo_Hinting);
break;
case FontHinting::LIGHT:
paint.mPaint.setHinting(SkPaint::kSlight_Hinting);
break;
case FontHinting::NORMAL:
paint.mPaint.setHinting(SkPaint::kNormal_Hinting);
break;
case FontHinting::FULL:
paint.mPaint.setHinting(SkPaint::kFull_Hinting);
break;
const GlyphRenderingOptionsCairo* cairoOptions =
static_cast<const GlyphRenderingOptionsCairo*>(aRenderingOptions);
paint.mPaint.setHinting(GfxHintingToSkiaHinting(cairoOptions->GetHinting()));
if (cairoOptions->GetAutoHinting()) {
paint.mPaint.setAutohinted(true);
}
if (static_cast<const GlyphRenderingOptionsCairo*>(aRenderingOptions)->GetAutoHinting()) {
paint.mPaint.setAutohinted(true);
if (cairoOptions->GetAntialiasMode() == AntialiasMode::NONE) {
paint.mPaint.setAntiAlias(false);
}
} else if (aFont->GetType() == FontType::MAC && shouldLCDRenderText) {
// SkFontHost_mac only supports subpixel antialiasing when hinting is turned off.

View File

@ -758,13 +758,14 @@ Factory::PurgeAllCaches()
#ifdef USE_SKIA_FREETYPE
already_AddRefed<GlyphRenderingOptions>
Factory::CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting)
Factory::CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting, AntialiasMode aAntialiasMode)
{
RefPtr<GlyphRenderingOptionsCairo> options =
new GlyphRenderingOptionsCairo();
options->SetHinting(aHinting);
options->SetAutoHinting(aAutoHinting);
options->SetAntialiasMode(aAntialiasMode);
return options.forget();
}
#endif

View File

@ -88,10 +88,24 @@ GfxAntialiasToCairoAntialias(AntialiasMode antialias)
return CAIRO_ANTIALIAS_GRAY;
case AntialiasMode::SUBPIXEL:
return CAIRO_ANTIALIAS_SUBPIXEL;
case AntialiasMode::DEFAULT:
default:
return CAIRO_ANTIALIAS_DEFAULT;
}
return CAIRO_ANTIALIAS_DEFAULT;
}
static inline AntialiasMode
CairoAntialiasToGfxAntialias(cairo_antialias_t aAntialias)
{
switch(aAntialias) {
case CAIRO_ANTIALIAS_NONE:
return AntialiasMode::NONE;
case CAIRO_ANTIALIAS_GRAY:
return AntialiasMode::GRAY;
case CAIRO_ANTIALIAS_SUBPIXEL:
return AntialiasMode::SUBPIXEL;
default:
return AntialiasMode::DEFAULT;
}
}
static inline cairo_filter_t
@ -232,6 +246,23 @@ CairoFormatToGfxFormat(cairo_format_t format)
}
}
static inline FontHinting
CairoHintingToGfxHinting(cairo_hint_style_t aHintStyle)
{
switch (aHintStyle) {
case CAIRO_HINT_STYLE_NONE:
return FontHinting::NONE;
case CAIRO_HINT_STYLE_SLIGHT:
return FontHinting::LIGHT;
case CAIRO_HINT_STYLE_MEDIUM:
return FontHinting::NORMAL;
case CAIRO_HINT_STYLE_FULL:
return FontHinting::FULL;
default:
return FontHinting::NORMAL;
}
}
SurfaceFormat GfxFormatForCairoSurface(cairo_surface_t* surface);
static inline void

View File

@ -296,6 +296,22 @@ ExtendModeToTileMode(ExtendMode aMode)
return SkShader::kClamp_TileMode;
}
static inline SkPaint::Hinting
GfxHintingToSkiaHinting(FontHinting aHinting)
{
switch (aHinting) {
case FontHinting::NONE:
return SkPaint::kNo_Hinting;
case FontHinting::LIGHT:
return SkPaint::kSlight_Hinting;
case FontHinting::NORMAL:
return SkPaint::kNormal_Hinting;
case FontHinting::FULL:
return SkPaint::kFull_Hinting;
}
return SkPaint::kNormal_Hinting;
}
} // namespace gfx
} // namespace mozilla

View File

@ -37,6 +37,7 @@ public:
GlyphRenderingOptionsCairo()
: mHinting(FontHinting::NORMAL)
, mAutoHinting(false)
, mAntialiasMode(AntialiasMode::DEFAULT)
{
}
@ -44,10 +45,13 @@ public:
void SetAutoHinting(bool aAutoHinting) { mAutoHinting = aAutoHinting; }
FontHinting GetHinting() const { return mHinting; }
bool GetAutoHinting() const { return mAutoHinting; }
void SetAntialiasMode(AntialiasMode aAntialiasMode) { mAntialiasMode = aAntialiasMode; }
virtual AntialiasMode GetAntialiasMode() const { return mAntialiasMode; }
virtual FontType GetType() const { return FontType::CAIRO; }
private:
FontHinting mHinting;
bool mAutoHinting;
AntialiasMode mAntialiasMode;
};
} // namespace gfx

View File

@ -307,8 +307,6 @@ CompositorChild::RecvUpdatePluginConfigurations(const nsIntPoint& aContentOffset
// Handle invalidation, this can be costly, avoid if it is not needed.
if (isVisible) {
// invalidate region (widget origin)
gfx::IntRect bounds = aPlugins[pluginsIdx].bounds();
gfx::IntRect rect(0, 0, bounds.width, bounds.height);
#if defined(XP_WIN)
// Work around for flash's crummy sandbox. See bug 762948. This call
// digs down into the window hirearchy, invalidating regions on
@ -330,16 +328,16 @@ CompositorChild::RecvUpdatePluginConfigurations(const nsIntPoint& aContentOffset
}
bool
CompositorChild::RecvUpdatePluginVisibility(const uintptr_t& aOwnerWidget,
nsTArray<uintptr_t>&& aVisibleIdList)
CompositorChild::RecvHideAllPlugins(const uintptr_t& aParentWidget)
{
#if !defined(XP_WIN) && !defined(MOZ_WIDGET_GTK)
NS_NOTREACHED("CompositorChild::RecvUpdatePluginVisibility calls "
NS_NOTREACHED("CompositorChild::RecvHideAllPlugins calls "
"unexpected on this platform.");
return false;
#else
MOZ_ASSERT(NS_IsMainThread());
nsIWidget::UpdateRegisteredPluginWindowVisibility(aOwnerWidget, aVisibleIdList);
nsTArray<uintptr_t> list;
nsIWidget::UpdateRegisteredPluginWindowVisibility(aParentWidget, list);
return true;
#endif // !defined(XP_WIN) && !defined(MOZ_WIDGET_GTK)
}

View File

@ -90,8 +90,7 @@ public:
nsTArray<PluginWindowData>&& aPlugins) override;
virtual bool
RecvUpdatePluginVisibility(const uintptr_t& aOwnerWidget,
nsTArray<uintptr_t>&& aWindowList) override;
RecvHideAllPlugins(const uintptr_t& aParentWidget) override;
/**
* Request that the parent tell us when graphics are ready on GPU.

View File

@ -1013,6 +1013,52 @@ CompositorParent::SetShadowProperties(Layer* aLayer)
}
}
// handles firing of before and after composite events through
// an raii type helper class.
class AutoFireCompositorEvents {
public:
explicit AutoFireCompositorEvents(CompositorParent* aTarget, bool aEnabled) :
mCompositor(aTarget),
mStart(TimeStamp::Now()),
mEnabled(aEnabled),
mWillSent(false),
mDidSent(false)
{
}
~AutoFireCompositorEvents()
{
WillComposite();
DidComposite();
}
void WillComposite() {
if (mEnabled && mCompositor && !mWillSent) {
TimeStamp now = TimeStamp::Now();
mCompositor->CompositeEvent(WILL_COMPOSITE, mStart, now);
}
mWillSent = true;
}
void DidComposite() {
if (mEnabled && mCompositor && !mDidSent) {
TimeStamp now = TimeStamp::Now();
mCompositor->CompositeEvent(DID_COMPOSITE, mStart, now);
}
mDidSent = true;
}
void Cancel() {
mEnabled = false;
}
CompositorParent* mCompositor;
TimeStamp mStart;
bool mEnabled;
bool mWillSent;
bool mDidSent;
};
void
CompositorParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRect)
{
@ -1033,9 +1079,10 @@ CompositorParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRe
}
#endif
// Takes care of fireing 'will' and 'did' composite events.
AutoFireCompositorEvents afce(this, !aTarget);
if (!CanComposite()) {
TimeStamp end = TimeStamp::Now();
DidComposite(start, end);
return;
}
@ -1054,10 +1101,13 @@ CompositorParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRe
mForceCompositionTask->Cancel();
mForceCompositionTask = nullptr;
} else {
afce.Cancel();
return;
}
}
afce.WillComposite();
mCompositionManager->ComputeRotation();
TimeStamp time = mIsTesting ? mTestTime : mCompositorScheduler->GetLastComposeTime();
@ -1077,11 +1127,6 @@ CompositorParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRe
mLayerManager->SetDebugOverlayWantsNextFrame(false);
mLayerManager->EndTransaction(time);
if (!aTarget) {
TimeStamp end = TimeStamp::Now();
DidComposite(start, end);
}
// We're not really taking advantage of the stored composite-again-time here.
// We might be able to skip the next few composites altogether. However,
// that's a bit complex to implement and we'll get most of the advantage
@ -1722,9 +1767,10 @@ public:
virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aParent) override;
void DidComposite(uint64_t aId,
TimeStamp& aCompositeStart,
TimeStamp& aCompositeEnd);
void CompositeEvent(CallbackType aType,
uint64_t aId,
TimeStamp& aCompositeStart,
TimeStamp& aCompositeEnd);
private:
// Private destructor, to discourage deletion outside of Release():
@ -1745,18 +1791,21 @@ private:
};
void
CompositorParent::DidComposite(TimeStamp& aCompositeStart,
TimeStamp& aCompositeEnd)
CompositorParent::CompositeEvent(CallbackType aType,
TimeStamp& aCompositeStart,
TimeStamp& aCompositeEnd)
{
if (mPendingTransaction) {
unused << SendDidComposite(0, mPendingTransaction, aCompositeStart, aCompositeEnd);
mPendingTransaction = 0;
}
if (mLayerManager) {
nsTArray<ImageCompositeNotification> notifications;
mLayerManager->ExtractImageCompositeNotifications(&notifications);
if (!notifications.IsEmpty()) {
unused << ImageBridgeParent::NotifyImageComposites(notifications);
if (aType == DID_COMPOSITE) {
if (mPendingTransaction) {
unused << SendDidComposite(0, mPendingTransaction, aCompositeStart, aCompositeEnd);
mPendingTransaction = 0;
}
if (mLayerManager) {
nsTArray<ImageCompositeNotification> notifications;
mLayerManager->ExtractImageCompositeNotifications(&notifications);
if (!notifications.IsEmpty()) {
unused << ImageBridgeParent::NotifyImageComposites(notifications);
}
}
}
@ -1765,8 +1814,8 @@ CompositorParent::DidComposite(TimeStamp& aCompositeStart,
it != sIndirectLayerTrees.end(); it++) {
LayerTreeState* lts = &it->second;
if (lts->mParent == this && lts->mCrossProcessParent) {
static_cast<CrossProcessCompositorParent*>(lts->mCrossProcessParent)->DidComposite(
it->first, aCompositeStart, aCompositeEnd);
static_cast<CrossProcessCompositorParent*>(lts->mCrossProcessParent)->CompositeEvent(
aType, it->first, aCompositeStart, aCompositeEnd);
}
}
}
@ -2002,10 +2051,8 @@ UpdatePluginWindowState(uint64_t aId)
// tree contained visible plugins and the new tree does not. All we need
// to do here is hide the plugins for the old tree, so don't waste time
// calculating clipping.
nsTArray<uintptr_t> aVisibleIdList;
uintptr_t parentWidget = (uintptr_t)lts.mParent->GetWidget();
unused << lts.mParent->SendUpdatePluginVisibility(parentWidget,
aVisibleIdList);
unused << lts.mParent->SendHideAllPlugins(parentWidget);
lts.mUpdatedPluginDataAvailable = false;
return;
}
@ -2030,18 +2077,10 @@ UpdatePluginWindowState(uint64_t aId)
}
}
// Hide all plugins, this remote layer tree is no longer active
// Hide all of our plugins, this remote layer tree is no longer active.
if (shouldHidePlugin) {
// hide all the plugins
for (uint32_t pluginsIdx = 0; pluginsIdx < lts.mPluginData.Length();
pluginsIdx++) {
lts.mPluginData[pluginsIdx].visible() = false;
}
nsIntPoint offset;
nsIntRegion region;
unused << lts.mParent->SendUpdatePluginConfigurations(offset,
region,
lts.mPluginData);
uintptr_t parentWidget = (uintptr_t)lts.mParent->GetWidget();
unused << lts.mParent->SendHideAllPlugins(parentWidget);
// Clear because there's no recovering from this until we receive
// new shadow layer plugin data in ShadowLayersUpdated.
lts.mPluginData.Clear();
@ -2050,19 +2089,32 @@ UpdatePluginWindowState(uint64_t aId)
#endif // #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
void
CrossProcessCompositorParent::DidComposite(uint64_t aId,
TimeStamp& aCompositeStart,
TimeStamp& aCompositeEnd)
CrossProcessCompositorParent::CompositeEvent(CallbackType aType,
uint64_t aId,
TimeStamp& aCompositeStart,
TimeStamp& aCompositeEnd)
{
sIndirectLayerTreesLock->AssertCurrentThreadOwns();
LayerTransactionParent *layerTree = sIndirectLayerTrees[aId].mLayerTree;
if (layerTree && layerTree->GetPendingTransactionId()) {
unused << SendDidComposite(aId, layerTree->GetPendingTransactionId(), aCompositeStart, aCompositeEnd);
layerTree->SetPendingTransactionId(0);
}
switch (aType) {
case WILL_COMPOSITE: {
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
UpdatePluginWindowState(aId);
UpdatePluginWindowState(aId);
#endif
break;
}
case DID_COMPOSITE: {
sIndirectLayerTreesLock->AssertCurrentThreadOwns();
LayerTransactionParent *layerTree = sIndirectLayerTrees[aId].mLayerTree;
if (layerTree && layerTree->GetPendingTransactionId()) {
unused << SendDidComposite(aId, layerTree->GetPendingTransactionId(), aCompositeStart, aCompositeEnd);
layerTree->SetPendingTransactionId(0);
}
break;
}
default:
NS_RUNTIMEABORT("not reached");
}
}
void

View File

@ -55,6 +55,12 @@ class CompositorParent;
class LayerManagerComposite;
class LayerTransactionParent;
// CompositeEvent related events
enum CallbackType {
WILL_COMPOSITE,
DID_COMPOSITE
};
struct ScopedLayerTreeRegistration
{
ScopedLayerTreeRegistration(uint64_t aLayersId,
@ -439,7 +445,14 @@ protected:
*/
bool CanComposite();
void DidComposite(TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd);
// Fires before and after composite events
void CompositeEvent(CallbackType aType, TimeStamp& aCompositeStart,
TimeStamp& aCompositeEnd);
void DidComposite(TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd) {
CompositeEvent(DID_COMPOSITE, aCompositeStart, aCompositeEnd);
}
friend class AutoFireCompositorEvents;
nsRefPtr<LayerManagerComposite> mLayerManager;
nsRefPtr<Compositor> mCompositor;

View File

@ -42,7 +42,6 @@ using mozilla::layers::DiagnosticTypes from "mozilla/layers/CompositorTypes.h";
using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h";
using struct mozilla::layers::FenceHandle from "mozilla/layers/FenceUtils.h";
using std::string from "string";
namespace mozilla {
namespace layers {
@ -232,7 +231,6 @@ struct CommonLayerAttributes {
Animation[] animations;
nsIntRegion invalidRegion;
FrameMetrics[] metrics;
string contentDescription;
nsCString displayListLog;
};

View File

@ -70,11 +70,10 @@ child:
PluginWindowData[] aPlugins);
/**
* Sets the list of currently visible plugin windows based on a
* list of plugin window ids.
* Hides all registered plugin widgets associated with a particular chrome
* widget.
*/
async UpdatePluginVisibility(uintptr_t aOwnerWidget,
uintptr_t[] aVisibleIdList);
async HideAllPlugins(uintptr_t aParentWidget);
/**
* Drop any buffers that might be retained on the child compositor

View File

@ -276,6 +276,10 @@ SkScalerContext_CairoFT::SkScalerContext_CairoFT(SkTypeface* typeface, const SkD
// See http://code.google.com/p/skia/issues/detail?id=222.
loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
#ifdef FT_LOAD_COLOR
loadFlags |= FT_LOAD_COLOR;
#endif
fLoadGlyphFlags = loadFlags;
}

View File

@ -21,6 +21,8 @@
#include "nsDirectoryServiceDefs.h"
#include "nsAppDirectoryServiceDefs.h"
#include "mozilla/gfx/HelpersCairo.h"
#include <fontconfig/fcfreetype.h>
#ifdef MOZ_WIDGET_GTK
@ -902,27 +904,18 @@ gfxFontconfigFont::GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams)
cairo_font_options_t *options = cairo_font_options_create();
cairo_scaled_font_get_font_options(scaled_font, options);
cairo_hint_style_t hint_style = cairo_font_options_get_hint_style(options);
cairo_antialias_t antialias = cairo_font_options_get_antialias(options);
cairo_font_options_destroy(options);
mozilla::gfx::FontHinting hinting;
mozilla::gfx::FontHinting hinting =
mozilla::gfx::CairoHintingToGfxHinting(hint_style);
switch (hint_style) {
case CAIRO_HINT_STYLE_NONE:
hinting = mozilla::gfx::FontHinting::NONE;
break;
case CAIRO_HINT_STYLE_SLIGHT:
hinting = mozilla::gfx::FontHinting::LIGHT;
break;
case CAIRO_HINT_STYLE_FULL:
hinting = mozilla::gfx::FontHinting::FULL;
break;
default:
hinting = mozilla::gfx::FontHinting::NORMAL;
break;
}
mozilla::gfx::AntialiasMode aaMode =
mozilla::gfx::CairoAntialiasToGfxAntialias(antialias);
// We don't want to force the use of the autohinter over the font's built in hints
return mozilla::gfx::Factory::CreateCairoGlyphRenderingOptions(hinting, false);
// The fontconfig AA mode must be passed along because it may override the hinting style.
return mozilla::gfx::Factory::CreateCairoGlyphRenderingOptions(hinting, false, aaMode);
}
#endif

View File

@ -28,6 +28,7 @@
#include <cairo.h>
#include <cairo-ft.h>
#include "mozilla/gfx/HelpersCairo.h"
#include <fontconfig/fcfreetype.h>
#include <pango/pango.h>
@ -2143,27 +2144,18 @@ gfxFcFont::GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams)
cairo_font_options_t *options = cairo_font_options_create();
cairo_scaled_font_get_font_options(scaled_font, options);
cairo_hint_style_t hint_style = cairo_font_options_get_hint_style(options);
cairo_antialias_t antialias = cairo_font_options_get_antialias(options);
cairo_font_options_destroy(options);
mozilla::gfx::FontHinting hinting;
mozilla::gfx::FontHinting hinting =
mozilla::gfx::CairoHintingToGfxHinting(hint_style);
switch (hint_style) {
case CAIRO_HINT_STYLE_NONE:
hinting = mozilla::gfx::FontHinting::NONE;
break;
case CAIRO_HINT_STYLE_SLIGHT:
hinting = mozilla::gfx::FontHinting::LIGHT;
break;
case CAIRO_HINT_STYLE_FULL:
hinting = mozilla::gfx::FontHinting::FULL;
break;
default:
hinting = mozilla::gfx::FontHinting::NORMAL;
break;
}
mozilla::gfx::AntialiasMode aaMode =
mozilla::gfx::CairoAntialiasToGfxAntialias(antialias);
// We don't want to force the use of the autohinter over the font's built in hints
return mozilla::gfx::Factory::CreateCairoGlyphRenderingOptions(hinting, false);
// The fontconfig AA mode must be passed along because it may override the hinting style.
return mozilla::gfx::Factory::CreateCairoGlyphRenderingOptions(hinting, false, aaMode);
}
#endif

View File

@ -187,6 +187,7 @@ private:
DECL_GFX_PREF(Live, "apz.y_stationary_size_multiplier", APZYStationarySizeMultiplier, float, 3.5f);
DECL_GFX_PREF(Live, "apz.zoom_animation_duration_ms", APZZoomAnimationDuration, int32_t, 250);
DECL_GFX_PREF(Live, "browser.ui.zoom.force-user-scalable", ForceUserScalable, bool, false);
DECL_GFX_PREF(Live, "browser.viewport.desktopWidth", DesktopViewportWidth, int32_t, 980);
DECL_GFX_PREF(Live, "dom.meta-viewport.enabled", MetaViewportEnabled, bool, false);

View File

@ -187,6 +187,7 @@ ProcessLink::SendMessage(Message *msg)
case mozilla::dom::PNuwa::Msg_Fork__ID:
case mozilla::dom::PNuwa::Reply_AddNewProcess__ID:
case mozilla::dom::PContent::Msg_NotifyPhoneStateChange__ID:
case mozilla::dom::PContent::Msg_ActivateA11y__ID:
case mozilla::hal_sandbox::PHal::Msg_NotifyNetworkChange__ID:
case GOODBYE_MESSAGE_TYPE:
break;

View File

@ -2189,7 +2189,7 @@ InlineTransparentTypedObject::getOrCreateBuffer(JSContext* cx)
ObjectWeakMap*& table = cx->compartment()->lazyArrayBuffers;
if (!table) {
table = cx->new_<ObjectWeakMap>(cx);
if (!table)
if (!table || !table->init())
return nullptr;
}

View File

@ -807,7 +807,7 @@ JSCompartment::setNewObjectMetadata(JSContext* cx, JSObject* obj)
assertSameCompartment(cx, metadata);
if (!objectMetadataTable) {
objectMetadataTable = cx->new_<ObjectWeakMap>(cx);
if (!objectMetadataTable)
if (!objectMetadataTable || !objectMetadataTable->init())
CrashAtUnhandlableOOM("setNewObjectMetadata");
}
if (!objectMetadataTable->add(cx, obj, metadata))

View File

@ -683,9 +683,12 @@ js::InitBareWeakMapCtor(JSContext* cx, HandleObject obj)
ObjectWeakMap::ObjectWeakMap(JSContext* cx)
: map(cx, nullptr)
{}
bool
ObjectWeakMap::init()
{
if (!map.init())
CrashAtUnhandlableOOM("ObjectWeakMap");
return map.init();
}
ObjectWeakMap::~ObjectWeakMap()
@ -696,6 +699,7 @@ ObjectWeakMap::~ObjectWeakMap()
JSObject*
ObjectWeakMap::lookup(const JSObject* obj)
{
MOZ_ASSERT(map.initialized());
if (ObjectValueMap::Ptr p = map.lookup(const_cast<JSObject*>(obj)))
return &p->value().toObject();
return nullptr;
@ -705,6 +709,7 @@ bool
ObjectWeakMap::add(JSContext* cx, JSObject* obj, JSObject* target)
{
MOZ_ASSERT(obj && target);
MOZ_ASSERT(map.initialized());
MOZ_ASSERT(!map.has(obj));
if (!map.put(obj, ObjectValue(*target))) {
@ -720,18 +725,21 @@ ObjectWeakMap::add(JSContext* cx, JSObject* obj, JSObject* target)
void
ObjectWeakMap::clear()
{
MOZ_ASSERT(map.initialized());
map.clear();
}
void
ObjectWeakMap::trace(JSTracer* trc)
{
MOZ_ASSERT(map.initialized());
map.trace(trc);
}
size_t
ObjectWeakMap::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
{
MOZ_ASSERT(map.initialized());
return map.sizeOfExcludingThis(mallocSizeOf);
}
@ -739,6 +747,7 @@ ObjectWeakMap::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
void
ObjectWeakMap::checkAfterMovingGC()
{
MOZ_ASSERT(map.initialized());
for (ObjectValueMap::Range r = map.all(); !r.empty(); r.popFront()) {
CheckGCThingAfterMovingGC(r.front().key().get());
CheckGCThingAfterMovingGC(&r.front().value().toObject());

View File

@ -51,11 +51,11 @@ js::DestroyHelperThreadsState()
gHelperThreadState = nullptr;
}
void
bool
js::EnsureHelperThreadsInitialized()
{
MOZ_ASSERT(gHelperThreadState);
gHelperThreadState->ensureInitialized();
return gHelperThreadState->ensureInitialized();
}
static size_t
@ -453,7 +453,7 @@ static const uint32_t HELPER_STACK_SIZE = kDefaultHelperStackSize;
static const uint32_t HELPER_STACK_QUOTA = kDefaultHelperStackQuota;
#endif
void
bool
GlobalHelperThreadState::ensureInitialized()
{
MOZ_ASSERT(CanUseExtraThreads());
@ -462,11 +462,11 @@ GlobalHelperThreadState::ensureInitialized()
AutoLockHelperThreadState lock;
if (threads)
return;
return true;
threads = js_pod_calloc<HelperThread>(threadCount);
if (!threads)
CrashAtUnhandlableOOM("GlobalHelperThreadState::ensureInitialized");
return false;
for (size_t i = 0; i < threadCount; i++) {
HelperThread& helper = threads[i];
@ -474,11 +474,15 @@ GlobalHelperThreadState::ensureInitialized()
helper.thread = PR_CreateThread(PR_USER_THREAD,
HelperThread::ThreadMain, &helper,
PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, HELPER_STACK_SIZE);
if (!helper.thread || !helper.threadData->init())
CrashAtUnhandlableOOM("GlobalHelperThreadState::ensureInitialized");
if (!helper.thread || !helper.threadData->init()) {
finishThreads();
return false;
}
}
resetAsmJSFailureState();
return true;
}
GlobalHelperThreadState::GlobalHelperThreadState()
@ -510,12 +514,7 @@ GlobalHelperThreadState::GlobalHelperThreadState()
void
GlobalHelperThreadState::finish()
{
if (threads) {
MOZ_ASSERT(CanUseExtraThreads());
for (size_t i = 0; i < threadCount; i++)
threads[i].destroy();
js_free(threads);
}
finishThreads();
PR_DestroyCondVar(consumerWakeup);
PR_DestroyCondVar(producerWakeup);
@ -525,6 +524,19 @@ GlobalHelperThreadState::finish()
ionLazyLinkList_.clear();
}
void
GlobalHelperThreadState::finishThreads()
{
if (!threads)
return;
MOZ_ASSERT(CanUseExtraThreads());
for (size_t i = 0; i < threadCount; i++)
threads[i].destroy();
js_free(threads);
threads = nullptr;
}
void
GlobalHelperThreadState::lock()
{

View File

@ -103,8 +103,9 @@ class GlobalHelperThreadState
GlobalHelperThreadState();
void ensureInitialized();
bool ensureInitialized();
void finish();
void finishThreads();
void lock();
void unlock();
@ -351,7 +352,7 @@ void
DestroyHelperThreadsState();
// Initialize helper threads unless already initialized.
void
bool
EnsureHelperThreadsInitialized();
// This allows the JS shell to override GetCPUCount() when passed the

View File

@ -283,10 +283,10 @@ JSRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
if (!regexpStack.init())
return false;
js::TlsPerThreadData.set(&mainThread);
if (CanUseExtraThreads() && !EnsureHelperThreadsInitialized())
return false;
if (CanUseExtraThreads())
EnsureHelperThreadsInitialized();
js::TlsPerThreadData.set(&mainThread);
if (!gc.init(maxbytes, maxNurseryBytes))
return false;

View File

@ -1921,7 +1921,7 @@ DebugScopes::~DebugScopes()
bool
DebugScopes::init()
{
return liveScopes.init() && missingScopes.init();
return proxiedScopes.init() && missingScopes.init() && liveScopes.init();
}
void

View File

@ -38,6 +38,7 @@ class ObjectWeakMap
public:
explicit ObjectWeakMap(JSContext* cx);
bool init();
~ObjectWeakMap();
JSObject* lookup(const JSObject* obj);

View File

@ -27,6 +27,7 @@ NS_IMPL_ISUPPORTS(ZoomConstraintsClient, nsIDOMEventListener, nsIObserver)
static const nsLiteralString DOM_META_ADDED = NS_LITERAL_STRING("DOMMetaAdded");
static const nsLiteralString DOM_META_CHANGED = NS_LITERAL_STRING("DOMMetaChanged");
static const nsLiteralCString BEFORE_FIRST_PAINT = NS_LITERAL_CSTRING("before-first-paint");
static const nsLiteralCString NS_PREF_CHANGED = NS_LITERAL_CSTRING("nsPref:changed");
using namespace mozilla;
using namespace mozilla::layers;
@ -76,6 +77,8 @@ ZoomConstraintsClient::Destroy()
observerService->RemoveObserver(this, BEFORE_FIRST_PAINT.Data());
}
Preferences::RemoveObserver(this, "browser.ui.zoom.force-user-scalable");
if (mGuid) {
if (nsIWidget* widget = GetWidget(mPresShell)) {
ZCC_LOG("Sending null constraints in %p for { %u, %" PRIu64 " }\n",
@ -111,6 +114,8 @@ ZoomConstraintsClient::Init(nsIPresShell* aPresShell, nsIDocument* aDocument)
if (observerService) {
observerService->AddObserver(this, BEFORE_FIRST_PAINT.Data(), false);
}
Preferences::AddStrongObserver(this, "browser.ui.zoom.force-user-scalable");
}
NS_IMETHODIMP
@ -136,6 +141,13 @@ ZoomConstraintsClient::Observe(nsISupports* aSubject, const char* aTopic, const
if (SameCOMIdentity(aSubject, mDocument) && BEFORE_FIRST_PAINT.EqualsASCII(aTopic)) {
ZCC_LOG("Got a before-first-paint event in %p\n", this);
RefreshZoomConstraints();
} else if (NS_PREF_CHANGED.EqualsASCII(aTopic)) {
ZCC_LOG("Got a pref-change event in %p\n", this);
// We need to run this later because all the pref change listeners need
// to execute before we can be guaranteed that gfxPrefs::ForceUserScalable()
// returns the updated value.
NS_DispatchToMainThread(NS_NewRunnableMethod(
this, &ZoomConstraintsClient::RefreshZoomConstraints));
}
return NS_OK;
}
@ -152,9 +164,14 @@ ComputeZoomConstraintsFromViewportInfo(const nsViewportInfo& aViewportInfo)
{
mozilla::layers::ZoomConstraints constraints;
constraints.mAllowZoom = aViewportInfo.IsZoomAllowed() && gfxPrefs::APZAllowZooming();
constraints.mAllowDoubleTapZoom = aViewportInfo.IsDoubleTapZoomAllowed() && gfxPrefs::APZAllowZooming();
constraints.mMinZoom.scale = aViewportInfo.GetMinZoom().scale;
constraints.mMaxZoom.scale = aViewportInfo.GetMaxZoom().scale;
constraints.mAllowDoubleTapZoom = constraints.mAllowZoom;
if (constraints.mAllowZoom) {
constraints.mMinZoom.scale = aViewportInfo.GetMinZoom().scale;
constraints.mMaxZoom.scale = aViewportInfo.GetMaxZoom().scale;
} else {
constraints.mMinZoom.scale = aViewportInfo.GetDefaultZoom().scale;
constraints.mMaxZoom.scale = aViewportInfo.GetDefaultZoom().scale;
}
return constraints;
}

View File

@ -180,32 +180,17 @@ nsresult
nsStyleSheetService::LoadAndRegisterSheetInternal(nsIURI *aSheetURI,
uint32_t aSheetType)
{
NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
aSheetType == USER_SHEET ||
aSheetType == AUTHOR_SHEET);
NS_ENSURE_ARG_POINTER(aSheetURI);
css::SheetParsingMode parsingMode;
switch (aSheetType) {
case AGENT_SHEET:
parsingMode = css::eAgentSheetFeatures;
break;
case USER_SHEET:
parsingMode = css::eUserSheetFeatures;
break;
case AUTHOR_SHEET:
parsingMode = css::eAuthorSheetFeatures;
break;
default:
NS_WARNING("invalid sheet type argument");
return NS_ERROR_INVALID_ARG;
}
nsRefPtr<css::Loader> loader = new css::Loader();
nsRefPtr<CSSStyleSheet> sheet;
nsresult rv = loader->LoadSheetSync(aSheetURI, parsingMode, true,
getter_AddRefs(sheet));
// Allow UA sheets, but not user sheets, to use unsafe rules
nsresult rv = loader->LoadSheetSync(aSheetURI, aSheetType == AGENT_SHEET,
true, getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv);
if (!mSheets[aSheetType].AppendObject(sheet)) {
@ -234,32 +219,18 @@ NS_IMETHODIMP
nsStyleSheetService::PreloadSheet(nsIURI *aSheetURI, uint32_t aSheetType,
nsIDOMStyleSheet **aSheet)
{
NS_PRECONDITION(aSheet, "Null out param");
NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
aSheetType == USER_SHEET ||
aSheetType == AUTHOR_SHEET);
NS_ENSURE_ARG_POINTER(aSheetURI);
css::SheetParsingMode parsingMode;
switch (aSheetType) {
case AGENT_SHEET:
parsingMode = css::eAgentSheetFeatures;
break;
case USER_SHEET:
parsingMode = css::eUserSheetFeatures;
break;
case AUTHOR_SHEET:
parsingMode = css::eAuthorSheetFeatures;
break;
default:
NS_WARNING("invalid sheet type argument");
return NS_ERROR_INVALID_ARG;
}
NS_PRECONDITION(aSheet, "Null out param");
nsRefPtr<css::Loader> loader = new css::Loader();
// Allow UA sheets, but not user sheets, to use unsafe rules
nsRefPtr<CSSStyleSheet> sheet;
nsresult rv = loader->LoadSheetSync(aSheetURI, parsingMode, true,
getter_AddRefs(sheet));
nsresult rv = loader->LoadSheetSync(aSheetURI, aSheetType == AGENT_SHEET,
true, getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv);
sheet.forget(aSheet);
return NS_OK;

View File

@ -48,6 +48,7 @@
== scoped-style-media.html scoped-style-media-ref.html
== scoped-style-namespace.html scoped-style-namespace-ref.html
== scoped-style-charset.html scoped-style-charset-ref.html
== scoped-style-document.html scoped-style-document-ref.html
HTTP(..) == scoped-style-font-face.html scoped-style-font-face-ref.html
== scoped-style-keyframes.html scoped-style-keyframes-ref.html
== scoped-style-supports.html scoped-style-supports-ref.html

View File

@ -0,0 +1,6 @@
<!DOCTYPE html>
<body>
<p>First</p>
<p style="color: blue">Second</p>
<p>Third</p>
</body>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<body>
<p>First</p>
<p>
<style scoped>
@-moz-document regexp("^.*scoped-style-document\\.html$") {
p { color: blue }
}
</style>
Second
</p>
<p>Third</p>
</body>

View File

@ -0,0 +1,21 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: A nested @supports rule with valid syntax and a passing condition must apply rules inside it</title>
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au" />
<link rel="help" href="http://www.w3.org/TR/css3-conditional/#at-supports" />
<link rel="help" href="http://www.w3.org/TR/css3-conditional/#at-document" />
<meta name="flags" content="" />
<meta name="assert" content="An outer @document rule with an inner @supports rule must apply the rules inside the @supports only if both the @supports and @document conditions pass."/>
<link rel="match" href="support/pass.xht" />
<style type="text/css"><![CDATA[
@-moz-document url-prefix("") {
@supports (color: green) {
html { background-color: green }
}
}
]]></style>
</head>
<body>
</body>
</html>

View File

@ -0,0 +1,20 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: A nested @supports rule with valid syntax and a passing condition must apply rules inside it</title>
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au" />
<link rel="help" href="http://www.w3.org/TR/css3-conditional/#at-supports" />
<meta name="flags" content="" />
<meta name="assert" content="An inner @document rule with an outer @supports rule must apply the rules inside the @document only if both the @supports and @document conditions pass."/>
<link rel="match" href="support/pass.xht" />
<style type="text/css"><![CDATA[
@supports (color: green) {
@-moz-document url-prefix("") {
html { background-color: green }
}
}
]]></style>
</head>
<body>
</body>
</html>

View File

@ -24,6 +24,8 @@
== css-supports-024.xht support/pass.xht
== css-supports-025.xht support/pass.xht
== css-supports-026.xht support/pass.xht
== css-supports-027.xht support/pass.xht
== css-supports-028.xht support/pass.xht
== css-supports-029.xht support/pass.xht
== css-supports-030.xht support/pass.xht
== css-supports-031.xht support/pass.xht

View File

@ -2309,14 +2309,11 @@ CSSStyleSheet::ParseSheet(const nsAString& aInput)
mInner->mNameSpaceMap = nullptr;
// allow unsafe rules if the style sheet's principal is the system principal
css::SheetParsingMode parsingMode =
nsContentUtils::IsSystemPrincipal(mInner->mPrincipal)
? css::eAgentSheetFeatures
: css::eAuthorSheetFeatures;
bool allowUnsafeRules = nsContentUtils::IsSystemPrincipal(mInner->mPrincipal);
nsCSSParser parser(loader, this);
nsresult rv = parser.ParseSheet(aInput, mInner->mSheetURI, mInner->mBaseURI,
mInner->mPrincipal, 1, parsingMode);
mInner->mPrincipal, 1, allowUnsafeRules);
DidDirty(); // we are always 'dirty' here since we always remove rules first
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -104,12 +104,6 @@ namespace css {
* Data needed to properly load a stylesheet *
*********************************************/
static_assert(eAuthorSheetFeatures == 0 &&
eUserSheetFeatures == 1 &&
eAgentSheetFeatures == 2,
"sheet parsing mode constants won't fit "
"in SheetLoadData::mParsingMode");
class SheetLoadData final : public nsIRunnable,
public nsIUnicharStreamLoaderObserver,
public nsIThreadObserver
@ -143,7 +137,7 @@ public:
nsIURI* aURI,
CSSStyleSheet* aSheet,
bool aSyncLoad,
SheetParsingMode aParsingMode,
bool aAllowUnsafeRules,
bool aUseSystemPrincipal,
const nsCString& aCharset,
nsICSSLoaderObserver* aObserver,
@ -221,12 +215,9 @@ public:
// created.
bool mWasAlternate : 1;
// mParsingMode controls access to nonstandard style constructs that
// are not safe for use on the public Web but necessary in UA sheets
// and/or useful in user sheets. The only values stored in this
// field are 0, 1, and 2; three bits are allocated to avoid issues
// should the enum type be signed.
SheetParsingMode mParsingMode : 3;
// mAllowUnsafeRules is true if we should allow unsafe rules to be parsed
// in the loaded sheet.
bool mAllowUnsafeRules : 1;
// mUseSystemPrincipal is true if the system principal should be used for
// this sheet, no matter what the channel principal is. Only true for sync
@ -342,7 +333,7 @@ SheetLoadData::SheetLoadData(Loader* aLoader,
mIsCancelled(false),
mMustNotify(false),
mWasAlternate(aIsAlternate),
mParsingMode(eAuthorSheetFeatures),
mAllowUnsafeRules(false),
mUseSystemPrincipal(false),
mSheetAlreadyComplete(false),
mOwningElement(aOwningElement),
@ -373,7 +364,7 @@ SheetLoadData::SheetLoadData(Loader* aLoader,
mIsCancelled(false),
mMustNotify(false),
mWasAlternate(false),
mParsingMode(eAuthorSheetFeatures),
mAllowUnsafeRules(false),
mUseSystemPrincipal(false),
mSheetAlreadyComplete(false),
mOwningElement(nullptr),
@ -385,7 +376,7 @@ SheetLoadData::SheetLoadData(Loader* aLoader,
if (mParentData) {
mSyncLoad = mParentData->mSyncLoad;
mIsNonDocumentSheet = mParentData->mIsNonDocumentSheet;
mParsingMode = mParentData->mParsingMode;
mAllowUnsafeRules = mParentData->mAllowUnsafeRules;
mUseSystemPrincipal = mParentData->mUseSystemPrincipal;
++(mParentData->mPendingChildren);
}
@ -398,7 +389,7 @@ SheetLoadData::SheetLoadData(Loader* aLoader,
nsIURI* aURI,
CSSStyleSheet* aSheet,
bool aSyncLoad,
SheetParsingMode aParsingMode,
bool aAllowUnsafeRules,
bool aUseSystemPrincipal,
const nsCString& aCharset,
nsICSSLoaderObserver* aObserver,
@ -416,7 +407,7 @@ SheetLoadData::SheetLoadData(Loader* aLoader,
mIsCancelled(false),
mMustNotify(false),
mWasAlternate(false),
mParsingMode(aParsingMode),
mAllowUnsafeRules(aAllowUnsafeRules),
mUseSystemPrincipal(aUseSystemPrincipal),
mSheetAlreadyComplete(false),
mOwningElement(nullptr),
@ -426,10 +417,6 @@ SheetLoadData::SheetLoadData(Loader* aLoader,
mCharsetHint(aCharset)
{
NS_PRECONDITION(mLoader, "Must have a loader!");
NS_PRECONDITION(aParsingMode == eAuthorSheetFeatures ||
aParsingMode == eUserSheetFeatures ||
aParsingMode == eAgentSheetFeatures,
"Unrecognized sheet parsing mode");
NS_POSTCONDITION(!mUseSystemPrincipal || mSyncLoad,
"Shouldn't use system principal for async loads");
@ -1758,7 +1745,7 @@ Loader::ParseSheet(const nsAString& aInput,
nsresult rv = parser.ParseSheet(aInput, sheetURI, baseURI,
aLoadData->mSheet->Principal(),
aLoadData->mLineNumber,
aLoadData->mParsingMode);
aLoadData->mAllowUnsafeRules);
mParsingDatas.RemoveElementAt(mParsingDatas.Length() - 1);
if (NS_FAILED(rv)) {
@ -2266,13 +2253,12 @@ Loader::LoadChildSheet(CSSStyleSheet* aParentSheet,
}
nsresult
Loader::LoadSheetSync(nsIURI* aURL,
SheetParsingMode aParsingMode,
Loader::LoadSheetSync(nsIURI* aURL, bool aAllowUnsafeRules,
bool aUseSystemPrincipal,
CSSStyleSheet** aSheet)
{
LOG(("css::Loader::LoadSheetSync"));
return InternalLoadNonDocumentSheet(aURL, aParsingMode,
return InternalLoadNonDocumentSheet(aURL, aAllowUnsafeRules,
aUseSystemPrincipal, nullptr,
EmptyCString(), aSheet, nullptr);
}
@ -2286,7 +2272,7 @@ Loader::LoadSheet(nsIURI* aURL,
{
LOG(("css::Loader::LoadSheet(aURL, aObserver, aSheet) api call"));
NS_PRECONDITION(aSheet, "aSheet is null");
return InternalLoadNonDocumentSheet(aURL, eAuthorSheetFeatures, false,
return InternalLoadNonDocumentSheet(aURL, false, false,
aOriginPrincipal, aCharset,
aSheet, aObserver);
}
@ -2301,7 +2287,7 @@ Loader::LoadSheet(nsIURI* aURL,
const nsAString& aIntegrity)
{
LOG(("css::Loader::LoadSheet(aURL, aObserver) api call"));
return InternalLoadNonDocumentSheet(aURL, eAuthorSheetFeatures, false,
return InternalLoadNonDocumentSheet(aURL, false, false,
aOriginPrincipal, aCharset,
nullptr, aObserver, aCORSMode,
aReferrerPolicy, aIntegrity);
@ -2309,7 +2295,7 @@ Loader::LoadSheet(nsIURI* aURL,
nsresult
Loader::InternalLoadNonDocumentSheet(nsIURI* aURL,
SheetParsingMode aParsingMode,
bool aAllowUnsafeRules,
bool aUseSystemPrincipal,
nsIPrincipal* aOriginPrincipal,
const nsCString& aCharset,
@ -2366,7 +2352,7 @@ Loader::InternalLoadNonDocumentSheet(nsIURI* aURL,
}
SheetLoadData* data =
new SheetLoadData(this, aURL, sheet, syncLoad, aParsingMode,
new SheetLoadData(this, aURL, sheet, syncLoad, aAllowUnsafeRules,
aUseSystemPrincipal, aCharset, aObserver,
aOriginPrincipal, mDocument);

View File

@ -142,33 +142,6 @@ enum StyleSheetState {
eSheetComplete
};
/**
* Enum defining the mode in which a sheet is to be parsed. This is
* usually, but not always, the same as the cascade level at which the
* sheet will apply (see nsStyleSet.h). Most of the Loader APIs only
* support loading of author sheets.
*
* Author sheets are the normal case: styles embedded in or linked
* from HTML pages. They are also the most restricted.
*
* User sheets can do anything author sheets can do, and also get
* access to a few CSS extensions that are not yet suitable for
* exposure on the public Web, but are very useful for expressing
* user style overrides, such as @-moz-document rules.
*
* Agent sheets have access to all author- and user-sheet features
* plus more extensions that are necessary for internal use but,
* again, not yet suitable for exposure on the public Web. Some of
* these are outright unsafe to expose; in particular, incorrect
* styling of anonymous box pseudo-elements can violate layout
* invariants.
*/
enum SheetParsingMode {
eAuthorSheetFeatures = 0,
eUserSheetFeatures,
eAgentSheetFeatures
};
class Loader final {
typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
@ -283,8 +256,13 @@ public:
* method can be used to load sheets not associated with a document.
*
* @param aURL the URL of the sheet to load
* @param aParsingMode the mode in which to parse the sheet
* (see comments at enum SheetParsingMode, above).
* @param aEnableUnsafeRules whether unsafe rules are enabled for this
* sheet load
* Unsafe rules are rules that can violate key Gecko invariants if misused.
* In particular, most anonymous box pseudoelements must be very carefully
* styled or we will have severe problems. Therefore unsafe rules should
* never be enabled for stylesheets controlled by untrusted sites; preferably
* unsafe rules should only be enabled for agent sheets.
* @param aUseSystemPrincipal if true, give the resulting sheet the system
* principal no matter where it's being loaded from.
* @param [out] aSheet the loaded, complete sheet.
@ -297,25 +275,22 @@ public:
* whether the data could be parsed as CSS and doesn't indicate anything
* about the status of child sheets of the returned sheet.
*/
nsresult LoadSheetSync(nsIURI* aURL,
SheetParsingMode aParsingMode,
nsresult LoadSheetSync(nsIURI* aURL, bool aEnableUnsafeRules,
bool aUseSystemPrincipal,
CSSStyleSheet** aSheet);
/**
* As above, but defaults aParsingMode to eAuthorSheetFeatures and
* aUseSystemPrincipal to false.
* As above, but aUseSystemPrincipal and aEnableUnsafeRules are assumed false.
*/
nsresult LoadSheetSync(nsIURI* aURL, CSSStyleSheet** aSheet) {
return LoadSheetSync(aURL, eAuthorSheetFeatures, false, aSheet);
return LoadSheetSync(aURL, false, false, aSheet);
}
/**
* Asynchronously load the stylesheet at aURL. If a successful result is
* returned, aObserver is guaranteed to be notified asynchronously once the
* sheet is loaded and marked complete. This method can be used to load
* sheets not associated with a document. This method cannot be used to
* load user or agent sheets.
* sheets not associated with a document.
*
* @param aURL the URL of the sheet to load
* @param aOriginPrincipal the principal to use for security checks. This
@ -471,7 +446,7 @@ private:
ImportRule* aParentRule);
nsresult InternalLoadNonDocumentSheet(nsIURI* aURL,
SheetParsingMode aParsingMode,
bool aAllowUnsafeRules,
bool aUseSystemPrincipal,
nsIPrincipal* aOriginPrincipal,
const nsCString& aCharset,

View File

@ -6,6 +6,7 @@
@import # { }
@namespace # { }
@media # { }
@-moz-document # { }
@font-face # { }
@page # { }
@-non-mozilla # { }

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="data:text/css,@-moz-document domain(example.com) {}';">
<link rel="stylesheet" href="data:text/css,@-moz-document domain(example.com) {}';">
<script>
// Force a unique inner for the second linked sheet
document.styleSheets[1].cssRules[0];
</script>
</head>
</html>

View File

@ -49,7 +49,9 @@ load 478321-1.xhtml
load 512851-1.xhtml
load 539613-1.xhtml
load 588627-1.html
skip load long-url-list-stack-overflow.html # skipped due to being slow (bug 477490)
load 495269-1.html
load 495269-2.html
load 498036-1.html
load 509155-1.html
load 509156-1.html

View File

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<style id="s"></style>
<script type="text/javascript">
// Duplicates the string 2^n times
function exp(s, n)
{
for (var i = 0; i < n; ++i)
s += s;
return s;
}
var stylesheet = "@-moz-document url(http://www.w3.org/)" + exp(", url-prefix(file:///)", 20) + " { }";
document.getElementById("s").textContent = stylesheet;
</script>
</head>
<body>
<div></div>
</body>
</html>

View File

@ -105,12 +105,6 @@ struct CSSParserInputState {
bool mHavePushBack;
};
static_assert(eAuthorSheetFeatures == 0 &&
eUserSheetFeatures == 1 &&
eAgentSheetFeatures == 2,
"sheet parsing mode constants won't fit "
"in CSSParserImpl::mParsingMode");
// Your basic top-down recursive descent style parser
// The exposed methods and members of this class are precisely those
// needed by nsCSSParser, far below.
@ -135,7 +129,7 @@ public:
nsIURI* aBaseURI,
nsIPrincipal* aSheetPrincipal,
uint32_t aLineNumber,
SheetParsingMode aParsingMode);
bool aAllowUnsafeRules);
nsresult ParseStyleAttribute(const nsAString& aAttributeValue,
nsIURI* aDocURL,
@ -319,20 +313,12 @@ public:
uint32_t aLineNumber,
uint32_t aLineOffset);
bool AgentRulesEnabled() const {
return mParsingMode == eAgentSheetFeatures;
}
bool UserRulesEnabled() const {
return mParsingMode == eAgentSheetFeatures ||
mParsingMode == eUserSheetFeatures;
}
nsCSSProps::EnabledState PropertyEnabledState() const {
static_assert(nsCSSProps::eEnabledForAllContent == 0,
"nsCSSProps::eEnabledForAllContent should be zero for "
"this bitfield to work");
nsCSSProps::EnabledState enabledState = nsCSSProps::eEnabledForAllContent;
if (AgentRulesEnabled()) {
if (mUnsafeRulesEnabled) {
enabledState |= nsCSSProps::eEnabledInUASheets;
}
if (mIsChromeOrCertifiedApp) {
@ -1218,12 +1204,8 @@ protected:
// True when the unitless length quirk applies.
bool mUnitlessLengthQuirk : 1;
// Controls access to nonstandard style constructs that are not safe
// for use on the public Web but necessary in UA sheets and/or
// useful in user sheets. The only values stored in this field are
// 0, 1, and 2; three bits are allocated to avoid issues should the
// enum type be signed.
SheetParsingMode mParsingMode : 3;
// True if unsafe rules should be allowed
bool mUnsafeRulesEnabled : 1;
// True if we are in parsing rules for Chrome or Certified App content,
// in which case CSS properties with the
@ -1352,7 +1334,7 @@ CSSParserImpl::CSSParserImpl()
mNavQuirkMode(false),
mHashlessColorQuirk(false),
mUnitlessLengthQuirk(false),
mParsingMode(eAuthorSheetFeatures),
mUnsafeRulesEnabled(false),
mIsChromeOrCertifiedApp(false),
mViewportUnitsEnabled(true),
mHTMLMediaMode(false),
@ -1459,7 +1441,7 @@ CSSParserImpl::ParseSheet(const nsAString& aInput,
nsIURI* aBaseURI,
nsIPrincipal* aSheetPrincipal,
uint32_t aLineNumber,
SheetParsingMode aParsingMode)
bool aAllowUnsafeRules)
{
NS_PRECONDITION(aSheetPrincipal, "Must have principal here!");
NS_PRECONDITION(aBaseURI, "need base URI");
@ -1504,7 +1486,7 @@ CSSParserImpl::ParseSheet(const nsAString& aInput,
mSection = eCSSSection_Charset; // sheet is empty, any rules are fair
}
mParsingMode = aParsingMode;
mUnsafeRulesEnabled = aAllowUnsafeRules;
mIsChromeOrCertifiedApp =
dom::IsChromeURI(aSheetURI) ||
aSheetPrincipal->GetAppStatus() == nsIPrincipal::APP_STATUS_CERTIFIED;
@ -1530,7 +1512,7 @@ CSSParserImpl::ParseSheet(const nsAString& aInput,
}
ReleaseScanner();
mParsingMode = eAuthorSheetFeatures;
mUnsafeRulesEnabled = false;
mIsChromeOrCertifiedApp = false;
// XXX check for low level errors
@ -1708,7 +1690,7 @@ CSSParserImpl::ParseProperty(const nsCSSProperty aPropID,
// Check for unknown or preffed off properties
if (eCSSProperty_UNKNOWN == aPropID ||
!(nsCSSProps::IsEnabled(aPropID) ||
(AgentRulesEnabled() &&
(mUnsafeRulesEnabled &&
nsCSSProps::PropHasFlags(aPropID,
CSS_PROPERTY_ALWAYS_ENABLED_IN_UA_SHEETS)))) {
NS_ConvertASCIItoUTF16 propName(nsCSSProps::GetStringValue(aPropID));
@ -2999,14 +2981,8 @@ CSSParserImpl::ParseAtRule(RuleAppendFunc aAppendFunc,
newSection = eCSSSection_General;
} else if (mToken.mIdent.LowerCaseEqualsLiteral("-moz-document")) {
if (UserRulesEnabled()) {
parseFunc = &CSSParserImpl::ParseMozDocumentRule;
newSection = eCSSSection_General;
} else {
REPORT_UNEXPECTED_TOKEN(PEMozDocumentRuleNotAllowed);
OUTPUT_ERROR();
return SkipAtRule(aInAtRule);
}
parseFunc = &CSSParserImpl::ParseMozDocumentRule;
newSection = eCSSSection_General;
} else if (mToken.mIdent.LowerCaseEqualsLiteral("font-face")) {
parseFunc = &CSSParserImpl::ParseFontFaceRule;
@ -5614,7 +5590,7 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask,
bool pseudoClassIsUserAction =
nsCSSPseudoClasses::IsUserActionPseudoClass(pseudoClassType);
if (!AgentRulesEnabled() &&
if (!mUnsafeRulesEnabled &&
((pseudoElementType < nsCSSPseudoElements::ePseudo_PseudoElementCount &&
nsCSSPseudoElements::PseudoElementIsUASheetOnly(pseudoElementType)) ||
(pseudoClassType != nsCSSPseudoClasses::ePseudoClass_NotPseudoClass &&
@ -5650,10 +5626,10 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask,
bool isPseudoElement =
(pseudoElementType < nsCSSPseudoElements::ePseudo_PseudoElementCount);
// anonymous boxes are only allowed if they're the tree boxes or we have
// enabled agent rules
// enabled unsafe rules
bool isAnonBox = isTreePseudo ||
(pseudoElementType == nsCSSPseudoElements::ePseudo_AnonBox &&
AgentRulesEnabled());
mUnsafeRulesEnabled);
bool isPseudoClass =
(pseudoClassType != nsCSSPseudoClasses::ePseudoClass_NotPseudoClass);
@ -10485,11 +10461,11 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue,
return false;
}
// We only allow 'script-level' when agent rules are enabled, because
// We only allow 'script-level' when unsafe rules are enabled, because
// otherwise it could interfere with rulenode optimizations if used in
// a non-MathML-enabled document. We also only allow math-display when
// agent rules are enabled.
if (!AgentRulesEnabled() &&
// unsafe rules are enabled.
if (!mUnsafeRulesEnabled &&
(aPropID == eCSSProperty_script_level ||
aPropID == eCSSProperty_math_display))
return false;
@ -15805,11 +15781,11 @@ nsCSSParser::ParseSheet(const nsAString& aInput,
nsIURI* aBaseURI,
nsIPrincipal* aSheetPrincipal,
uint32_t aLineNumber,
SheetParsingMode aParsingMode)
bool aAllowUnsafeRules)
{
return static_cast<CSSParserImpl*>(mImpl)->
ParseSheet(aInput, aSheetURI, aBaseURI, aSheetPrincipal, aLineNumber,
aParsingMode);
aAllowUnsafeRules);
}
nsresult

View File

@ -9,7 +9,6 @@
#define nsCSSParser_h___
#include "mozilla/Attributes.h"
#include "mozilla/css/Loader.h"
#include "nsCSSProperty.h"
#include "nsCSSScanner.h"
@ -33,6 +32,7 @@ class CSSVariableValues;
namespace css {
class Rule;
class Declaration;
class Loader;
class StyleRule;
} // namespace css
} // namespace mozilla
@ -77,14 +77,15 @@ public:
* @param aSheetPrincipal the principal of the stylesheet. This must match
* the principal of the sheet passed to SetStyleSheet.
* @param aLineNumber the line number of the first line of the sheet.
* @param aParsingMode see SheetParsingMode in css/Loader.h
* @param aAllowUnsafeRules see aEnableUnsafeRules in
* mozilla::css::Loader::LoadSheetSync
*/
nsresult ParseSheet(const nsAString& aInput,
nsIURI* aSheetURL,
nsIURI* aBaseURI,
nsIPrincipal* aSheetPrincipal,
uint32_t aLineNumber,
mozilla::css::SheetParsingMode aParsingMode);
bool aAllowUnsafeRules);
// Parse HTML style attribute or its equivalent in other markup
// languages. aBaseURL is the base url to use for relative links in

View File

@ -19,7 +19,6 @@
#include "nsPrintfCString.h"
using namespace mozilla;
using namespace mozilla::css;
static bool sNumberControlEnabled;
@ -60,7 +59,7 @@ nsLayoutStylesheetCache::ScrollbarsSheet()
if (!gStyleCache->mScrollbarsSheet) {
// Scrollbars don't need access to unsafe rules
LoadSheetURL("chrome://global/skin/scrollbars.css",
gStyleCache->mScrollbarsSheet, eAuthorSheetFeatures);
gStyleCache->mScrollbarsSheet, false);
}
return gStyleCache->mScrollbarsSheet;
@ -74,7 +73,7 @@ nsLayoutStylesheetCache::FormsSheet()
if (!gStyleCache->mFormsSheet) {
// forms.css needs access to unsafe rules
LoadSheetURL("resource://gre-resources/forms.css",
gStyleCache->mFormsSheet, eAgentSheetFeatures);
gStyleCache->mFormsSheet, true);
}
return gStyleCache->mFormsSheet;
@ -91,7 +90,7 @@ nsLayoutStylesheetCache::NumberControlSheet()
if (!gStyleCache->mNumberControlSheet) {
LoadSheetURL("resource://gre-resources/number-control.css",
gStyleCache->mNumberControlSheet, eAgentSheetFeatures);
gStyleCache->mNumberControlSheet, true);
}
return gStyleCache->mNumberControlSheet;
@ -118,7 +117,7 @@ nsLayoutStylesheetCache::UASheet()
if (!gStyleCache->mUASheet) {
LoadSheetURL("resource://gre-resources/ua.css",
gStyleCache->mUASheet, eAgentSheetFeatures);
gStyleCache->mUASheet, true);
}
return gStyleCache->mUASheet;
@ -131,7 +130,7 @@ nsLayoutStylesheetCache::HTMLSheet()
if (!gStyleCache->mHTMLSheet) {
LoadSheetURL("resource://gre-resources/html.css",
gStyleCache->mHTMLSheet, eAgentSheetFeatures);
gStyleCache->mHTMLSheet, true);
}
return gStyleCache->mHTMLSheet;
@ -179,7 +178,7 @@ nsLayoutStylesheetCache::MathMLSheet()
if (!gStyleCache->mMathMLSheet) {
LoadSheetURL("resource://gre-resources/mathml.css",
gStyleCache->mMathMLSheet, eAgentSheetFeatures);
gStyleCache->mMathMLSheet, true);
}
return gStyleCache->mMathMLSheet;
@ -200,7 +199,7 @@ nsLayoutStylesheetCache::NoScriptSheet()
if (!gStyleCache->mNoScriptSheet) {
LoadSheetURL("resource://gre-resources/noscript.css",
gStyleCache->mNoScriptSheet, eAgentSheetFeatures);
gStyleCache->mNoScriptSheet, true);
}
return gStyleCache->mNoScriptSheet;
@ -213,7 +212,7 @@ nsLayoutStylesheetCache::NoFramesSheet()
if (!gStyleCache->mNoFramesSheet) {
LoadSheetURL("resource://gre-resources/noframes.css",
gStyleCache->mNoFramesSheet, eAgentSheetFeatures);
gStyleCache->mNoFramesSheet, true);
}
return gStyleCache->mNoFramesSheet;
@ -252,7 +251,7 @@ nsLayoutStylesheetCache::ContentEditableSheet()
if (!gStyleCache->mContentEditableSheet) {
LoadSheetURL("resource://gre/res/contenteditable.css",
gStyleCache->mContentEditableSheet, eAgentSheetFeatures);
gStyleCache->mContentEditableSheet, true);
}
return gStyleCache->mContentEditableSheet;
@ -265,7 +264,7 @@ nsLayoutStylesheetCache::DesignModeSheet()
if (!gStyleCache->mDesignModeSheet) {
LoadSheetURL("resource://gre/res/designmode.css",
gStyleCache->mDesignModeSheet, eAgentSheetFeatures);
gStyleCache->mDesignModeSheet, true);
}
return gStyleCache->mDesignModeSheet;
@ -344,17 +343,17 @@ nsLayoutStylesheetCache::nsLayoutStylesheetCache()
// And make sure that we load our UA sheets. No need to do this
// per-profile, since they're profile-invariant.
LoadSheetURL("resource://gre-resources/counterstyles.css",
mCounterStylesSheet, eAgentSheetFeatures);
mCounterStylesSheet, true);
LoadSheetURL("resource://gre-resources/full-screen-override.css",
mFullScreenOverrideSheet, eAgentSheetFeatures);
mFullScreenOverrideSheet, true);
LoadSheetURL("chrome://global/content/minimal-xul.css",
mMinimalXULSheet, eAgentSheetFeatures);
mMinimalXULSheet, true);
LoadSheetURL("resource://gre-resources/quirk.css",
mQuirkSheet, eAgentSheetFeatures);
mQuirkSheet, true);
LoadSheetURL("resource://gre/res/svg.css",
mSVGSheet, eAgentSheetFeatures);
mSVGSheet, true);
LoadSheetURL("chrome://global/content/xul.css",
mXULSheet, eAgentSheetFeatures);
mXULSheet, true);
// The remaining sheets are created on-demand do to their use being rarer
// (which helps save memory for Firefox OS apps) or because they need to
@ -421,27 +420,25 @@ nsLayoutStylesheetCache::InitFromProfile()
contentFile->Append(NS_LITERAL_STRING("userContent.css"));
chromeFile->Append(NS_LITERAL_STRING("userChrome.css"));
LoadSheetFile(contentFile, mUserContentSheet, eUserSheetFeatures);
LoadSheetFile(chromeFile, mUserChromeSheet, eUserSheetFeatures);
LoadSheetFile(contentFile, mUserContentSheet);
LoadSheetFile(chromeFile, mUserChromeSheet);
}
/* static */ void
nsLayoutStylesheetCache::LoadSheetURL(const char* aURL,
nsRefPtr<CSSStyleSheet>& aSheet,
SheetParsingMode aParsingMode)
bool aEnableUnsafeRules)
{
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), aURL);
LoadSheet(uri, aSheet, aParsingMode);
LoadSheet(uri, aSheet, aEnableUnsafeRules);
if (!aSheet) {
NS_ERROR(nsPrintfCString("Could not load %s", aURL).get());
}
}
void
nsLayoutStylesheetCache::LoadSheetFile(nsIFile* aFile,
nsRefPtr<CSSStyleSheet>& aSheet,
SheetParsingMode aParsingMode)
nsLayoutStylesheetCache::LoadSheetFile(nsIFile* aFile, nsRefPtr<CSSStyleSheet>& aSheet)
{
bool exists = false;
aFile->Exists(&exists);
@ -451,7 +448,7 @@ nsLayoutStylesheetCache::LoadSheetFile(nsIFile* aFile,
nsCOMPtr<nsIURI> uri;
NS_NewFileURI(getter_AddRefs(uri), aFile);
LoadSheet(uri, aSheet, aParsingMode);
LoadSheet(uri, aSheet, false);
}
static void
@ -468,7 +465,7 @@ ErrorLoadingBuiltinSheet(nsIURI* aURI, const char* aMsg)
void
nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI,
nsRefPtr<CSSStyleSheet>& aSheet,
SheetParsingMode aParsingMode)
bool aEnableUnsafeRules)
{
if (!aURI) {
ErrorLoadingBuiltinSheet(aURI, "null URI");
@ -485,7 +482,7 @@ nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI,
}
nsresult rv = gCSSLoader->LoadSheetSync(aURI, aParsingMode, true,
nsresult rv = gCSSLoader->LoadSheetSync(aURI, aEnableUnsafeRules, true,
getter_AddRefs(aSheet));
if (NS_FAILED(rv)) {
ErrorLoadingBuiltinSheet(aURI,

View File

@ -13,13 +13,15 @@
#include "mozilla/Attributes.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/css/Loader.h"
class nsIFile;
class nsIURI;
namespace mozilla {
class CSSStyleSheet;
namespace css {
class Loader;
} // namespace css
} // namespace mozilla
class nsLayoutStylesheetCache final
@ -68,12 +70,11 @@ private:
void InitMemoryReporter();
static void LoadSheetURL(const char* aURL,
nsRefPtr<mozilla::CSSStyleSheet>& aSheet,
mozilla::css::SheetParsingMode aParsingMode);
bool aEnableUnsafeRules);
static void LoadSheetFile(nsIFile* aFile,
nsRefPtr<mozilla::CSSStyleSheet>& aSheet,
mozilla::css::SheetParsingMode aParsingMode);
nsRefPtr<mozilla::CSSStyleSheet>& aSheet);
static void LoadSheet(nsIURI* aURI, nsRefPtr<mozilla::CSSStyleSheet>& aSheet,
mozilla::css::SheetParsingMode aParsingMode);
bool aEnableUnsafeRules);
static void InvalidateSheet(nsRefPtr<mozilla::CSSStyleSheet>& aSheet);
static void DependentPrefChanged(const char* aPref, void* aData);
void BuildPreferenceSheet(nsRefPtr<mozilla::CSSStyleSheet>& aSheet,

View File

@ -8,9 +8,6 @@ support-files =
hover_helper.html
match.png
mismatch.png
moz_document_condition_text.css
moz_document_nesting.css
moz_document_serialization.css
[test_addSheet.html]
[test_additional_sheets.html]
@ -21,9 +18,4 @@ support-files =
[test_bug535806.xul]
[test_hover.html]
skip-if = buildapp == 'mulet'
[test_moz_document_condition_text.html]
[test_moz_document_crashes.html]
[test_moz_document_matching.html]
[test_moz_document_nesting.html]
[test_moz_document_serialization.html]
[test_moz_document_usability.html]
[test_moz_document_rules.html]

View File

@ -1,10 +0,0 @@
/* Bug 814907 (@-moz-document cases) */
@-moz-document url(http://www.example.com/) {}
@-moz-document url('http://www.example.com/') {}
@-moz-document url("http://www.example.com/") {}
@-moz-document url-prefix('http://www.example.com/') {}
@-moz-document url-prefix("http://www.example.com/") {}
@-moz-document domain('example.com') {}
@-moz-document domain("example.com") {}
@-moz-document regexp('http://www.w3.org/TR/\\d{4}/[^/]*-CSS2-\\d{8}/') {}
@-moz-document regexp("http://www.w3.org/TR/\\d{4}/[^/]*-CSS2-\\d{8}/") {}

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