author | Carsten "Tomcat" Book <cbook@mozilla.com> |
Tue, 29 Dec 2015 12:39:21 +0100 | |
changeset 277867 | e29ff13d30cd6e4d11c47ceb201e24dc14390cea |
parent 277866 | 61a36f055e0bbf9df522a805b9380014625c2043 (current diff) |
parent 277774 | 9ddf0da90fb3bc1ae29966dc596013fc54a44bd2 (diff) |
child 277868 | 773075ac2210560980913e8f79ea6b9fcb10a1d0 |
push id | 69628 |
push user | cbook@mozilla.com |
push date | Wed, 30 Dec 2015 11:16:09 +0000 |
treeherder | mozilla-inbound@b493cf33851f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 46.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -16,17 +16,17 @@ <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/> <!--original fetch url was git://github.com/mozilla/--> <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G repositories for all targets --> - <project name="gaia" path="gaia" remote="mozillaorg" revision="15a00047c0868cc8f4c8ec4af253b82ac54d70dd"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="63c3a57ad9935b9c61057a29ee27a1c6ed6a9e23"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/> <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/> <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
--- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -16,17 +16,17 @@ <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/> <!--original fetch url was git://github.com/mozilla/--> <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G repositories for all targets --> - <project name="gaia" path="gaia" remote="mozillaorg" revision="15a00047c0868cc8f4c8ec4af253b82ac54d70dd"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="63c3a57ad9935b9c61057a29ee27a1c6ed6a9e23"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/> <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/> <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
--- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -16,17 +16,17 @@ <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/> <!--original fetch url was git://github.com/mozilla/--> <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G repositories for all targets --> - <project name="gaia" path="gaia" remote="mozillaorg" revision="15a00047c0868cc8f4c8ec4af253b82ac54d70dd"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="63c3a57ad9935b9c61057a29ee27a1c6ed6a9e23"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/> <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/> <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/> <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/> <!-- Gonk-specific things and forks --> <project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/> <project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c"> <copyfile dest="Makefile" src="core/root.mk"/>
--- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -16,17 +16,17 @@ <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/> <!--original fetch url was git://github.com/mozilla/--> <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G repositories for all targets --> - <project name="gaia" path="gaia" remote="mozillaorg" revision="15a00047c0868cc8f4c8ec4af253b82ac54d70dd"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="63c3a57ad9935b9c61057a29ee27a1c6ed6a9e23"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/> <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/> <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="660169a3d7e034a892359e39135e8c2785a6ad6f"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
--- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -16,17 +16,17 @@ <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/> <!--original fetch url was git://github.com/mozilla/--> <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G repositories for all targets --> - <project name="gaia" path="gaia" remote="mozillaorg" revision="15a00047c0868cc8f4c8ec4af253b82ac54d70dd"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="63c3a57ad9935b9c61057a29ee27a1c6ed6a9e23"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/> <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/> <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> @@ -134,18 +134,18 @@ <project name="platform/external/icu4c" path="external/icu4c" remote="aosp" revision="b4c6379528887dc25ca9991a535a8d92a61ad6b6"/> <project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="2da3a2d5100f8afa1229bb50aa2a29ea0aaf8417"/> <project name="platform_system_core" path="system/core" remote="b2g" revision="8586f55fe4b015911b48e731b69c592ad82a0807"/> <default remote="caf" revision="refs/tags/android-4.4.2_r1" sync-j="4"/> <!-- Emulator specific things --> <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="72ffdf71c68a96309212eb13d63560d66db14c9e"/> <project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="58800ecb50e4e41cfb0a36cb43c82b73fb3612e5"/> <project name="platform_bionic" path="bionic" remote="b2g" revision="3e85c4683c121530c1c3a48c696a569bf5f587e2"/> - <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="30809c2bb8448d670490afad6b20bfc1719478c1"/> + <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="39bdda3051dd1d96da3ab369bc654290cb8d463c"/> <project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="f37bd545063039e30a92f2550ae78c0e6e4e2d08"/> <project name="platform_external_wpa_supplicant_8" path="external/wpa_supplicant_8" remote="b2g" revision="0c6a6547cd1fd302fa2b0f6e375654df36bf0ec4"/> - <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="3865e5be2dd7cb5007ca521922c25d301610d2f3"/> + <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="c0dd0098328f3992e1ca09d6d4355729243863d5"/> <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="5f4b68c799927b6e078f987b12722c3a6ccd4a45"/> <project name="platform/development" path="development" revision="5968ff4e13e0d696ad8d972281fc27ae5a12829b"/> <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="6a1bb59af65b6485b1090522f66fac95c3f9e22c"/> <project name="android-sdk" path="sdk" remote="b2g" revision="0951179277915335251c5e11d242e4e1a8c2236f"/> <project name="darwinstreamingserver" path="system/darwinstreamingserver" remote="b2g" revision="cf85968c7f85e0ec36e72c87ceb4837a943b8af6"/> </manifest>
--- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -16,17 +16,17 @@ <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/> <!--original fetch url was git://github.com/mozilla/--> <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G repositories for all targets --> - <project name="gaia" path="gaia" remote="mozillaorg" revision="15a00047c0868cc8f4c8ec4af253b82ac54d70dd"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="63c3a57ad9935b9c61057a29ee27a1c6ed6a9e23"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/> <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/> <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
--- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -16,17 +16,17 @@ <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/> <!--original fetch url was git://github.com/mozilla/--> <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G repositories for all targets --> - <project name="gaia" path="gaia" remote="mozillaorg" revision="15a00047c0868cc8f4c8ec4af253b82ac54d70dd"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="63c3a57ad9935b9c61057a29ee27a1c6ed6a9e23"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/> <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/> <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/> <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/> <!-- Gonk-specific things and forks --> <project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/> <project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c"> <copyfile dest="Makefile" src="core/root.mk"/>
--- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -16,17 +16,17 @@ <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/> <!--original fetch url was git://github.com/mozilla/--> <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G repositories for all targets --> - <project name="gaia" path="gaia" remote="mozillaorg" revision="15a00047c0868cc8f4c8ec4af253b82ac54d70dd"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="63c3a57ad9935b9c61057a29ee27a1c6ed6a9e23"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/> <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/> <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
--- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "15a00047c0868cc8f4c8ec4af253b82ac54d70dd", + "git_revision": "63c3a57ad9935b9c61057a29ee27a1c6ed6a9e23", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "c5581349d9fc778655021601422c00c17f453a0a", + "revision": "9cfeee1568995b5cf0f58db8924baff387871876", "repo_path": "integration/gaia-central" }
--- a/b2g/config/nexus-4-kk/sources.xml +++ b/b2g/config/nexus-4-kk/sources.xml @@ -16,17 +16,17 @@ <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/> <!--original fetch url was git://github.com/mozilla/--> <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G repositories for all targets --> - <project name="gaia" path="gaia" remote="mozillaorg" revision="15a00047c0868cc8f4c8ec4af253b82ac54d70dd"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="63c3a57ad9935b9c61057a29ee27a1c6ed6a9e23"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/> <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/> <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
--- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -16,17 +16,17 @@ <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/> <!--original fetch url was git://github.com/mozilla/--> <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G repositories for all targets --> - <project name="gaia" path="gaia" remote="mozillaorg" revision="15a00047c0868cc8f4c8ec4af253b82ac54d70dd"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="63c3a57ad9935b9c61057a29ee27a1c6ed6a9e23"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/> <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/> <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="660169a3d7e034a892359e39135e8c2785a6ad6f"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
--- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -16,17 +16,17 @@ <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/> <!--original fetch url was git://github.com/mozilla/--> <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G repositories for all targets --> - <project name="gaia" path="gaia" remote="mozillaorg" revision="15a00047c0868cc8f4c8ec4af253b82ac54d70dd"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="63c3a57ad9935b9c61057a29ee27a1c6ed6a9e23"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/> <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/> <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
--- a/browser/base/content/test/general/mochitest.ini +++ b/browser/base/content/test/general/mochitest.ini @@ -24,17 +24,17 @@ support-files = offlineEvent.cacheManifest^headers^ offlineEvent.html subtst_contextmenu.html video.ogg [test_bug364677.html] [test_bug395533.html] [test_contextmenu.html] -skip-if = toolkit == "gtk2" || toolkit == "gtk3" || (os == 'mac' && os_version != '10.6') # disabled on Linux due to bug 513558, on Mac after 10.6 due to bug 792304 +skip-if = toolkit == "gtk2" || toolkit == "gtk3" || (os == 'mac' && os_version != '10.6') || e10s # disabled on Linux due to bug 513558, on Mac after 10.6 due to bug 792304 [test_contextmenu_input.html] skip-if = toolkit == "gtk2" || toolkit == "gtk3" || e10s # disabled on Linux due to bug 513558 [test_feed_discovery.html] skip-if = e10s [test_offlineNotification.html] skip-if = buildapp == 'mulet' || e10s # Bug 1066070 - I don't think either popup notifications nor addon install stuff works? [test_offline_gzip.html] skip-if = buildapp == 'mulet' || e10s # Bug 1066070 - I don't think either popup notifications nor addon install stuff works?
--- a/dom/audiochannel/AudioChannelAgent.cpp +++ b/dom/audiochannel/AudioChannelAgent.cpp @@ -36,17 +36,16 @@ NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(AudioChannelAgent) NS_IMPL_CYCLE_COLLECTING_RELEASE(AudioChannelAgent) AudioChannelAgent::AudioChannelAgent() : mAudioChannelType(AUDIO_AGENT_CHANNEL_ERROR) , mInnerWindowID(0) , mIsRegToService(false) - , mNotifyPlayback(false) { } AudioChannelAgent::~AudioChannelAgent() { Shutdown(); } @@ -203,18 +202,17 @@ AudioChannelAgent::InitInternal(nsIDOMWi MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug, ("AudioChannelAgent, InitInternal, this = %p, type = %d, " "owner = %p, hasCallback = %d\n", this, mAudioChannelType, mWindow.get(), (!!mCallback || !!mWeakCallback))); return NS_OK; } -NS_IMETHODIMP AudioChannelAgent::NotifyStartedPlaying(uint32_t aNotifyPlayback, - float *aVolume, +NS_IMETHODIMP AudioChannelAgent::NotifyStartedPlaying(float *aVolume, bool* aMuted) { MOZ_ASSERT(aVolume); MOZ_ASSERT(aMuted); // Window-less AudioChannelAgents are muted by default. if (!mWindow) { *aVolume = 0; @@ -223,43 +221,42 @@ NS_IMETHODIMP AudioChannelAgent::NotifyS } RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate(); if (mAudioChannelType == AUDIO_AGENT_CHANNEL_ERROR || service == nullptr || mIsRegToService) { return NS_ERROR_FAILURE; } - service->RegisterAudioChannelAgent(this, aNotifyPlayback, + service->RegisterAudioChannelAgent(this, static_cast<AudioChannel>(mAudioChannelType)); service->GetState(mWindow, mAudioChannelType, aVolume, aMuted); MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug, ("AudioChannelAgent, NotifyStartedPlaying, this = %p, mute = %d, " "volume = %f\n", this, *aMuted, *aVolume)); - mNotifyPlayback = aNotifyPlayback; mIsRegToService = true; return NS_OK; } NS_IMETHODIMP AudioChannelAgent::NotifyStoppedPlaying() { if (mAudioChannelType == AUDIO_AGENT_CHANNEL_ERROR || !mIsRegToService) { return NS_ERROR_FAILURE; } MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug, ("AudioChannelAgent, NotifyStoppedPlaying, this = %p\n", this)); RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate(); if (service) { - service->UnregisterAudioChannelAgent(this, mNotifyPlayback); + service->UnregisterAudioChannelAgent(this); } mIsRegToService = false; return NS_OK; } already_AddRefed<nsIAudioChannelAgentCallback> AudioChannelAgent::GetCallback() @@ -295,22 +292,33 @@ AudioChannelAgent::WindowVolumeChanged() } uint64_t AudioChannelAgent::WindowID() const { return mWindow ? mWindow->WindowID() : 0; } +uint64_t +AudioChannelAgent::InnerWindowID() const +{ + return mInnerWindowID; +} + void -AudioChannelAgent::WindowAudioCaptureChanged(uint64_t aInnerWindowID) +AudioChannelAgent::WindowAudioCaptureChanged(uint64_t aInnerWindowID, + bool aCapture) { if (aInnerWindowID != mInnerWindowID) { return; } nsCOMPtr<nsIAudioChannelAgentCallback> callback = GetCallback(); if (!callback) { return; } - callback->WindowAudioCaptureChanged(); + MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug, + ("AudioChannelAgent, WindowAudioCaptureChanged, this = %p, " + "capture = %d\n", this, aCapture)); + + callback->WindowAudioCaptureChanged(aCapture); }
--- a/dom/audiochannel/AudioChannelAgent.h +++ b/dom/audiochannel/AudioChannelAgent.h @@ -29,24 +29,25 @@ public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_NSIAUDIOCHANNELAGENT NS_DECL_CYCLE_COLLECTION_CLASS(AudioChannelAgent) AudioChannelAgent(); void WindowVolumeChanged(); - void WindowAudioCaptureChanged(uint64_t aInnerWindowID); + void WindowAudioCaptureChanged(uint64_t aInnerWindowID, bool aCapture); nsPIDOMWindow* Window() const { return mWindow; } uint64_t WindowID() const; + uint64_t InnerWindowID() const; private: virtual ~AudioChannelAgent(); // Returns mCallback if that's non-null, or otherwise tries to get an // nsIAudioChannelAgentCallback out of mWeakCallback. already_AddRefed<nsIAudioChannelAgentCallback> GetCallback(); @@ -61,16 +62,15 @@ private: nsCOMPtr<nsPIDOMWindow> mWindow; nsCOMPtr<nsIAudioChannelAgentCallback> mCallback; nsWeakPtr mWeakCallback; int32_t mAudioChannelType; uint64_t mInnerWindowID; bool mIsRegToService; - bool mNotifyPlayback; }; } // namespace dom } // namespace mozilla #endif
--- a/dom/audiochannel/AudioChannelService.cpp +++ b/dom/audiochannel/AudioChannelService.cpp @@ -263,17 +263,16 @@ AudioChannelService::AudioChannelService } AudioChannelService::~AudioChannelService() { } void AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent, - uint32_t aNotifyPlayback, AudioChannel aChannel) { uint64_t windowID = aAgent->WindowID(); AudioChannelWindow* winData = GetWindowData(windowID); if (!winData) { winData = new AudioChannelWindow(windowID); mWindows.AppendElement(winData); } @@ -284,29 +283,34 @@ AudioChannelService::RegisterAudioChanne ++winData->mChannels[(uint32_t)aChannel].mNumberOfAgents; // The first one, we must inform the BrowserElementAudioChannel. if (winData->mChannels[(uint32_t)aChannel].mNumberOfAgents == 1) { NotifyChannelActive(aAgent->WindowID(), aChannel, true); } // If this is the first agent for this window, we must notify the observers. - if (aNotifyPlayback == nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY && - winData->mAgents.Length() == 1) { + if (winData->mAgents.Length() == 1) { RefPtr<MediaPlaybackRunnable> runnable = new MediaPlaybackRunnable(aAgent->Window(), true /* active */); NS_DispatchToCurrentThread(runnable); } + // If the window has already been captured, the agent of that window should + // also be captured. + if (winData->mIsAudioCaptured) { + aAgent->WindowAudioCaptureChanged(aAgent->InnerWindowID(), + winData->mIsAudioCaptured); + } + MaybeSendStatusUpdate(); } void -AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent, - uint32_t aNotifyPlayback) +AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent) { AudioChannelWindow* winData = GetWindowData(aAgent->WindowID()); if (!winData) { return; } if (winData->mAgents.Contains(aAgent)) { int32_t channel = aAgent->AudioChannelType(); @@ -328,23 +332,27 @@ AudioChannelService::UnregisterAudioChan #ifdef MOZ_WIDGET_GONK bool active = AnyAudioChannelIsActive(); for (uint32_t i = 0; i < mSpeakerManager.Length(); i++) { mSpeakerManager[i]->SetAudioChannelActive(active); } #endif // If this is the last agent for this window, we must notify the observers. - if (aNotifyPlayback == nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY && - winData->mAgents.IsEmpty()) { + if (winData->mAgents.IsEmpty()) { RefPtr<MediaPlaybackRunnable> runnable = new MediaPlaybackRunnable(aAgent->Window(), false /* active */); NS_DispatchToCurrentThread(runnable); } + // No need to capture non-audible object. + if (winData->mIsAudioCaptured) { + aAgent->WindowAudioCaptureChanged(aAgent->InnerWindowID(), false); + } + MaybeSendStatusUpdate(); } void AudioChannelService::RegisterTabParent(TabParent* aTabParent) { MOZ_ASSERT(aTabParent); MOZ_ASSERT(!mTabParents.Contains(aTabParent)); @@ -622,42 +630,51 @@ AudioChannelService::RefreshAgentsVolume nsTObserverArray<AudioChannelAgent*>::ForwardIterator iter(winData->mAgents); while (iter.HasMore()) { iter.GetNext()->WindowVolumeChanged(); } } void -AudioChannelService::RefreshAgentsCapture(nsPIDOMWindow* aWindow, - uint64_t aInnerWindowID) +AudioChannelService::SetWindowAudioCaptured(nsPIDOMWindow* aWindow, + uint64_t aInnerWindowID, + bool aCapture) { + MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aWindow); MOZ_ASSERT(aWindow->IsOuterWindow()); + MOZ_LOG(GetAudioChannelLog(), LogLevel::Debug, + ("AudioChannelService, SetWindowAudioCaptured, window = %p, " + "aCapture = %d\n", aWindow, aCapture)); + nsCOMPtr<nsPIDOMWindow> topWindow = aWindow->GetScriptableTop(); if (!topWindow) { return; } AudioChannelWindow* winData = GetWindowData(topWindow->WindowID()); // This can happen, but only during shutdown, because the the outer window // changes ScriptableTop, so that its ID is different. // In this case either we are capturing, and it's too late because the window // has been closed anyways, or we are un-capturing, and everything has already // been cleaned up by the HTMLMediaElements or the AudioContexts. if (!winData) { return; } - nsTObserverArray<AudioChannelAgent*>::ForwardIterator - iter(winData->mAgents); - while (iter.HasMore()) { - iter.GetNext()->WindowAudioCaptureChanged(aInnerWindowID); + if (aCapture != winData->mIsAudioCaptured) { + winData->mIsAudioCaptured = aCapture; + nsTObserverArray<AudioChannelAgent*>::ForwardIterator + iter(winData->mAgents); + while (iter.HasMore()) { + iter.GetNext()->WindowAudioCaptureChanged(aInnerWindowID, aCapture); + } } } /* static */ const nsAttrValue::EnumTable* AudioChannelService::GetAudioChannelTable() { return kMozAudioChannelAttributeTable; } @@ -785,17 +802,17 @@ AudioChannelService::SetAudioChannelVolu float aVolume) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aWindow); MOZ_ASSERT(aWindow->IsOuterWindow()); MOZ_LOG(GetAudioChannelLog(), LogLevel::Debug, ("AudioChannelService, SetAudioChannelVolume, window = %p, type = %d, " - "volume = %d\n", aWindow, aAudioChannel, aVolume)); + "volume = %f\n", aWindow, aAudioChannel, aVolume)); AudioChannelWindow* winData = GetOrCreateWindowData(aWindow); winData->mChannels[(uint32_t)aAudioChannel].mVolume = aVolume; RefreshAgentsVolumeAndPropagate(aAudioChannel, aWindow); } NS_IMETHODIMP AudioChannelService::SetAudioChannelVolume(nsIDOMWindow* aWindow,
--- a/dom/audiochannel/AudioChannelService.h +++ b/dom/audiochannel/AudioChannelService.h @@ -51,25 +51,23 @@ public: static PRLogModuleInfo* GetAudioChannelLog(); /** * Any audio channel agent that starts playing should register itself to * this service, sharing the AudioChannel. */ void RegisterAudioChannelAgent(AudioChannelAgent* aAgent, - uint32_t aNotifyPlayback, AudioChannel aChannel); /** * Any audio channel agent that stops playing should unregister itself to * this service. */ - void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent, - uint32_t aNotifyPlayback); + void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent); /** * For nested iframes. */ void RegisterTabParent(TabParent* aTabParent); void UnregisterTabParent(TabParent* aTabParent); /** @@ -119,18 +117,19 @@ public: void RefreshAgentsVolumeAndPropagate(AudioChannel aAudioChannel, nsPIDOMWindow* aWindow); // This method needs to know the inner window that wants to capture audio. We // group agents per top outer window, but we can have multiple innerWindow per // top outerWindow (subiframes, etc.) and we have to identify all the agents // just for a particular innerWindow. - void RefreshAgentsCapture(nsPIDOMWindow* aWindow, - uint64_t aInnerWindowID); + void SetWindowAudioCaptured(nsPIDOMWindow* aWindow, + uint64_t aInnerWindowID, + bool aCapture); #ifdef MOZ_WIDGET_GONK void RegisterSpeakerManager(SpeakerManagerService* aSpeakerManager) { if (!mSpeakerManager.Contains(aSpeakerManager)) { mSpeakerManager.AppendElement(aSpeakerManager); } @@ -184,23 +183,25 @@ private: bool mMuted; uint32_t mNumberOfAgents; }; struct AudioChannelWindow final { explicit AudioChannelWindow(uint64_t aWindowID) - : mWindowID(aWindowID) + : mWindowID(aWindowID), + mIsAudioCaptured(false) { // Workaround for bug1183033, system channel type can always playback. mChannels[(int16_t)AudioChannel::System].mMuted = false; } uint64_t mWindowID; + bool mIsAudioCaptured; AudioChannelConfig mChannels[NUMBER_OF_AUDIO_CHANNELS]; // Raw pointer because the AudioChannelAgent must unregister itself. nsTObserverArray<AudioChannelAgent*> mAgents; }; AudioChannelWindow* GetOrCreateWindowData(nsPIDOMWindow* aWindow);
--- a/dom/audiochannel/nsIAudioChannelAgent.idl +++ b/dom/audiochannel/nsIAudioChannelAgent.idl @@ -1,45 +1,45 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsISupports.idl" interface nsIDOMWindow; -[uuid(5fe83b24-38b9-4901-a4a1-d1bd57d3fe18)] +[uuid(0a451ee0-972e-11e5-a837-0800200c9a66)] interface nsIAudioChannelAgentCallback : nsISupports { /** * Notified when the window volume/mute is changed */ void windowVolumeChanged(in float aVolume, in bool aMuted); /** * Notified when the capture state is changed. */ - void windowAudioCaptureChanged(); + void windowAudioCaptureChanged(in bool aCapture); }; /** * This interface provides an agent for gecko components to participate * in the audio channel service. Gecko components are responsible for * 1. Indicating what channel type they are using (via the init() member * function). * 2. Before playing, checking the playable status of the channel. * 3. Notifying the agent when they start/stop using this channel. * 4. Notifying the agent of changes to the visibility of the component using * this channel. * * The agent will invoke a callback to notify Gecko components of * 1. Changes to the playable status of this channel. */ -[uuid(18222148-1b32-463d-b050-b741f43a07ba)] +[uuid(ab7e21c0-970c-11e5-a837-0800200c9a66)] interface nsIAudioChannelAgent : nsISupports { const long AUDIO_AGENT_CHANNEL_NORMAL = 0; const long AUDIO_AGENT_CHANNEL_CONTENT = 1; const long AUDIO_AGENT_CHANNEL_NOTIFICATION = 2; const long AUDIO_AGENT_CHANNEL_ALARM = 3; const long AUDIO_AGENT_CHANNEL_TELEPHONY = 4; const long AUDIO_AGENT_CHANNEL_RINGER = 5; @@ -47,19 +47,16 @@ interface nsIAudioChannelAgent : nsISupp const long AUDIO_AGENT_CHANNEL_SYSTEM = 7; const long AUDIO_AGENT_CHANNEL_ERROR = 1000; const long AUDIO_AGENT_STATE_NORMAL = 0; const long AUDIO_AGENT_STATE_MUTED = 1; const long AUDIO_AGENT_STATE_FADED = 2; - const long AUDIO_AGENT_DONT_NOTIFY = 0; - const long AUDIO_AGENT_NOTIFY = 1; - /** * Before init() is called, this returns AUDIO_AGENT_CHANNEL_ERROR. */ readonly attribute long audioChannelType; %{C++ inline int32_t AudioChannelType() { int32_t channel; @@ -96,29 +93,25 @@ interface nsIAudioChannelAgent : nsISupp void initWithWeakCallback(in nsIDOMWindow window, in long channelType, in nsIAudioChannelAgentCallback callback); /** * Notify the agent that we want to start playing. * Note: Gecko component SHOULD call this function first then start to * play audio stream only when return value is true. * - * @param notifyPlaying - * Whether to send audio-playback notifications, one of AUDIO_CHANNEL_NOTIFY - * or AUDIO_CHANNEL_DONT_NOTIFY. - * * @return * normal state: the agent has registered with audio channel service and * the component should start playback. * muted state: the agent has registered with audio channel service but * the component should not start playback. * faded state: the agent has registered with audio channel service the * component should start playback as well as reducing the volume. */ - void notifyStartedPlaying(in unsigned long notifyPlayback, out float volume, out bool muted); + void notifyStartedPlaying(out float volume, out bool muted); /** * Notify the agent we no longer want to play. * * Note : even if notifyStartedPlaying() returned false, the agent would * still be registered with the audio channel service and receive callbacks * for status changes. So notifyStoppedPlaying must still eventually be * called to unregister the agent with the channel service.
--- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -3738,17 +3738,17 @@ nsresult nsPIDOMWindow::SetAudioCapture(bool aCapture) { MOZ_ASSERT(IsInnerWindow()); mAudioCaptured = aCapture; RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate(); if (service) { - service->RefreshAgentsCapture(GetOuterWindow(), mWindowID); + service->SetWindowAudioCaptured(GetOuterWindow(), mWindowID, aCapture); } return NS_OK; } // nsISpeechSynthesisGetter #ifdef MOZ_WEBSPEECH
--- a/dom/camera/DOMCameraControl.cpp +++ b/dom/camera/DOMCameraControl.cpp @@ -1182,18 +1182,17 @@ nsDOMCameraControl::NotifyRecordingStatu return NS_ERROR_UNEXPECTED; } // Camera app will stop recording when it falls to the background, so no callback is necessary. mAudioChannelAgent->Init(mWindow, (int32_t)AudioChannel::Content, nullptr); // Video recording doesn't output any sound, so it's not necessary to check canPlay. float volume = 0.0; bool muted = true; - rv = mAudioChannelAgent->NotifyStartedPlaying(nsIAudioChannelAgent::AUDIO_AGENT_DONT_NOTIFY, - &volume, &muted); + rv = mAudioChannelAgent->NotifyStartedPlaying(&volume, &muted); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } #endif return rv; }
--- a/dom/crypto/CryptoKey.cpp +++ b/dom/crypto/CryptoKey.cpp @@ -969,21 +969,26 @@ CryptoKey::PrivateKeyToJwk(SECKEYPrivate SECKEYPublicKey* CreateECPublicKey(const SECItem* aKeyData, const nsString& aNamedCurve) { ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); if (!arena) { return nullptr; } - SECKEYPublicKey* key = PORT_ArenaZNew(arena, SECKEYPublicKey); + // It's important that this be a ScopedSECKEYPublicKey, as this ensures that + // SECKEY_DestroyPublicKey will be called on it. If this doesn't happen, when + // CryptoKey::PublicKeyValid is called on it and it gets moved to the internal + // PKCS#11 slot, it will leak a reference to the slot. + ScopedSECKEYPublicKey key(PORT_ArenaZNew(arena, SECKEYPublicKey)); if (!key) { return nullptr; } + key->arena = nullptr; // key doesn't own the arena; it won't get double-freed key->keyType = ecKey; key->pkcs11Slot = nullptr; key->pkcs11ID = CK_INVALID_HANDLE; // Create curve parameters. SECItem* params = CreateECParamsForCurve(aNamedCurve, arena); if (!params) { return nullptr;
--- a/dom/fmradio/FMRadio.cpp +++ b/dom/fmradio/FMRadio.cpp @@ -449,33 +449,32 @@ FMRadio::DisableRDS() void FMRadio::EnableAudioChannelAgent() { NS_ENSURE_TRUE_VOID(mAudioChannelAgent); float volume = 0.0; bool muted = true; - mAudioChannelAgent->NotifyStartedPlaying(nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY, - &volume, &muted); + mAudioChannelAgent->NotifyStartedPlaying(&volume, &muted); WindowVolumeChanged(volume, muted); mAudioChannelAgentEnabled = true; } NS_IMETHODIMP FMRadio::WindowVolumeChanged(float aVolume, bool aMuted) { IFMRadioService::Singleton()->EnableAudio(!aMuted); // TODO: what about the volume? return NS_OK; } NS_IMETHODIMP -FMRadio::WindowAudioCaptureChanged() +FMRadio::WindowAudioCaptureChanged(bool aCapture) { return NS_OK; } NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FMRadio) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY(nsIAudioChannelAgentCallback) NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
--- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -109,41 +109,28 @@ static mozilla::LazyLogModule gMediaElem #include "mozilla/EventStateManager.h" using namespace mozilla::layers; using mozilla::net::nsMediaFragmentURIParser; class MOZ_STACK_CLASS AutoNotifyAudioChannelAgent { RefPtr<mozilla::dom::HTMLMediaElement> mElement; - bool mShouldNotify; MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER; public: - AutoNotifyAudioChannelAgent(mozilla::dom::HTMLMediaElement* aElement, - bool aNotify - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + explicit AutoNotifyAudioChannelAgent(mozilla::dom::HTMLMediaElement* aElement + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : mElement(aElement) - , mShouldNotify(aNotify) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; - if (mShouldNotify) { - // The audio channel agent may not exist now. - if (mElement->MaybeCreateAudioChannelAgent()) { - mElement->NotifyAudioChannelAgent(false); - } - } - } + } + ~AutoNotifyAudioChannelAgent() { - if (mShouldNotify) { - // The audio channel agent is destroyed at this point. - if (mElement->MaybeCreateAudioChannelAgent()) { - mElement->NotifyAudioChannelAgent(true); - } - } + mElement->UpdateAudioChannelPlayingState(); } }; namespace mozilla { namespace dom { // Number of milliseconds between progress events as defined by spec static const uint32_t PROGRESS_MS = 350; @@ -3394,20 +3381,17 @@ void HTMLMediaElement::ProcessMediaFragm void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo, nsAutoPtr<const MetadataTags> aTags) { MOZ_ASSERT(NS_IsMainThread()); // If the element is gaining or losing an audio track, we need to notify // the audio channel agent so that the correct audio-playback events will // get dispatched. - bool audioTrackChanging = mMediaInfo.HasAudio() != aInfo->HasAudio(); - AutoNotifyAudioChannelAgent autoNotify(this, - audioTrackChanging && - mPlayingThroughTheAudioChannel); + AutoNotifyAudioChannelAgent autoNotify(this); mMediaInfo = *aInfo; mIsEncrypted = aInfo->IsEncrypted() #ifdef MOZ_EME || mPendingEncryptedInitData.IsEncrypted() #endif // MOZ_EME ; mTags = aTags.forget(); @@ -4357,18 +4341,16 @@ void HTMLMediaElement::DoRemoveSelfRefer // We don't need the shutdown observer anymore. Unregistering releases // its reference to us, which we were using as our self-reference. nsContentUtils::UnregisterShutdownObserver(this); } nsresult HTMLMediaElement::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData) { - NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); - if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { mShuttingDown = true; AddRemoveSelfReference(); } return NS_OK; } bool @@ -4756,16 +4738,21 @@ HTMLMediaElement::MaybeCreateAudioChanne bool HTMLMediaElement::IsPlayingThroughTheAudioChannel() const { // Are we paused or muted if (mPaused || Muted()) { return false; } + // If this element doesn't have any audio tracks. + if (!HasAudio()) { + return false; + } + // The volume should not be ~0 if (std::fabs(Volume()) <= 1e-7) { return false; } // We should consider any bfcached page or inactive document as non-playing. if (!IsActive()) { return false; @@ -4811,33 +4798,25 @@ HTMLMediaElement::UpdateAudioChannelPlay NotifyAudioChannelAgent(mPlayingThroughTheAudioChannel); } } } void HTMLMediaElement::NotifyAudioChannelAgent(bool aPlaying) { - // Immediately check if this should go to the MSG instead of the normal - // media playback route. - WindowAudioCaptureChanged(); - // This is needed to pass nsContentUtils::IsCallerChrome(). // AudioChannel API should not called from content but it can happen that // this method has some content JS in its stack. AutoNoJSAPI nojsapi; if (aPlaying) { - // Don't notify playback if this element doesn't have any audio tracks. - uint32_t notify = HasAudio() ? nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY : - nsIAudioChannelAgent::AUDIO_AGENT_DONT_NOTIFY; - float volume = 0.0; bool muted = true; - mAudioChannelAgent->NotifyStartedPlaying(notify, &volume, &muted); + mAudioChannelAgent->NotifyStartedPlaying(&volume, &muted); WindowVolumeChanged(volume, muted); } else { mAudioChannelAgent->NotifyStoppedPlaying(); mAudioChannelAgent = nullptr; } } NS_IMETHODIMP HTMLMediaElement::WindowVolumeChanged(float aVolume, bool aMuted) @@ -4989,27 +4968,27 @@ HTMLMediaElement::GetTopLevelPrincipal() if (!doc) { return nullptr; } principal = doc->NodePrincipal(); return principal.forget(); } #endif // MOZ_EME -NS_IMETHODIMP HTMLMediaElement::WindowAudioCaptureChanged() +NS_IMETHODIMP HTMLMediaElement::WindowAudioCaptureChanged(bool aCapture) { MOZ_ASSERT(mAudioChannelAgent); + MOZ_ASSERT(HasAudio()); if (!OwnerDoc()->GetInnerWindow()) { return NS_OK; } - bool captured = OwnerDoc()->GetInnerWindow()->GetAudioCaptured(); - - if (captured != mAudioCapturedByWindow) { - if (captured) { + + if (aCapture != mAudioCapturedByWindow) { + if (aCapture) { mAudioCapturedByWindow = true; nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(OwnerDoc()->GetParentObject()); uint64_t id = window->WindowID(); MediaStreamGraph* msg = MediaStreamGraph::GetInstance(MediaStreamGraph::AUDIO_THREAD_DRIVER, mAudioChannel); @@ -5035,17 +5014,17 @@ NS_IMETHODIMP HTMLMediaElement::WindowAu mDecoder->RemoveOutputStream(ps); } mCaptureStreamPort->Destroy(); mCaptureStreamPort = nullptr; } } - return NS_OK; + return NS_OK; } AudioTrackList* HTMLMediaElement::AudioTracks() { if (!mAudioTrackList) { nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(OwnerDoc()->GetParentObject()); mAudioTrackList = new AudioTrackList(window, this);
--- a/dom/media/webaudio/AudioDestinationNode.cpp +++ b/dom/media/webaudio/AudioDestinationNode.cpp @@ -532,41 +532,39 @@ AudioDestinationNode::WindowVolumeChange } } SetCanPlay(aVolume, aMuted); return NS_OK; } NS_IMETHODIMP -AudioDestinationNode::WindowAudioCaptureChanged() +AudioDestinationNode::WindowAudioCaptureChanged(bool aCapture) { MOZ_ASSERT(mAudioChannelAgent); if (!mStream || Context()->IsOffline()) { return NS_OK; } nsCOMPtr<nsPIDOMWindow> ownerWindow = GetOwner(); if (!ownerWindow) { return NS_OK; } - bool captured = ownerWindow->GetAudioCaptured(); - - if (captured != mCaptured) { - if (captured) { + if (aCapture != mCaptured) { + if (aCapture) { nsCOMPtr<nsPIDOMWindow> window = Context()->GetParentObject(); uint64_t id = window->WindowID(); mCaptureStreamPort = mStream->Graph()->ConnectToCaptureStream(id, mStream); } else { mCaptureStreamPort->Destroy(); } - mCaptured = captured; + mCaptured = aCapture; } return NS_OK; } AudioChannel AudioDestinationNode::MozAudioChannelType() const { @@ -648,20 +646,17 @@ AudioDestinationNode::CreateAudioChannel mAudioChannelAgent = new AudioChannelAgent(); rv = mAudioChannelAgent->InitWithWeakCallback(GetOwner(), static_cast<int32_t>(mAudioChannel), this); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - rv = WindowAudioCaptureChanged(); - NS_WARN_IF(NS_FAILED(rv)); - return rv; - + return NS_OK; } void AudioDestinationNode::NotifyStableState() { mExtraCurrentTimeUpdatedSinceLastStableState = false; } @@ -741,20 +736,18 @@ AudioDestinationNode::InputMuted(bool aM if (aMuted) { mAudioChannelAgent->NotifyStoppedPlaying(); return; } float volume = 0.0; bool muted = true; - nsresult rv = mAudioChannelAgent->NotifyStartedPlaying(nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY, - &volume, &muted); + nsresult rv = mAudioChannelAgent->NotifyStartedPlaying(&volume, &muted); if (NS_WARN_IF(NS_FAILED(rv))) { return; } - WindowAudioCaptureChanged(); WindowVolumeChanged(volume, muted); } } // namespace dom } // namespace mozilla
--- a/dom/media/webspeech/synth/nsSpeechTask.cpp +++ b/dom/media/webspeech/synth/nsSpeechTask.cpp @@ -691,17 +691,17 @@ nsSpeechTask::CreateAudioChannelAgent() } mAudioChannelAgent = new AudioChannelAgent(); mAudioChannelAgent->InitWithWeakCallback(mUtterance->GetOwner(), static_cast<int32_t>(AudioChannelService::GetDefaultAudioChannel()), this); float volume = 0.0f; bool muted = true; - mAudioChannelAgent->NotifyStartedPlaying(nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY, &volume, &muted); + mAudioChannelAgent->NotifyStartedPlaying(&volume, &muted); } void nsSpeechTask::DestroyAudioChannelAgent() { if (mAudioChannelAgent) { mAudioChannelAgent->NotifyStoppedPlaying(); mAudioChannelAgent = nullptr; @@ -711,17 +711,17 @@ nsSpeechTask::DestroyAudioChannelAgent() NS_IMETHODIMP nsSpeechTask::WindowVolumeChanged(float aVolume, bool aMuted) { SetAudioOutputVolume(aMuted ? 0.0 : mVolume * aVolume); return NS_OK; } NS_IMETHODIMP -nsSpeechTask::WindowAudioCaptureChanged() +nsSpeechTask::WindowAudioCaptureChanged(bool aCapture) { // This is not supported yet. return NS_OK; } void nsSpeechTask::SetAudioOutputVolume(float aVolume) {
--- a/dom/plugins/base/nsNPAPIPlugin.cpp +++ b/dom/plugins/base/nsNPAPIPlugin.cpp @@ -2291,18 +2291,17 @@ NPError if (isMuted) { rv = agent->NotifyStoppedPlaying(); if (NS_WARN_IF(NS_FAILED(rv))) { return NPERR_NO_ERROR; } } else { float volume = 0.0; bool muted = true; - rv = agent->NotifyStartedPlaying(nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY, - &volume, &muted); + rv = agent->NotifyStartedPlaying(&volume, &muted); if (NS_WARN_IF(NS_FAILED(rv))) { return NPERR_NO_ERROR; } rv = inst->WindowVolumeChanged(volume, muted); if (NS_WARN_IF(NS_FAILED(rv))) { return NPERR_NO_ERROR; }
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -1855,17 +1855,17 @@ nsNPAPIPluginInstance::WindowVolumeChang { // We just support mute/unmute nsresult rv = SetMuted(aMuted); NS_WARN_IF(NS_FAILED(rv)); return rv; } NS_IMETHODIMP -nsNPAPIPluginInstance::WindowAudioCaptureChanged() +nsNPAPIPluginInstance::WindowAudioCaptureChanged(bool aCapture) { return NS_OK; } nsresult nsNPAPIPluginInstance::SetMuted(bool aIsMuted) { if (RUNNING != mRunning)
--- a/dom/telephony/Telephony.cpp +++ b/dom/telephony/Telephony.cpp @@ -557,18 +557,17 @@ Telephony::HandleAudioAgentState() mAudioAgent = nullptr; if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } else if (!activeCall.IsNull() && !mIsAudioStartPlaying) { mIsAudioStartPlaying = true; float volume; bool muted; - rv = mAudioAgent->NotifyStartedPlaying(nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY, - &volume, &muted); + rv = mAudioAgent->NotifyStartedPlaying(&volume, &muted); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } // In B2G, the system app manages audio playback policy. If there is a new // sound want to be playback, it must wait for the permission from the // system app. It means that the sound would be muted first, and then be // unmuted. For telephony, the behaviors are hold() first, then resume(). @@ -707,17 +706,17 @@ Telephony::WindowVolumeChanged(float aVo mHaveDispatchedInterruptBeginEvent = mMuted; } } return NS_OK; } NS_IMETHODIMP -Telephony::WindowAudioCaptureChanged() +Telephony::WindowAudioCaptureChanged(bool aCapture) { // Do nothing, it's useless for the telephony object. return NS_OK; } // nsITelephonyListener NS_IMETHODIMP
--- a/gfx/2d/FilterNodeD2D1.cpp +++ b/gfx/2d/FilterNodeD2D1.cpp @@ -570,16 +570,20 @@ FilterNodeD2D1::Create(ID2D1DeviceContex hr = aDC->CreateEffect(GetCLDIDForFilterType(aType), getter_AddRefs(effect)); if (FAILED(hr) || !effect) { gfxCriticalErrorOnce() << "Failed to create effect for FilterType: " << hexa(hr); return nullptr; } + if (aType == FilterType::ARITHMETIC_COMBINE) { + effect->SetValue(D2D1_ARITHMETICCOMPOSITE_PROP_CLAMP_OUTPUT, TRUE); + } + RefPtr<FilterNodeD2D1> filter = new FilterNodeD2D1(effect, aType); if (HasUnboundedOutputRegion(aType)) { // These filters can produce non-transparent output from transparent // input pixels, and we want them to have an unbounded output region. filter = new FilterNodeExtendInputAdapterD2D1(aDC, filter, aType); }
--- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -43,16 +43,17 @@ #include "cairo.h" #include "harfbuzz/hb.h" #include "harfbuzz/hb-ot.h" #include "graphite2/Font.h" #include <algorithm> +#include <limits> #include <cmath> using namespace mozilla; using namespace mozilla::gfx; using namespace mozilla::unicode; using mozilla::services::GetObserverService; gfxFontCache *gfxFontCache::gGlobalCache = nullptr; @@ -1854,32 +1855,32 @@ gfxFont::DrawGlyphs(gfxShapedText void gfxFont::DrawEmphasisMarks(gfxTextRun* aShapedText, gfxPoint* aPt, uint32_t aOffset, uint32_t aCount, const EmphasisMarkDrawParams& aParams) { gfxFloat& inlineCoord = aParams.isVertical ? aPt->y : aPt->x; uint32_t markLength = aParams.mark->GetLength(); - gfxFloat clusterStart = NAN; + gfxFloat clusterStart = -std::numeric_limits<gfxFloat>::infinity(); bool shouldDrawEmphasisMark = false; for (uint32_t i = 0, idx = aOffset; i < aCount; ++i, ++idx) { if (aParams.spacing) { inlineCoord += aParams.direction * aParams.spacing[i].mBefore; } - if (aShapedText->IsClusterStart(idx)) { + if (aShapedText->IsClusterStart(idx) || + clusterStart == -std::numeric_limits<gfxFloat>::infinity()) { clusterStart = inlineCoord; } if (aShapedText->CharMayHaveEmphasisMark(idx)) { shouldDrawEmphasisMark = true; } inlineCoord += aParams.direction * aShapedText->GetAdvanceForGlyph(idx); if (shouldDrawEmphasisMark && (i + 1 == aCount || aShapedText->IsClusterStart(idx + 1))) { - MOZ_ASSERT(!std::isnan(clusterStart), "Should have cluster start"); gfxFloat clusterAdvance = inlineCoord - clusterStart; // Move the coord backward to get the needed start point. gfxFloat delta = (clusterAdvance + aParams.advance) / 2; inlineCoord -= delta; aParams.mark->Draw(aParams.context, *aPt, DrawMode::GLYPH_FILL, 0, markLength, nullptr, nullptr, nullptr); inlineCoord += delta; shouldDrawEmphasisMark = false;
--- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -2103,16 +2103,28 @@ DumpObject(JSContext* cx, unsigned argc, DumpObject(obj); args.rval().setUndefined(); return true; } #endif +static bool +SharedMemoryEnabled(JSContext* cx, unsigned argc, Value* vp) +{ + CallArgs args = CallArgsFromVp(argc, vp); +#ifdef ENABLE_SHARED_ARRAY_BUFFER + args.rval().setBoolean(true); +#else + args.rval().setBoolean(false); +#endif + return true; +} + #ifdef NIGHTLY_BUILD static bool ObjectAddress(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() != 1) { RootedObject callee(cx, &args.callee()); ReportUsageError(cx, callee, "Wrong number of arguments"); @@ -3503,16 +3515,20 @@ gc::ZealModeHelpText), " the last array element is implicitly |target|.\n"), #ifdef DEBUG JS_FN_HELP("dumpObject", DumpObject, 1, 0, "dumpObject()", " Dump an internal representation of an object."), #endif + JS_FN_HELP("sharedMemoryEnabled", SharedMemoryEnabled, 0, 0, +"sharedMemoryEnabled()", +" Return true if SharedArrayBuffer and Atomics are enabled"), + #ifdef NIGHTLY_BUILD JS_FN_HELP("objectAddress", ObjectAddress, 1, 0, "objectAddress(obj)", " Return the current address of the object. For debugging only--this\n" " address may change during a moving GC."), JS_FN_HELP("sharedAddress", SharedAddress, 1, 0, "sharedAddress(obj)",
--- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -352,48 +352,32 @@ BytecodeEmitter::emitDupAt(unsigned slot if (!emitN(JSOP_DUPAT, 3, &off)) return false; jsbytecode* pc = code(off); SET_UINT24(pc, slotFromTop); return true; } -/* XXX too many "... statement" L10N gaffes below -- fix via js.msg! */ -const char js_with_statement_str[] = "with statement"; -const char js_finally_block_str[] = "finally block"; - -static const char * const statementName[] = { - "label statement", /* LABEL */ - "if statement", /* IF */ - "else statement", /* ELSE */ - "destructuring body", /* BODY */ - "switch statement", /* SWITCH */ - "block", /* BLOCK */ - js_with_statement_str, /* WITH */ - "catch block", /* CATCH */ - "try block", /* TRY */ - js_finally_block_str, /* FINALLY */ - js_finally_block_str, /* SUBROUTINE */ - "do loop", /* DO_LOOP */ - "for loop", /* FOR_LOOP */ - "for/in loop", /* FOR_IN_LOOP */ - "for/of loop", /* FOR_OF_LOOP */ - "while loop", /* WHILE_LOOP */ - "spread", /* SPREAD */ -}; - -static_assert(MOZ_ARRAY_LENGTH(statementName) == uint16_t(StmtType::LIMIT), - "statementName array and StmtType enum must be consistent"); - static const char* StatementName(StmtInfoBCE* stmt) { if (!stmt) return js_script_str; + + /* XXX too many "... statement" L10N gaffes -- fix via js.msg! */ + static const char* const statementName[] = { + #define STATEMENT_TYPE_NAME(name, desc) desc, + FOR_EACH_STATEMENT_TYPE(STATEMENT_TYPE_NAME) + #undef STATEMENT_TYPE_NAME + }; + + static_assert(MOZ_ARRAY_LENGTH(statementName) == uint16_t(StmtType::LIMIT), + "statementName array and StmtType enum must be consistent"); + return statementName[uint16_t(stmt->type)]; } static void ReportStatementTooLarge(TokenStream& ts, StmtInfoBCE* stmt) { ts.reportError(JSMSG_NEED_DIET, StatementName(stmt)); }
--- a/js/src/frontend/FullParseHandler.h +++ b/js/src/frontend/FullParseHandler.h @@ -589,23 +589,36 @@ class FullParseHandler BinaryNode* pn = new_<BinaryNode>(PNK_COMPREHENSIONFOR, op, TokenPos(begin, body->pn_pos.end), forHead, body); if (!pn) return null(); pn->pn_iflags = JSOP_ITER; return pn; } + ParseNode* newComprehensionBinding(ParseNode* kid) { + MOZ_ASSERT(kid->isKind(PNK_NAME)); + return new_<ListNode>(PNK_LET, JSOP_NOP, kid); + } + ParseNode* newForHead(ParseNodeKind kind, ParseNode* pn1, ParseNode* pn2, ParseNode* pn3, const TokenPos& pos) { MOZ_ASSERT(kind == PNK_FORIN || kind == PNK_FOROF || kind == PNK_FORHEAD); return new_<TernaryNode>(kind, JSOP_NOP, pn1, pn2, pn3, pos); } + void initForLetBlock(ParseNode* forLetImpliedBlock, ParseNode* nestedForLoop) { + MOZ_ASSERT(forLetImpliedBlock->isKind(PNK_LEXICALSCOPE)); + MOZ_ASSERT(nestedForLoop->isKind(PNK_FOR)); + + forLetImpliedBlock->pn_expr = nestedForLoop; + forLetImpliedBlock->pn_pos = nestedForLoop->pn_pos; + } + ParseNode* newSwitchStatement(uint32_t begin, ParseNode* discriminant, ParseNode* caseList) { TokenPos pos(begin, caseList->pn_pos.end); return new_<BinaryNode>(PNK_SWITCH, JSOP_NOP, pos, discriminant, caseList); } ParseNode* newCaseOrDefault(uint32_t begin, ParseNode* expr, ParseNode* body) { return new_<CaseClause>(expr, body, begin); } @@ -769,36 +782,68 @@ class FullParseHandler void setPosition(ParseNode* pn, const TokenPos& pos) { pn->pn_pos = pos; } TokenPos getPosition(ParseNode* pn) { return pn->pn_pos; } + bool isDeclarationKind(ParseNodeKind kind) { + return kind == PNK_VAR || kind == PNK_LET || kind == PNK_CONST; + } + ParseNode* newList(ParseNodeKind kind, JSOp op = JSOP_NOP) { - MOZ_ASSERT(kind != PNK_VAR); + MOZ_ASSERT(!isDeclarationKind(kind)); return new_<ListNode>(kind, op, pos()); } + ParseNode* newList(ParseNodeKind kind, uint32_t begin, JSOp op = JSOP_NOP) { + MOZ_ASSERT(!isDeclarationKind(kind)); return new_<ListNode>(kind, op, TokenPos(begin, begin + 1)); } + + ParseNode* newList(ParseNodeKind kind, ParseNode* kid, JSOp op = JSOP_NOP) { + MOZ_ASSERT(!isDeclarationKind(kind)); + return new_<ListNode>(kind, op, kid); + } + ParseNode* newDeclarationList(ParseNodeKind kind, JSOp op = JSOP_NOP) { - MOZ_ASSERT(kind == PNK_VAR || kind == PNK_CONST || kind == PNK_LET); + MOZ_ASSERT(isDeclarationKind(kind)); return new_<ListNode>(kind, op, pos()); } - /* New list with one initial child node. kid must be non-null. */ - ParseNode* newList(ParseNodeKind kind, ParseNode* kid, JSOp op = JSOP_NOP) { - MOZ_ASSERT(kind != PNK_VAR); + ParseNode* newDeclarationList(ParseNodeKind kind, ParseNode* kid, JSOp op = JSOP_NOP) { + MOZ_ASSERT(isDeclarationKind(kind)); return new_<ListNode>(kind, op, kid); } - ParseNode* newDeclarationList(ParseNodeKind kind, ParseNode* kid, JSOp op = JSOP_NOP) { - MOZ_ASSERT(kind == PNK_VAR || kind == PNK_CONST || kind == PNK_LET); - return new_<ListNode>(kind, op, kid); + + bool isDeclarationList(ParseNode* node) { + return isDeclarationKind(node->getKind()); + } + + bool declarationIsVar(ParseNode* node) { + MOZ_ASSERT(isDeclarationList(node)); + return node->isKind(PNK_VAR); + } + + bool declarationIsLet(ParseNode* node) { + MOZ_ASSERT(isDeclarationList(node)); + return node->isKind(PNK_LET); + } + + bool declarationIsConst(ParseNode* node) { + MOZ_ASSERT(isDeclarationList(node)); + return node->isKind(PNK_CONST); + } + + ParseNode* singleBindingFromDeclaration(ParseNode* decl) { + MOZ_ASSERT(isDeclarationList(decl)); + MOZ_ASSERT(decl->pn_count == 1); + return decl->pn_head; } ParseNode* newCatchList() { return new_<ListNode>(PNK_CATCHLIST, JSOP_NOP, pos()); } ParseNode* newCommaExpressionList(ParseNode* kid) { return newList(PNK_COMMA, kid, JSOP_NOP);
--- a/js/src/frontend/ParseNode.cpp +++ b/js/src/frontend/ParseNode.cpp @@ -770,20 +770,16 @@ Parser<FullParseHandler>::cloneParseTree pn->pn_u = opn->pn_u; break; #undef NULLCHECK } return pn; } -template <> -ParseNode* -Parser<FullParseHandler>::cloneLeftHandSide(ParseNode* opn); - /* * Used by Parser::cloneLeftHandSide to clone a default expression * in the form of * [a = default] or {a: b = default} */ template <> ParseNode* Parser<FullParseHandler>::cloneDestructuringDefault(ParseNode* opn) @@ -886,16 +882,26 @@ Parser<FullParseHandler>::cloneLeftHandS pn->setDefn(false); handler.linkUseToDef(pn, (Definition*) opn); } } return pn; } +template <> +SyntaxParseHandler::Node +Parser<SyntaxParseHandler>::cloneLeftHandSide(Node node) +{ + // See the comment in SyntaxParseHandler::singleBindingFromDeclaration for + // why this is okay. + MOZ_ASSERT(node == SyntaxParseHandler::NodeUnparenthesizedName); + return SyntaxParseHandler::NodeGeneric; +} + } /* namespace frontend */ } /* namespace js */ #ifdef DEBUG static const char * const parseNodeNames[] = { #define STRINGIFY(name) #name, FOR_EACH_PARSE_NODE_KIND(STRINGIFY)
--- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -1516,16 +1516,25 @@ struct BindData return isConst_; } bool isAnnexB() { MOZ_ASSERT(isInitialized()); return isAnnexB_; } + // The BoundNames of LexicalDeclaration and ForDeclaration must not contain + // 'let'. (CatchParameter is the only lexical binding form without this + // restriction.) + bool mustNotBindLet() { + MOZ_ASSERT(isInitialized()); + return isConst_ || + (kind_ == LexicalBinding && letData_.overflow != JSMSG_TOO_MANY_CATCH_VARS); + } + const LetData& letData() { MOZ_ASSERT(kind_ == LexicalBinding); return letData_; } bool bind(HandlePropertyName name, Parser<ParseHandler>* parser) { MOZ_ASSERT(isInitialized()); MOZ_ASSERT(nameNode_ != ParseHandler::null()); @@ -3547,16 +3556,23 @@ Parser<FullParseHandler>::bindLexical(Bi HandlePropertyName name, Parser<FullParseHandler>* parser) { ParseContext<FullParseHandler>* pc = parser->pc; ParseNode* pn = data->nameNode(); if (!parser->checkStrictBinding(name, pn)) return false; ExclusiveContext* cx = parser->context; + + // Most lexical declaration patterns can't bind the name 'let'. + if (data->mustNotBindLet() && name == cx->names().let) { + parser->report(ParseError, false, pn, JSMSG_LEXICAL_DECL_DEFINES_LET); + return false; + } + Rooted<StaticBlockObject*> blockObj(cx, data->letData().blockObj); uint32_t index = StaticBlockObject::LOCAL_INDEX_LIMIT; if (blockObj) { // Leave the scope coordinate free on global lexicals. // // For block-level lets, assign block-local index to pn->pn_scopecoord // right away. The emitter will adjust the node's slot based on its @@ -4351,231 +4367,359 @@ Parser<ParseHandler>::newBindingNode(Pro } } } /* Make a new node for this declarator name (or destructuring pattern). */ return newName(name); } +template <typename ParseHandler> +typename ParseHandler::Node +Parser<ParseHandler>::expressionAfterForInOrOf(ParseNodeKind forHeadKind, + YieldHandling yieldHandling) +{ + MOZ_ASSERT(forHeadKind == PNK_FORIN || forHeadKind == PNK_FOROF); + + return forHeadKind == PNK_FOROF + ? assignExpr(InAllowed, yieldHandling, TripledotProhibited) + : expr(InAllowed, yieldHandling, TripledotProhibited); +} + +template <typename ParseHandler> +typename ParseHandler::Node +Parser<ParseHandler>::declarationPattern(Node decl, TokenKind tt, BindData<ParseHandler>* data, + bool initialDeclaration, YieldHandling yieldHandling, + ParseNodeKind* forHeadKind, + Node* forInOrOfExpression) +{ + MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_LB) || + tokenStream.isCurrentTokenType(TOK_LC)); + + Node pattern; + { + pc->inDeclDestructuring = true; + pattern = primaryExpr(yieldHandling, TripledotProhibited, tt); + pc->inDeclDestructuring = false; + } + if (!pattern) + return null(); + + if (initialDeclaration && forHeadKind) { + bool isForIn, isForOf; + if (!matchInOrOf(&isForIn, &isForOf)) + return null(); + + if (isForIn) + *forHeadKind = PNK_FORIN; + else if (isForOf) + *forHeadKind = PNK_FOROF; + else + *forHeadKind = PNK_FORHEAD; + + if (*forHeadKind != PNK_FORHEAD) { + // |for (const ... in ...);| and |for (const ... of ...);| are + // syntax errors for now. We'll fix this in bug 449811. + if (handler.declarationIsConst(decl)) { + report(ParseError, false, pattern, JSMSG_BAD_CONST_DECL); + return null(); + } + + if (!checkDestructuringPattern(data, pattern)) + return null(); + + *forInOrOfExpression = expressionAfterForInOrOf(*forHeadKind, yieldHandling); + if (!*forInOrOfExpression) + return null(); + + return pattern; + } + } + + // See comment below for bindBeforeInitializer in the code that + // handles the non-destructuring case. + bool bindBeforeInitializer = handler.declarationIsVar(decl); + if (bindBeforeInitializer) { + if (!checkDestructuringPattern(data, pattern)) + return null(); + } + + MUST_MATCH_TOKEN(TOK_ASSIGN, JSMSG_BAD_DESTRUCT_DECL); + + Node init = assignExpr(forHeadKind ? InProhibited : InAllowed, + yieldHandling, TripledotProhibited); + if (!init) + return null(); + + if (forHeadKind) { + // For for(;;) declarations, consistency with |for (;| parsing requires + // that the ';' first be examined as Operand, even though absence of a + // binary operator (examined with modifier None) terminated |init|. + // For all other declarations, through ASI's infinite majesty, a next + // token on a new line would begin an expression. + tokenStream.addModifierException(TokenStream::OperandIsNone); + } + + if (!bindBeforeInitializer) { + if (!checkDestructuringPattern(data, pattern)) + return null(); + } + + return handler.newBinary(PNK_ASSIGN, pattern, init); +} + +template <typename ParseHandler> +bool +Parser<ParseHandler>::initializerInNameDeclaration(Node decl, Node binding, + Handle<PropertyName*> name, + BindData<ParseHandler>* data, + bool initialDeclaration, + YieldHandling yieldHandling, + ParseNodeKind* forHeadKind, + Node* forInOrOfExpression) +{ + MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_ASSIGN)); + + // Lexical bindings can't be accessed until initialized. A declaration + // of the form |let x = x| raises a ReferenceError, as the 'x' on the + // RHS accesses the binding before it's initialized. + // + // If we're not parsing a lexical declaration, bind the name now. + // Otherwise we must wait until after parsing the initializing + // assignment. + bool bindBeforeInitializer = handler.declarationIsVar(decl); + if (bindBeforeInitializer) { + if (!data->bind(name, this)) + return false; + } + + Node initializer = assignExpr(forHeadKind ? InProhibited : InAllowed, + yieldHandling, TripledotProhibited); + if (!initializer) + return false; + + bool performAssignment = true; + if (forHeadKind) { + if (initialDeclaration) { + bool isForIn, isForOf; + if (!matchInOrOf(&isForIn, &isForOf)) + return false; + + // An initialized declaration can't appear in a for-of: + // + // for (var/let/const x = ... of ...); // BAD + if (isForOf) { + report(ParseError, false, binding, JSMSG_BAD_FOR_LEFTSIDE); + return false; + } + + if (isForIn) { + // Lexical declarations in for-in loops can't be initialized: + // + // for (let/const x = ... in ...); // BAD + if (!handler.declarationIsVar(decl)) { + report(ParseError, false, binding, JSMSG_BAD_FOR_LEFTSIDE); + return false; + } + + // This leaves only initialized for-in |var| declarations. ES6 + // forbids these, yet they sadly still occur, rarely, on the + // web. *Don't* assign, and warn about this invalid syntax to + // incrementally move to ES6 semantics. + *forHeadKind = PNK_FORIN; + performAssignment = false; + if (!report(ParseWarning, pc->sc->strict(), initializer, + JSMSG_INVALID_FOR_IN_DECL_WITH_INIT)) + { + return false; + } + + *forInOrOfExpression = expressionAfterForInOrOf(PNK_FORIN, yieldHandling); + if (!*forInOrOfExpression) + return null(); + } else { + *forHeadKind = PNK_FORHEAD; + } + } + + if (*forHeadKind == PNK_FORHEAD) { + // Per Parser::forHeadStart, the semicolon in |for (;| is + // ultimately gotten as Operand. But initializer expressions + // terminate with the absence of an operator gotten as None, so we + // need an exception. + tokenStream.addModifierException(TokenStream::OperandIsNone); + } + } + + if (performAssignment) { + if (!bindBeforeInitializer && !data->bind(name, this)) + return false; + + if (!handler.finishInitializerAssignment(binding, initializer)) + return false; + } + + return true; +} + +template <typename ParseHandler> +typename ParseHandler::Node +Parser<ParseHandler>::declarationName(Node decl, TokenKind tt, BindData<ParseHandler>* data, + bool initialDeclaration, YieldHandling yieldHandling, + ParseNodeKind* forHeadKind, Node* forInOrOfExpression) +{ + if (tt != TOK_NAME) { + // Anything other than TOK_YIELD or TOK_NAME is an error. + if (tt != TOK_YIELD) { + report(ParseError, false, null(), JSMSG_NO_VARIABLE_NAME); + return null(); + } + + // TOK_YIELD is only okay if it's treated as a name. + if (!checkYieldNameValidity()) + return null(); + } + + RootedPropertyName name(context, tokenStream.currentName()); + Node binding = newBindingNode(name, handler.declarationIsVar(decl), HoistVars); + if (!binding) + return null(); + MOZ_ASSERT(data->isConst() == handler.declarationIsConst(decl)); + if (data->isConst()) + handler.setFlag(binding, PND_CONST); + data->setNameNode(binding); + + // The '=' context after a variable name in a declaration is an opportunity + // for ASI, and thus for the next token to start an ExpressionStatement: + // + // var foo // VariableDeclaration + // /bar/g; // ExpressionStatement + // + // Therefore get the token here as Operand. + bool matched; + if (!tokenStream.matchToken(&matched, TOK_ASSIGN, TokenStream::Operand)) + return null(); + + if (matched) { + if (!initializerInNameDeclaration(decl, binding, name, data, initialDeclaration, + yieldHandling, forHeadKind, forInOrOfExpression)) + { + return null(); + } + } else { + tokenStream.addModifierException(TokenStream::NoneIsOperand); + + bool constRequiringInitializer = handler.declarationIsConst(decl); + if (initialDeclaration && forHeadKind) { + bool isForIn, isForOf; + if (!matchInOrOf(&isForIn, &isForOf)) + return null(); + + if (isForIn || isForOf) { + // XXX Uncomment this when fixing bug 449811. Until then, + // |for (const ... in/of ...)| remains an error. + //constRequiringInitializer = false; + + *forHeadKind = isForIn ? PNK_FORIN : PNK_FOROF; + } else { + *forHeadKind = PNK_FORHEAD; + } + } + + if (constRequiringInitializer) { + report(ParseError, false, binding, JSMSG_BAD_CONST_DECL); + return null(); + } + + bool bindBeforeInitializer = handler.declarationIsVar(decl); + if (bindBeforeInitializer) { + if (!data->bind(name, this)) + return null(); + } + + if (forHeadKind && *forHeadKind != PNK_FORHEAD) { + *forInOrOfExpression = expressionAfterForInOrOf(*forHeadKind, yieldHandling); + if (!*forInOrOfExpression) + return null(); + } + + if (!bindBeforeInitializer) { + if (!data->bind(name, this)) + return null(); + } + } + + handler.setLexicalDeclarationOp(binding, data->op()); + return binding; +} + /* * The 'blockObj' parameter is non-null when parsing the 'vars' in a let * expression, block statement, non-top-level let declaration in statement * context, and the let-initializer of a for-statement. */ template <typename ParseHandler> typename ParseHandler::Node -Parser<ParseHandler>::variables(YieldHandling yieldHandling, - ParseNodeKind kind, - ForInitLocation location, - bool* psimple, StaticBlockObject* blockObj, VarContext varContext) -{ - MOZ_ASSERT(kind == PNK_VAR || kind == PNK_CONST || kind == PNK_LET); - - /* - * The simple flag is set if the declaration has the form 'var x', with - * only one variable declared and no initializer expression. - */ - MOZ_ASSERT_IF(psimple, *psimple); +Parser<ParseHandler>::declarationList(YieldHandling yieldHandling, + ParseNodeKind kind, + StaticBlockObject* blockObj /* = nullptr */, + ParseNodeKind* forHeadKind /* = nullptr */, + Node* forInOrOfExpression /* = nullptr */) +{ + MOZ_ASSERT(kind == PNK_VAR || kind == PNK_LET || kind == PNK_CONST); + MOZ_ASSERT_IF(blockObj != nullptr, kind == PNK_LET || kind == PNK_CONST); JSOp op; switch (kind) { case PNK_VAR: op = JSOP_DEFVAR; break; case PNK_CONST: op = JSOP_DEFCONST; break; case PNK_LET: op = JSOP_DEFLET; break; default: MOZ_CRASH("unknown variable kind"); } - Node pn = handler.newDeclarationList(kind, op); - if (!pn) + Node decl = handler.newDeclarationList(kind, op); + if (!decl) return null(); BindData<ParseHandler> data(context); if (kind == PNK_VAR) data.initVar(op); else - data.initLexical(varContext, op, blockObj, JSMSG_TOO_MANY_LOCALS); - - bool first = true; - Node pn2; - while (true) { - do { - if (psimple && !first) - *psimple = false; - first = false; - - TokenKind tt; - if (!tokenStream.getToken(&tt)) - return null(); - if (tt == TOK_LB || tt == TOK_LC) { - if (psimple) - *psimple = false; - - pc->inDeclDestructuring = true; - pn2 = primaryExpr(yieldHandling, TripledotProhibited, tt); - pc->inDeclDestructuring = false; - if (!pn2) - return null(); - - bool parsingForInOrOfInit = false; - if (location == InForInit) { - bool isForIn, isForOf; - if (!matchInOrOf(&isForIn, &isForOf)) - return null(); - parsingForInOrOfInit = isForIn || isForOf; - } - - // See comment below for bindBeforeInitializer in the code that - // handles the non-destructuring case. - bool bindBeforeInitializer = (kind != PNK_LET && kind != PNK_CONST) || - parsingForInOrOfInit; - if (bindBeforeInitializer && !checkDestructuringPattern(&data, pn2)) - return null(); - - if (parsingForInOrOfInit) { - tokenStream.ungetToken(); - handler.addList(pn, pn2); - break; - } - - MUST_MATCH_TOKEN(TOK_ASSIGN, JSMSG_BAD_DESTRUCT_DECL); - - Node init = assignExpr(location == InForInit ? InProhibited : InAllowed, - yieldHandling, TripledotProhibited); - if (!init) - return null(); - - // Ban the nonsensical |for (var V = E1 in E2);| where V is a - // destructuring pattern. See bug 1164741 for background. - if (location == InForInit && kind == PNK_VAR) { - TokenKind afterInit; - if (!tokenStream.peekToken(&afterInit)) - return null(); - if (afterInit == TOK_IN) { - report(ParseError, false, init, JSMSG_INVALID_FOR_INOF_DECL_WITH_INIT, - "in"); - return null(); - } - } - - if (!bindBeforeInitializer && !checkDestructuringPattern(&data, pn2)) - return null(); - - pn2 = handler.newBinary(PNK_ASSIGN, pn2, init); - if (!pn2) - return null(); - - handler.addList(pn, pn2); - break; - } - - if (tt != TOK_NAME) { - if (tt == TOK_YIELD) { - if (!checkYieldNameValidity()) - return null(); - } else { - report(ParseError, false, null(), JSMSG_NO_VARIABLE_NAME); - return null(); - } - } - - RootedPropertyName name(context, tokenStream.currentName()); - pn2 = newBindingNode(name, kind == PNK_VAR, varContext); - if (!pn2) - return null(); - if (data.isConst()) - handler.setFlag(pn2, PND_CONST); - data.setNameNode(pn2); - - handler.addList(pn, pn2); - - bool matched; - // The '=' context after a variable name in a declaration is an - // opportunity for ASI, and thus for the next token to start an - // ExpressionStatement: - // - // var foo // VariableDeclaration - // /bar/g; // ExpressionStatement - // - // Therefore we must get the token here as Operand. - if (!tokenStream.matchToken(&matched, TOK_ASSIGN, TokenStream::Operand)) - return null(); - if (!matched) { - tokenStream.addModifierException(TokenStream::NoneIsOperand); - - if (data.isConst() && location == NotInForInit) { - report(ParseError, false, null(), JSMSG_BAD_CONST_DECL); - return null(); - } - - if (!data.bind(name, this)) - return null(); - } else { - if (psimple) - *psimple = false; - - // In ES6, lexical bindings may not be accessed until - // initialized. So a declaration of the form |let x = x| results - // in a ReferenceError, as the 'x' on the RHS is accessing the let - // binding before it is initialized. - // - // If we are not parsing a let declaration, bind the name - // now. Otherwise we must wait until after parsing the initializing - // assignment. - bool bindBeforeInitializer = kind != PNK_LET && kind != PNK_CONST; - if (bindBeforeInitializer && !data.bind(name, this)) - return null(); - - Node init = assignExpr(location == InForInit ? InProhibited : InAllowed, - yieldHandling, TripledotProhibited); - if (!init) - return null(); - - // Ignore an initializer if we have a for-in loop declaring a - // |var| with an initializer: |for (var v = ... in ...);|. - // Warn that this syntax is invalid so that developers looking - // in the console know to fix this. ES<6 permitted the - // initializer while ES6 doesn't; ignoring it seems the best - // way to incrementally move to ES6 semantics. - bool performAssignment = true; - if (location == InForInit && kind == PNK_VAR) { - TokenKind afterInit; - if (!tokenStream.peekToken(&afterInit)) - return null(); - if (afterInit == TOK_IN) { - performAssignment = false; - if (!report(ParseWarning, pc->sc->strict(), init, - JSMSG_INVALID_FOR_INOF_DECL_WITH_INIT, "in")) - { - return null(); - } - } - } - - if (performAssignment) { - if (!bindBeforeInitializer && !data.bind(name, this)) - return null(); - - if (!handler.finishInitializerAssignment(pn2, init)) - return null(); - } - } - - handler.setLexicalDeclarationOp(pn2, data.op()); - handler.setEndPosition(pn, pn2); - } while (false); - - bool matched; + data.initLexical(HoistVars, op, blockObj, JSMSG_TOO_MANY_LOCALS); + + bool matched; + bool initialDeclaration = true; + do { + MOZ_ASSERT_IF(!initialDeclaration && forHeadKind, + *forHeadKind == PNK_FORHEAD); + + TokenKind tt; + if (!tokenStream.getToken(&tt)) + return null(); + + Node binding = (tt == TOK_LB || tt == TOK_LC) + ? declarationPattern(decl, tt, &data, initialDeclaration, yieldHandling, + forHeadKind, forInOrOfExpression) + : declarationName(decl, tt, &data, initialDeclaration, yieldHandling, + forHeadKind, forInOrOfExpression); + if (!binding) + return null(); + + handler.addList(decl, binding); + + if (forHeadKind && *forHeadKind != PNK_FORHEAD) + break; + + initialDeclaration = false; + if (!tokenStream.matchToken(&matched, TOK_COMMA)) return null(); - if (!matched) - break; - } - - return pn; + } while (matched); + + return decl; } template <> bool Parser<FullParseHandler>::checkAndPrepareLexical(PrepareLexicalKind prepareWhat, const TokenPos& errorPos) { /* @@ -4680,16 +4824,31 @@ CurrentLexicalStaticBlock(ParseContext<F return &pc->innermostStaticScope()->as<StaticBlockObject>(); MOZ_ASSERT(pc->atBodyLevel() && (!pc->sc->isGlobalContext() || HasNonSyntacticStaticScopeChain(pc->innermostStaticScope()))); return nullptr; } template <> +void +Parser<SyntaxParseHandler>::assertCurrentLexicalStaticBlockIs(ParseContext<SyntaxParseHandler>* pc, + Handle<StaticBlockObject*> blockObj) +{ +} + +template <> +void +Parser<FullParseHandler>::assertCurrentLexicalStaticBlockIs(ParseContext<FullParseHandler>* pc, + Handle<StaticBlockObject*> blockObj) +{ + MOZ_ASSERT(CurrentLexicalStaticBlock(pc) == blockObj); +} + +template <> bool Parser<FullParseHandler>::prepareAndBindInitializedLexicalWithNode(HandlePropertyName name, PrepareLexicalKind prepareWhat, ParseNode* pn, const TokenPos& pos) { BindData<FullParseHandler> data(context); if (!checkAndPrepareLexical(prepareWhat, pos)) @@ -4741,22 +4900,23 @@ Parser<FullParseHandler>::lexicalDeclara * is the VariableEnvironment, i.e., body-level lets are in * the same environment record as vars. * * However, they cannot be parsed exactly as vars, as ES6 * requires that uninitialized lets throw ReferenceError on use. * * See 8.1.1.1.6 and the note in 13.2.1. */ - ParseNodeKind kind = isConst ? PNK_CONST : PNK_LET; - ParseNode* pn = variables(yieldHandling, kind, NotInForInit, - nullptr, CurrentLexicalStaticBlock(pc), HoistVars); - if (!pn) - return null(); - return MatchOrInsertSemicolonAfterExpression(tokenStream) ? pn : nullptr; + ParseNode* decl = + declarationList(yieldHandling, isConst ? PNK_CONST : PNK_LET, + CurrentLexicalStaticBlock(pc)); + if (!decl || !MatchOrInsertSemicolonAfterExpression(tokenStream)) + return null(); + + return decl; } template <> SyntaxParseHandler::Node Parser<SyntaxParseHandler>::lexicalDeclaration(YieldHandling, bool) { JS_ALWAYS_FALSE(abortIfSyntaxParser()); return SyntaxParseHandler::NodeFailure; @@ -5225,17 +5385,17 @@ Parser<FullParseHandler>::exportDeclarat const ClassNode& cls = kid->as<ClassNode>(); MOZ_ASSERT(cls.names()); if (!addExportName(cls.names()->innerBinding()->pn_atom)) return null(); break; } case TOK_VAR: - kid = variables(YieldIsName, PNK_VAR, NotInForInit); + kid = declarationList(YieldIsName, PNK_VAR); if (!kid) return null(); if (!MatchOrInsertSemicolonAfterExpression(tokenStream)) return null(); if (!addExportNamesForDeclaration(kid)) return null(); break; @@ -5415,69 +5575,198 @@ Parser<ParseHandler>::whileStatement(Yie template <typename ParseHandler> bool Parser<ParseHandler>::matchInOrOf(bool* isForInp, bool* isForOfp) { TokenKind tt; if (!tokenStream.getToken(&tt)) return false; + *isForInp = tt == TOK_IN; *isForOfp = tt == TOK_NAME && tokenStream.currentToken().name() == context->names().of; if (!*isForInp && !*isForOfp) { tokenStream.ungetToken(); } else { if (tt == TOK_NAME && !checkUnescapedName()) return false; } + + MOZ_ASSERT_IF(*isForInp || *isForOfp, *isForInp != *isForOfp); return true; } -template <> +template <class ParseHandler> bool -Parser<FullParseHandler>::isValidForStatementLHS(ParseNode* pn1, JSVersion version, - bool isForDecl, bool isForEach, - ParseNodeKind headKind) -{ - if (isForDecl) - return pn1->pn_count < 2 && !pn1->isKind(PNK_CONST); - - switch (pn1->getKind()) { - case PNK_ARRAY: - case PNK_CALL: - case PNK_DOT: - case PNK_ELEM: - case PNK_NAME: - case PNK_OBJECT: - return true; - - default: +Parser<ParseHandler>::validateForInOrOfLHSExpression(Node target) +{ + if (handler.isUnparenthesizedDestructuringPattern(target)) + return checkDestructuringPattern(nullptr, target); + + // All other permitted targets are simple. + if (!reportIfNotValidSimpleAssignmentTarget(target, ForInOrOfTarget)) return false; - } -} - -template <> + + if (handler.isPropertyAccess(target)) + return true; + + if (handler.maybeNameAnyParentheses(target)) { + // The arguments/eval identifiers are simple in non-strict mode code, + // but warn to discourage use nonetheless. + if (!reportIfArgumentsEvalTarget(target)) + return false; + + handler.adjustGetToSet(target); + handler.markAsAssigned(target); + return true; + } + + if (handler.isFunctionCall(target)) + return makeSetCall(target, JSMSG_BAD_FOR_LEFTSIDE); + + report(ParseError, false, target, JSMSG_BAD_FOR_LEFTSIDE); + return false; +} + +template <class ParseHandler> bool -Parser<FullParseHandler>::checkForHeadConstInitializers(ParseNode* pn1) -{ - if (!pn1->isKind(PNK_CONST)) +Parser<ParseHandler>::forHeadStart(YieldHandling yieldHandling, + ParseNodeKind* forHeadKind, + Node* forInitialPart, + Maybe<AutoPushStmtInfoPC>& letStmt, + MutableHandle<StaticBlockObject*> blockObj, + Node* forLetImpliedBlock, + Node* forInOrOfExpression) +{ + MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_LP)); + + TokenKind tt; + if (!tokenStream.peekToken(&tt, TokenStream::Operand)) + return null(); + + // Super-duper easy case: |for (;| is a C-style for-loop with no init + // component. + if (tt == TOK_SEMI) { + *forInitialPart = null(); + *forHeadKind = PNK_FORHEAD; return true; - - for (ParseNode* assign = pn1->pn_head; assign; assign = assign->pn_next) { - MOZ_ASSERT(assign->isKind(PNK_ASSIGN) || assign->isKind(PNK_NAME)); - if (assign->isKind(PNK_NAME) && !assign->isAssigned()) + } + + // Parsing after |for (var| is also relatively simple (from this method's + // point of view). No block-related work complicates matters, so delegate + // to Parser::declaration. + if (tt == TOK_VAR) { + tokenStream.consumeKnownToken(tt, TokenStream::Operand); + + // Pass null for block object because |var| declarations don't use one. + *forInitialPart = declarationList(yieldHandling, PNK_VAR, nullptr, forHeadKind, + forInOrOfExpression); + return *forInitialPart != null(); + } + + // Otherwise we have a lexical declaration or an expression. + + // For-in loop backwards compatibility requires that |let| starting a + // for-loop that's not a (new to ES6) for-of loop, in non-strict mode code, + // parse as an identifier. (|let| in for-of is always a declaration.) + // Thus we must can't just sniff out TOK_CONST/TOK_LET here. :-( + bool parsingLexicalDeclaration = false; + bool letIsIdentifier = false; + if (tt == TOK_LET || tt == TOK_CONST) { + parsingLexicalDeclaration = true; + tokenStream.consumeKnownToken(tt, TokenStream::Operand); + } else if (tt == TOK_NAME && tokenStream.nextName() == context->names().let) { + // Check for the backwards-compatibility corner case in sloppy + // mode like |for (let in e)| where the 'let' token should be + // parsed as an identifier. + if (!peekShouldParseLetDeclaration(&parsingLexicalDeclaration, TokenStream::Operand)) + return false; + + letIsIdentifier = !parsingLexicalDeclaration; + } + + if (parsingLexicalDeclaration) { + handler.disableSyntaxParser(); + + // Set up the block chain for the lexical declaration. + blockObj.set(StaticBlockObject::create(context)); + if (!blockObj) + return false; + blockObj->initEnclosingScopeFromParser(pc->innermostStaticScope()); + letStmt.emplace(*this, StmtType::BLOCK); + *forLetImpliedBlock = pushLetScope(blockObj, *letStmt); + if (!*forLetImpliedBlock) return false; - // PNK_ASSIGN nodes (destructuring assignment) are always assignments. - } - return true; -} - -template <> -ParseNode* -Parser<FullParseHandler>::forStatement(YieldHandling yieldHandling) + (*letStmt)->isForLetBlock = true; + + assertCurrentLexicalStaticBlockIs(pc, blockObj); + *forInitialPart = declarationList(yieldHandling, tt == TOK_CONST ? PNK_CONST : PNK_LET, + blockObj, forHeadKind, forInOrOfExpression); + return *forInitialPart != null(); + } + + // Finally, handle for-loops that start with expressions. Pass + // |InProhibited| so that |in| isn't parsed in a RelationalExpression as a + // binary operator. |in| makes it a for-in loop, *not* an |in| expression. + *forInitialPart = expr(InProhibited, yieldHandling, TripledotProhibited); + if (!*forInitialPart) + return false; + + bool isForIn, isForOf; + if (!matchInOrOf(&isForIn, &isForOf)) + return false; + + // If we don't encounter 'in'/'of', we have a for(;;) loop. We've handled + // the init expression; the caller handles the rest. Allow the Operand + // modifier when regetting: Operand must be used to examine the ';' in + // |for (;|, and our caller handles this case and that. + if (!isForIn && !isForOf) { + *forHeadKind = PNK_FORHEAD; + tokenStream.addModifierException(TokenStream::OperandIsNone); + return true; + } + + MOZ_ASSERT(isForIn != isForOf); + + // In a for-of loop, 'let' that starts the loop head is a |let| keyword, + // per the [lookahead ≠let] restriction on the LeftHandSideExpression + // variant of such loops. Expressions that start with |let| can't be used + // here. + // + // var let = {}; + // for (let.prop of [1]) // BAD + // break; + // + // See ES6 13.7. + if (isForOf && letIsIdentifier) { + report(ParseError, false, *forInitialPart, JSMSG_LET_STARTING_FOROF_LHS); + return false; + } + + *forHeadKind = isForIn ? PNK_FORIN : PNK_FOROF; + + if (!validateForInOrOfLHSExpression(*forInitialPart)) + return false; + + // Finally, parse the iterated expression, making the for-loop's closing + // ')' the next token. + *forInOrOfExpression = expressionAfterForInOrOf(*forHeadKind, yieldHandling); + return *forInOrOfExpression != null(); +} + +template <class ParseHandler> +typename ParseHandler::Node +Parser<ParseHandler>::cloneForInOrOfDeclarationForAssignment(Node decl) +{ + return cloneLeftHandSide(handler.singleBindingFromDeclaration(decl)); +} + +template <class ParseHandler> +typename ParseHandler::Node +Parser<ParseHandler>::forStatement(YieldHandling yieldHandling) { MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FOR)); uint32_t begin = pos().begin; AutoPushStmtInfoPC forStmt(*this, StmtType::FOR_LOOP); bool isForEach = false; unsigned iflags = 0; @@ -5494,432 +5783,205 @@ Parser<FullParseHandler>::forStatement(Y if (!report(ParseWarning, pc->sc->strict(), null(), JSMSG_DEPRECATED_FOR_EACH)) return null(); } } } MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR); - // True if we have 'for (var/let/const ...)'. - bool isForDecl = false; + // PNK_FORHEAD, PNK_FORIN, or PNK_FOROF depending on the loop type. + ParseNodeKind headKind; + + // |x| in either |for (x; ...; ...)| or |for (x in/of ...)|. + Node startNode; // The next three variables are used to implement `for (let/const ...)`. // // We generate an implicit block, wrapping the whole loop, to store loop // variables declared this way. Note that if the loop uses `for (var...)` // instead, those variables go on some existing enclosing scope, so no // implicit block scope is created. // // All three variables remain null/none if the loop is any other form. // // blockObj is the static block object for the implicit block scope. RootedStaticBlockObject blockObj(context); + // The PNK_LEXICALSCOPE node containing blockObj's ObjectBox. + Node forLetImpliedBlock = null(); + // letStmt is the BLOCK StmtInfo for the implicit block. // // Caution: `letStmt.emplace()` creates some Rooted objects. Rooteds must // be created/destroyed in FIFO order. Therefore adding a Rooted in this // function, between this point and the .emplace() call below, would trip // assertions. Maybe<AutoPushStmtInfoPC> letStmt; - // The PNK_LEXICALSCOPE node containing blockObj's ObjectBox. - ParseNode* forLetImpliedBlock = nullptr; - - // True if a 'let' token at the head is parsed as an identifier instead of - // as starting a declaration. - bool letIsIdentifier = false; - - // Set to 'x' in 'for (x; ...; ...)' or 'for (x in ...)'. - ParseNode* pn1; - - TokenStream::Modifier modifier = TokenStream::Operand; + // The expression being iterated over, for for-in/of loops only. Unused + // for for(;;) loops. + Node iteratedExpr; + + // Parse the entirety of the loop-head for a for-in/of loop (so the next + // token is the closing ')'): + // + // for (... in/of ...) ... + // ^next token + // + // ...OR, parse up to the first ';' in a C-style for-loop: + // + // for (...; ...; ...) ... + // ^next token + // + // In either case the subsequent token can be consistently accessed using + // TokenStream::None semantics. + if (!forHeadStart(yieldHandling, &headKind, &startNode, letStmt, &blockObj, + &forLetImpliedBlock, &iteratedExpr)) { - TokenKind tt; - if (!tokenStream.peekToken(&tt, TokenStream::Operand)) - return null(); - if (tt == TOK_SEMI) { - pn1 = nullptr; - } else { - // Set pn1 to a variable list or an initializing expression. - // - // Pass |InForInit| to Parser::variables when parsing declarations - // to trigger |for|-specific parsing for that one position. In a - // normal variable declaration, any initializer may be an |in| - // expression. But for declarations at the start of a for-loop - // head, initializers can't contain |in|. (Such syntax conflicts - // with ES5's |for (var i = 0 in foo)| syntax, removed in ES6, that - // we "support" by ignoring the |= 0|.) - if (tt == TOK_VAR) { - isForDecl = true; - tokenStream.consumeKnownToken(tt, TokenStream::Operand); - pn1 = variables(yieldHandling, PNK_VAR, InForInit); - } else if (tt == TOK_LET || tt == TOK_CONST || - (tt == TOK_NAME && tokenStream.nextName() == context->names().let)) { - handler.disableSyntaxParser(); - - // Check for the backwards-compatibility corner case in sloppy - // mode like |for (let in e)| where the 'let' token should be - // parsed as an identifier. - bool parseDecl; - if (tt == TOK_NAME) { - if (!peekShouldParseLetDeclaration(&parseDecl, TokenStream::Operand)) - return null(); - letIsIdentifier = !parseDecl; - } else { - parseDecl = true; - tokenStream.consumeKnownToken(tt, TokenStream::Operand); - } - - if (parseDecl) { - bool constDecl = tt == TOK_CONST; - isForDecl = true; - - // Initialize the enclosing scope manually for the call to - // |variables| below. - blockObj = StaticBlockObject::create(context); - if (!blockObj) - return null(); - blockObj->initEnclosingScopeFromParser(pc->innermostStaticScope()); - letStmt.emplace(*this, StmtType::BLOCK); - forLetImpliedBlock = pushLetScope(blockObj, *letStmt); - if (!forLetImpliedBlock) - return null(); - (*letStmt)->isForLetBlock = true; - - MOZ_ASSERT(CurrentLexicalStaticBlock(pc) == blockObj); - pn1 = variables(yieldHandling, constDecl ? PNK_CONST : PNK_LET, InForInit, - nullptr, blockObj, HoistVars); - } else { - pn1 = expr(InProhibited, yieldHandling, TripledotProhibited); - } - } else { - // Pass |InProhibited| when parsing an expression so that |in| - // isn't parsed in a RelationalExpression as a binary operator. - // In this context, |in| is part of a for-in loop -- *not* part - // of a binary expression. - pn1 = expr(InProhibited, yieldHandling, TripledotProhibited); - } - if (!pn1) - return null(); - modifier = TokenStream::None; - } - } - - MOZ_ASSERT_IF(isForDecl, pn1->isArity(PN_LIST)); - MOZ_ASSERT(letStmt.isSome() == (isForDecl && (pn1->isOp(JSOP_DEFLET) || pn1->isOp(JSOP_DEFCONST)))); - - // If there's an |in| keyword here, it's a for-in loop, by dint of careful - // parsing of |pn1|. - ParseNode* pn2; /* forHead->pn_kid2 */ - ParseNode* pn3; /* forHead->pn_kid3 */ - ParseNodeKind headKind = PNK_FORHEAD; - if (pn1) { - bool isForIn, isForOf; - if (!matchInOrOf(&isForIn, &isForOf)) - return null(); - - // In for-in loops, a 'let' token may be used as an identifier for - // backwards-compatibility reasons, e.g., |for (let in e)|. In for-of - // loops, a 'let' token is never parsed as an identifier. Forbid - // trying to parse a for-of loop if we have parsed a 'let' token as an - // identifier above. - // - // See ES6 13.7.5.1. - if (isForIn) - headKind = PNK_FORIN; - else if (isForOf && !letIsIdentifier) - headKind = PNK_FOROF; - } - + return null(); + } + + MOZ_ASSERT(headKind == PNK_FORIN || headKind == PNK_FOROF || headKind == PNK_FORHEAD); + + Node pn1; + Node pn2; + Node pn3; + TokenStream::Modifier modifier; if (headKind == PNK_FOROF || headKind == PNK_FORIN) { + // |target| is the LeftHandSideExpression or declaration to which the + // per-iteration value (an arbitrary value exposed by the iteration + // protocol, or a string naming a property) is assigned. + Node target = startNode; + /* * Parse the rest of the for/in or for/of head. * * Here pn1 is everything to the left of 'in' or 'of'. At the end of * this block, pn1 is a decl or nullptr, pn2 is the assignment target * that receives the enumeration value each iteration, and pn3 is the * rhs of 'in'. */ if (headKind == PNK_FOROF) { forStmt->type = StmtType::FOR_OF_LOOP; if (isForEach) { - report(ParseError, false, null(), JSMSG_BAD_FOR_EACH_LOOP); + report(ParseError, false, startNode, JSMSG_BAD_FOR_EACH_LOOP); return null(); } } else { forStmt->type = StmtType::FOR_IN_LOOP; iflags |= JSITER_ENUMERATE; } - /* Check that the left side of the 'in' or 'of' is valid. */ - if (!isValidForStatementLHS(pn1, versionNumber(), isForDecl, isForEach, headKind)) { - report(ParseError, false, pn1, JSMSG_BAD_FOR_LEFTSIDE); - return null(); - } - /* * After the following if-else, pn2 will point to the name or * destructuring pattern on in's left. pn1 will point to the decl, if * any, else nullptr. Note that the "declaration with initializer" case * rewrites the loop-head, moving the decl and setting pn1 to nullptr. */ - if (isForDecl) { - pn2 = pn1->pn_head; - if ((pn2->isKind(PNK_NAME) && pn2->maybeExpr()) || pn2->isKind(PNK_ASSIGN)) { - MOZ_ASSERT(!(headKind == PNK_FORIN && pn1->isKind(PNK_VAR)), - "Parser::variables should have ignored the " - "initializer in the ES5-sanctioned, ES6-prohibited " - "|for (var ... = ... in ...)| syntax"); - - // Otherwise, this bizarre |for (const/let x = ... in/of ...)| - // loop isn't valid ES6 and has never been permitted in - // SpiderMonkey. - report(ParseError, false, pn2, JSMSG_INVALID_FOR_INOF_DECL_WITH_INIT, - headKind == PNK_FOROF ? "of" : "in"); - return null(); - } + if (handler.isDeclarationList(target)) { + pn1 = target; + + // Make a copy of the declaration that can be passed to + // BytecodeEmitter::emitAssignment. + pn2 = cloneForInOrOfDeclarationForAssignment(target); + if (!pn2) + return null(); } else { - /* Not a declaration. */ MOZ_ASSERT(!letStmt); - pn2 = pn1; - pn1 = nullptr; + pn1 = null(); + pn2 = target; if (!checkAndMarkAsAssignmentLhs(pn2, PlainAssignment)) return null(); } - pn3 = (headKind == PNK_FOROF) - ? assignExpr(InAllowed, yieldHandling, TripledotProhibited) - : expr(InAllowed, yieldHandling, TripledotProhibited); - if (!pn3) - return null(); + pn3 = iteratedExpr; + + if (handler.maybeNameAnyParentheses(pn2)) { + // Beware 'for (arguments in ...)' with or without a 'var'. + handler.markAsAssigned(pn2); + } + + // Parser::declaration consumed everything up to the closing ')'. That + // token follows an {Assignment,}Expression, so the next token must be + // consumed as if an operator continued the expression, i.e. as None. modifier = TokenStream::None; - - if (isForDecl) { - /* - * pn2 is part of a declaration. Make a copy that can be passed to - * BytecodeEmitter::emitAssignment. - */ - pn2 = cloneLeftHandSide(pn2); - if (!pn2) - return null(); - } - - ParseNodeKind kind2 = pn2->getKind(); - MOZ_ASSERT(kind2 != PNK_ASSIGN, "forStatement TOK_ASSIGN"); - - if (kind2 == PNK_NAME) { - /* Beware 'for (arguments in ...)' with or without a 'var'. */ - pn2->markAsAssigned(); - } } else { + Node init = startNode; + if (isForEach) { reportWithOffset(ParseError, false, begin, JSMSG_BAD_FOR_EACH_LOOP); return null(); } - MOZ_ASSERT(headKind == PNK_FORHEAD); - - if (letStmt) { - // Ensure here that the previously-unchecked assignment mandate for - // const declarations holds. - if (!checkForHeadConstInitializers(pn1)) { - report(ParseError, false, nullptr, JSMSG_BAD_CONST_DECL); - return null(); - } - } - - /* Parse the loop condition or null into pn2. */ - MUST_MATCH_TOKEN_MOD(TOK_SEMI, modifier, JSMSG_SEMI_AFTER_FOR_INIT); + // Look for an operand: |for (;| means we might have already examined + // this semicolon with that modifier. + MUST_MATCH_TOKEN_MOD(TOK_SEMI, TokenStream::Operand, JSMSG_SEMI_AFTER_FOR_INIT); + TokenKind tt; if (!tokenStream.peekToken(&tt, TokenStream::Operand)) return null(); + + Node test; + TokenStream::Modifier mod; if (tt == TOK_SEMI) { - pn2 = nullptr; - modifier = TokenStream::Operand; + test = null(); + mod = TokenStream::Operand; } else { - pn2 = expr(InAllowed, yieldHandling, TripledotProhibited); - if (!pn2) - return null(); - modifier = TokenStream::None; - } - - /* Parse the update expression or null into pn3. */ - MUST_MATCH_TOKEN_MOD(TOK_SEMI, modifier, JSMSG_SEMI_AFTER_FOR_COND); + test = expr(InAllowed, yieldHandling, TripledotProhibited); + if (!test) + return null(); + mod = TokenStream::None; + } + + MUST_MATCH_TOKEN_MOD(TOK_SEMI, mod, JSMSG_SEMI_AFTER_FOR_COND); + if (!tokenStream.peekToken(&tt, TokenStream::Operand)) return null(); + + Node update; if (tt == TOK_RP) { - pn3 = nullptr; - modifier = TokenStream::Operand; + update = null(); + mod = TokenStream::Operand; } else { - pn3 = expr(InAllowed, yieldHandling, TripledotProhibited); - if (!pn3) - return null(); - modifier = TokenStream::None; - } + update = expr(InAllowed, yieldHandling, TripledotProhibited); + if (!update) + return null(); + mod = TokenStream::None; + } + + modifier = mod; + pn1 = init; + pn2 = test; + pn3 = update; } MUST_MATCH_TOKEN_MOD(TOK_RP, modifier, JSMSG_PAREN_AFTER_FOR_CTRL); TokenPos headPos(begin, pos().end); - ParseNode* forHead = handler.newForHead(headKind, pn1, pn2, pn3, headPos); + Node forHead = handler.newForHead(headKind, pn1, pn2, pn3, headPos); if (!forHead) return null(); - /* Parse the loop body. */ - ParseNode* body = statement(yieldHandling); + Node body = statement(yieldHandling); if (!body) return null(); - ParseNode* forLoop = handler.newForStatement(begin, forHead, body, iflags); + Node forLoop = handler.newForStatement(begin, forHead, body, iflags); if (!forLoop) return null(); if (forLetImpliedBlock) { - forLetImpliedBlock->pn_expr = forLoop; - forLetImpliedBlock->pn_pos = forLoop->pn_pos; + handler.initForLetBlock(forLetImpliedBlock, forLoop); return forLetImpliedBlock; } return forLoop; } -template <> -SyntaxParseHandler::Node -Parser<SyntaxParseHandler>::forStatement(YieldHandling yieldHandling) -{ - /* - * 'for' statement parsing is fantastically complicated and requires being - * able to inspect the parse tree for previous parts of the 'for'. Syntax - * parsing of 'for' statements is thus done separately, and only handles - * the types of 'for' statements likely to be seen in web content. - */ - MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FOR)); - - AutoPushStmtInfoPC forStmt(*this, StmtType::FOR_LOOP); - - /* Don't parse 'for each' loops. */ - if (allowsForEachIn()) { - TokenKind tt; - if (!tokenStream.peekToken(&tt)) - return null(); - // Not all "yield" tokens are names, but the ones that aren't names are - // invalid in this context anyway. - if (tt == TOK_NAME || tt == TOK_YIELD) { - JS_ALWAYS_FALSE(abortIfSyntaxParser()); - return null(); - } - } - - MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR); - - /* True if we have 'for (var ...)'. */ - bool isForDecl = false; - bool simpleForDecl = true; - - /* Set to 'x' in 'for (x ;... ;...)' or 'for (x in ...)'. */ - Node lhsNode; - - TokenStream::Modifier modifier = TokenStream::Operand; - { - TokenKind tt; - if (!tokenStream.peekToken(&tt, TokenStream::Operand)) - return null(); - if (tt == TOK_SEMI) { - lhsNode = null(); - } else { - /* Set lhsNode to a var list or an initializing expression. */ - if (tt == TOK_VAR) { - isForDecl = true; - tokenStream.consumeKnownToken(tt, TokenStream::Operand); - lhsNode = variables(yieldHandling, PNK_VAR, InForInit, &simpleForDecl); - } else if (tt == TOK_CONST || tt == TOK_LET || - (tt == TOK_NAME && tokenStream.nextName() == context->names().let)) - { - JS_ALWAYS_FALSE(abortIfSyntaxParser()); - return null(); - } else { - lhsNode = expr(InProhibited, yieldHandling, TripledotProhibited); - } - if (!lhsNode) - return null(); - modifier = TokenStream::None; - } - } - - // If there's an |in| keyword here, it's a for-in loop, by dint of careful - // parsing of |pn1|. - bool isForIn = false, isForOf = false; - if (lhsNode) { - if (!matchInOrOf(&isForIn, &isForOf)) - return null(); - } - if (isForIn || isForOf) { - /* Parse the rest of the for/in or for/of head. */ - forStmt->type = isForOf ? StmtType::FOR_OF_LOOP : StmtType::FOR_IN_LOOP; - - /* Check that the left side of the 'in' or 'of' is valid. */ - if (!isForDecl && - !handler.maybeNameAnyParentheses(lhsNode) && - !handler.isPropertyAccess(lhsNode)) - { - JS_ALWAYS_FALSE(abortIfSyntaxParser()); - return null(); - } - - if (!simpleForDecl) { - JS_ALWAYS_FALSE(abortIfSyntaxParser()); - return null(); - } - - if (!isForDecl && !checkAndMarkAsAssignmentLhs(lhsNode, PlainAssignment)) - return null(); - - if (!(isForIn - ? expr(InAllowed, yieldHandling, TripledotProhibited) - : assignExpr(InAllowed, yieldHandling, TripledotProhibited))) - { - return null(); - } - modifier = TokenStream::None; - } else { - /* Parse the loop condition or null. */ - MUST_MATCH_TOKEN_MOD(TOK_SEMI, modifier, JSMSG_SEMI_AFTER_FOR_INIT); - TokenKind tt; - if (!tokenStream.peekToken(&tt, TokenStream::Operand)) - return null(); - modifier = TokenStream::Operand; - if (tt != TOK_SEMI) { - if (!expr(InAllowed, yieldHandling, TripledotProhibited)) - return null(); - modifier = TokenStream::None; - } - - /* Parse the update expression or null. */ - MUST_MATCH_TOKEN_MOD(TOK_SEMI, modifier, JSMSG_SEMI_AFTER_FOR_COND); - if (!tokenStream.peekToken(&tt, TokenStream::Operand)) - return null(); - modifier = TokenStream::Operand; - if (tt != TOK_RP) { - if (!expr(InAllowed, yieldHandling, TripledotProhibited)) - return null(); - modifier = TokenStream::None; - } - } - - MUST_MATCH_TOKEN_MOD(TOK_RP, modifier, JSMSG_PAREN_AFTER_FOR_CTRL); - - /* Parse the loop body. */ - if (!statement(yieldHandling)) - return null(); - - return SyntaxParseHandler::NodeGeneric; -} - template <typename ParseHandler> typename ParseHandler::Node Parser<ParseHandler>::switchStatement(YieldHandling yieldHandling) { MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_SWITCH)); uint32_t begin = pos().begin; MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_SWITCH); @@ -6901,35 +6963,46 @@ Parser<SyntaxParseHandler>::classDefinit return SyntaxParseHandler::NodeFailure; } template <typename ParseHandler> bool Parser<ParseHandler>::shouldParseLetDeclaration(bool* parseDeclOut) { TokenKind tt; - *parseDeclOut = false; - if (!tokenStream.peekToken(&tt)) return false; - switch (tt) { - case TOK_NAME: - // |let let| is disallowed per ES6 13.3.1.1. - *parseDeclOut = tokenStream.nextName() != context->names().let; - break; - - case TOK_LC: - case TOK_LB: - // |let {| and |let [| are destructuring declarations. + if (tt == TOK_NAME) { + // |let| followed by a name is a lexical declaration. This is so even + // if the name is on a new line. ASI applies *only* if an offending + // token not allowed by the grammar is encountered, and there's no + // [no LineTerminator here] restriction in LexicalDeclaration or + // ForDeclaration forbidding a line break. + // + // It's a tricky point, but this is true *even if* the name is "let", a + // name that can't be bound by LexicalDeclaration or ForDeclaration. + // Per ES6 5.3, static semantics early errors are validated *after* + // determining productions matching the source text. So in this + // example: + // + // let // ASI opportunity...except not + // let; + // + // the text matches LexicalDeclaration. *Then* static semantics in + // ES6 13.3.1.1 (corresponding to the LexicalDeclaration production + // just chosen), per ES6 5.3, are validated to recognize the Script as + // invalid. It can't be evaluated, so a SyntaxError is thrown. *parseDeclOut = true; - break; - - default: - break; + } else if (tt == TOK_LB || tt == TOK_LC) { + *parseDeclOut = true; + } else { + // Whatever we have isn't a declaration. Either it's an expression, or + // it's invalid: expression-parsing code will decide. + *parseDeclOut = false; } return true; } template <typename ParseHandler> bool Parser<ParseHandler>::peekShouldParseLetDeclaration(bool* parseDeclOut, @@ -6972,17 +7045,17 @@ Parser<ParseHandler>::statement(YieldHan switch (tt) { // BlockStatement[?Yield, ?Return] case TOK_LC: return blockStatement(yieldHandling); // VariableStatement[?Yield] case TOK_VAR: { - Node pn = variables(yieldHandling, PNK_VAR, NotInForInit); + Node pn = declarationList(yieldHandling, PNK_VAR); if (!pn) return null(); if (!MatchOrInsertSemicolonAfterExpression(tokenStream)) return null(); return pn; } // EmptyStatement @@ -7018,27 +7091,30 @@ Parser<ParseHandler>::statement(YieldHan if (!checkYieldNameValidity()) return null(); return labeledStatement(yieldHandling); } return expressionStatement(yieldHandling); } case TOK_NAME: { - // 'let' is a contextual keyword in sloppy node. In strict mode, it is - // always lexed as TOK_LET except following case: + // 'let' is a contextual keyword outside strict mode. In strict mode + // it's always tokenized as TOK_LET except in this one weird case: // - // "use strict" - // let a = 1; + // "use strict" // ExpressionStatement, terminated by ASI + // let a = 1; // LexicalDeclaration // - // There 'let' is lexed as TOK_NAME before parsing directive. + // We can't apply strict mode until we know "use strict" is the entire + // statement, but we can't know "use strict" is the entire statement + // until we see the next token. So 'let' is still TOK_NAME here. if (tokenStream.currentName() == context->names().let) { bool parseDecl; if (!shouldParseLetDeclaration(&parseDecl)) return null(); + if (parseDecl) return lexicalDeclaration(yieldHandling, /* isConst = */ false); } TokenKind next; if (!tokenStream.peekToken(&next)) return null(); if (next == TOK_COLON) @@ -7642,16 +7718,20 @@ Parser<ParseHandler>::reportIfNotValidSi case KeyedDestructuringAssignment: errnum = JSMSG_BAD_DESTRUCT_TARGET; break; case PlainAssignment: case CompoundAssignment: errnum = JSMSG_BAD_LEFTSIDE_OF_ASS; break; + + case ForInOrOfTarget: + errnum = JSMSG_BAD_FOR_LEFTSIDE; + break; } report(ParseError, pc->sc->strict(), target, errnum, extra); return false; } template <typename ParseHandler> bool @@ -8534,17 +8614,17 @@ Parser<ParseHandler>::comprehensionFor(G if (!blockObj) return null(); // Initialize the enclosing scope manually for the call to |bind| // below, which is before the call to |pushLetScope|. blockObj->initEnclosingScopeFromParser(pc->innermostStaticScope()); data.initLexical(DontHoistVars, JSOP_DEFLET, blockObj, JSMSG_TOO_MANY_LOCALS); - Node decls = handler.newList(PNK_LET, lhs); + Node decls = handler.newComprehensionBinding(lhs); if (!decls) return null(); data.setNameNode(lhs); if (!data.bind(name, this)) return null(); Node letScope = pushLetScope(blockObj, stmtInfo); if (!letScope) return null();
--- a/js/src/frontend/Parser.h +++ b/js/src/frontend/Parser.h @@ -1,20 +1,20 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=8 sts=4 et sw=4 tw=99: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* JS parser. */ + #ifndef frontend_Parser_h #define frontend_Parser_h -/* - * JS parser definitions. - */ +#include "mozilla/Maybe.h" #include "jspubtd.h" #include "frontend/BytecodeCompiler.h" #include "frontend/FullParseHandler.h" #include "frontend/ParseMaps.h" #include "frontend/ParseNode.h" #include "frontend/SharedContext.h" @@ -664,37 +664,99 @@ class Parser : private JS::AutoGCRooter, Node functionStmt(YieldHandling yieldHandling, DefaultHandling defaultHandling); Node functionExpr(InvokedPrediction invoked = PredictUninvoked); Node statements(YieldHandling yieldHandling); Node blockStatement(YieldHandling yieldHandling); Node ifStatement(YieldHandling yieldHandling); Node doWhileStatement(YieldHandling yieldHandling); Node whileStatement(YieldHandling yieldHandling); + Node forStatement(YieldHandling yieldHandling); + bool forHeadStart(YieldHandling yieldHandling, + ParseNodeKind* forHeadKind, + Node* forInitialPart, + mozilla::Maybe<AutoPushStmtInfoPC>& letStmt, + MutableHandle<StaticBlockObject*> blockObj, + Node* forLetImpliedBlock, + Node* forInOrOfExpression); + bool validateForInOrOfLHSExpression(Node target); + Node expressionAfterForInOrOf(ParseNodeKind forHeadKind, YieldHandling yieldHandling); + + void assertCurrentLexicalStaticBlockIs(ParseContext<ParseHandler>* pc, + Handle<StaticBlockObject*> blockObj); + Node switchStatement(YieldHandling yieldHandling); Node continueStatement(YieldHandling yieldHandling); Node breakStatement(YieldHandling yieldHandling); Node returnStatement(YieldHandling yieldHandling); Node withStatement(YieldHandling yieldHandling); Node labeledStatement(YieldHandling yieldHandling); Node throwStatement(YieldHandling yieldHandling); Node tryStatement(YieldHandling yieldHandling); Node debuggerStatement(); Node lexicalDeclaration(YieldHandling yieldHandling, bool isConst); Node importDeclaration(); Node exportDeclaration(); Node expressionStatement(YieldHandling yieldHandling, InvokedPrediction invoked = PredictUninvoked); - Node variables(YieldHandling yieldHandling, - ParseNodeKind kind, - ForInitLocation location, - bool* psimple = nullptr, StaticBlockObject* blockObj = nullptr, - VarContext varContext = HoistVars); + + // Declaration parsing. The main entrypoint is Parser::declarationList, + // with sub-functionality split out into the remaining methods. + + // |blockObj| may be non-null only when |kind| corresponds to a lexical + // declaration (that is, PNK_LET or PNK_CONST). + // + // The for* parameters, for normal declarations, should be null/ignored. + // They should be non-null only when Parser::forHeadStart parses a + // declaration at the start of a for-loop head. + // + // In this case, on success |*forHeadKind| is PNK_FORHEAD, PNK_FORIN, or + // PNK_FOROF, corresponding to the three for-loop kinds. The precise value + // indicates what was parsed. + // + // If parsing recognized a for(;;) loop, the next token is the ';' within + // the loop-head that separates the init/test parts. + // + // Otherwise, for for-in/of loops, the next token is the ')' ending the + // loop-head. Additionally, the expression that the loop iterates over was + // parsed into |*forInOrOfExpression|. + Node declarationList(YieldHandling yieldHandling, + ParseNodeKind kind, + StaticBlockObject* blockObj = nullptr, + ParseNodeKind* forHeadKind = nullptr, + Node* forInOrOfExpression = nullptr); + + // The items in a declaration list are either patterns or names, with or + // without initializers. These two methods parse a single pattern/name and + // any associated initializer -- and if parsing an |initialDeclaration| + // will, if parsing in a for-loop head (as specified by |forHeadKind| being + // non-null), consume additional tokens up to the closing ')' in a + // for-in/of loop head, returning the iterated expression in + // |*forInOrOfExpression|. (An "initial declaration" is the first + // declaration in a declaration list: |a| but not |b| in |var a, b|, |{c}| + // but not |d| in |let {c} = 3, d|.) + Node declarationPattern(Node decl, TokenKind tt, BindData<ParseHandler>* data, + bool initialDeclaration, YieldHandling yieldHandling, + ParseNodeKind* forHeadKind, Node* forInOrOfExpression); + Node declarationName(Node decl, TokenKind tt, BindData<ParseHandler>* data, + bool initialDeclaration, YieldHandling yieldHandling, + ParseNodeKind* forHeadKind, Node* forInOrOfExpression); + + // Having parsed a name (not found in a destructuring pattern) declared by + // a declaration, with the current token being the '=' separating the name + // from its initializer, parse and bind that initializer -- and possibly + // consume trailing in/of and subsequent expression, if so directed by + // |forHeadKind|. + bool initializerInNameDeclaration(Node decl, Node binding, Handle<PropertyName*> name, + BindData<ParseHandler>* data, bool initialDeclaration, + YieldHandling yieldHandling, ParseNodeKind* forHeadKind, + Node* forInOrOfExpression); + Node expr(InHandling inHandling, YieldHandling yieldHandling, TripledotHandling tripledotHandling, InvokedPrediction invoked = PredictUninvoked); Node assignExpr(InHandling inHandling, YieldHandling yieldHandling, TripledotHandling tripledotHandling, InvokedPrediction invoked = PredictUninvoked); Node assignExprWithoutYield(YieldHandling yieldHandling, unsigned err); Node yieldExpression(InHandling inHandling); @@ -778,17 +840,18 @@ class Parser : private JS::AutoGCRooter, #endif } enum AssignmentFlavor { PlainAssignment, CompoundAssignment, KeyedDestructuringAssignment, IncrementAssignment, - DecrementAssignment + DecrementAssignment, + ForInOrOfTarget }; bool checkAndMarkAsAssignmentLhs(Node pn, AssignmentFlavor flavor); bool matchInOrOf(bool* isForInp, bool* isForOfp); bool checkFunctionArguments(); bool defineFunctionThis(); @@ -797,20 +860,16 @@ class Parser : private JS::AutoGCRooter, bool makeDefIntoUse(Definition* dn, Node pn, HandleAtom atom); bool bindLexicalFunctionName(HandlePropertyName funName, ParseNode* pn); bool bindBodyLevelFunctionName(HandlePropertyName funName, ParseNode** pn); bool checkFunctionDefinition(HandlePropertyName funName, Node* pn, FunctionSyntaxKind kind, bool* pbodyProcessed, Node* assignmentForAnnexBOut); bool finishFunctionDefinition(Node pn, FunctionBox* funbox, Node body); bool addFreeVariablesFromLazyFunction(JSFunction* fun, ParseContext<ParseHandler>* pc); - bool isValidForStatementLHS(Node pn1, JSVersion version, bool forDecl, bool forEach, - ParseNodeKind headKind); - bool checkForHeadConstInitializers(Node pn1); - // Use when the current token is TOK_NAME and is known to be 'let'. bool shouldParseLetDeclaration(bool* parseDeclOut); // Use when the lookahead token is TOK_NAME and is known to be 'let'. If a // let declaration should be parsed, the TOK_NAME token of 'let' is // consumed. Otherwise, the current token remains the TOK_NAME token of // 'let'. bool peekShouldParseLetDeclaration(bool* parseDeclOut, TokenStream::Modifier modifier); @@ -872,18 +931,20 @@ class Parser : private JS::AutoGCRooter, bool checkDestructuringObject(BindData<ParseHandler>* data, Node objectPattern); bool checkDestructuringName(BindData<ParseHandler>* data, Node expr); bool bindInitialized(BindData<ParseHandler>* data, HandlePropertyName name, Node pn); bool bindInitialized(BindData<ParseHandler>* data, Node pn); bool bindUninitialized(BindData<ParseHandler>* data, HandlePropertyName name, Node pn); bool bindUninitialized(BindData<ParseHandler>* data, Node pn); bool makeSetCall(Node node, unsigned errnum); + + Node cloneForInOrOfDeclarationForAssignment(Node decl); + Node cloneLeftHandSide(Node opn); Node cloneDestructuringDefault(Node opn); - Node cloneLeftHandSide(Node opn); Node cloneParseTree(Node opn); Node newNumber(const Token& tok) { return handler.newNumber(tok.number(), tok.decimalPoint(), tok.pos); } static bool bindDestructuringArg(BindData<ParseHandler>* data,
--- a/js/src/frontend/SharedContext.h +++ b/js/src/frontend/SharedContext.h @@ -453,44 +453,43 @@ SharedContext::asModuleBox() // invalidate DebugScope proxies for unaliased locals in a generator frame, as // the generator frame will be copied out to the heap and released only by GC. inline bool SharedContext::allLocalsAliased() { return bindingsAccessedDynamically() || (isFunctionBox() && asFunctionBox()->isGenerator()); } +// NOTE: If you add a new type of statement that is a scope, add it between +// WITH and CATCH, or you'll break StmtInfoBase::linksScope. If you add +// a non-looping statement type, add it before DO_LOOP or you'll break +// StmtInfoBase::isLoop(). +#define FOR_EACH_STATEMENT_TYPE(macro) \ + macro(LABEL, "label statement") \ + macro(IF, "if statement") \ + macro(ELSE, "else statement") \ + macro(SEQ, "destructuring body") \ + macro(BLOCK, "block") \ + macro(SWITCH, "switch statement") \ + macro(WITH, "with statement") \ + macro(CATCH, "catch block") \ + macro(TRY, "try block") \ + macro(FINALLY, "finally block") \ + macro(SUBROUTINE, "finally block") \ + macro(DO_LOOP, "do loop") \ + macro(FOR_LOOP, "for loop") \ + macro(FOR_IN_LOOP, "for/in loop") \ + macro(FOR_OF_LOOP, "for/of loop") \ + macro(WHILE_LOOP, "while loop") \ + macro(SPREAD, "spread") -/* - * NB: If you add a new type of statement that is a scope, add it between - * STMT_WITH and STMT_CATCH, or you will break StmtInfoBase::linksScope. If you - * add a non-looping statement type, add it before STMT_DO_LOOP or you will - * break StmtInfoBase::isLoop(). - * - * Also remember to keep the statementName array in BytecodeEmitter.cpp in - * sync. - */ enum class StmtType : uint16_t { - LABEL, /* labeled statement: L: s */ - IF, /* if (then) statement */ - ELSE, /* else clause of if statement */ - SEQ, /* synthetic sequence of statements */ - BLOCK, /* compound statement: { s1[;... sN] } */ - SWITCH, /* switch statement */ - WITH, /* with statement */ - CATCH, /* catch block */ - TRY, /* try block */ - FINALLY, /* finally block */ - SUBROUTINE, /* gosub-target subroutine body */ - DO_LOOP, /* do/while loop statement */ - FOR_LOOP, /* for loop statement */ - FOR_IN_LOOP, /* for/in loop statement */ - FOR_OF_LOOP, /* for/of loop statement */ - WHILE_LOOP, /* while loop statement */ - SPREAD, /* spread operator (pseudo for/of) */ +#define DECLARE_STMTTYPE_ENUM(name, desc) name, + FOR_EACH_STATEMENT_TYPE(DECLARE_STMTTYPE_ENUM) +#undef DECLARE_STMTTYPE_ENUM LIMIT }; /* * A comment on the encoding of the js::StmtType enum and StmtInfoBase * type-testing methods: * * StmtInfoBase::maybeScope() tells whether a statement type is always, or may
--- a/js/src/frontend/SyntaxParseHandler.h +++ b/js/src/frontend/SyntaxParseHandler.h @@ -37,21 +37,26 @@ class SyntaxParseHandler public: enum Node { NodeFailure = 0, NodeGeneric, NodeGetProp, NodeStringExprStatement, NodeReturn, - NodeHoistableDeclaration, NodeBreak, NodeThrow, NodeEmptyStatement, + NodeVarDeclaration, + NodeLetDeclaration, + NodeConstDeclaration, + + NodeFunctionDefinition, + // This is needed for proper assignment-target handling. ES6 formally // requires function calls *not* pass IsValidSimpleAssignmentTarget, // but at last check there were still sites with |f() = 5| and similar // in code not actually executed (or at least not executed enough to be // noticed). NodeFunctionCall, // Nodes representing *parenthesized* IsValidSimpleAssignmentTarget @@ -326,34 +331,47 @@ class SyntaxParseHandler Node newPropertyByValue(Node pn, Node kid, uint32_t end) { return NodeElement; } bool addCatchBlock(Node catchList, Node letBlock, Node catchName, Node catchGuard, Node catchBody) { return true; } bool setLastFunctionArgumentDefault(Node funcpn, Node pn) { return true; } void setLastFunctionArgumentDestructuring(Node funcpn, Node pn) {} - Node newFunctionDefinition() { return NodeHoistableDeclaration; } + Node newFunctionDefinition() { return NodeFunctionDefinition; } void setFunctionBody(Node pn, Node kid) {} void setFunctionBox(Node pn, FunctionBox* funbox) {} - Node newFunctionDefinitionForAnnexB(Node pn, Node assignment) { return NodeHoistableDeclaration; } + Node newFunctionDefinitionForAnnexB(Node pn, Node assignment) { return NodeFunctionDefinition; } void addFunctionArgument(Node pn, Node argpn) {} Node newForStatement(uint32_t begin, Node forHead, Node body, unsigned iflags) { return NodeGeneric; } Node newComprehensionFor(uint32_t begin, Node forHead, Node body) { return NodeGeneric; } + Node newComprehensionBinding(Node kid) { + // Careful: we're asking this well after the name was parsed, so the + // value returned may not correspond to |kid|'s actual name. But it + // *will* be truthy iff |kid| was a name, so we're safe. + MOZ_ASSERT(maybeUnparenthesizedName(kid)); + return NodeGeneric; + } + Node newForHead(ParseNodeKind kind, Node decls, Node lhs, Node rhs, const TokenPos& pos) { return NodeGeneric; } + void initForLetBlock(Node forLetImpliedBlock, Node nestedForLoop) { + MOZ_ASSERT(forLetImpliedBlock == NodeGeneric); // per newForStatement + MOZ_ASSERT(nestedForLoop == NodeGeneric); // per newLexicalScope + } + Node newLexicalScope(ObjectBox* blockbox) { return NodeGeneric; } void setLexicalScopeBody(Node block, Node body) {} Node newLetBlock(Node vars, Node block, const TokenPos& pos) { return NodeGeneric; } bool finishInitializerAssignment(Node pn, Node init) { return true; } @@ -369,48 +387,96 @@ class SyntaxParseHandler void setPosition(Node pn, const TokenPos& pos) {} TokenPos getPosition(Node pn) { return tokenStream.currentToken().pos; } Node newList(ParseNodeKind kind, JSOp op = JSOP_NOP) { MOZ_ASSERT(kind != PNK_VAR); + MOZ_ASSERT(kind != PNK_LET); + MOZ_ASSERT(kind != PNK_CONST); return NodeGeneric; } Node newList(ParseNodeKind kind, uint32_t begin, JSOp op = JSOP_NOP) { - return NodeGeneric; - } - Node newDeclarationList(ParseNodeKind kind, JSOp op = JSOP_NOP) { - MOZ_ASSERT(kind == PNK_VAR || kind == PNK_CONST || kind == PNK_LET); - return kind == PNK_VAR ? NodeHoistableDeclaration : NodeGeneric; + return newList(kind, op); } Node newList(ParseNodeKind kind, Node kid, JSOp op = JSOP_NOP) { - MOZ_ASSERT(kind != PNK_VAR); - return NodeGeneric; + return newList(kind, op); + } + + Node newDeclarationList(ParseNodeKind kind, JSOp op = JSOP_NOP) { + if (kind == PNK_VAR) + return NodeVarDeclaration; + if (kind == PNK_LET) + return NodeLetDeclaration; + MOZ_ASSERT(kind == PNK_CONST); + return NodeConstDeclaration; } Node newDeclarationList(ParseNodeKind kind, Node kid, JSOp op = JSOP_NOP) { - MOZ_ASSERT(kind == PNK_VAR || kind == PNK_CONST || kind == PNK_LET); - return kind == PNK_VAR ? NodeHoistableDeclaration : NodeGeneric; + return newDeclarationList(kind, op); + } + + bool isDeclarationList(Node node) { + return node == NodeVarDeclaration || + node == NodeLetDeclaration || + node == NodeConstDeclaration; + } + + bool declarationIsVar(Node node) { + MOZ_ASSERT(isDeclarationList(node)); + return node == NodeVarDeclaration; + } + + bool declarationIsLet(Node node) { + MOZ_ASSERT(isDeclarationList(node)); + return node == NodeLetDeclaration; + } + + bool declarationIsConst(Node node) { + MOZ_ASSERT(isDeclarationList(node)); + return node == NodeConstDeclaration; + } + + Node singleBindingFromDeclaration(Node decl) { + MOZ_ASSERT(isDeclarationList(decl)); + + // This is, unfortunately, very dodgy. Obviously NodeVarDeclaration + // can store no info on the arbitrary number of bindings it could + // contain. + // + // But this method is called only for cloning for-in/of declarations + // as initialization targets. That context simplifies matters. If the + // binding is a single name, it'll always syntax-parse (or it would + // already have been rejected as assigning/binding a forbidden name). + // Otherwise the binding is a destructuring pattern. But syntax + // parsing would *already* have aborted when it saw a destructuring + // pattern. So we can just say any old thing here, because the only + // time we'll be wrong is a case that syntax parsing has already + // rejected. Use NodeUnparenthesizedName so the SyntaxParseHandler + // Parser::cloneLeftHandSide can assert it sees only this. + return NodeUnparenthesizedName; } Node newCatchList() { return newList(PNK_CATCHLIST, JSOP_NOP); } Node newCommaExpressionList(Node kid) { return NodeUnparenthesizedCommaExpr; } void addList(Node list, Node kid) { MOZ_ASSERT(list == NodeGeneric || list == NodeUnparenthesizedArray || list == NodeUnparenthesizedObject || list == NodeUnparenthesizedCommaExpr || - list == NodeHoistableDeclaration || + list == NodeVarDeclaration || + list == NodeLetDeclaration || + list == NodeConstDeclaration || list == NodeFunctionCall); } Node newAssignment(ParseNodeKind kind, Node lhs, Node rhs, ParseContext<SyntaxParseHandler>* pc, JSOp op) { if (kind == PNK_ASSIGN) return NodeUnparenthesizedAssignment; @@ -429,17 +495,19 @@ class SyntaxParseHandler return node == NodeUnparenthesizedAssignment; } bool isReturnStatement(Node node) { return node == NodeReturn; } bool isStatementPermittedAfterReturnStatement(Node pn) { - return pn == NodeHoistableDeclaration || pn == NodeBreak || pn == NodeThrow || + return pn == NodeFunctionDefinition || pn == NodeVarDeclaration || + pn == NodeBreak || + pn == NodeThrow || pn == NodeEmptyStatement; } bool isSuperBase(Node pn) { return pn == NodeSuperBase; } void setOp(Node pn, JSOp op) {}
--- a/js/src/jit-test/tests/asm.js/gating.js +++ b/js/src/jit-test/tests/asm.js/gating.js @@ -1,18 +1,20 @@ // Check gating of shared memory features in asm.js (bug 1171540, -// bug 1231624). +// bug 1231624, bug 1231338). // // In asm.js, importing any atomic is a signal that shared memory is // being used. If an atomic is imported, and if shared memory is // disabled in the build or in the run then a type error should be // signaled for the module at the end of the declaration section and // the module should not be an asm.js module. -if (!this.SharedArrayBuffer || !isAsmJSCompilationAvailable()) +// Do not guard on the presence of SharedArrayBuffer, we test that later. + +if (!isAsmJSCompilationAvailable()) quit(0); // This code is not run, we only care whether it compiles as asm.js. function module_a(stdlib, foreign, heap) { "use asm"; var i32a = new stdlib.Int32Array(heap);
--- a/js/src/jit-test/tests/parser/letContextualKeyword.js +++ b/js/src/jit-test/tests/parser/letContextualKeyword.js @@ -11,19 +11,100 @@ function expectError(str) { eval(`let x = 42; assertEq(x, 42);`); eval(`var let = 42; assertEq(let, 42);`); eval(`let;`); eval(`[...let] = [];`); eval(`function let() { return 42; } assertEq(let(), 42);`) eval(`let {x:x} = {x:42}; assertEq(x, 42);`); eval(`let [x] = [42]; assertEq(x, 42);`); + eval(`for (let x in [1]) { assertEq(x, "0"); }`); +expectError(`for (const x in [1]) { assertEq(x, "0"); }`); // XXX bug 449811 + eval(`for (let x of [1]) { assertEq(x, 1); }`); +expectError(`for (const x of [1]) { assertEq(x, 1); }`); // XXX bug 449811 + eval(`for (let i = 0; i < 1; i++) { assertEq(i, 0); }`); +eval(`var done = false; for (const i = 0; !done; done = true) { assertEq(i, 0); }`); + +eval(`for (let of of [1]) { assertEq(of, 1); }`); +expectError(`for (const of of [1]) { assertEq(of, 1); }`); // XXX bug 449811 + +eval(`try { throw 17; } catch (let) { assertEq(let, 17); }`); +eval(`try { throw [17]; } catch ([let]) { assertEq(let, 17); }`); +eval(`try { throw { x: 17 }; } catch ({ x: let }) { assertEq(let, 17); }`); +eval(`try { throw {}; } catch ({ x: let = 17 }) { assertEq(let, 17); }`); + +expectError(`try { throw [17, 42]; } catch ([let, let]) {}`); + eval(`for (let in [1]) { assertEq(let, "0"); }`); -eval(`for (let of of [1]) { assertEq(of, 1); }`); -eval(`for (let/1;;) { break; }`); +eval(`for (let / 1; ; ) { break; }`); +expectError(`let = {}; for (let.x of;;);`); expectError(`for (let of [1]) { }`); -expectError(`let let = 42;`); + +expectError(`for (let let in [1]) { }`); +expectError(`for (const let in [1]) { }`); + +expectError(`for (let let of [1]) { }`); +expectError(`for (const let of [1]) { }`); + +expectError(`for (let let = 17; false; ) { }`); +expectError(`for (const let = 17; false; ) { }`); + +expectError(`for (let [let] = 17; false; ) { }`); +expectError(`for (const [let] = 17; false; ) { }`); + +expectError(`for (let [let = 42] = 17; false; ) { }`); +expectError(`for (const [let = 42] = 17; false; ) { }`); + +expectError(`for (let { x: let } = 17; false; ) { }`); +expectError(`for (const { x: let } = 17; false; ) { }`); + +expectError(`for (let { x: let = 42 } = 17; false; ) { }`); +expectError(`for (const { x: let = 42 } = 17; false; ) { }`); + +expectError("let\nlet;"); +expectError("const\nlet;"); + +expectError(`let let = 17;`); +expectError(`const let = 17;`); + +expectError(`let [let] = 17;`); +expectError(`const [let] = 17;`); + +expectError(`let [let = 42] = 17;`); +expectError(`const [let = 42] = 17;`); + +expectError(`let {let} = 17;`); +expectError(`const {let} = 17;`); + +expectError(`let { let = 42 } = 17;`); +expectError(`const { let = 42 } = 17;`); + +expectError(`let { x: let } = 17;`); +expectError(`const { x: let } = 17;`); + +expectError(`let { x: let = 42 } = 17;`); +expectError(`const { x: let = 42 } = 17;`); + +expectError(`let { ['y']: let } = 17;`); +expectError(`const { ['y']: let } = 17;`); + +expectError(`let { ['y']: let = 42 } = 17;`); +expectError(`const { ['y']: let = 42 } = 17;`); + +expectError(`let { x: [let] } = { x: 17 };`); +expectError(`const { x: [let] } = { x: 17 };`); + +expectError(`let { x: [let = 42] } = { x: 17 };`); +expectError(`const { x: [let = 42] } = { x: 17 };`); + +expectError(`let [foo, let] = 42;`); +expectError(`const [foo, let] = 42;`); + +expectError(`let [foo, { let }] = [17, {}];`); +expectError(`const [foo, { let }] = [17, {}];`); + expectError(`"use strict"; var let = 42;`); expectError(`"use strict"; function let() {}`); expectError(`"use strict"; for (let of [1]) {}`); +expectError(`"use strict"; try {} catch (let) {}`);
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/sab-gating.js @@ -0,0 +1,8 @@ +// Check gating of shared memory features in plain js (bug 1231338). + +// Need this testing function to continue. +if (!this.sharedMemoryEnabled) + quit(0); + +assertEq(sharedMemoryEnabled(), !!this.SharedArrayBuffer); +assertEq(sharedMemoryEnabled(), !!this.Atomics);
--- a/js/src/jit/ExecutableAllocator.cpp +++ b/js/src/jit/ExecutableAllocator.cpp @@ -403,13 +403,9 @@ ExecutableAllocator::poisonCode(JSRuntim if (pool->isMarked()) { reprotectPool(rt, pool, Executable); pool->unmark(); } pool->release(); } } -#if TARGET_OS_IPHONE bool ExecutableAllocator::nonWritableJitCode = true; -#else -bool ExecutableAllocator::nonWritableJitCode = false; -#endif
--- a/js/src/jit/ExecutableAllocatorWin.cpp +++ b/js/src/jit/ExecutableAllocatorWin.cpp @@ -121,16 +121,20 @@ ExceptionHandler(PEXCEPTION_RECORD excep return sJitExceptionHandler(exceptionRecord, context); } // For an explanation of the problem being solved here, see // SetJitExceptionFilter in jsfriendapi.h. static bool RegisterExecutableMemory(void* p, size_t bytes, size_t pageSize) { + DWORD oldProtect; + if (!VirtualProtect(p, pageSize, PAGE_READWRITE, &oldProtect)) + return false; + ExceptionHandlerRecord* r = reinterpret_cast<ExceptionHandlerRecord*>(p); // All these fields are specified to be offsets from the base of the // executable code (which is 'p'), even if they have 'Address' in their // names. In particular, exceptionHandler is a ULONG offset which is a // 32-bit integer. Since 'p' can be farther than INT32_MAX away from // sJitExceptionHandler, we must generate a little thunk inside the // record. The record is put on its own page so that we can take away write @@ -153,17 +157,16 @@ RegisterExecutableMemory(void* p, size_t r->thunk[1] = 0xb8; void* handler = JS_FUNC_TO_DATA_PTR(void*, ExceptionHandler); memcpy(&r->thunk[2], &handler, 8); // jmp rax r->thunk[10] = 0xff; r->thunk[11] = 0xe0; - DWORD oldProtect; if (!VirtualProtect(p, pageSize, PAGE_EXECUTE_READ, &oldProtect)) return false; return RtlAddFunctionTable(&r->runtimeFunction, 1, reinterpret_cast<DWORD64>(p)); } static void UnregisterExecutableMemory(void* p, size_t bytes, size_t pageSize)
--- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -176,16 +176,17 @@ JitRuntime::JitRuntime(JSRuntime* rt) argumentsRectifier_(nullptr), argumentsRectifierReturnAddr_(nullptr), invalidator_(nullptr), debugTrapHandler_(nullptr), baselineDebugModeOSRHandler_(nullptr), functionWrappers_(nullptr), osrTempData_(nullptr), preventBackedgePatching_(false), + backedgeTarget_(BackedgeLoopHeader), ionReturnOverride_(MagicValue(JS_ARG_POISON)), jitcodeGlobalTable_(nullptr) { } JitRuntime::~JitRuntime() { js_delete(functionWrappers_); @@ -366,16 +367,22 @@ JitRuntime::patchIonBackedges(JSRuntime* } else { // We must be called from InterruptRunningJitCode, or a signal handler // triggered there. rt->handlingJitInterrupt() ensures we can't reenter // this code. MOZ_ASSERT(!preventBackedgePatching_); MOZ_ASSERT(rt->handlingJitInterrupt()); } + // Do nothing if we know all backedges are already jumping to `target`. + if (backedgeTarget_ == target) + return; + + backedgeTarget_ = target; + backedgeExecAlloc_.makeAllWritable(); // Patch all loop backedges in Ion code so that they either jump to the // normal loop header or to an interrupt handler each time they run. for (InlineListIterator<PatchableBackedge> iter(backedgeList_.begin()); iter != backedgeList_.end(); iter++) { @@ -1142,21 +1149,19 @@ IonScript::copyPatchableBackedges(JSCont PatchableBackedge* patchableBackedge = &backedgeList()[i]; info.backedge.fixup(&masm); CodeLocationJump backedge(code, info.backedge); CodeLocationLabel loopHeader(code, CodeOffset(info.loopHeader->offset())); CodeLocationLabel interruptCheck(code, CodeOffset(info.interruptCheck->offset())); new(patchableBackedge) PatchableBackedge(backedge, loopHeader, interruptCheck); - // Point the backedge to either of its possible targets, according to - // whether an interrupt is currently desired, matching the targets - // established by ensureIonCodeAccessible() above. We don't handle the - // interrupt immediately as the interrupt lock is held here. - if (cx->runtime()->hasPendingInterrupt()) + // Point the backedge to either of its possible targets, matching the + // other backedges in the runtime. + if (jrt->backedgeTarget() == JitRuntime::BackedgeInterruptCheck) PatchBackedge(backedge, interruptCheck, JitRuntime::BackedgeInterruptCheck); else PatchBackedge(backedge, loopHeader, JitRuntime::BackedgeLoopHeader); jrt->addPatchableBackedge(patchableBackedge); } }
--- a/js/src/jit/JitCompartment.h +++ b/js/src/jit/JitCompartment.h @@ -77,16 +77,23 @@ class PatchableBackedge : public InlineL CodeLocationLabel loopHeader, CodeLocationLabel interruptCheck) : backedge(backedge), loopHeader(loopHeader), interruptCheck(interruptCheck) {} }; class JitRuntime { + public: + enum BackedgeTarget { + BackedgeLoopHeader, + BackedgeInterruptCheck + }; + + private: friend class JitCompartment; // Executable allocator for all code except asm.js code and Ion code with // patchable backedges (see below). ExecutableAllocator execAlloc_; // Executable allocator for Ion scripts with patchable backedges. ExecutableAllocator backedgeExecAlloc_; @@ -147,17 +154,21 @@ class JitRuntime // Buffer for OSR from baseline to Ion. To avoid holding on to this for // too long, it's also freed in JitCompartment::mark and in EnterBaseline // (after returning from JIT code). uint8_t* osrTempData_; // If true, the signal handler to interrupt Ion code should not attempt to // patch backedges, as we're busy modifying data structures. - volatile bool preventBackedgePatching_; + mozilla::Atomic<bool> preventBackedgePatching_; + + // Whether patchable backedges currently jump to the loop header or the + // interrupt check. + BackedgeTarget backedgeTarget_; // List of all backedges in all Ion code. The backedge edge list is accessed // asynchronously when the main thread is paused and preventBackedgePatching_ // is false. Thus, the list must only be mutated while preventBackedgePatching_ // is true. InlineList<PatchableBackedge> backedgeList_; // In certain cases, we want to optimize certain opcodes to typed instructions, @@ -242,30 +253,28 @@ class JitRuntime jrt_->preventBackedgePatching_ = prev_; } } }; bool preventBackedgePatching() const { return preventBackedgePatching_; } + BackedgeTarget backedgeTarget() const { + return backedgeTarget_; + } void addPatchableBackedge(PatchableBackedge* backedge) { MOZ_ASSERT(preventBackedgePatching_); backedgeList_.pushFront(backedge); } void removePatchableBackedge(PatchableBackedge* backedge) { MOZ_ASSERT(preventBackedgePatching_); backedgeList_.remove(backedge); } - enum BackedgeTarget { - BackedgeLoopHeader, - BackedgeInterruptCheck - }; - void patchIonBackedges(JSRuntime* rt, BackedgeTarget target); JitCode* getVMWrapper(const VMFunction& f) const; JitCode* debugTrapHandler(JSContext* cx); JitCode* getBaselineDebugModeOSRHandler(JSContext* cx); void* getBaselineDebugModeOSRHandlerAddress(JSContext* cx, bool popFrameReg); JitCode* getGenericBailoutHandler() const {
--- a/js/src/jit/arm64/Assembler-arm64.cpp +++ b/js/src/jit/arm64/Assembler-arm64.cpp @@ -568,17 +568,21 @@ TraceDataRelocations(JSTracer* trc, uint // All pointers on AArch64 will have the top bits cleared. // If those bits are not cleared, this must be a Value. if (literal >> JSVAL_TAG_SHIFT) { jsval_layout layout; layout.asBits = literal; Value v = IMPL_TO_JSVAL(layout); TraceManuallyBarrieredEdge(trc, &v, "ion-masm-value"); - *literalAddr = JSVAL_TO_IMPL(v).asBits; + if (*literalAddr != JSVAL_TO_IMPL(v).asBits) { + // Only update the code if the value changed, because the code + // is not writable if we're not moving objects. + *literalAddr = JSVAL_TO_IMPL(v).asBits; + } // TODO: When we can, flush caches here if a pointer was moved. continue; } // No barriers needed since the pointers are constants. TraceManuallyBarrieredGenericPointerEdge(trc, reinterpret_cast<gc::Cell**>(literalAddr), "ion-masm-ptr");
--- a/js/src/jit/x86-shared/Assembler-x86-shared.cpp +++ b/js/src/jit/x86-shared/Assembler-x86-shared.cpp @@ -57,18 +57,21 @@ TraceDataRelocations(JSTracer* trc, uint // All pointers on x64 will have the top bits cleared. If those bits // are not cleared, this must be a Value. uintptr_t* word = reinterpret_cast<uintptr_t*>(ptr); if (*word >> JSVAL_TAG_SHIFT) { jsval_layout layout; layout.asBits = *word; Value v = IMPL_TO_JSVAL(layout); TraceManuallyBarrieredEdge(trc, &v, "ion-masm-value"); - if (*word != JSVAL_TO_IMPL(v).asBits) + if (*word != JSVAL_TO_IMPL(v).asBits) { + // Only update the code if the Value changed, because the code + // is not writable if we're not moving objects. *word = JSVAL_TO_IMPL(v).asBits; + } continue; } #endif // No barrier needed since these are constants. TraceManuallyBarrieredGenericPointerEdge(trc, reinterpret_cast<gc::Cell**>(ptr), "ion-masm-ptr"); }
--- a/js/src/js.msg +++ b/js/src/js.msg @@ -195,18 +195,20 @@ MSG_DEF(JSMSG_BAD_BINDING, 1 MSG_DEF(JSMSG_BAD_CONST_DECL, 0, JSEXN_SYNTAXERR, "missing = in const declaration") MSG_DEF(JSMSG_BAD_CONTINUE, 0, JSEXN_SYNTAXERR, "continue must be inside loop") MSG_DEF(JSMSG_BAD_DESTRUCT_ASS, 0, JSEXN_REFERENCEERR, "invalid destructuring assignment operator") MSG_DEF(JSMSG_BAD_DESTRUCT_TARGET, 0, JSEXN_SYNTAXERR, "invalid destructuring target") MSG_DEF(JSMSG_BAD_DESTRUCT_PARENS, 0, JSEXN_SYNTAXERR, "destructuring patterns in assignments can't be parenthesized") MSG_DEF(JSMSG_BAD_DESTRUCT_DECL, 0, JSEXN_SYNTAXERR, "missing = in destructuring declaration") MSG_DEF(JSMSG_BAD_DUP_ARGS, 0, JSEXN_SYNTAXERR, "duplicate argument names not allowed in this context") MSG_DEF(JSMSG_BAD_FOR_EACH_LOOP, 0, JSEXN_SYNTAXERR, "invalid for each loop") -MSG_DEF(JSMSG_BAD_FOR_LEFTSIDE, 0, JSEXN_SYNTAXERR, "invalid for/in left-hand side") -MSG_DEF(JSMSG_BAD_GENERATOR_RETURN, 1, JSEXN_TYPEERR, "generator function {0} returns a value") +MSG_DEF(JSMSG_BAD_FOR_LEFTSIDE, 0, JSEXN_SYNTAXERR, "invalid for-in/of left-hand side") +MSG_DEF(JSMSG_LEXICAL_DECL_DEFINES_LET,0, JSEXN_SYNTAXERR, "a lexical declaration can't define a 'let' binding") +MSG_DEF(JSMSG_LET_STARTING_FOROF_LHS, 0, JSEXN_SYNTAXERR, "an expression X in 'for (X of Y)' must not start with 'let'") +MSG_DEF(JSMSG_BAD_GENERATOR_RETURN, 1, JSEXN_TYPEERR, "generator function {0} returns a value") MSG_DEF(JSMSG_BAD_YIELD_SYNTAX, 0, JSEXN_SYNTAXERR, "yield expression must be parenthesized") MSG_DEF(JSMSG_BAD_GENERATOR_SYNTAX, 0, JSEXN_SYNTAXERR, "generator expression must be parenthesized") MSG_DEF(JSMSG_BAD_GENEXP_BODY, 1, JSEXN_SYNTAXERR, "illegal use of {0} in generator expression") MSG_DEF(JSMSG_BAD_INCOP_OPERAND, 0, JSEXN_REFERENCEERR, "invalid increment/decrement operand") MSG_DEF(JSMSG_BAD_METHOD_DEF, 0, JSEXN_SYNTAXERR, "bad method definition") MSG_DEF(JSMSG_BAD_OCTAL, 1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant") MSG_DEF(JSMSG_BAD_OPERAND, 1, JSEXN_SYNTAXERR, "invalid {0} operand") MSG_DEF(JSMSG_BAD_PROP_ID, 0, JSEXN_SYNTAXERR, "invalid property id") @@ -259,17 +261,17 @@ MSG_DEF(JSMSG_EQUAL_AS_ASSIGN, 0 MSG_DEF(JSMSG_EXPORT_DECL_AT_TOP_LEVEL,0, JSEXN_SYNTAXERR, "export declarations may only appear at top level of a module") MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY, 0, JSEXN_SYNTAXERR, "finally without try") MSG_DEF(JSMSG_FROM_AFTER_IMPORT_CLAUSE, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after import clause") MSG_DEF(JSMSG_FROM_AFTER_EXPORT_STAR, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after export *") MSG_DEF(JSMSG_GARBAGE_AFTER_INPUT, 2, JSEXN_SYNTAXERR, "unexpected garbage after {0}, starting with {1}") MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER, 0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal") MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 0, JSEXN_SYNTAXERR, "illegal character") MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 0, JSEXN_SYNTAXERR, "import declarations may only appear at top level of a module") -MSG_DEF(JSMSG_INVALID_FOR_INOF_DECL_WITH_INIT,1,JSEXN_SYNTAXERR,"for-{0} loop head declarations may not have initializers") +MSG_DEF(JSMSG_INVALID_FOR_IN_DECL_WITH_INIT,0,JSEXN_SYNTAXERR,"for-in loop head declarations may not have initializers") MSG_DEF(JSMSG_IN_AFTER_FOR_NAME, 0, JSEXN_SYNTAXERR, "missing 'in' or 'of' after for") MSG_DEF(JSMSG_LABEL_NOT_FOUND, 0, JSEXN_SYNTAXERR, "label not found") MSG_DEF(JSMSG_LET_CLASS_BINDING, 0, JSEXN_SYNTAXERR, "'let' is not a valid name for a class") MSG_DEF(JSMSG_LET_COMP_BINDING, 0, JSEXN_SYNTAXERR, "'let' is not a valid name for a comprehension variable") MSG_DEF(JSMSG_LEXICAL_DECL_NOT_IN_BLOCK, 1, JSEXN_SYNTAXERR, "{0} declaration not directly within block") MSG_DEF(JSMSG_LEXICAL_DECL_LABEL, 1, JSEXN_SYNTAXERR, "{0} declarations cannot be labelled") MSG_DEF(JSMSG_FUNCTION_LABEL, 0, JSEXN_SYNTAXERR, "functions cannot be labelled") MSG_DEF(JSMSG_SLOPPY_FUNCTION_LABEL, 0, JSEXN_SYNTAXERR, "functions can only be labelled inside blocks") @@ -306,17 +308,17 @@ MSG_DEF(JSMSG_PAREN_BEFORE_CATCH, 0 MSG_DEF(JSMSG_PAREN_BEFORE_COND, 0, JSEXN_SYNTAXERR, "missing ( before condition") MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL, 0, JSEXN_SYNTAXERR, "missing ( before formal parameters") MSG_DEF(JSMSG_PAREN_BEFORE_LET, 0, JSEXN_SYNTAXERR, "missing ( before let head") MSG_DEF(JSMSG_PAREN_BEFORE_SWITCH, 0, JSEXN_SYNTAXERR, "missing ( before switch expression") MSG_DEF(JSMSG_PAREN_BEFORE_WITH, 0, JSEXN_SYNTAXERR, "missing ( before with-statement object") MSG_DEF(JSMSG_PAREN_IN_PAREN, 0, JSEXN_SYNTAXERR, "missing ) in parenthetical") MSG_DEF(JSMSG_RC_AFTER_EXPORT_SPEC_LIST, 0, JSEXN_SYNTAXERR, "missing '}' after export specifier list") MSG_DEF(JSMSG_RC_AFTER_IMPORT_SPEC_LIST, 0, JSEXN_SYNTAXERR, "missing '}' after module specifier list") -MSG_DEF(JSMSG_REDECLARED_CATCH_IDENTIFIER, 1, JSEXN_TYPEERR, "redeclaration of identifier '{0}' in catch") +MSG_DEF(JSMSG_REDECLARED_CATCH_IDENTIFIER, 1, JSEXN_SYNTAXERR, "redeclaration of identifier '{0}' in catch") MSG_DEF(JSMSG_REDECLARED_PARAM, 1, JSEXN_TYPEERR, "redeclaration of formal parameter {0}") MSG_DEF(JSMSG_RESERVED_ID, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier") MSG_DEF(JSMSG_REST_WITH_DEFAULT, 0, JSEXN_SYNTAXERR, "rest parameter may not have a default") MSG_DEF(JSMSG_SELFHOSTED_TOP_LEVEL_LEXICAL, 1, JSEXN_SYNTAXERR, "self-hosted code cannot contain top-level {0} declarations") MSG_DEF(JSMSG_SELFHOSTED_UNBOUND_NAME, 0, JSEXN_TYPEERR, "self-hosted code may not contain unbound name lookups") MSG_DEF(JSMSG_SEMI_AFTER_FOR_COND, 0, JSEXN_SYNTAXERR, "missing ; after for-loop condition") MSG_DEF(JSMSG_SEMI_AFTER_FOR_INIT, 0, JSEXN_SYNTAXERR, "missing ; after for-loop initializer") MSG_DEF(JSMSG_SEMI_BEFORE_STMNT, 0, JSEXN_SYNTAXERR, "missing ; before statement")
--- a/js/src/moz.build +++ b/js/src/moz.build @@ -608,16 +608,19 @@ if CONFIG['MOZ_ETW']: GENERATED_FILES = [ 'ETWProvider.h', ] # This will get the ETW provider resources into the library mozjs.dll RESFILE = 'ETWProvider.res' if CONFIG['NIGHTLY_BUILD']: DEFINES['ENABLE_BINARYDATA'] = True + +# Also in shell/moz.build +if CONFIG['NIGHTLY_BUILD']: DEFINES['ENABLE_SHARED_ARRAY_BUFFER'] = True DEFINES['ENABLE_SIMD'] = True DEFINES['EXPORT_JS_API'] = True if CONFIG['JS_HAS_CTYPES']: DEFINES['JS_HAS_CTYPES'] = True for var in ('DLL_PREFIX', 'DLL_SUFFIX'):
--- a/js/src/shell/moz.build +++ b/js/src/shell/moz.build @@ -13,16 +13,20 @@ if CONFIG['JS_SHELL_NAME']: UNIFIED_SOURCES += [ 'js.cpp', 'jsoptparse.cpp', 'OSObject.cpp' ] DEFINES['EXPORT_JS_API'] = True +# Also in ../moz.build +if CONFIG['NIGHTLY_BUILD']: + DEFINES['ENABLE_SHARED_ARRAY_BUFFER'] = True + if CONFIG['_MSC_VER']: # unnecessary PGO for js shell. But gcc cannot turn off pgo because it is # necessary to link PGO lib on gcc when a object/static lib are compiled # for PGO. NO_PGO = True LOCAL_INCLUDES += [ '!..',
--- a/js/src/tests/js1_6/Regress/regress-355002.js +++ b/js/src/tests/js1_6/Regress/regress-355002.js @@ -15,17 +15,17 @@ test(); //----------------------------------------------------------------------------- function test() { enterFunc ('test'); printBugNumber(BUGNUMBER); printStatus (summary); - expect = 'SyntaxError: invalid for/in left-hand side'; + expect = 'SyntaxError: invalid for-in/of left-hand side'; actual = ''; try { eval('for each (this in []) { }'); } catch(ex) { actual = ex + '';
--- a/js/src/vm/Xdr.h +++ b/js/src/vm/Xdr.h @@ -24,21 +24,21 @@ namespace js { * versions. If deserialization fails, the data should be invalidated if * possible. * * When you change this, run make_opcode_doc.py and copy the new output into * this wiki page: * * https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode */ -static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 338; +static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 339; static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND); -static_assert(JSErr_Limit == 432, +static_assert(JSErr_Limit == 434, "GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or " "removed MSG_DEFs from js.msg, you should increment " "XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's " "expected JSErr_Limit value."); class XDRBuffer { public: explicit XDRBuffer(JSContext* cx)
--- a/layout/reftests/svg/filters/feComposite-2-ref.svg +++ b/layout/reftests/svg/filters/feComposite-2-ref.svg @@ -1,7 +1,9 @@ <svg xmlns="http://www.w3.org/2000/svg"> <rect x="0" y="0" width="50" height="100" fill="#00ff00"/> <rect x="0" y="0" width="50" height="100" fill="#ff0000" opacity="0.5"/> <rect x="50" y="0" width="50" height="100" fill="#ff0000" opacity="0.5"/> +<rect x="100" y="0" width="50" height="100" fill="#808080"/> + </svg>
--- a/layout/reftests/svg/filters/feComposite-2.svg +++ b/layout/reftests/svg/filters/feComposite-2.svg @@ -5,9 +5,23 @@ <feComposite style="color-interpolation-filters:sRGB" in="flood" operator="over" in2="SourceGraphic"/> </filter> <g filter="url(#f1)"> <rect x="0" y="0" width="50" height="100" fill="#00ff00"/> <rect x="50" y="0" width="50" height="100" fill="#00ff00" opacity="0"/> </g> +<!-- Test that the arithmetic operator actually clamp the result --> +<filter id="f2" filterUnits="userSpaceOnUse" primitiveUnits="userSpaceOnUse" style="color-interpolation-filters:sRGB"> + <feFlood flood-color="#ffffff" result="flood" x="100" y="0" width="50" height="100"/> + <feComposite result="c" in="SourceGraphic" in2="flood" operator="arithmetic" k2="1" k3="1"/> + <feComponentTransfer in="c"> + <feFuncR type="linear" slope="0.5"/> + <feFuncG type="linear" slope="0.5"/> + <feFuncB type="linear" slope="0.5"/> + </feComponentTransfer> +</filter> +<g filter="url(#f2)"> + <rect x="100" y="0" width="50" height="100" fill="#ff0000"/> +</g> + </svg>
--- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -79,17 +79,17 @@ NS_NewComputedDOMStyle(dom::Element* aEl */ struct nsComputedStyleMap { friend class nsComputedDOMStyle; struct Entry { // Create a pointer-to-member-function type. - typedef mozilla::dom::CSSValue* (nsComputedDOMStyle::*ComputeMethod)(); + typedef already_AddRefed<CSSValue> (nsComputedDOMStyle::*ComputeMethod)(); nsCSSProperty mProperty; ComputeMethod mGetter; bool IsLayoutFlushNeeded() const { return nsCSSProps::PropHasFlags(mProperty, CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH); @@ -883,63 +883,63 @@ nsComputedDOMStyle::IndexedGetter(uint32 aFound = false; } ClearCurrentStyleSources(); } // Property getters... -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBinding() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleDisplay* display = StyleDisplay(); if (display->mBinding) { val->SetURI(display->mBinding->GetURI()); } else { val->SetIdent(eCSSKeyword_none); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetClear() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBreakType, nsCSSProps::kClearKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFloat() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mFloats, nsCSSProps::kFloatKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBottom() { return GetOffsetWidthFor(NS_SIDE_BOTTOM); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetStackSizing() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(StyleXUL()->mStretchStack ? eCSSKeyword_stretch_to_fit : eCSSKeyword_ignore); - return val; + return val.forget(); } void nsComputedDOMStyle::SetToRGBAColor(nsROCSSPrimitiveValue* aValue, nscolor aColor) { if (NS_GET_A(aColor) == 0) { aValue->SetIdent(eCSSKeyword_transparent); @@ -958,138 +958,138 @@ nsComputedDOMStyle::SetToRGBAColor(nsROC red->SetNumber(NS_GET_R(aColor)); green->SetNumber(NS_GET_G(aColor)); blue->SetNumber(NS_GET_B(aColor)); alpha->SetNumber(nsStyleUtil::ColorComponentToFloat(a)); aValue->SetColor(rgbColor); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetColor() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetToRGBAColor(val, StyleColor()->mColor); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOpacity() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetNumber(StyleDisplay()->mOpacity); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetColumnCount() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleColumn* column = StyleColumn(); if (column->mColumnCount == NS_STYLE_COLUMN_COUNT_AUTO) { val->SetIdent(eCSSKeyword_auto); } else { val->SetNumber(column->mColumnCount); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetColumnWidth() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; // XXX fix the auto case. When we actually have a column frame, I think // we should return the computed column width. SetValueToCoord(val, StyleColumn()->mColumnWidth, true); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetColumnGap() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleColumn* column = StyleColumn(); if (column->mColumnGap.GetUnit() == eStyleUnit_Normal) { val->SetAppUnits(StyleFont()->mFont.size); } else { SetValueToCoord(val, StyleColumn()->mColumnGap, true); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetColumnFill() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleColumn()->mColumnFill, nsCSSProps::kColumnFillKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetColumnRuleWidth() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetAppUnits(StyleColumn()->GetComputedColumnRuleWidth()); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetColumnRuleStyle() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleColumn()->mColumnRuleStyle, nsCSSProps::kBorderStyleKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetColumnRuleColor() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleColumn* column = StyleColumn(); nscolor ruleColor; if (column->mColumnRuleColorIsForeground) { ruleColor = StyleColor()->mColor; } else { ruleColor = column->mColumnRuleColor; } SetToRGBAColor(val, ruleColor); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetContent() { const nsStyleContent *content = StyleContent(); if (content->ContentCount() == 0) { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_none); - return val; + return val.forget(); } if (content->ContentCount() == 1 && content->ContentAt(0).mType == eStyleContentType_AltContent) { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword__moz_alt_content); - return val; - } - - nsDOMCSSValueList *valueList = GetROCSSValueList(false); + return val.forget(); + } + + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); for (uint32_t i = 0, i_end = content->ContentCount(); i < i_end; ++i) { RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleContentData &data = content->ContentAt(i); switch (data.mType) { case eStyleContentType_String: { @@ -1168,61 +1168,61 @@ nsComputedDOMStyle::DoGetContent() case eStyleContentType_AltContent: default: NS_NOTREACHED("unexpected type"); break; } valueList->AppendCSSValue(val.forget()); } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetCounterIncrement() { const nsStyleContent *content = StyleContent(); if (content->CounterIncrementCount() == 0) { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_none); - return val; - } - - nsDOMCSSValueList *valueList = GetROCSSValueList(false); + return val.forget(); + } + + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); for (uint32_t i = 0, i_end = content->CounterIncrementCount(); i < i_end; ++i) { RefPtr<nsROCSSPrimitiveValue> name = new nsROCSSPrimitiveValue; RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue; const nsStyleCounterData *data = content->GetCounterIncrementAt(i); nsAutoString escaped; nsStyleUtil::AppendEscapedCSSIdent(data->mCounter, escaped); name->SetString(escaped); value->SetNumber(data->mValue); // XXX This should really be integer valueList->AppendCSSValue(name.forget()); valueList->AppendCSSValue(value.forget()); } - return valueList; + return valueList.forget(); } /* Convert the stored representation into a list of two values and then hand * it back. */ -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTransformOrigin() { /* We need to build up a list of two values. We'll call them * width and height. */ /* Store things as a value list */ - nsDOMCSSValueList* valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); /* Now, get the values. */ const nsStyleDisplay* display = StyleDisplay(); RefPtr<nsROCSSPrimitiveValue> width = new nsROCSSPrimitiveValue; SetValueToCoord(width, display->mTransformOrigin[0], false, &nsComputedDOMStyle::GetFrameBoundsWidthForTransform); valueList->AppendCSSValue(width.forget()); @@ -1235,95 +1235,95 @@ nsComputedDOMStyle::DoGetTransformOrigin if (display->mTransformOrigin[2].GetUnit() != eStyleUnit_Coord || display->mTransformOrigin[2].GetCoordValue() != 0) { RefPtr<nsROCSSPrimitiveValue> depth = new nsROCSSPrimitiveValue; SetValueToCoord(depth, display->mTransformOrigin[2], false, nullptr); valueList->AppendCSSValue(depth.forget()); } - return valueList; + return valueList.forget(); } /* Convert the stored representation into a list of two values and then hand * it back. */ -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPerspectiveOrigin() { /* We need to build up a list of two values. We'll call them * width and height. */ /* Store things as a value list */ - nsDOMCSSValueList* valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); /* Now, get the values. */ const nsStyleDisplay* display = StyleDisplay(); RefPtr<nsROCSSPrimitiveValue> width = new nsROCSSPrimitiveValue; SetValueToCoord(width, display->mPerspectiveOrigin[0], false, &nsComputedDOMStyle::GetFrameBoundsWidthForTransform); valueList->AppendCSSValue(width.forget()); RefPtr<nsROCSSPrimitiveValue> height = new nsROCSSPrimitiveValue; SetValueToCoord(height, display->mPerspectiveOrigin[1], false, &nsComputedDOMStyle::GetFrameBoundsHeightForTransform); valueList->AppendCSSValue(height.forget()); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPerspective() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, StyleDisplay()->mChildPerspective, false); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBackfaceVisibility() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBackfaceVisibility, nsCSSProps::kBackfaceVisibilityKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTransformStyle() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mTransformStyle, nsCSSProps::kTransformStyleKTable)); - return val; + return val.forget(); } /* If the property is "none", hand back "none" wrapped in a value. * Otherwise, compute the aggregate transform matrix and hands it back in a * "matrix" wrapper. */ -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTransform() { /* First, get the display data. We'll need it. */ const nsStyleDisplay* display = StyleDisplay(); /* If there are no transforms, then we should construct a single-element * entry and hand it back. */ if (!display->mSpecifiedTransform) { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; /* Set it to "none." */ val->SetIdent(eCSSKeyword_none); - return val; + return val.forget(); } /* Otherwise, we need to compute the current value of the transform matrix, * store it in a string, and hand it back to the caller. */ /* Use the inner frame for the reference box. If we don't have an inner * frame we use empty dimensions to allow us to continue (and percentage @@ -1346,27 +1346,27 @@ nsComputedDOMStyle::DoGetTransform() mStyleContext->PresContext(), dummy, refBox, float(mozilla::AppUnitsPerCSSPixel())); return MatrixToCSSValue(matrix); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTransformBox() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mTransformBox, nsCSSProps::kTransformBoxKTable)); - return val; -} - -/* static */ nsROCSSPrimitiveValue* + return val.forget(); +} + +/* static */ already_AddRefed<nsROCSSPrimitiveValue> nsComputedDOMStyle::MatrixToCSSValue(const mozilla::gfx::Matrix4x4& matrix) { bool is3D = !matrix.Is2D(); nsAutoString resultString(NS_LITERAL_STRING("matrix")); if (is3D) { resultString.AppendLiteral("3d"); } @@ -1407,237 +1407,237 @@ nsComputedDOMStyle::MatrixToCSSValue(con resultString.AppendLiteral(", "); resultString.AppendFloat(matrix._43); resultString.AppendLiteral(", "); resultString.AppendFloat(matrix._44); } resultString.Append(')'); /* Create a value to hold our result. */ - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetString(resultString); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetCounterReset() { const nsStyleContent *content = StyleContent(); if (content->CounterResetCount() == 0) { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_none); - return val; - } - - nsDOMCSSValueList *valueList = GetROCSSValueList(false); + return val.forget(); + } + + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); for (uint32_t i = 0, i_end = content->CounterResetCount(); i < i_end; ++i) { RefPtr<nsROCSSPrimitiveValue> name = new nsROCSSPrimitiveValue; RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue; const nsStyleCounterData *data = content->GetCounterResetAt(i); nsAutoString escaped; nsStyleUtil::AppendEscapedCSSIdent(data->mCounter, escaped); name->SetString(escaped); value->SetNumber(data->mValue); // XXX This should really be integer valueList->AppendCSSValue(name.forget()); valueList->AppendCSSValue(value.forget()); } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetQuotes() { const nsStyleQuotes *quotes = StyleQuotes(); if (quotes->QuotesCount() == 0) { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_none); - return val; - } - - nsDOMCSSValueList *valueList = GetROCSSValueList(false); + return val.forget(); + } + + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); for (uint32_t i = 0, i_end = quotes->QuotesCount(); i < i_end; ++i) { RefPtr<nsROCSSPrimitiveValue> openVal = new nsROCSSPrimitiveValue; RefPtr<nsROCSSPrimitiveValue> closeVal = new nsROCSSPrimitiveValue; nsString s; nsStyleUtil::AppendEscapedCSSString(*quotes->OpenQuoteAt(i), s); openVal->SetString(s); s.Truncate(); nsStyleUtil::AppendEscapedCSSString(*quotes->CloseQuoteAt(i), s); closeVal->SetString(s); valueList->AppendCSSValue(openVal.forget()); valueList->AppendCSSValue(closeVal.forget()); } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontFamily() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleFont* font = StyleFont(); nsAutoString fontlistStr; nsStyleUtil::AppendEscapedCSSFontFamilyList(font->mFont.fontlist, fontlistStr); val->SetString(fontlistStr); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontSize() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; // Note: StyleFont()->mSize is the 'computed size'; // StyleFont()->mFont.size is the 'actual size' val->SetAppUnits(StyleFont()->mSize); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontSizeAdjust() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleFont *font = StyleFont(); if (font->mFont.sizeAdjust >= 0.0f) { val->SetNumber(font->mFont.sizeAdjust); } else { val->SetIdent(eCSSKeyword_none); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOsxFontSmoothing() { if (nsContentUtils::ShouldResistFingerprinting( mPresShell->GetPresContext()->GetDocShell())) return nullptr; - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.smoothing, nsCSSProps::kFontSmoothingKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontStretch() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.stretch, nsCSSProps::kFontStretchKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontStyle() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.style, nsCSSProps::kFontStyleKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontWeight() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleFont* font = StyleFont(); uint16_t weight = font->mFont.weight; NS_ASSERTION(weight % 100 == 0, "unexpected value of font-weight"); val->SetNumber(weight); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontFeatureSettings() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleFont* font = StyleFont(); if (font->mFont.fontFeatureSettings.IsEmpty()) { val->SetIdent(eCSSKeyword_normal); } else { nsAutoString result; nsStyleUtil::AppendFontFeatureSettings(font->mFont.fontFeatureSettings, result); val->SetString(result); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontKerning() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.kerning, nsCSSProps::kFontKerningKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontLanguageOverride() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleFont* font = StyleFont(); if (font->mFont.languageOverride.IsEmpty()) { val->SetIdent(eCSSKeyword_normal); } else { nsString str; nsStyleUtil::AppendEscapedCSSString(font->mFont.languageOverride, str); val->SetString(str); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontSynthesis() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; int32_t intValue = StyleFont()->mFont.synthesis; if (0 == intValue) { val->SetIdent(eCSSKeyword_none); } else { nsAutoString valueStr; nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_synthesis, intValue, NS_FONT_SYNTHESIS_WEIGHT, NS_FONT_SYNTHESIS_STYLE, valueStr); val->SetString(valueStr); } - return val; + return val.forget(); } // return a value *only* for valid longhand values from CSS 2.1, either // normal or small-caps only -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontVariant() { const nsFont& f = StyleFont()->mFont; // if any of the other font-variant subproperties other than // font-variant-caps are not normal then can't calculate a computed value if (f.variantAlternates || f.variantEastAsian || f.variantLigatures || f.variantNumeric || f.variantPosition) { @@ -1651,31 +1651,31 @@ nsComputedDOMStyle::DoGetFontVariant() break; case NS_FONT_VARIANT_CAPS_SMALLCAPS: keyword = eCSSKeyword_small_caps; break; default: return nullptr; } - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(keyword); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontVariantAlternates() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; int32_t intValue = StyleFont()->mFont.variantAlternates; if (0 == intValue) { val->SetIdent(eCSSKeyword_normal); - return val; + return val.forget(); } // first, include enumerated values nsAutoString valueStr; nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_alternates, intValue & NS_FONT_VARIANT_ALTERNATES_ENUMERATED_MASK, NS_FONT_VARIANT_ALTERNATES_HISTORICAL, @@ -1683,161 +1683,161 @@ nsComputedDOMStyle::DoGetFontVariantAlte // next, include functional values if present if (intValue & NS_FONT_VARIANT_ALTERNATES_FUNCTIONAL_MASK) { nsStyleUtil::SerializeFunctionalAlternates(StyleFont()->mFont.alternateValues, valueStr); } val->SetString(valueStr); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontVariantCaps() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; int32_t intValue = StyleFont()->mFont.variantCaps; if (0 == intValue) { val->SetIdent(eCSSKeyword_normal); } else { val->SetIdent( nsCSSProps::ValueToKeywordEnum(intValue, nsCSSProps::kFontVariantCapsKTable)); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontVariantEastAsian() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; int32_t intValue = StyleFont()->mFont.variantEastAsian; if (0 == intValue) { val->SetIdent(eCSSKeyword_normal); } else { nsAutoString valueStr; nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_east_asian, intValue, NS_FONT_VARIANT_EAST_ASIAN_JIS78, NS_FONT_VARIANT_EAST_ASIAN_RUBY, valueStr); val->SetString(valueStr); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontVariantLigatures() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; int32_t intValue = StyleFont()->mFont.variantLigatures; if (0 == intValue) { val->SetIdent(eCSSKeyword_normal); } else if (NS_FONT_VARIANT_LIGATURES_NONE == intValue) { val->SetIdent(eCSSKeyword_none); } else { nsAutoString valueStr; nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_ligatures, intValue, NS_FONT_VARIANT_LIGATURES_NONE, NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL, valueStr); val->SetString(valueStr); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontVariantNumeric() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; int32_t intValue = StyleFont()->mFont.variantNumeric; if (0 == intValue) { val->SetIdent(eCSSKeyword_normal); } else { nsAutoString valueStr; nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_numeric, intValue, NS_FONT_VARIANT_NUMERIC_LINING, NS_FONT_VARIANT_NUMERIC_ORDINAL, valueStr); val->SetString(valueStr); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFontVariantPosition() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; int32_t intValue = StyleFont()->mFont.variantPosition; if (0 == intValue) { val->SetIdent(eCSSKeyword_normal); } else { val->SetIdent( nsCSSProps::ValueToKeywordEnum(intValue, nsCSSProps::kFontVariantPositionKTable)); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::GetBackgroundList(uint8_t nsStyleBackground::Layer::* aMember, uint32_t nsStyleBackground::* aCount, const KTableEntry aTable[]) { const nsStyleBackground* bg = StyleBackground(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); for (uint32_t i = 0, i_end = bg->*aCount; i < i_end; ++i) { RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(bg->mLayers[i].*aMember, aTable)); valueList->AppendCSSValue(val.forget()); } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBackgroundAttachment() { return GetBackgroundList(&nsStyleBackground::Layer::mAttachment, &nsStyleBackground::mAttachmentCount, nsCSSProps::kBackgroundAttachmentKTable); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBackgroundClip() { return GetBackgroundList(&nsStyleBackground::Layer::mClip, &nsStyleBackground::mClipCount, nsCSSProps::kBackgroundOriginKTable); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBackgroundColor() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetToRGBAColor(val, StyleBackground()->mBackgroundColor); - return val; + return val.forget(); } static void SetValueToCalc(const nsStyleCoord::CalcValue *aCalc, nsROCSSPrimitiveValue *aValue) { RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nsAutoString tmp, result; @@ -2114,43 +2114,43 @@ nsComputedDOMStyle::SetValueToStyleImage aValue->SetIdent(eCSSKeyword_none); break; default: NS_NOTREACHED("unexpected image type"); break; } } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBackgroundImage() { const nsStyleBackground* bg = StyleBackground(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); for (uint32_t i = 0, i_end = bg->mImageCount; i < i_end; ++i) { RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleImage& image = bg->mLayers[i].mImage; SetValueToStyleImage(image, val); valueList->AppendCSSValue(val.forget()); } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBackgroundBlendMode() { return GetBackgroundList(&nsStyleBackground::Layer::mBlendMode, &nsStyleBackground::mBlendModeCount, nsCSSProps::kBlendModeKTable); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBackgroundOrigin() { return GetBackgroundList(&nsStyleBackground::Layer::mOrigin, &nsStyleBackground::mOriginCount, nsCSSProps::kBackgroundOriginKTable); } void @@ -2178,38 +2178,38 @@ nsComputedDOMStyle::SetValueToPosition( SetValueToPositionCoord(aPosition.mXPosition, valX); aValueList->AppendCSSValue(valX.forget()); RefPtr<nsROCSSPrimitiveValue> valY = new nsROCSSPrimitiveValue; SetValueToPositionCoord(aPosition.mYPosition, valY); aValueList->AppendCSSValue(valY.forget()); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBackgroundPosition() { const nsStyleBackground* bg = StyleBackground(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); for (uint32_t i = 0, i_end = bg->mPositionCount; i < i_end; ++i) { RefPtr<nsDOMCSSValueList> itemList = GetROCSSValueList(false); SetValueToPosition(bg->mLayers[i].mPosition, itemList); valueList->AppendCSSValue(itemList.forget()); } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBackgroundRepeat() { const nsStyleBackground* bg = StyleBackground(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); for (uint32_t i = 0, i_end = bg->mRepeatCount; i < i_end; ++i) { RefPtr<nsDOMCSSValueList> itemList = GetROCSSValueList(false); RefPtr<nsROCSSPrimitiveValue> valX = new nsROCSSPrimitiveValue; const uint8_t& xRepeat = bg->mLayers[i].mRepeat.mXRepeat; const uint8_t& yRepeat = bg->mLayers[i].mRepeat.mYRepeat; @@ -2241,25 +2241,25 @@ nsComputedDOMStyle::DoGetBackgroundRepea } itemList->AppendCSSValue(valX.forget()); if (valY) { itemList->AppendCSSValue(valY.forget()); } valueList->AppendCSSValue(itemList.forget()); } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBackgroundSize() { const nsStyleBackground* bg = StyleBackground(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); for (uint32_t i = 0, i_end = bg->mSizeCount; i < i_end; ++i) { const nsStyleBackground::Size &size = bg->mLayers[i].mSize; switch (size.mWidthType) { case nsStyleBackground::Size::eContain: case nsStyleBackground::Size::eCover: { MOZ_ASSERT(size.mWidthType == size.mHeightType, @@ -2322,41 +2322,41 @@ nsComputedDOMStyle::DoGetBackgroundSize( itemList->AppendCSSValue(valX.forget()); itemList->AppendCSSValue(valY.forget()); valueList->AppendCSSValue(itemList.forget()); break; } } } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetGridTemplateAreas() { const css::GridTemplateAreasValue* areas = StylePosition()->mGridTemplateAreas; if (!areas) { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_none); - return val; + return val.forget(); } MOZ_ASSERT(!areas->mTemplates.IsEmpty(), "Unexpected empty array in GridTemplateAreasValue"); - nsDOMCSSValueList *valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); for (uint32_t i = 0; i < areas->mTemplates.Length(); i++) { nsAutoString str; nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[i], str); RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetString(str); valueList->AppendCSSValue(val.forget()); } - return valueList; + return valueList.forget(); } void nsComputedDOMStyle::AppendGridLineNames(nsString& aResult, const nsTArray<nsString>& aLineNames) { MOZ_ASSERT(!aLineNames.IsEmpty(), "expected some line names"); uint32_t numLines = aLineNames.Length(); @@ -2405,28 +2405,28 @@ nsComputedDOMStyle::AppendGridLineNames( } AppendGridLineNames(lineNamesString, aLineNames2); } lineNamesString.Append(']'); val->SetString(lineNamesString); aValueList->AppendCSSValue(val.forget()); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTrackSize(const nsStyleCoord& aMinValue, const nsStyleCoord& aMaxValue) { if (aMinValue == aMaxValue) { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, aMinValue, true, nullptr, nsCSSProps::kGridTrackBreadthKTable); - return val; - } - - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + return val.forget(); + } + + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nsAutoString argumentStr, minmaxStr; minmaxStr.AppendLiteral("minmax("); SetValueToCoord(val, aMinValue, true, nullptr, nsCSSProps::kGridTrackBreadthKTable); val->GetCssText(argumentStr); minmaxStr.Append(argumentStr); @@ -2434,29 +2434,29 @@ nsComputedDOMStyle::GetGridTrackSize(con SetValueToCoord(val, aMaxValue, true, nullptr, nsCSSProps::kGridTrackBreadthKTable); val->GetCssText(argumentStr); minmaxStr.Append(argumentStr); minmaxStr.Append(char16_t(')')); val->SetString(minmaxStr); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTemplateColumnsRows(const nsStyleGridTemplate& aTrackList, const nsTArray<nscoord>* aTrackSizes) { if (aTrackList.mIsSubgrid) { // XXX TODO: add support for repeat(auto-fill) for 'subgrid' (bug 1234311) NS_ASSERTION(aTrackList.mMinTrackSizingFunctions.IsEmpty() && aTrackList.mMaxTrackSizingFunctions.IsEmpty(), "Unexpected sizing functions with subgrid"); - nsDOMCSSValueList* valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); RefPtr<nsROCSSPrimitiveValue> subgridKeyword = new nsROCSSPrimitiveValue; subgridKeyword->SetIdent(eCSSKeyword_subgrid); valueList->AppendCSSValue(subgridKeyword.forget()); for (uint32_t i = 0; i < aTrackList.mLineNameLists.Length(); i++) { if (MOZ_UNLIKELY(aTrackList.IsRepeatAutoIndex(i))) { MOZ_ASSERT(aTrackList.mIsAutoFill, "subgrid can only have 'auto-fill'"); @@ -2469,48 +2469,48 @@ nsComputedDOMStyle::GetGridTemplateColum valueList->AppendCSSValue(start.forget()); AppendGridLineNames(valueList, aTrackList.mRepeatAutoLineNameListBefore); RefPtr<nsROCSSPrimitiveValue> end = new nsROCSSPrimitiveValue; end->SetString(NS_LITERAL_STRING(")")); valueList->AppendCSSValue(end.forget()); } AppendGridLineNames(valueList, aTrackList.mLineNameLists[i]); } - return valueList; + return valueList.forget(); } uint32_t numSizes = aTrackList.mMinTrackSizingFunctions.Length(); MOZ_ASSERT(aTrackList.mMaxTrackSizingFunctions.Length() == numSizes, "Different number of min and max track sizing functions"); // An empty <track-list> is represented as "none" in syntax. if (numSizes == 0) { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_none); - return val; - } - - nsDOMCSSValueList* valueList = GetROCSSValueList(false); + return val.forget(); + } + + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); // Delimiting N tracks requires N+1 lines: // one before each track, plus one at the very end. MOZ_ASSERT(aTrackList.mLineNameLists.Length() == numSizes + 1, "Unexpected number of line name lists"); if (aTrackSizes) { // We've done layout on the grid and have resolved the sizes of its tracks, // so we'll return those sizes here. The grid spec says we MAY use // repeat(<positive-integer>, Npx) here for consecutive tracks with the same // size, but that doesn't seem worth doing since even for repeat(auto-*) // the resolved size might differ for the repeated tracks. const uint32_t numTracks = aTrackSizes->Length(); MOZ_ASSERT(numTracks > 0 || (aTrackList.HasRepeatAuto() && !aTrackList.mIsAutoFill), "only 'auto-fit' can result in zero tracks"); if (numTracks == 0) { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_none); - return val; + return val.forget(); } int32_t endOfRepeat = 0; // first index after any repeat() tracks int32_t offsetToLastRepeat = 0; if (aTrackList.HasRepeatAuto()) { // offsetToLastRepeat is -1 if all repeat(auto-fit) tracks are empty offsetToLastRepeat = numTracks + 1 - aTrackList.mLineNameLists.Length(); endOfRepeat = aTrackList.mRepeatAutoIndex + offsetToLastRepeat + 1; } @@ -2569,113 +2569,104 @@ nsComputedDOMStyle::GetGridTemplateColum RefPtr<nsROCSSPrimitiveValue> start = new nsROCSSPrimitiveValue; start->SetString(aTrackList.mIsAutoFill ? NS_LITERAL_STRING("repeat(auto-fill,") : NS_LITERAL_STRING("repeat(auto-fit,")); valueList->AppendCSSValue(start.forget()); if (!aTrackList.mRepeatAutoLineNameListBefore.IsEmpty()) { AppendGridLineNames(valueList, aTrackList.mRepeatAutoLineNameListBefore); } - // XXXdholbert The |tmpTrackSize| RefPtr variable below can go away once - // we fix bug 1234676 and can make GetGridTrackSize return an - // already_AddRefed value. - RefPtr<CSSValue> tmpTrackSize = + valueList->AppendCSSValue( GetGridTrackSize(aTrackList.mMinTrackSizingFunctions[i], - aTrackList.mMaxTrackSizingFunctions[i]); - - valueList->AppendCSSValue(tmpTrackSize.forget()); + aTrackList.mMaxTrackSizingFunctions[i])); if (!aTrackList.mRepeatAutoLineNameListAfter.IsEmpty()) { AppendGridLineNames(valueList, aTrackList.mRepeatAutoLineNameListAfter); } RefPtr<nsROCSSPrimitiveValue> end = new nsROCSSPrimitiveValue; end->SetString(NS_LITERAL_STRING(")")); valueList->AppendCSSValue(end.forget()); } else { - // XXXdholbert The |tmpTrackSize| RefPtr variable below can go away once - // we fix bug 1234676 and make GetGridTrackSize return an - // already_AddRefed value. - RefPtr<CSSValue> tmpTrackSize = + valueList->AppendCSSValue( GetGridTrackSize(aTrackList.mMinTrackSizingFunctions[i], - aTrackList.mMaxTrackSizingFunctions[i]); - valueList->AppendCSSValue(tmpTrackSize.forget()); + aTrackList.mMaxTrackSizingFunctions[i])); } } } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetGridAutoFlow() { nsAutoString str; nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_grid_auto_flow, StylePosition()->mGridAutoFlow, NS_STYLE_GRID_AUTO_FLOW_ROW, NS_STYLE_GRID_AUTO_FLOW_DENSE, str); - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetString(str); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetGridAutoColumns() { return GetGridTrackSize(StylePosition()->mGridAutoColumnsMin, StylePosition()->mGridAutoColumnsMax); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetGridAutoRows() { return GetGridTrackSize(StylePosition()->mGridAutoRowsMin, StylePosition()->mGridAutoRowsMax); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetGridTemplateColumns() { const nsTArray<nscoord>* trackSizes = nullptr; if (mInnerFrame) { nsIFrame* gridContainerCandidate = mInnerFrame->GetContentInsertionFrame(); if (gridContainerCandidate && gridContainerCandidate->GetType() == nsGkAtoms::gridContainerFrame) { auto gridContainer = static_cast<nsGridContainerFrame*>(gridContainerCandidate); trackSizes = gridContainer->GetComputedTemplateColumns(); } } return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateColumns, trackSizes); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetGridTemplateRows() { const nsTArray<nscoord>* trackSizes = nullptr; if (mInnerFrame) { nsIFrame* gridContainerCandidate = mInnerFrame->GetContentInsertionFrame(); if (gridContainerCandidate && gridContainerCandidate->GetType() == nsGkAtoms::gridContainerFrame) { auto gridContainer = static_cast<nsGridContainerFrame*>(gridContainerCandidate); trackSizes = gridContainer->GetComputedTemplateRows(); } } return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateRows, trackSizes); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridLine(const nsStyleGridLine& aGridLine) { if (aGridLine.IsAuto()) { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_auto); - return val; - } - - nsDOMCSSValueList* valueList = GetROCSSValueList(false); + return val.forget(); + } + + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); if (aGridLine.mHasSpan) { RefPtr<nsROCSSPrimitiveValue> span = new nsROCSSPrimitiveValue; span->SetIdent(eCSSKeyword_span); valueList->AppendCSSValue(span.forget()); } if (aGridLine.mInteger != 0) { @@ -2689,416 +2680,416 @@ nsComputedDOMStyle::GetGridLine(const ns nsString escapedLineName; nsStyleUtil::AppendEscapedCSSIdent(aGridLine.mLineName, escapedLineName); lineName->SetString(escapedLineName); valueList->AppendCSSValue(lineName.forget()); } NS_ASSERTION(valueList->Length() > 0, "Should have appended at least one value"); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetGridColumnStart() { return GetGridLine(StylePosition()->mGridColumnStart); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetGridColumnEnd() { return GetGridLine(StylePosition()->mGridColumnEnd); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetGridRowStart() { return GetGridLine(StylePosition()->mGridRowStart); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetGridRowEnd() { return GetGridLine(StylePosition()->mGridRowEnd); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetGridColumnGap() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetAppUnits(StylePosition()->mGridColumnGap); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetGridRowGap() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetAppUnits(StylePosition()->mGridRowGap); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPaddingTop() { return GetPaddingWidthFor(NS_SIDE_TOP); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPaddingBottom() { return GetPaddingWidthFor(NS_SIDE_BOTTOM); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPaddingLeft() { return GetPaddingWidthFor(NS_SIDE_LEFT); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPaddingRight() { return GetPaddingWidthFor(NS_SIDE_RIGHT); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderCollapse() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleTableBorder()->mBorderCollapse, nsCSSProps::kBorderCollapseKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderSpacing() { - nsDOMCSSValueList *valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); RefPtr<nsROCSSPrimitiveValue> xSpacing = new nsROCSSPrimitiveValue; RefPtr<nsROCSSPrimitiveValue> ySpacing = new nsROCSSPrimitiveValue; const nsStyleTableBorder *border = StyleTableBorder(); xSpacing->SetAppUnits(border->mBorderSpacingCol); ySpacing->SetAppUnits(border->mBorderSpacingRow); valueList->AppendCSSValue(xSpacing.forget()); valueList->AppendCSSValue(ySpacing.forget()); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetCaptionSide() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleTableBorder()->mCaptionSide, nsCSSProps::kCaptionSideKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetEmptyCells() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleTableBorder()->mEmptyCells, nsCSSProps::kEmptyCellsKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTableLayout() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleTable()->mLayoutStrategy, nsCSSProps::kTableLayoutKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderTopStyle() { return GetBorderStyleFor(NS_SIDE_TOP); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderBottomStyle() { return GetBorderStyleFor(NS_SIDE_BOTTOM); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderLeftStyle() { return GetBorderStyleFor(NS_SIDE_LEFT); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderRightStyle() { return GetBorderStyleFor(NS_SIDE_RIGHT); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderBottomColors() { return GetBorderColorsFor(NS_SIDE_BOTTOM); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderLeftColors() { return GetBorderColorsFor(NS_SIDE_LEFT); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderRightColors() { return GetBorderColorsFor(NS_SIDE_RIGHT); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderTopColors() { return GetBorderColorsFor(NS_SIDE_TOP); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderBottomLeftRadius() { return GetEllipseRadii(StyleBorder()->mBorderRadius, NS_CORNER_BOTTOM_LEFT, true); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderBottomRightRadius() { return GetEllipseRadii(StyleBorder()->mBorderRadius, NS_CORNER_BOTTOM_RIGHT, true); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderTopLeftRadius() { return GetEllipseRadii(StyleBorder()->mBorderRadius, NS_CORNER_TOP_LEFT, true); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderTopRightRadius() { return GetEllipseRadii(StyleBorder()->mBorderRadius, NS_CORNER_TOP_RIGHT, true); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderTopWidth() { return GetBorderWidthFor(NS_SIDE_TOP); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderBottomWidth() { return GetBorderWidthFor(NS_SIDE_BOTTOM); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderLeftWidth() { return GetBorderWidthFor(NS_SIDE_LEFT); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderRightWidth() { return GetBorderWidthFor(NS_SIDE_RIGHT); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderTopColor() { return GetBorderColorFor(NS_SIDE_TOP); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderBottomColor() { return GetBorderColorFor(NS_SIDE_BOTTOM); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderLeftColor() { return GetBorderColorFor(NS_SIDE_LEFT); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderRightColor() { return GetBorderColorFor(NS_SIDE_RIGHT); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMarginTopWidth() { return GetMarginWidthFor(NS_SIDE_TOP); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMarginBottomWidth() { return GetMarginWidthFor(NS_SIDE_BOTTOM); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMarginLeftWidth() { return GetMarginWidthFor(NS_SIDE_LEFT); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMarginRightWidth() { return GetMarginWidthFor(NS_SIDE_RIGHT); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMarkerOffset() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, StyleContent()->mMarkerOffset, false); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOrient() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOrient, nsCSSProps::kOrientKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetScrollBehavior() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mScrollBehavior, nsCSSProps::kScrollBehaviorKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetScrollSnapType() { const nsStyleDisplay* display = StyleDisplay(); if (display->mScrollSnapTypeX != display->mScrollSnapTypeY) { // No value to return. We can't express this combination of // values as a shorthand. return nullptr; } - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mScrollSnapTypeX, nsCSSProps::kScrollSnapTypeKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetScrollSnapTypeX() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mScrollSnapTypeX, nsCSSProps::kScrollSnapTypeKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetScrollSnapTypeY() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mScrollSnapTypeY, nsCSSProps::kScrollSnapTypeKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::GetScrollSnapPoints(const nsStyleCoord& aCoord) { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; if (aCoord.GetUnit() == eStyleUnit_None) { val->SetIdent(eCSSKeyword_none); } else { nsAutoString argumentString; SetCssTextToCoord(argumentString, aCoord); nsAutoString tmp; tmp.AppendLiteral("repeat("); tmp.Append(argumentString); tmp.Append(')'); val->SetString(tmp); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetScrollSnapPointsX() { return GetScrollSnapPoints(StyleDisplay()->mScrollSnapPointsX); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetScrollSnapPointsY() { return GetScrollSnapPoints(StyleDisplay()->mScrollSnapPointsY); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetScrollSnapDestination() { - nsDOMCSSValueList* valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); SetValueToPosition(StyleDisplay()->mScrollSnapDestination, valueList); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetScrollSnapCoordinate() { const nsStyleDisplay* sd = StyleDisplay(); if (sd->mScrollSnapCoordinate.IsEmpty()) { // Having no snap coordinates is interpreted as "none" - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_none); - return val; + return val.forget(); } else { - nsDOMCSSValueList* valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); for (size_t i = 0, i_end = sd->mScrollSnapCoordinate.Length(); i < i_end; ++i) { RefPtr<nsDOMCSSValueList> itemList = GetROCSSValueList(false); SetValueToPosition(sd->mScrollSnapCoordinate[i], itemList); valueList->AppendCSSValue(itemList.forget()); } - return valueList; - } -} - -CSSValue* + return valueList.forget(); + } +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOutlineWidth() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleOutline* outline = StyleOutline(); nscoord width; if (outline->GetOutlineStyle() == NS_STYLE_BORDER_STYLE_NONE) { NS_ASSERTION(outline->GetOutlineWidth(width) && width == 0, "unexpected width"); width = 0; @@ -3106,79 +3097,79 @@ nsComputedDOMStyle::DoGetOutlineWidth() #ifdef DEBUG bool res = #endif outline->GetOutlineWidth(width); NS_ASSERTION(res, "percent outline doesn't exist"); } val->SetAppUnits(width); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOutlineStyle() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleOutline()->GetOutlineStyle(), nsCSSProps::kOutlineStyleKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOutlineOffset() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetAppUnits(StyleOutline()->mOutlineOffset); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOutlineRadiusBottomLeft() { return GetEllipseRadii(StyleOutline()->mOutlineRadius, NS_CORNER_BOTTOM_LEFT, false); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOutlineRadiusBottomRight() { return GetEllipseRadii(StyleOutline()->mOutlineRadius, NS_CORNER_BOTTOM_RIGHT, false); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOutlineRadiusTopLeft() { return GetEllipseRadii(StyleOutline()->mOutlineRadius, NS_CORNER_TOP_LEFT, false); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOutlineRadiusTopRight() { return GetEllipseRadii(StyleOutline()->mOutlineRadius, NS_CORNER_TOP_RIGHT, false); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOutlineColor() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nscolor color; if (!StyleOutline()->GetOutlineColor(color)) color = StyleColor()->mColor; SetToRGBAColor(val, color); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::GetEllipseRadii(const nsStyleCorners& aRadius, uint8_t aFullCorner, bool aIsBorder) // else outline { nsStyleCoord radiusX, radiusY; if (mInnerFrame && aIsBorder) { nscoord radii[8]; mInnerFrame->GetBorderRadii(radii); @@ -3202,46 +3193,46 @@ nsComputedDOMStyle::GetEllipseRadii(cons &nsComputedDOMStyle::GetFrameBorderRectHeight, 0, true); radiusY.SetCoordValue(v); } } // for compatibility, return a single value if X and Y are equal if (radiusX == radiusY) { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, radiusX, true); - return val; - } - - nsDOMCSSValueList *valueList = GetROCSSValueList(false); + return val.forget(); + } + + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); RefPtr<nsROCSSPrimitiveValue> valX = new nsROCSSPrimitiveValue; RefPtr<nsROCSSPrimitiveValue> valY = new nsROCSSPrimitiveValue; SetValueToCoord(valX, radiusX, true); SetValueToCoord(valY, radiusY, true); valueList->AppendCSSValue(valX.forget()); valueList->AppendCSSValue(valY.forget()); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::GetCSSShadowArray(nsCSSShadowArray* aArray, const nscolor& aDefaultColor, bool aIsBoxShadow) { if (!aArray) { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_none); - return val; + return val.forget(); } static nscoord nsCSSShadowItem::* const shadowValuesNoSpread[] = { &nsCSSShadowItem::mXOffset, &nsCSSShadowItem::mYOffset, &nsCSSShadowItem::mRadius }; @@ -3257,17 +3248,17 @@ nsComputedDOMStyle::GetCSSShadowArray(ns if (aIsBoxShadow) { shadowValues = shadowValuesWithSpread; shadowValuesLength = ArrayLength(shadowValuesWithSpread); } else { shadowValues = shadowValuesNoSpread; shadowValuesLength = ArrayLength(shadowValuesNoSpread); } - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); for (nsCSSShadowItem *item = aArray->ShadowAt(0), *item_end = item + aArray->Length(); item < item_end; ++item) { RefPtr<nsDOMCSSValueList> itemList = GetROCSSValueList(false); // Color is either the specified shadow color or the foreground color RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; @@ -3293,79 +3284,79 @@ nsComputedDOMStyle::GetCSSShadowArray(ns val->SetIdent( nsCSSProps::ValueToKeywordEnum(NS_STYLE_BOX_SHADOW_INSET, nsCSSProps::kBoxShadowTypeKTable)); itemList->AppendCSSValue(val.forget()); } valueList->AppendCSSValue(itemList.forget()); } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBoxDecorationBreak() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleBorder()->mBoxDecorationBreak, nsCSSProps::kBoxDecorationBreakKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBoxShadow() { return GetCSSShadowArray(StyleBorder()->mBoxShadow, StyleColor()->mColor, true); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetZIndex() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, StylePosition()->mZIndex, false); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetListStyleImage() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleList* list = StyleList(); if (!list->GetListStyleImage()) { val->SetIdent(eCSSKeyword_none); } else { nsCOMPtr<nsIURI> uri; if (list->GetListStyleImage()) { list->GetListStyleImage()->GetURI(getter_AddRefs(uri)); } val->SetURI(uri); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetListStylePosition() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleList()->mListStylePosition, nsCSSProps::kListStylePositionKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetListStyleType() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; CounterStyle* style = StyleList()->GetCounterStyle(); AnonymousCounterStyle* anonymous = style->AsAnonymous(); nsString tmp; if (!anonymous) { // want SetIdent nsString type; StyleList()->GetListStyleType(type); nsStyleUtil::AppendEscapedCSSIdent(type, tmp); @@ -3394,23 +3385,23 @@ nsComputedDOMStyle::DoGetListStyleType() "No symbols in the anonymous counter style"); for (size_t i = 0, iend = symbols.Length(); i < iend; i++) { nsStyleUtil::AppendEscapedCSSString(symbols[i], tmp); tmp.Append(' '); } tmp.Replace(tmp.Length() - 1, 1, char16_t(')')); } val->SetString(tmp); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetImageRegion() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleList* list = StyleList(); if (list->mImageRegion.width <= 0 || list->mImageRegion.height <= 0) { val->SetIdent(eCSSKeyword_auto); } else { // create the cssvalues for the sides, stick them in the rect object nsROCSSPrimitiveValue *topVal = new nsROCSSPrimitiveValue; @@ -3421,180 +3412,168 @@ nsComputedDOMStyle::DoGetImageRegion() bottomVal, leftVal); topVal->SetAppUnits(list->mImageRegion.y); rightVal->SetAppUnits(list->mImageRegion.width + list->mImageRegion.x); bottomVal->SetAppUnits(list->mImageRegion.height + list->mImageRegion.y); leftVal->SetAppUnits(list->mImageRegion.x); val->SetRect(domRect); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetLineHeight() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nscoord lineHeight; if (GetLineHeightCoord(lineHeight)) { val->SetAppUnits(lineHeight); } else { SetValueToCoord(val, StyleText()->mLineHeight, true, nullptr, nsCSSProps::kLineHeightKTable); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetRubyAlign() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum( StyleText()->mRubyAlign, nsCSSProps::kRubyAlignKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetRubyPosition() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum( StyleText()->mRubyPosition, nsCSSProps::kRubyPositionKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetVerticalAlign() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, StyleTextReset()->mVerticalAlign, false, &nsComputedDOMStyle::GetLineHeightCoord, nsCSSProps::kVerticalAlignKTable); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::CreateTextAlignValue(uint8_t aAlign, bool aAlignTrue, const KTableEntry aTable[]) { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(aAlign, aTable)); if (!aAlignTrue) { - return val; - } - - // XXXdholbert Really we should store |val| in a RefPtr right away, and our - // return-type should be already_AddRefed. See bug 1234676. For now, we only - // put it in a RefPtr (for the benefit of AppendCSSValue) after we know we're - // not returning it directly. - RefPtr<nsROCSSPrimitiveValue> refcountedVal = val; - val = nullptr; // (to avoid accidental reuse/misuse) + return val.forget(); + } RefPtr<nsROCSSPrimitiveValue> first = new nsROCSSPrimitiveValue; first->SetIdent(eCSSKeyword_true); - nsDOMCSSValueList* valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); valueList->AppendCSSValue(first.forget()); - valueList->AppendCSSValue(refcountedVal.forget()); - return valueList; -} - -CSSValue* + valueList->AppendCSSValue(val.forget()); + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextAlign() { const nsStyleText* style = StyleText(); return CreateTextAlignValue(style->mTextAlign, style->mTextAlignTrue, nsCSSProps::kTextAlignKTable); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextAlignLast() { const nsStyleText* style = StyleText(); return CreateTextAlignValue(style->mTextAlignLast, style->mTextAlignLastTrue, nsCSSProps::kTextAlignLastKTable); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextCombineUpright() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; uint8_t tch = StyleText()->mTextCombineUpright; if (tch <= NS_STYLE_TEXT_COMBINE_UPRIGHT_ALL) { val->SetIdent( nsCSSProps::ValueToKeywordEnum(tch, nsCSSProps::kTextCombineUprightKTable)); } else if (tch <= NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_2) { val->SetString(NS_LITERAL_STRING("digits 2")); } else if (tch <= NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_3) { val->SetString(NS_LITERAL_STRING("digits 3")); } else { val->SetString(NS_LITERAL_STRING("digits 4")); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextDecoration() { const nsStyleTextReset* textReset = StyleTextReset(); bool isInitialStyle = textReset->GetDecorationStyle() == NS_STYLE_TEXT_DECORATION_STYLE_SOLID; nscolor color; bool isForegroundColor; textReset->GetDecorationColor(color, isForegroundColor); if (isInitialStyle && isForegroundColor) { return DoGetTextDecorationLine(); } - nsDOMCSSValueList *valueList = GetROCSSValueList(false); - - // XXXdholbert The |tmp| RefPtr variable below can go away once we fix bug - // 1234676 and make the DoGet* functions return an already_AddRefed value. - RefPtr<CSSValue> tmp = DoGetTextDecorationLine(); - valueList->AppendCSSValue(tmp.forget()); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); + + valueList->AppendCSSValue(DoGetTextDecorationLine()); if (!isInitialStyle) { - tmp = DoGetTextDecorationStyle(); - valueList->AppendCSSValue(tmp.forget()); + valueList->AppendCSSValue(DoGetTextDecorationStyle()); } if (!isForegroundColor) { - tmp = DoGetTextDecorationColor(); - valueList->AppendCSSValue(tmp.forget()); - } - - return valueList; -} - -CSSValue* + valueList->AppendCSSValue(DoGetTextDecorationColor()); + } + + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextDecorationColor() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nscolor color; bool isForeground; StyleTextReset()->GetDecorationColor(color, isForeground); if (isForeground) { color = StyleColor()->mColor; } SetToRGBAColor(val, color); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextDecorationLine() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; int32_t intValue = StyleTextReset()->mTextDecorationLine; if (NS_STYLE_TEXT_DECORATION_LINE_NONE == intValue) { val->SetIdent(eCSSKeyword_none); } else { nsAutoString decorationLineString; // Clear the -moz-anchor-decoration bit and the OVERRIDE_ALL bits -- we @@ -3602,81 +3581,81 @@ nsComputedDOMStyle::DoGetTextDecorationL intValue &= ~(NS_STYLE_TEXT_DECORATION_LINE_PREF_ANCHORS | NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL); nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_text_decoration_line, intValue, NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, NS_STYLE_TEXT_DECORATION_LINE_BLINK, decorationLineString); val->SetString(decorationLineString); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextDecorationStyle() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleTextReset()->GetDecorationStyle(), nsCSSProps::kTextDecorationStyleKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextEmphasisColor() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleText* text = StyleText(); nscolor color = text->mTextEmphasisColorForeground ? StyleColor()->mColor : text->mTextEmphasisColor; SetToRGBAColor(val, color); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextEmphasisPosition() { auto position = StyleText()->mTextEmphasisPosition; MOZ_ASSERT(!(position & NS_STYLE_TEXT_EMPHASIS_POSITION_OVER) != !(position & NS_STYLE_TEXT_EMPHASIS_POSITION_UNDER)); RefPtr<nsROCSSPrimitiveValue> first = new nsROCSSPrimitiveValue; first->SetIdent((position & NS_STYLE_TEXT_EMPHASIS_POSITION_OVER) ? eCSSKeyword_over : eCSSKeyword_under); MOZ_ASSERT(!(position & NS_STYLE_TEXT_EMPHASIS_POSITION_LEFT) != !(position & NS_STYLE_TEXT_EMPHASIS_POSITION_RIGHT)); RefPtr<nsROCSSPrimitiveValue> second = new nsROCSSPrimitiveValue; second->SetIdent((position & NS_STYLE_TEXT_EMPHASIS_POSITION_LEFT) ? eCSSKeyword_left : eCSSKeyword_right); - nsDOMCSSValueList* valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); valueList->AppendCSSValue(first.forget()); valueList->AppendCSSValue(second.forget()); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextEmphasisStyle() { auto style = StyleText()->mTextEmphasisStyle; if (style == NS_STYLE_TEXT_EMPHASIS_STYLE_NONE) { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_none); - return val; + return val.forget(); } if (style == NS_STYLE_TEXT_EMPHASIS_STYLE_STRING) { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nsString tmp; nsStyleUtil::AppendEscapedCSSString( StyleText()->mTextEmphasisStyleString, tmp); val->SetString(tmp); - return val; + return val.forget(); } RefPtr<nsROCSSPrimitiveValue> fillVal = new nsROCSSPrimitiveValue; if ((style & NS_STYLE_TEXT_EMPHASIS_STYLE_FILL_MASK) == NS_STYLE_TEXT_EMPHASIS_STYLE_FILLED) { fillVal->SetIdent(eCSSKeyword_filled); } else { MOZ_ASSERT((style & NS_STYLE_TEXT_EMPHASIS_STYLE_FILL_MASK) == @@ -3684,253 +3663,253 @@ nsComputedDOMStyle::DoGetTextEmphasisSty fillVal->SetIdent(eCSSKeyword_open); } RefPtr<nsROCSSPrimitiveValue> shapeVal = new nsROCSSPrimitiveValue; shapeVal->SetIdent(nsCSSProps::ValueToKeywordEnum( style & NS_STYLE_TEXT_EMPHASIS_STYLE_SHAPE_MASK, nsCSSProps::kTextEmphasisStyleShapeKTable)); - nsDOMCSSValueList* valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); valueList->AppendCSSValue(fillVal.forget()); valueList->AppendCSSValue(shapeVal.forget()); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextIndent() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, StyleText()->mTextIndent, false, &nsComputedDOMStyle::GetCBContentWidth); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextOrientation() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mTextOrientation, nsCSSProps::kTextOrientationKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextOverflow() { const nsStyleTextReset *style = StyleTextReset(); RefPtr<nsROCSSPrimitiveValue> first = new nsROCSSPrimitiveValue; const nsStyleTextOverflowSide *side = style->mTextOverflow.GetFirstValue(); if (side->mType == NS_STYLE_TEXT_OVERFLOW_STRING) { nsString str; nsStyleUtil::AppendEscapedCSSString(side->mString, str); first->SetString(str); } else { first->SetIdent( nsCSSProps::ValueToKeywordEnum(side->mType, nsCSSProps::kTextOverflowKTable)); } side = style->mTextOverflow.GetSecondValue(); if (!side) { - return first; + return first.forget(); } RefPtr<nsROCSSPrimitiveValue> second = new nsROCSSPrimitiveValue; if (side->mType == NS_STYLE_TEXT_OVERFLOW_STRING) { nsString str; nsStyleUtil::AppendEscapedCSSString(side->mString, str); second->SetString(str); } else { second->SetIdent( nsCSSProps::ValueToKeywordEnum(side->mType, nsCSSProps::kTextOverflowKTable)); } - nsDOMCSSValueList *valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); valueList->AppendCSSValue(first.forget()); valueList->AppendCSSValue(second.forget()); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextShadow() { return GetCSSShadowArray(StyleText()->mTextShadow, StyleColor()->mColor, false); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextTransform() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleText()->mTextTransform, nsCSSProps::kTextTransformKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTabSize() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetNumber(StyleText()->mTabSize); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetLetterSpacing() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, StyleText()->mLetterSpacing, false); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetWordSpacing() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, StyleText()->mWordSpacing, false); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetWhiteSpace() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleText()->mWhiteSpace, nsCSSProps::kWhitespaceKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetWindowDragging() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mWindowDragging, nsCSSProps::kWindowDraggingKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetWindowShadow() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mWindowShadow, nsCSSProps::kWindowShadowKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetWordBreak() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleText()->mWordBreak, nsCSSProps::kWordBreakKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetWordWrap() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleText()->mWordWrap, nsCSSProps::kWordWrapKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetHyphens() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleText()->mHyphens, nsCSSProps::kHyphensKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextSizeAdjust() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; switch (StyleText()->mTextSizeAdjust) { default: NS_NOTREACHED("unexpected value"); // fall through case NS_STYLE_TEXT_SIZE_ADJUST_AUTO: val->SetIdent(eCSSKeyword_auto); break; case NS_STYLE_TEXT_SIZE_ADJUST_NONE: val->SetIdent(eCSSKeyword_none); break; } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPointerEvents() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mPointerEvents, nsCSSProps::kPointerEventsKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetVisibility() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mVisible, nsCSSProps::kVisibilityKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetWritingMode() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mWritingMode, nsCSSProps::kWritingModeKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetDirection() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mDirection, nsCSSProps::kDirectionKTable)); - return val; + return val.forget(); } static_assert(NS_STYLE_UNICODE_BIDI_NORMAL == 0, "unicode-bidi style constants not as expected"); -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetUnicodeBidi() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleTextReset()->mUnicodeBidi, nsCSSProps::kUnicodeBidiKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetCursor() { - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); const nsStyleUserInterface *ui = StyleUserInterface(); for (nsCursorImage *item = ui->mCursorArray, *item_end = ui->mCursorArray + ui->mCursorArrayLength; item < item_end; ++item) { RefPtr<nsDOMCSSValueList> itemList = GetROCSSValueList(false); @@ -3953,434 +3932,434 @@ nsComputedDOMStyle::DoGetCursor() } valueList->AppendCSSValue(itemList.forget()); } RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(ui->mCursor, nsCSSProps::kCursorKTable)); valueList->AppendCSSValue(val.forget()); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetAppearance() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mAppearance, nsCSSProps::kAppearanceKTable)); - return val; -} - - -CSSValue* + return val.forget(); +} + + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBoxAlign() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxAlign, nsCSSProps::kBoxAlignKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBoxDirection() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxDirection, nsCSSProps::kBoxDirectionKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBoxFlex() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetNumber(StyleXUL()->mBoxFlex); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBoxOrdinalGroup() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetNumber(StyleXUL()->mBoxOrdinal); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBoxOrient() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxOrient, nsCSSProps::kBoxOrientKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBoxPack() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxPack, nsCSSProps::kBoxPackKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBoxSizing() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(uint8_t(StylePosition()->mBoxSizing), nsCSSProps::kBoxSizingKTable)); - return val; + return val.forget(); } /* Border image properties */ -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderImageSource() { const nsStyleBorder* border = StyleBorder(); - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleImage& image = border->mBorderImageSource; SetValueToStyleImage(image, val); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderImageSlice() { - nsDOMCSSValueList* valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); const nsStyleBorder* border = StyleBorder(); // Four slice numbers. NS_FOR_CSS_SIDES (side) { RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, border->mBorderImageSlice.Get(side), true, nullptr); valueList->AppendCSSValue(val.forget()); } // Fill keyword. if (NS_STYLE_BORDER_IMAGE_SLICE_FILL == border->mBorderImageFill) { RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_fill); valueList->AppendCSSValue(val.forget()); } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderImageWidth() { const nsStyleBorder* border = StyleBorder(); - nsDOMCSSValueList* valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); NS_FOR_CSS_SIDES (side) { RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, border->mBorderImageWidth.Get(side), true, nullptr); valueList->AppendCSSValue(val.forget()); } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderImageOutset() { - nsDOMCSSValueList *valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); const nsStyleBorder* border = StyleBorder(); // four slice numbers NS_FOR_CSS_SIDES (side) { RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, border->mBorderImageOutset.Get(side), true, nullptr); valueList->AppendCSSValue(val.forget()); } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderImageRepeat() { - nsDOMCSSValueList* valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); const nsStyleBorder* border = StyleBorder(); // horizontal repeat RefPtr<nsROCSSPrimitiveValue> valX = new nsROCSSPrimitiveValue; valX->SetIdent( nsCSSProps::ValueToKeywordEnum(border->mBorderImageRepeatH, nsCSSProps::kBorderImageRepeatKTable)); valueList->AppendCSSValue(valX.forget()); // vertical repeat RefPtr<nsROCSSPrimitiveValue> valY = new nsROCSSPrimitiveValue; valY->SetIdent( nsCSSProps::ValueToKeywordEnum(border->mBorderImageRepeatV, nsCSSProps::kBorderImageRepeatKTable)); valueList->AppendCSSValue(valY.forget()); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFlexBasis() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; // XXXdholbert We could make this more automagic and resolve percentages // if we wanted, by passing in a PercentageBaseGetter instead of nullptr // below. Logic would go like this: // if (i'm a flex item) { // if (my flex container is horizontal) { // percentageBaseGetter = &nsComputedDOMStyle::GetCBContentWidth; // } else { // percentageBaseGetter = &nsComputedDOMStyle::GetCBContentHeight; // } // } SetValueToCoord(val, StylePosition()->mFlexBasis, true, nullptr, nsCSSProps::kWidthKTable); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFlexDirection() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StylePosition()->mFlexDirection, nsCSSProps::kFlexDirectionKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFlexGrow() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetNumber(StylePosition()->mFlexGrow); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFlexShrink() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetNumber(StylePosition()->mFlexShrink); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFlexWrap() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StylePosition()->mFlexWrap, nsCSSProps::kFlexWrapKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOrder() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetNumber(StylePosition()->mOrder); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetAlignContent() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nsAutoString str; auto align = StylePosition()->ComputedAlignContent(); nsCSSValue::AppendAlignJustifyValueToString(align & NS_STYLE_ALIGN_ALL_BITS, str); auto fallback = align >> NS_STYLE_ALIGN_ALL_SHIFT; if (fallback) { str.Append(' '); nsCSSValue::AppendAlignJustifyValueToString(fallback, str); } val->SetString(str); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetAlignItems() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nsAutoString str; auto align = StylePosition()->ComputedAlignItems(StyleDisplay()); nsCSSValue::AppendAlignJustifyValueToString(align, str); val->SetString(str); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetAlignSelf() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; auto align = StylePosition()-> ComputedAlignSelf(StyleDisplay(), mStyleContext->GetParent()); nsAutoString str; nsCSSValue::AppendAlignJustifyValueToString(align, str); val->SetString(str); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetJustifyContent() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nsAutoString str; auto justify = StylePosition()->ComputedJustifyContent(StyleDisplay()); nsCSSValue::AppendAlignJustifyValueToString(justify & NS_STYLE_JUSTIFY_ALL_BITS, str); auto fallback = justify >> NS_STYLE_JUSTIFY_ALL_SHIFT; if (fallback) { MOZ_ASSERT(nsCSSProps::ValueToKeywordEnum(fallback & ~NS_STYLE_JUSTIFY_FLAG_BITS, nsCSSProps::kAlignSelfPosition) != eCSSKeyword_UNKNOWN, "unknown fallback value"); str.Append(' '); nsCSSValue::AppendAlignJustifyValueToString(fallback, str); } val->SetString(str); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetJustifyItems() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nsAutoString str; auto justify = StylePosition()-> ComputedJustifyItems(StyleDisplay(), mStyleContext->GetParent()); nsCSSValue::AppendAlignJustifyValueToString(justify, str); val->SetString(str); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetJustifySelf() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nsAutoString str; auto justify = StylePosition()-> ComputedJustifySelf(StyleDisplay(), mStyleContext->GetParent()); nsCSSValue::AppendAlignJustifyValueToString(justify, str); val->SetString(str); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFloatEdge() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleBorder()->mFloatEdge, nsCSSProps::kFloatEdgeKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetForceBrokenImageIcon() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetNumber(StyleUIReset()->mForceBrokenImageIcon); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetImageOrientation() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nsAutoString string; nsStyleImageOrientation orientation = StyleVisibility()->mImageOrientation; if (orientation.IsFromImage()) { string.AppendLiteral("from-image"); } else { nsStyleUtil::AppendAngleValue(orientation.AngleAsCoord(), string); if (orientation.IsFlipped()) { string.AppendLiteral(" flip"); } } val->SetString(string); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetIMEMode() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mIMEMode, nsCSSProps::kIMEModeKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetUserFocus() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mUserFocus, nsCSSProps::kUserFocusKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetUserInput() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mUserInput, nsCSSProps::kUserInputKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetUserModify() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mUserModify, nsCSSProps::kUserModifyKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetUserSelect() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mUserSelect, nsCSSProps::kUserSelectKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetDisplay() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mDisplay, nsCSSProps::kDisplayKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetContain() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; int32_t mask = StyleDisplay()->mContain; if (mask == 0) { val->SetIdent(eCSSKeyword_none); } else if (mask & NS_STYLE_CONTAIN_STRICT) { NS_ASSERTION(mask == (NS_STYLE_CONTAIN_STRICT | NS_STYLE_CONTAIN_ALL_BITS), "contain: strict should imply contain: layout style paint"); @@ -4389,32 +4368,32 @@ nsComputedDOMStyle::DoGetContain() nsAutoString valueStr; nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_contain, mask, NS_STYLE_CONTAIN_LAYOUT, NS_STYLE_CONTAIN_PAINT, valueStr); val->SetString(valueStr); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPosition() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mPosition, nsCSSProps::kPositionKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetClip() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleDisplay* display = StyleDisplay(); if (display->mClipFlags == NS_STYLE_CLIP_AUTO) { val->SetIdent(eCSSKeyword_auto); } else { // create the cssvalues for the sides, stick them in the rect object nsROCSSPrimitiveValue *topVal = new nsROCSSPrimitiveValue; @@ -4444,161 +4423,161 @@ nsComputedDOMStyle::DoGetClip() if (display->mClipFlags & NS_STYLE_CLIP_LEFT_AUTO) { leftVal->SetIdent(eCSSKeyword_auto); } else { leftVal->SetAppUnits(display->mClip.x); } val->SetRect(domRect); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetWillChange() { const nsTArray<nsString>& willChange = StyleDisplay()->mWillChange; if (willChange.IsEmpty()) { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_auto); - return val; - } - - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + return val.forget(); + } + + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); for (size_t i = 0; i < willChange.Length(); i++) { const nsString& willChangeIdentifier = willChange[i]; RefPtr<nsROCSSPrimitiveValue> property = new nsROCSSPrimitiveValue; property->SetString(willChangeIdentifier); valueList->AppendCSSValue(property.forget()); } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOverflow() { const nsStyleDisplay* display = StyleDisplay(); if (display->mOverflowX != display->mOverflowY) { // No value to return. We can't express this combination of // values as a shorthand. return nullptr; } - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(display->mOverflowX, nsCSSProps::kOverflowKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOverflowX() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOverflowX, nsCSSProps::kOverflowSubKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOverflowY() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOverflowY, nsCSSProps::kOverflowSubKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetOverflowClipBox() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOverflowClipBox, nsCSSProps::kOverflowClipBoxKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetResize() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mResize, nsCSSProps::kResizeKTable)); - return val; -} - - -CSSValue* + return val.forget(); +} + + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPageBreakAfter() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleDisplay *display = StyleDisplay(); if (display->mBreakAfter) { val->SetIdent(eCSSKeyword_always); } else { val->SetIdent(eCSSKeyword_auto); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPageBreakBefore() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleDisplay *display = StyleDisplay(); if (display->mBreakBefore) { val->SetIdent(eCSSKeyword_always); } else { val->SetIdent(eCSSKeyword_auto); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPageBreakInside() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBreakInside, nsCSSProps::kPageBreakInsideKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTouchAction() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; int32_t intValue = StyleDisplay()->mTouchAction; // None and Auto and Manipulation values aren't allowed // to be in conjunction with other values. // But there are all checks in CSSParserImpl::ParseTouchAction nsAutoString valueStr; nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_touch_action, intValue, NS_STYLE_TOUCH_ACTION_NONE, NS_STYLE_TOUCH_ACTION_MANIPULATION, valueStr); val->SetString(valueStr); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetHeight() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; bool calcHeight = false; if (mInnerFrame) { calcHeight = true; const nsStyleDisplay* displayData = StyleDisplay(); if (displayData->mDisplay == NS_STYLE_DISPLAY_INLINE && @@ -4626,23 +4605,23 @@ nsComputedDOMStyle::DoGetHeight() StyleCoordToNSCoord(positionData->mMaxHeight, &nsComputedDOMStyle::GetCBContentHeight, nscoord_MAX, true); SetValueToCoord(val, positionData->mHeight, true, nullptr, nsCSSProps::kWidthKTable, minHeight, maxHeight); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetWidth() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; bool calcWidth = false; if (mInnerFrame) { calcWidth = true; const nsStyleDisplay *displayData = StyleDisplay(); if (displayData->mDisplay == NS_STYLE_DISPLAY_INLINE && @@ -4670,63 +4649,63 @@ nsComputedDOMStyle::DoGetWidth() StyleCoordToNSCoord(positionData->mMaxWidth, &nsComputedDOMStyle::GetCBContentWidth, nscoord_MAX, true); SetValueToCoord(val, positionData->mWidth, true, nullptr, nsCSSProps::kWidthKTable, minWidth, maxWidth); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMaxHeight() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, StylePosition()->mMaxHeight, true, &nsComputedDOMStyle::GetCBContentHeight, nsCSSProps::kWidthKTable); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMaxWidth() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, StylePosition()->mMaxWidth, true, &nsComputedDOMStyle::GetCBContentWidth, nsCSSProps::kWidthKTable); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMinHeight() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nsStyleCoord minHeight = StylePosition()->mMinHeight; if (eStyleUnit_Auto == minHeight.GetUnit()) { // In non-flexbox contexts, "min-height: auto" means "min-height: 0" // XXXdholbert For flex items, we should set |minHeight| to the // -moz-min-content keyword, instead of 0, once we support -moz-min-content // as a height value. minHeight.SetCoordValue(0); } SetValueToCoord(val, minHeight, true, &nsComputedDOMStyle::GetCBContentHeight, nsCSSProps::kWidthKTable); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMinWidth() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nsStyleCoord minWidth = StylePosition()->mMinWidth; if (eStyleUnit_Auto == minWidth.GetUnit()) { // "min-width: auto" means "0", unless we're a flex item in a horizontal // flex container, in which case it means "min-content" minWidth.SetCoordValue(0); if (mOuterFrame && mOuterFrame->IsFlexItem()) { @@ -4738,79 +4717,79 @@ nsComputedDOMStyle::DoGetMinWidth() if (static_cast<nsFlexContainerFrame*>(flexContainer)->IsHorizontal()) { minWidth.SetIntValue(NS_STYLE_WIDTH_MIN_CONTENT, eStyleUnit_Enumerated); } } } SetValueToCoord(val, minWidth, true, &nsComputedDOMStyle::GetCBContentWidth, nsCSSProps::kWidthKTable); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMixBlendMode() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mMixBlendMode, nsCSSProps::kBlendModeKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetIsolation() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mIsolation, nsCSSProps::kIsolationKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetObjectFit() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StylePosition()->mObjectFit, nsCSSProps::kObjectFitKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetObjectPosition() { - nsDOMCSSValueList* valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); SetValueToPosition(StylePosition()->mObjectPosition, valueList); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetLeft() { return GetOffsetWidthFor(NS_SIDE_LEFT); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetRight() { return GetOffsetWidthFor(NS_SIDE_RIGHT); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTop() { return GetOffsetWidthFor(NS_SIDE_TOP); } nsDOMCSSValueList* nsComputedDOMStyle::GetROCSSValueList(bool aCommaDelimited) { return new nsDOMCSSValueList(aCommaDelimited, true); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::GetOffsetWidthFor(mozilla::css::Side aSide) { const nsStyleDisplay* display = StyleDisplay(); AssertFlushedPendingReflows(); uint8_t position = display->mPosition; if (!mOuterFrame) { @@ -4831,17 +4810,17 @@ nsComputedDOMStyle::GetOffsetWidthFor(mo case NS_STYLE_POSITION_FIXED: return GetAbsoluteOffset(aSide); default: NS_ERROR("Invalid position"); return nullptr; } } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::GetAbsoluteOffset(mozilla::css::Side aSide) { MOZ_ASSERT(mOuterFrame, "need a frame, so we can call GetContainingBlock()"); nsIFrame* container = mOuterFrame->GetContainingBlock(); nsMargin margin = mOuterFrame->GetUsedMargin(); nsMargin border = container->GetUsedBorder(); nsMargin scrollbarSizes(0, 0, 0, 0); @@ -4882,30 +4861,30 @@ nsComputedDOMStyle::GetAbsoluteOffset(mo offset = rect.x - margin.left - border.left - scrollbarSizes.left; break; default: NS_ERROR("Invalid side"); break; } - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetAppUnits(offset); - return val; + return val.forget(); } static_assert(NS_SIDE_TOP == 0 && NS_SIDE_RIGHT == 1 && NS_SIDE_BOTTOM == 2 && NS_SIDE_LEFT == 3, "box side constants not as expected for NS_OPPOSITE_SIDE"); #define NS_OPPOSITE_SIDE(s_) mozilla::css::Side(((s_) + 2) & 3) -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::GetRelativeOffset(mozilla::css::Side aSide) { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStylePosition* positionData = StylePosition(); int32_t sign = 1; nsStyleCoord coord = positionData->mOffset.Get(aSide); NS_ASSERTION(coord.GetUnit() == eStyleUnit_Coord || coord.GetUnit() == eStyleUnit_Percent || coord.GetUnit() == eStyleUnit_Auto || @@ -4919,72 +4898,72 @@ nsComputedDOMStyle::GetRelativeOffset(mo PercentageBaseGetter baseGetter; if (aSide == NS_SIDE_LEFT || aSide == NS_SIDE_RIGHT) { baseGetter = &nsComputedDOMStyle::GetCBContentWidth; } else { baseGetter = &nsComputedDOMStyle::GetCBContentHeight; } val->SetAppUnits(sign * StyleCoordToNSCoord(coord, baseGetter, 0, false)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::GetStickyOffset(mozilla::css::Side aSide) { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStylePosition* positionData = StylePosition(); nsStyleCoord coord = positionData->mOffset.Get(aSide); NS_ASSERTION(coord.GetUnit() == eStyleUnit_Coord || coord.GetUnit() == eStyleUnit_Percent || coord.GetUnit() == eStyleUnit_Auto || coord.IsCalcUnit(), "Unexpected unit"); if (coord.GetUnit() == eStyleUnit_Auto) { val->SetIdent(eCSSKeyword_auto); - return val; + return val.forget(); } PercentageBaseGetter baseGetter; if (aSide == NS_SIDE_LEFT || aSide == NS_SIDE_RIGHT) { baseGetter = &nsComputedDOMStyle::GetScrollFrameContentWidth; } else { baseGetter = &nsComputedDOMStyle::GetScrollFrameContentHeight; } val->SetAppUnits(StyleCoordToNSCoord(coord, baseGetter, 0, false)); - return val; -} - - -CSSValue* + return val.forget(); +} + + +already_AddRefed<CSSValue> nsComputedDOMStyle::GetStaticOffset(mozilla::css::Side aSide) { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, StylePosition()->mOffset.Get(aSide), false); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::GetPaddingWidthFor(mozilla::css::Side aSide) { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; if (!mInnerFrame) { SetValueToCoord(val, StylePadding()->mPadding.Get(aSide), true); } else { AssertFlushedPendingReflows(); val->SetAppUnits(mInnerFrame->GetUsedPadding().Side(aSide)); } - return val; + return val.forget(); } bool nsComputedDOMStyle::GetLineHeightCoord(nscoord& aCoord) { AssertFlushedPendingReflows(); nscoord blockHeight = NS_AUTOHEIGHT; @@ -5015,106 +4994,106 @@ nsComputedDOMStyle::GetLineHeightCoord(n if (font->mFont.size != font->mSize) { fCoord = fCoord * (float(font->mSize) / float(font->mFont.size)); } aCoord = NSToCoordRound(fCoord); return true; } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::GetBorderColorsFor(mozilla::css::Side aSide) { const nsStyleBorder *border = StyleBorder(); if (border->mBorderColors) { nsBorderColors* borderColors = border->mBorderColors[aSide]; if (borderColors) { - nsDOMCSSValueList *valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); do { RefPtr<nsROCSSPrimitiveValue> primitive = new nsROCSSPrimitiveValue; SetToRGBAColor(primitive, borderColors->mColor); valueList->AppendCSSValue(primitive.forget()); borderColors = borderColors->mNext; } while (borderColors); - return valueList; + return valueList.forget(); } } - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_none); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::GetBorderWidthFor(mozilla::css::Side aSide) { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nscoord width; if (mInnerFrame) { AssertFlushedPendingReflows(); width = mInnerFrame->GetUsedBorder().Side(aSide); } else { width = StyleBorder()->GetComputedBorderWidth(aSide); } val->SetAppUnits(width); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::GetBorderColorFor(mozilla::css::Side aSide) { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nscolor color; bool foreground; StyleBorder()->GetBorderColor(aSide, color, foreground); if (foreground) { color = StyleColor()->mColor; } SetToRGBAColor(val, color); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::GetMarginWidthFor(mozilla::css::Side aSide) { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; if (!mInnerFrame) { SetValueToCoord(val, StyleMargin()->mMargin.Get(aSide), false); } else { AssertFlushedPendingReflows(); // For tables, GetUsedMargin always returns an empty margin, so we // should read the margin from the outer table frame instead. val->SetAppUnits(mOuterFrame->GetUsedMargin().Side(aSide)); NS_ASSERTION(mOuterFrame == mInnerFrame || mInnerFrame->GetUsedMargin() == nsMargin(0, 0, 0, 0), "Inner tables must have zero margins"); } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::GetBorderStyleFor(mozilla::css::Side aSide) { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleBorder()->GetBorderStyle(aSide), nsCSSProps::kBorderStyleKTable)); - return val; + return val.forget(); } void nsComputedDOMStyle::SetValueToCoord(nsROCSSPrimitiveValue* aValue, const nsStyleCoord& aCoord, bool aClampNegativeCalc, PercentageBaseGetter aPercentageBaseGetter, const KTableEntry aTable[], @@ -5385,20 +5364,20 @@ nsComputedDOMStyle::GetFrameBoundsHeight } AssertFlushedPendingReflows(); aHeight = nsStyleTransformMatrix::TransformReferenceBox(mInnerFrame).Height(); return true; } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::GetSVGPaintFor(bool aFill) { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleSVG* svg = StyleSVG(); const nsStyleSVGPaint* paint = nullptr; if (aFill) paint = &svg->mFill; else paint = &svg->mStroke; @@ -5413,322 +5392,315 @@ nsComputedDOMStyle::GetSVGPaintFor(bool } case eStyleSVGPaintType_Color: { SetToRGBAColor(val, paint->mPaint.mColor); break; } case eStyleSVGPaintType_Server: { - nsDOMCSSValueList *valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); RefPtr<nsROCSSPrimitiveValue> fallback = new nsROCSSPrimitiveValue; - // XXXdholbert Really we should store |val| in a RefPtr right away, and - // our return-type should be already_AddRefed. See bug 1234676. For now, - // we only put it in a RefPtr (for the benefit of AppendCSSValue) after - // we know we're not returning it directly. - RefPtr<nsROCSSPrimitiveValue> refcountedVal = val; - val = nullptr; // (to avoid accidental reuse/misuse) - - refcountedVal->SetURI(paint->mPaint.mPaintServer); + val->SetURI(paint->mPaint.mPaintServer); SetToRGBAColor(fallback, paint->mFallbackColor); - valueList->AppendCSSValue(refcountedVal.forget()); + valueList->AppendCSSValue(val.forget()); valueList->AppendCSSValue(fallback.forget()); - return valueList; + return valueList.forget(); } case eStyleSVGPaintType_ContextFill: { val->SetIdent(eCSSKeyword_context_fill); break; } case eStyleSVGPaintType_ContextStroke: { val->SetIdent(eCSSKeyword_context_stroke); break; } } - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFill() { return GetSVGPaintFor(true); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetStroke() { return GetSVGPaintFor(false); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMarkerEnd() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleSVG* svg = StyleSVG(); if (svg->mMarkerEnd) val->SetURI(svg->mMarkerEnd); else val->SetIdent(eCSSKeyword_none); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMarkerMid() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleSVG* svg = StyleSVG(); if (svg->mMarkerMid) val->SetURI(svg->mMarkerMid); else val->SetIdent(eCSSKeyword_none); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMarkerStart() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleSVG* svg = StyleSVG(); if (svg->mMarkerStart) val->SetURI(svg->mMarkerStart); else val->SetIdent(eCSSKeyword_none); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetStrokeDasharray() { const nsStyleSVG* svg = StyleSVG(); if (!svg->mStrokeDasharrayLength || !svg->mStrokeDasharray) { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_none); - return val; - } - - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + return val.forget(); + } + + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); for (uint32_t i = 0; i < svg->mStrokeDasharrayLength; i++) { RefPtr<nsROCSSPrimitiveValue> dash = new nsROCSSPrimitiveValue; SetValueToCoord(dash, svg->mStrokeDasharray[i], true); valueList->AppendCSSValue(dash.forget()); } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetStrokeDashoffset() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, StyleSVG()->mStrokeDashoffset, false); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetStrokeWidth() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToCoord(val, StyleSVG()->mStrokeWidth, true); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetVectorEffect() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleSVGReset()->mVectorEffect, nsCSSProps::kVectorEffectKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFillOpacity() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetNumber(StyleSVG()->mFillOpacity); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFloodOpacity() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetNumber(StyleSVGReset()->mFloodOpacity); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetStopOpacity() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetNumber(StyleSVGReset()->mStopOpacity); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetStrokeMiterlimit() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetNumber(StyleSVG()->mStrokeMiterlimit); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetStrokeOpacity() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetNumber(StyleSVG()->mStrokeOpacity); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetClipRule() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum( StyleSVG()->mClipRule, nsCSSProps::kFillRuleKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFillRule() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(nsCSSProps::ValueToKeywordEnum( StyleSVG()->mFillRule, nsCSSProps::kFillRuleKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetStrokeLinecap() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleSVG()->mStrokeLinecap, nsCSSProps::kStrokeLinecapKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetStrokeLinejoin() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleSVG()->mStrokeLinejoin, nsCSSProps::kStrokeLinejoinKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextAnchor() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleSVG()->mTextAnchor, nsCSSProps::kTextAnchorKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetColorInterpolation() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleSVG()->mColorInterpolation, nsCSSProps::kColorInterpolationKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetColorInterpolationFilters() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleSVG()->mColorInterpolationFilters, nsCSSProps::kColorInterpolationKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetDominantBaseline() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleSVGReset()->mDominantBaseline, nsCSSProps::kDominantBaselineKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetImageRendering() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleSVG()->mImageRendering, nsCSSProps::kImageRenderingKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetShapeRendering() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleSVG()->mShapeRendering, nsCSSProps::kShapeRenderingKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTextRendering() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleSVG()->mTextRendering, nsCSSProps::kTextRenderingKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFloodColor() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetToRGBAColor(val, StyleSVGReset()->mFloodColor); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetLightingColor() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetToRGBAColor(val, StyleSVGReset()->mLightingColor); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetStopColor() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetToRGBAColor(val, StyleSVGReset()->mStopColor); - return val; + return val.forget(); } inline void AppendBasicShapeTypeToString(nsStyleBasicShape::Type aType, nsAutoString& aString) { nsCSSKeyword functionName; switch (aType) { case nsStyleBasicShape::Type::ePolygon: @@ -5796,21 +5768,21 @@ nsComputedDOMStyle::BasicShapeRadiiToStr aCssText.Append(horizontalString); if (horizontalString == verticalString) { return; } aCssText.AppendLiteral(" / "); aCssText.Append(verticalString); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::CreatePrimitiveValueForClipPath( const nsStyleBasicShape* aStyleBasicShape, uint8_t aSizingBox) { - nsDOMCSSValueList* valueList = GetROCSSValueList(false); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); if (aStyleBasicShape) { nsStyleBasicShape::Type type = aStyleBasicShape->GetShapeType(); // Shape function name and opening parenthesis. nsAutoString shapeFunctionString; AppendBasicShapeTypeToString(type, shapeFunctionString); shapeFunctionString.Append('('); switch (type) { case nsStyleBasicShape::Type::ePolygon: { @@ -5874,51 +5846,51 @@ nsComputedDOMStyle::CreatePrimitiveValue } shapeFunctionString.Append(')'); RefPtr<nsROCSSPrimitiveValue> functionValue = new nsROCSSPrimitiveValue; functionValue->SetString(shapeFunctionString); valueList->AppendCSSValue(functionValue.forget()); } if (aSizingBox == NS_STYLE_CLIP_SHAPE_SIZING_NOBOX) { - return valueList; + return valueList.forget(); } nsAutoString boxString; AppendASCIItoUTF16( nsCSSProps::ValueToKeyword(aSizingBox, nsCSSProps::kClipShapeSizingKTable), boxString); RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetString(boxString); valueList->AppendCSSValue(val.forget()); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetClipPath() { const nsStyleSVGReset* svg = StyleSVGReset(); switch (svg->mClipPath.GetType()) { case NS_STYLE_CLIP_PATH_SHAPE: return CreatePrimitiveValueForClipPath(svg->mClipPath.GetBasicShape(), svg->mClipPath.GetSizingBox()); case NS_STYLE_CLIP_PATH_BOX: return CreatePrimitiveValueForClipPath(nullptr, svg->mClipPath.GetSizingBox()); case NS_STYLE_CLIP_PATH_URL: { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetURI(svg->mClipPath.GetURL()); - return val; + return val.forget(); } case NS_STYLE_CLIP_PATH_NONE: { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_none); - return val; + return val.forget(); } default: NS_NOTREACHED("unexpected type"); } return nullptr; } void @@ -5967,118 +5939,118 @@ nsComputedDOMStyle::CreatePrimitiveValue // Filter function closing parenthesis. filterFunctionString.Append(')'); value->SetString(filterFunctionString); return value.forget(); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetFilter() { const nsTArray<nsStyleFilter>& filters = StyleSVGReset()->mFilters; if (filters.IsEmpty()) { - nsROCSSPrimitiveValue* value = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue; value->SetIdent(eCSSKeyword_none); - return value; - } - - nsDOMCSSValueList* valueList = GetROCSSValueList(false); + return value.forget(); + } + + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); for(uint32_t i = 0; i < filters.Length(); i++) { RefPtr<CSSValue> value = CreatePrimitiveValueForStyleFilter(filters[i]); valueList->AppendCSSValue(value.forget()); } - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMask() { - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; const nsStyleSVGReset* svg = StyleSVGReset(); if (svg->mMask) val->SetURI(svg->mMask); else val->SetIdent(eCSSKeyword_none); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMaskType() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetIdent( nsCSSProps::ValueToKeywordEnum(StyleSVGReset()->mMaskType, nsCSSProps::kMaskTypeKTable)); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPaintOrder() { - nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; nsAutoString string; uint8_t paintOrder = StyleSVG()->mPaintOrder; nsStyleUtil::AppendPaintOrderValue(paintOrder, string); val->SetString(string); - return val; -} - -CSSValue* + return val.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTransitionDelay() { const nsStyleDisplay* display = StyleDisplay(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); MOZ_ASSERT(display->mTransitionDelayCount > 0, "first item must be explicit"); uint32_t i = 0; do { const StyleTransition *transition = &display->mTransitions[i]; RefPtr<nsROCSSPrimitiveValue> delay = new nsROCSSPrimitiveValue; delay->SetTime((float)transition->GetDelay() / (float)PR_MSEC_PER_SEC); valueList->AppendCSSValue(delay.forget()); } while (++i < display->mTransitionDelayCount); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTransitionDuration() { const nsStyleDisplay* display = StyleDisplay(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); MOZ_ASSERT(display->mTransitionDurationCount > 0, "first item must be explicit"); uint32_t i = 0; do { const StyleTransition *transition = &display->mTransitions[i]; RefPtr<nsROCSSPrimitiveValue> duration = new nsROCSSPrimitiveValue; duration->SetTime((float)transition->GetDuration() / (float)PR_MSEC_PER_SEC); valueList->AppendCSSValue(duration.forget()); } while (++i < display->mTransitionDurationCount); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTransitionProperty() { const nsStyleDisplay* display = StyleDisplay(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); MOZ_ASSERT(display->mTransitionPropertyCount > 0, "first item must be explicit"); uint32_t i = 0; do { const StyleTransition *transition = &display->mTransitions[i]; RefPtr<nsROCSSPrimitiveValue> property = new nsROCSSPrimitiveValue; nsCSSProperty cssprop = transition->GetProperty(); @@ -6095,17 +6067,17 @@ nsComputedDOMStyle::DoGetTransitionPrope property->SetString(escaped); // really want SetIdent } else property->SetString(nsCSSProps::GetStringValue(cssprop)); valueList->AppendCSSValue(property.forget()); } while (++i < display->mTransitionPropertyCount); - return valueList; + return valueList.forget(); } void nsComputedDOMStyle::AppendTimingFunction(nsDOMCSSValueList *aValueList, const nsTimingFunction& aTimingFunction) { RefPtr<nsROCSSPrimitiveValue> timingFunction = new nsROCSSPrimitiveValue; @@ -6129,40 +6101,40 @@ nsComputedDOMStyle::AppendTimingFunction nsStyleUtil::AppendCubicBezierKeywordTimingFunction(aTimingFunction.mType, tmp); break; } timingFunction->SetString(tmp); aValueList->AppendCSSValue(timingFunction.forget()); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetTransitionTimingFunction() { const nsStyleDisplay* display = StyleDisplay(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); MOZ_ASSERT(display->mTransitionTimingFunctionCount > 0, "first item must be explicit"); uint32_t i = 0; do { AppendTimingFunction(valueList, display->mTransitions[i].GetTimingFunction()); } while (++i < display->mTransitionTimingFunctionCount); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetAnimationName() { const nsStyleDisplay* display = StyleDisplay(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); MOZ_ASSERT(display->mAnimationNameCount > 0, "first item must be explicit"); uint32_t i = 0; do { const StyleAnimation *animation = &display->mAnimations[i]; RefPtr<nsROCSSPrimitiveValue> property = new nsROCSSPrimitiveValue; @@ -6172,132 +6144,132 @@ nsComputedDOMStyle::DoGetAnimationName() } else { nsAutoString escaped; nsStyleUtil::AppendEscapedCSSIdent(animation->GetName(), escaped); property->SetString(escaped); // really want SetIdent } valueList->AppendCSSValue(property.forget()); } while (++i < display->mAnimationNameCount); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetAnimationDelay() { const nsStyleDisplay* display = StyleDisplay(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); MOZ_ASSERT(display->mAnimationDelayCount > 0, "first item must be explicit"); uint32_t i = 0; do { const StyleAnimation *animation = &display->mAnimations[i]; RefPtr<nsROCSSPrimitiveValue> delay = new nsROCSSPrimitiveValue; delay->SetTime((float)animation->GetDelay() / (float)PR_MSEC_PER_SEC); valueList->AppendCSSValue(delay.forget()); } while (++i < display->mAnimationDelayCount); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetAnimationDuration() { const nsStyleDisplay* display = StyleDisplay(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); MOZ_ASSERT(display->mAnimationDurationCount > 0, "first item must be explicit"); uint32_t i = 0; do { const StyleAnimation *animation = &display->mAnimations[i]; RefPtr<nsROCSSPrimitiveValue> duration = new nsROCSSPrimitiveValue; duration->SetTime((float)animation->GetDuration() / (float)PR_MSEC_PER_SEC); valueList->AppendCSSValue(duration.forget()); } while (++i < display->mAnimationDurationCount); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetAnimationTimingFunction() { const nsStyleDisplay* display = StyleDisplay(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); MOZ_ASSERT(display->mAnimationTimingFunctionCount > 0, "first item must be explicit"); uint32_t i = 0; do { AppendTimingFunction(valueList, display->mAnimations[i].GetTimingFunction()); } while (++i < display->mAnimationTimingFunctionCount); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetAnimationDirection() { const nsStyleDisplay* display = StyleDisplay(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); MOZ_ASSERT(display->mAnimationDirectionCount > 0, "first item must be explicit"); uint32_t i = 0; do { const StyleAnimation *animation = &display->mAnimations[i]; RefPtr<nsROCSSPrimitiveValue> direction = new nsROCSSPrimitiveValue; direction->SetIdent( nsCSSProps::ValueToKeywordEnum( static_cast<int32_t>(animation->GetDirection()), nsCSSProps::kAnimationDirectionKTable)); valueList->AppendCSSValue(direction.forget()); } while (++i < display->mAnimationDirectionCount); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetAnimationFillMode() { const nsStyleDisplay* display = StyleDisplay(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); MOZ_ASSERT(display->mAnimationFillModeCount > 0, "first item must be explicit"); uint32_t i = 0; do { const StyleAnimation *animation = &display->mAnimations[i]; RefPtr<nsROCSSPrimitiveValue> fillMode = new nsROCSSPrimitiveValue; fillMode->SetIdent( nsCSSProps::ValueToKeywordEnum( static_cast<int32_t>(animation->GetFillMode()), nsCSSProps::kAnimationFillModeKTable)); valueList->AppendCSSValue(fillMode.forget()); } while (++i < display->mAnimationFillModeCount); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetAnimationIterationCount() { const nsStyleDisplay* display = StyleDisplay(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); MOZ_ASSERT(display->mAnimationIterationCountCount > 0, "first item must be explicit"); uint32_t i = 0; do { const StyleAnimation *animation = &display->mAnimations[i]; RefPtr<nsROCSSPrimitiveValue> iterationCount = new nsROCSSPrimitiveValue; @@ -6313,65 +6285,65 @@ nsComputedDOMStyle::DoGetAnimationIterat if (f == inf) { iterationCount->SetIdent(eCSSKeyword_infinite); } else { iterationCount->SetNumber(f); } valueList->AppendCSSValue(iterationCount.forget()); } while (++i < display->mAnimationIterationCountCount); - return valueList; -} - -CSSValue* + return valueList.forget(); +} + +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetAnimationPlayState() { const nsStyleDisplay* display = StyleDisplay(); - nsDOMCSSValueList *valueList = GetROCSSValueList(true); + RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true); MOZ_ASSERT(display->mAnimationPlayStateCount > 0, "first item must be explicit"); uint32_t i = 0; do { const StyleAnimation *animation = &display->mAnimations[i]; RefPtr<nsROCSSPrimitiveValue> playState = new nsROCSSPrimitiveValue; playState->SetIdent( nsCSSProps::ValueToKeywordEnum(animation->GetPlayState(), nsCSSProps::kAnimationPlayStateKTable)); valueList->AppendCSSValue(playState.forget()); } while (++i < display->mAnimationPlayStateCount); - return valueList; + return valueList.forget(); } static void MarkComputedStyleMapDirty(const char* aPref, void* aData) { static_cast<nsComputedStyleMap*>(aData)->MarkDirty(); } -CSSValue* +already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetCustomProperty(const nsAString& aPropertyName) { MOZ_ASSERT(nsCSSProps::IsCustomPropertyName(aPropertyName)); const nsStyleVariables* variables = StyleVariables(); nsString variableValue; const nsAString& name = Substring(aPropertyName, CSS_CUSTOM_NAME_PREFIX_LENGTH); if (!variables->mVariables.Get(name, variableValue)) { return nullptr; } - nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetString(variableValue); - return val; + return val.forget(); } void nsComputedDOMStyle::ParentChainChanged(nsIContent* aContent) { NS_ASSERTION(mContent == aContent, "didn't we register mContent?"); NS_ASSERTION(mResolvedStyleContext, "should have only registered an observer when "
--- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -42,27 +42,30 @@ struct nsStyleFilter; class nsStyleGradient; struct nsStyleImage; class nsStyleSides; struct nsTimingFunction; class nsComputedDOMStyle final : public nsDOMCSSDeclaration , public nsStubMutationObserver { -public: +private: + // Convenience typedefs: typedef nsCSSProps::KTableEntry KTableEntry; + typedef mozilla::dom::CSSValue CSSValue; +public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsComputedDOMStyle, nsICSSDeclaration) NS_DECL_NSICSSDECLARATION NS_DECL_NSIDOMCSSSTYLEDECLARATION_HELPER - virtual already_AddRefed<mozilla::dom::CSSValue> + virtual already_AddRefed<CSSValue> GetPropertyCSSValue(const nsAString& aProp, mozilla::ErrorResult& aRv) override; using nsICSSDeclaration::GetPropertyCSSValue; virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName) override; enum StyleType { eDefaultOnly, // Only includes UA and user sheets eAll // Includes all stylesheets @@ -101,17 +104,18 @@ public: // nsDOMCSSDeclaration abstract methods which should never be called // on a nsComputedDOMStyle object, but must be defined to avoid // compile errors. virtual mozilla::css::Declaration* GetCSSDeclaration(Operation) override; virtual nsresult SetCSSDeclaration(mozilla::css::Declaration*) override; virtual nsIDocument* DocToUpdate() override; virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) override; - static nsROCSSPrimitiveValue* MatrixToCSSValue(const mozilla::gfx::Matrix4x4& aMatrix); + static already_AddRefed<nsROCSSPrimitiveValue> + MatrixToCSSValue(const mozilla::gfx::Matrix4x4& aMatrix); static void RegisterPrefChangeCallbacks(); static void UnregisterPrefChangeCallbacks(); // nsIMutationObserver NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED private: @@ -120,435 +124,433 @@ private: void AssertFlushedPendingReflows() { NS_ASSERTION(mFlushedPendingReflows, "property getter should have been marked layout-dependent"); } nsMargin GetAdjustedValuesForBoxSizing(); // Helper method for DoGetTextAlign[Last]. - mozilla::dom::CSSValue* CreateTextAlignValue(uint8_t aAlign, - bool aAlignTrue, - const KTableEntry aTable[]); + already_AddRefed<CSSValue> CreateTextAlignValue(uint8_t aAlign, + bool aAlignTrue, + const KTableEntry aTable[]); // This indicates error by leaving mStyleContext null. void UpdateCurrentStyleSources(bool aNeedsLayoutFlush); void ClearCurrentStyleSources(); // Helper functions called by UpdateCurrentStyleSources. void ClearStyleContext(); void SetResolvedStyleContext(RefPtr<nsStyleContext>&& aContext); void SetFrameStyleContext(nsStyleContext* aContext); #define STYLE_STRUCT(name_, checkdata_cb_) \ const nsStyle##name_ * Style##name_() { \ return mStyleContext->Style##name_(); \ } #include "nsStyleStructList.h" #undef STYLE_STRUCT - // All of the property getters below return a pointer to a refcounted object - // that has just been created, but the refcount is still 0. Caller must take - // ownership. + already_AddRefed<CSSValue> GetEllipseRadii(const nsStyleCorners& aRadius, + uint8_t aFullCorner, + bool aIsBorder); // else outline - mozilla::dom::CSSValue* GetEllipseRadii(const nsStyleCorners& aRadius, - uint8_t aFullCorner, - bool aIsBorder); // else outline + already_AddRefed<CSSValue> GetOffsetWidthFor(mozilla::css::Side aSide); - mozilla::dom::CSSValue* GetOffsetWidthFor(mozilla::css::Side aSide); + already_AddRefed<CSSValue> GetAbsoluteOffset(mozilla::css::Side aSide); - mozilla::dom::CSSValue* GetAbsoluteOffset(mozilla::css::Side aSide); + already_AddRefed<CSSValue> GetRelativeOffset(mozilla::css::Side aSide); - mozilla::dom::CSSValue* GetRelativeOffset(mozilla::css::Side aSide); + already_AddRefed<CSSValue> GetStickyOffset(mozilla::css::Side aSide); - mozilla::dom::CSSValue* GetStickyOffset(mozilla::css::Side aSide); + already_AddRefed<CSSValue> GetStaticOffset(mozilla::css::Side aSide); - mozilla::dom::CSSValue* GetStaticOffset(mozilla::css::Side aSide); - - mozilla::dom::CSSValue* GetPaddingWidthFor(mozilla::css::Side aSide); + already_AddRefed<CSSValue> GetPaddingWidthFor(mozilla::css::Side aSide); - mozilla::dom::CSSValue* GetBorderColorsFor(mozilla::css::Side aSide); + already_AddRefed<CSSValue> GetBorderColorsFor(mozilla::css::Side aSide); - mozilla::dom::CSSValue* GetBorderStyleFor(mozilla::css::Side aSide); + already_AddRefed<CSSValue> GetBorderStyleFor(mozilla::css::Side aSide); - mozilla::dom::CSSValue* GetBorderWidthFor(mozilla::css::Side aSide); + already_AddRefed<CSSValue> GetBorderWidthFor(mozilla::css::Side aSide); - mozilla::dom::CSSValue* GetBorderColorFor(mozilla::css::Side aSide); + already_AddRefed<CSSValue> GetBorderColorFor(mozilla::css::Side aSide); - mozilla::dom::CSSValue* GetMarginWidthFor(mozilla::css::Side aSide); + already_AddRefed<CSSValue> GetMarginWidthFor(mozilla::css::Side aSide); - mozilla::dom::CSSValue* GetSVGPaintFor(bool aFill); + already_AddRefed<CSSValue> GetSVGPaintFor(bool aFill); // Appends all aLineNames (must be non-empty) space-separated to aResult. void AppendGridLineNames(nsString& aResult, const nsTArray<nsString>& aLineNames); // Appends aLineNames (if non-empty) as a CSSValue* to aValueList. void AppendGridLineNames(nsDOMCSSValueList* aValueList, const nsTArray<nsString>& aLineNames); // Appends aLineNames1/2 (if non-empty) as a CSSValue* to aValueList. void AppendGridLineNames(nsDOMCSSValueList* aValueList, const nsTArray<nsString>& aLineNames1, const nsTArray<nsString>& aLineNames2); - mozilla::dom::CSSValue* GetGridTrackSize(const nsStyleCoord& aMinSize, - const nsStyleCoord& aMaxSize); - mozilla::dom::CSSValue* GetGridTemplateColumnsRows(const nsStyleGridTemplate& aTrackList, - const nsTArray<nscoord>* aTrackSizes); - mozilla::dom::CSSValue* GetGridLine(const nsStyleGridLine& aGridLine); + already_AddRefed<CSSValue> GetGridTrackSize(const nsStyleCoord& aMinSize, + const nsStyleCoord& aMaxSize); + already_AddRefed<CSSValue> GetGridTemplateColumnsRows( + const nsStyleGridTemplate& aTrackList, + const nsTArray<nscoord>* aTrackSizes); + already_AddRefed<CSSValue> GetGridLine(const nsStyleGridLine& aGridLine); bool GetLineHeightCoord(nscoord& aCoord); - mozilla::dom::CSSValue* GetCSSShadowArray(nsCSSShadowArray* aArray, - const nscolor& aDefaultColor, - bool aIsBoxShadow); + already_AddRefed<CSSValue> GetCSSShadowArray(nsCSSShadowArray* aArray, + const nscolor& aDefaultColor, + bool aIsBoxShadow); - mozilla::dom::CSSValue* GetBackgroundList(uint8_t nsStyleBackground::Layer::* aMember, - uint32_t nsStyleBackground::* aCount, - const KTableEntry aTable[]); + already_AddRefed<CSSValue> GetBackgroundList( + uint8_t nsStyleBackground::Layer::* aMember, + uint32_t nsStyleBackground::* aCount, + const KTableEntry aTable[]); void GetCSSGradientString(const nsStyleGradient* aGradient, nsAString& aString); void GetImageRectString(nsIURI* aURI, const nsStyleSides& aCropRect, nsString& aString); - mozilla::dom::CSSValue* GetScrollSnapPoints(const nsStyleCoord& aCoord); + already_AddRefed<CSSValue> GetScrollSnapPoints(const nsStyleCoord& aCoord); void AppendTimingFunction(nsDOMCSSValueList *aValueList, const nsTimingFunction& aTimingFunction); /* Properties queryable as CSSValues. * To avoid a name conflict with nsIDOM*CSS2Properties, these are all * DoGetXXX instead of GetXXX. */ - mozilla::dom::CSSValue* DoGetAppearance(); + already_AddRefed<CSSValue> DoGetAppearance(); /* Box properties */ - mozilla::dom::CSSValue* DoGetBoxAlign(); - mozilla::dom::CSSValue* DoGetBoxDecorationBreak(); - mozilla::dom::CSSValue* DoGetBoxDirection(); - mozilla::dom::CSSValue* DoGetBoxFlex(); - mozilla::dom::CSSValue* DoGetBoxOrdinalGroup(); - mozilla::dom::CSSValue* DoGetBoxOrient(); - mozilla::dom::CSSValue* DoGetBoxPack(); - mozilla::dom::CSSValue* DoGetBoxSizing(); + already_AddRefed<CSSValue> DoGetBoxAlign(); + already_AddRefed<CSSValue> DoGetBoxDecorationBreak(); + already_AddRefed<CSSValue> DoGetBoxDirection(); + already_AddRefed<CSSValue> DoGetBoxFlex(); + already_AddRefed<CSSValue> DoGetBoxOrdinalGroup(); + already_AddRefed<CSSValue> DoGetBoxOrient(); + already_AddRefed<CSSValue> DoGetBoxPack(); + already_AddRefed<CSSValue> DoGetBoxSizing(); - mozilla::dom::CSSValue* DoGetWidth(); - mozilla::dom::CSSValue* DoGetHeight(); - mozilla::dom::CSSValue* DoGetMaxHeight(); - mozilla::dom::CSSValue* DoGetMaxWidth(); - mozilla::dom::CSSValue* DoGetMinHeight(); - mozilla::dom::CSSValue* DoGetMinWidth(); - mozilla::dom::CSSValue* DoGetMixBlendMode(); - mozilla::dom::CSSValue* DoGetIsolation(); - mozilla::dom::CSSValue* DoGetObjectFit(); - mozilla::dom::CSSValue* DoGetObjectPosition(); - mozilla::dom::CSSValue* DoGetLeft(); - mozilla::dom::CSSValue* DoGetTop(); - mozilla::dom::CSSValue* DoGetRight(); - mozilla::dom::CSSValue* DoGetBottom(); - mozilla::dom::CSSValue* DoGetStackSizing(); + already_AddRefed<CSSValue> DoGetWidth(); + already_AddRefed<CSSValue> DoGetHeight(); + already_AddRefed<CSSValue> DoGetMaxHeight(); + already_AddRefed<CSSValue> DoGetMaxWidth(); + already_AddRefed<CSSValue> DoGetMinHeight(); + already_AddRefed<CSSValue> DoGetMinWidth(); + already_AddRefed<CSSValue> DoGetMixBlendMode(); + already_AddRefed<CSSValue> DoGetIsolation(); + already_AddRefed<CSSValue> DoGetObjectFit(); + already_AddRefed<CSSValue> DoGetObjectPosition(); + already_AddRefed<CSSValue> DoGetLeft(); + already_AddRefed<CSSValue> DoGetTop(); + already_AddRefed<CSSValue> DoGetRight(); + already_AddRefed<CSSValue> DoGetBottom(); + already_AddRefed<CSSValue> DoGetStackSizing(); /* Font properties */ - mozilla::dom::CSSValue* DoGetColor(); - mozilla::dom::CSSValue* DoGetFontFamily(); - mozilla::dom::CSSValue* DoGetFontFeatureSettings(); - mozilla::dom::CSSValue* DoGetFontKerning(); - mozilla::dom::CSSValue* DoGetFontLanguageOverride(); - mozilla::dom::CSSValue* DoGetFontSize(); - mozilla::dom::CSSValue* DoGetFontSizeAdjust(); - mozilla::dom::CSSValue* DoGetOsxFontSmoothing(); - mozilla::dom::CSSValue* DoGetFontStretch(); - mozilla::dom::CSSValue* DoGetFontStyle(); - mozilla::dom::CSSValue* DoGetFontSynthesis(); - mozilla::dom::CSSValue* DoGetFontVariant(); - mozilla::dom::CSSValue* DoGetFontVariantAlternates(); - mozilla::dom::CSSValue* DoGetFontVariantCaps(); - mozilla::dom::CSSValue* DoGetFontVariantEastAsian(); - mozilla::dom::CSSValue* DoGetFontVariantLigatures(); - mozilla::dom::CSSValue* DoGetFontVariantNumeric(); - mozilla::dom::CSSValue* DoGetFontVariantPosition(); - mozilla::dom::CSSValue* DoGetFontWeight(); + already_AddRefed<CSSValue> DoGetColor(); + already_AddRefed<CSSValue> DoGetFontFamily(); + already_AddRefed<CSSValue> DoGetFontFeatureSettings(); + already_AddRefed<CSSValue> DoGetFontKerning(); + already_AddRefed<CSSValue> DoGetFontLanguageOverride(); + already_AddRefed<CSSValue> DoGetFontSize(); + already_AddRefed<CSSValue> DoGetFontSizeAdjust(); + already_AddRefed<CSSValue> DoGetOsxFontSmoothing(); + already_AddRefed<CSSValue> DoGetFontStretch(); + already_AddRefed<CSSValue> DoGetFontStyle(); + already_AddRefed<CSSValue> DoGetFontSynthesis(); + already_AddRefed<CSSValue> DoGetFontVariant(); + already_AddRefed<CSSValue> DoGetFontVariantAlternates(); + already_AddRefed<CSSValue> DoGetFontVariantCaps(); + already_AddRefed<CSSValue> DoGetFontVariantEastAsian(); + already_AddRefed<CSSValue> DoGetFontVariantLigatures(); + already_AddRefed<CSSValue> DoGetFontVariantNumeric(); + already_AddRefed<CSSValue> DoGetFontVariantPosition(); + already_AddRefed<CSSValue> DoGetFontWeight(); /* Grid properties */ - mozilla::dom::CSSValue* DoGetGridAutoFlow(); - mozilla::dom::CSSValue* DoGetGridAutoColumns(); - mozilla::dom::CSSValue* DoGetGridAutoRows(); - mozilla::dom::CSSValue* DoGetGridTemplateAreas(); - mozilla::dom::CSSValue* DoGetGridTemplateColumns(); - mozilla::dom::CSSValue* DoGetGridTemplateRows(); - mozilla::dom::CSSValue* DoGetGridColumnStart(); - mozilla::dom::CSSValue* DoGetGridColumnEnd(); - mozilla::dom::CSSValue* DoGetGridRowStart(); - mozilla::dom::CSSValue* DoGetGridRowEnd(); - mozilla::dom::CSSValue* DoGetGridColumnGap(); - mozilla::dom::CSSValue* DoGetGridRowGap(); + already_AddRefed<CSSValue> DoGetGridAutoFlow(); + already_AddRefed<CSSValue> DoGetGridAutoColumns(); + already_AddRefed<CSSValue> DoGetGridAutoRows(); + already_AddRefed<CSSValue> DoGetGridTemplateAreas(); + already_AddRefed<CSSValue> DoGetGridTemplateColumns(); + already_AddRefed<CSSValue> DoGetGridTemplateRows(); + already_AddRefed<CSSValue> DoGetGridColumnStart(); + already_AddRefed<CSSValue> DoGetGridColumnEnd(); + already_AddRefed<CSSValue> DoGetGridRowStart(); + already_AddRefed<CSSValue> DoGetGridRowEnd(); + already_AddRefed<CSSValue> DoGetGridColumnGap(); + already_AddRefed<CSSValue> DoGetGridRowGap(); /* Background properties */ - mozilla::dom::CSSValue* DoGetBackgroundAttachment(); - mozilla::dom::CSSValue* DoGetBackgroundColor(); - mozilla::dom::CSSValue* DoGetBackgroundImage(); - mozilla::dom::CSSValue* DoGetBackgroundPosition(); - mozilla::dom::CSSValue* DoGetBackgroundRepeat(); - mozilla::dom::CSSValue* DoGetBackgroundClip(); - mozilla::dom::CSSValue* DoGetBackgroundBlendMode(); - mozilla::dom::CSSValue* DoGetBackgroundOrigin(); - mozilla::dom::CSSValue* DoGetBackgroundSize(); + already_AddRefed<CSSValue> DoGetBackgroundAttachment(); + already_AddRefed<CSSValue> DoGetBackgroundColor(); + already_AddRefed<CSSValue> DoGetBackgroundImage(); + already_AddRefed<CSSValue> DoGetBackgroundPosition(); + already_AddRefed<CSSValue> DoGetBackgroundRepeat(); + already_AddRefed<CSSValue> DoGetBackgroundClip(); + already_AddRefed<CSSValue> DoGetBackgroundBlendMode(); + already_AddRefed<CSSValue> DoGetBackgroundOrigin(); + already_AddRefed<CSSValue> DoGetBackgroundSize(); /* Padding properties */ - mozilla::dom::CSSValue* DoGetPaddingTop(); - mozilla::dom::CSSValue* DoGetPaddingBottom(); - mozilla::dom::CSSValue* DoGetPaddingLeft(); - mozilla::dom::CSSValue* DoGetPaddingRight(); + already_AddRefed<CSSValue> DoGetPaddingTop(); + already_AddRefed<CSSValue> DoGetPaddingBottom(); + already_AddRefed<CSSValue> DoGetPaddingLeft(); + already_AddRefed<CSSValue> DoGetPaddingRight(); /* Table Properties */ - mozilla::dom::CSSValue* DoGetBorderCollapse(); - mozilla::dom::CSSValue* DoGetBorderSpacing(); - mozilla::dom::CSSValue* DoGetCaptionSide(); - mozilla::dom::CSSValue* DoGetEmptyCells(); - mozilla::dom::CSSValue* DoGetTableLayout(); - mozilla::dom::CSSValue* DoGetVerticalAlign(); + already_AddRefed<CSSValue> DoGetBorderCollapse(); + already_AddRefed<CSSValue> DoGetBorderSpacing(); + already_AddRefed<CSSValue> DoGetCaptionSide(); + already_AddRefed<CSSValue> DoGetEmptyCells(); + already_AddRefed<CSSValue> DoGetTableLayout(); + already_AddRefed<CSSValue> DoGetVerticalAlign(); /* Border Properties */ - mozilla::dom::CSSValue* DoGetBorderTopStyle(); - mozilla::dom::CSSValue* DoGetBorderBottomStyle(); - mozilla::dom::CSSValue* DoGetBorderLeftStyle(); - mozilla::dom::CSSValue* DoGetBorderRightStyle(); - mozilla::dom::CSSValue* DoGetBorderTopWidth(); - mozilla::dom::CSSValue* DoGetBorderBottomWidth(); - mozilla::dom::CSSValue* DoGetBorderLeftWidth(); - mozilla::dom::CSSValue* DoGetBorderRightWidth(); - mozilla::dom::CSSValue* DoGetBorderTopColor(); - mozilla::dom::CSSValue* DoGetBorderBottomColor(); - mozilla::dom::CSSValue* DoGetBorderLeftColor(); - mozilla::dom::CSSValue* DoGetBorderRightColor(); - mozilla::dom::CSSValue* DoGetBorderBottomColors(); - mozilla::dom::CSSValue* DoGetBorderLeftColors(); - mozilla::dom::CSSValue* DoGetBorderRightColors(); - mozilla::dom::CSSValue* DoGetBorderTopColors(); - mozilla::dom::CSSValue* DoGetBorderBottomLeftRadius(); - mozilla::dom::CSSValue* DoGetBorderBottomRightRadius(); - mozilla::dom::CSSValue* DoGetBorderTopLeftRadius(); - mozilla::dom::CSSValue* DoGetBorderTopRightRadius(); - mozilla::dom::CSSValue* DoGetFloatEdge(); + already_AddRefed<CSSValue> DoGetBorderTopStyle(); + already_AddRefed<CSSValue> DoGetBorderBottomStyle(); + already_AddRefed<CSSValue> DoGetBorderLeftStyle(); + already_AddRefed<CSSValue> DoGetBorderRightStyle(); + already_AddRefed<CSSValue> DoGetBorderTopWidth(); + already_AddRefed<CSSValue> DoGetBorderBottomWidth(); + already_AddRefed<CSSValue> DoGetBorderLeftWidth(); + already_AddRefed<CSSValue> DoGetBorderRightWidth(); + already_AddRefed<CSSValue> DoGetBorderTopColor(); + already_AddRefed<CSSValue> DoGetBorderBottomColor(); + already_AddRefed<CSSValue> DoGetBorderLeftColor(); + already_AddRefed<CSSValue> DoGetBorderRightColor(); + already_AddRefed<CSSValue> DoGetBorderBottomColors(); + already_AddRefed<CSSValue> DoGetBorderLeftColors(); + already_AddRefed<CSSValue> DoGetBorderRightColors(); + already_AddRefed<CSSValue> DoGetBorderTopColors(); + already_AddRefed<CSSValue> DoGetBorderBottomLeftRadius(); + already_AddRefed<CSSValue> DoGetBorderBottomRightRadius(); + already_AddRefed<CSSValue> DoGetBorderTopLeftRadius(); + already_AddRefed<CSSValue> DoGetBorderTopRightRadius(); + already_AddRefed<CSSValue> DoGetFloatEdge(); /* Border Image */ - mozilla::dom::CSSValue* DoGetBorderImageSource(); - mozilla::dom::CSSValue* DoGetBorderImageSlice(); - mozilla::dom::CSSValue* DoGetBorderImageWidth(); - mozilla::dom::CSSValue* DoGetBorderImageOutset(); - mozilla::dom::CSSValue* DoGetBorderImageRepeat(); + already_AddRefed<CSSValue> DoGetBorderImageSource(); + already_AddRefed<CSSValue> DoGetBorderImageSlice(); + already_AddRefed<CSSValue> DoGetBorderImageWidth(); + already_AddRefed<CSSValue> DoGetBorderImageOutset(); + already_AddRefed<CSSValue> DoGetBorderImageRepeat(); /* Box Shadow */ - mozilla::dom::CSSValue* DoGetBoxShadow(); + already_AddRefed<CSSValue> DoGetBoxShadow(); /* Window Shadow */ - mozilla::dom::CSSValue* DoGetWindowShadow(); + already_AddRefed<CSSValue> DoGetWindowShadow(); /* Margin Properties */ - mozilla::dom::CSSValue* DoGetMarginTopWidth(); - mozilla::dom::CSSValue* DoGetMarginBottomWidth(); - mozilla::dom::CSSValue* DoGetMarginLeftWidth(); - mozilla::dom::CSSValue* DoGetMarginRightWidth(); + already_AddRefed<CSSValue> DoGetMarginTopWidth(); + already_AddRefed<CSSValue> DoGetMarginBottomWidth(); + already_AddRefed<CSSValue> DoGetMarginLeftWidth(); + already_AddRefed<CSSValue> DoGetMarginRightWidth(); /* Outline Properties */ - mozilla::dom::CSSValue* DoGetOutlineWidth(); - mozilla::dom::CSSValue* DoGetOutlineStyle(); - mozilla::dom::CSSValue* DoGetOutlineColor(); - mozilla::dom::CSSValue* DoGetOutlineOffset(); - mozilla::dom::CSSValue* DoGetOutlineRadiusBottomLeft(); - mozilla::dom::CSSValue* DoGetOutlineRadiusBottomRight(); - mozilla::dom::CSSValue* DoGetOutlineRadiusTopLeft(); - mozilla::dom::CSSValue* DoGetOutlineRadiusTopRight(); + already_AddRefed<CSSValue> DoGetOutlineWidth(); + already_AddRefed<CSSValue> DoGetOutlineStyle(); + already_AddRefed<CSSValue> DoGetOutlineColor(); + already_AddRefed<CSSValue> DoGetOutlineOffset(); + already_AddRefed<CSSValue> DoGetOutlineRadiusBottomLeft(); + already_AddRefed<CSSValue> DoGetOutlineRadiusBottomRight(); + already_AddRefed<CSSValue> DoGetOutlineRadiusTopLeft(); + already_AddRefed<CSSValue> DoGetOutlineRadiusTopRight(); /* Content Properties */ - mozilla::dom::CSSValue* DoGetContent(); - mozilla::dom::CSSValue* DoGetCounterIncrement(); - mozilla::dom::CSSValue* DoGetCounterReset(); - mozilla::dom::CSSValue* DoGetMarkerOffset(); + already_AddRefed<CSSValue> DoGetContent(); + already_AddRefed<CSSValue> DoGetCounterIncrement(); + already_AddRefed<CSSValue> DoGetCounterReset(); + already_AddRefed<CSSValue> DoGetMarkerOffset(); /* Quotes Properties */ - mozilla::dom::CSSValue* DoGetQuotes(); + already_AddRefed<CSSValue> DoGetQuotes(); /* z-index */ - mozilla::dom::CSSValue* DoGetZIndex(); + already_AddRefed<CSSValue> DoGetZIndex(); /* List properties */ - mozilla::dom::CSSValue* DoGetListStyleImage(); - mozilla::dom::CSSValue* DoGetListStylePosition(); - mozilla::dom::CSSValue* DoGetListStyleType(); - mozilla::dom::CSSValue* DoGetImageRegion(); + already_AddRefed<CSSValue> DoGetListStyleImage(); + already_AddRefed<CSSValue> DoGetListStylePosition(); + already_AddRefed<CSSValue> DoGetListStyleType(); + already_AddRefed<CSSValue> DoGetImageRegion(); /* Text Properties */ - mozilla::dom::CSSValue* DoGetLineHeight(); - mozilla::dom::CSSValue* DoGetRubyAlign(); - mozilla::dom::CSSValue* DoGetRubyPosition(); - mozilla::dom::CSSValue* DoGetTextAlign(); - mozilla::dom::CSSValue* DoGetTextAlignLast(); - mozilla::dom::CSSValue* DoGetTextCombineUpright(); - mozilla::dom::CSSValue* DoGetTextDecoration(); - mozilla::dom::CSSValue* DoGetTextDecorationColor(); - mozilla::dom::CSSValue* DoGetTextDecorationLine(); - mozilla::dom::CSSValue* DoGetTextDecorationStyle(); - mozilla::dom::CSSValue* DoGetTextEmphasisColor(); - mozilla::dom::CSSValue* DoGetTextEmphasisPosition(); - mozilla::dom::CSSValue* DoGetTextEmphasisStyle(); - mozilla::dom::CSSValue* DoGetTextIndent(); - mozilla::dom::CSSValue* DoGetTextOrientation(); - mozilla::dom::CSSValue* DoGetTextOverflow(); - mozilla::dom::CSSValue* DoGetTextTransform(); - mozilla::dom::CSSValue* DoGetTextShadow(); - mozilla::dom::CSSValue* DoGetLetterSpacing(); - mozilla::dom::CSSValue* DoGetWordSpacing(); - mozilla::dom::CSSValue* DoGetWhiteSpace(); - mozilla::dom::CSSValue* DoGetWordBreak(); - mozilla::dom::CSSValue* DoGetWordWrap(); - mozilla::dom::CSSValue* DoGetHyphens(); - mozilla::dom::CSSValue* DoGetTabSize(); - mozilla::dom::CSSValue* DoGetTextSizeAdjust(); + already_AddRefed<CSSValue> DoGetLineHeight(); + already_AddRefed<CSSValue> DoGetRubyAlign(); + already_AddRefed<CSSValue> DoGetRubyPosition(); + already_AddRefed<CSSValue> DoGetTextAlign(); + already_AddRefed<CSSValue> DoGetTextAlignLast(); + already_AddRefed<CSSValue> DoGetTextCombineUpright(); + already_AddRefed<CSSValue> DoGetTextDecoration(); + already_AddRefed<CSSValue> DoGetTextDecorationColor(); + already_AddRefed<CSSValue> DoGetTextDecorationLine(); + already_AddRefed<CSSValue> DoGetTextDecorationStyle(); + already_AddRefed<CSSValue> DoGetTextEmphasisColor(); + already_AddRefed<CSSValue> DoGetTextEmphasisPosition(); + already_AddRefed<CSSValue> DoGetTextEmphasisStyle(); + already_AddRefed<CSSValue> DoGetTextIndent(); + already_AddRefed<CSSValue> DoGetTextOrientation(); + already_AddRefed<CSSValue> DoGetTextOverflow(); + already_AddRefed<CSSValue> DoGetTextTransform(); + already_AddRefed<CSSValue> DoGetTextShadow(); + already_AddRefed<CSSValue> DoGetLetterSpacing(); + already_AddRefed<CSSValue> DoGetWordSpacing(); + already_AddRefed<CSSValue> DoGetWhiteSpace(); + already_AddRefed<CSSValue> DoGetWordBreak(); + already_AddRefed<CSSValue> DoGetWordWrap(); + already_AddRefed<CSSValue> DoGetHyphens(); + already_AddRefed<CSSValue> DoGetTabSize(); + already_AddRefed<CSSValue> DoGetTextSizeAdjust(); /* Visibility properties */ - mozilla::dom::CSSValue* DoGetOpacity(); - mozilla::dom::CSSValue* DoGetPointerEvents(); - mozilla::dom::CSSValue* DoGetVisibility(); - mozilla::dom::CSSValue* DoGetWritingMode(); + already_AddRefed<CSSValue> DoGetOpacity(); + already_AddRefed<CSSValue> DoGetPointerEvents(); + already_AddRefed<CSSValue> DoGetVisibility(); + already_AddRefed<CSSValue> DoGetWritingMode(); /* Direction properties */ - mozilla::dom::CSSValue* DoGetDirection(); - mozilla::dom::CSSValue* DoGetUnicodeBidi(); + already_AddRefed<CSSValue> DoGetDirection(); + already_AddRefed<CSSValue> DoGetUnicodeBidi(); /* Display properties */ - mozilla::dom::CSSValue* DoGetBinding(); - mozilla::dom::CSSValue* DoGetClear(); - mozilla::dom::CSSValue* DoGetFloat(); - mozilla::dom::CSSValue* DoGetDisplay(); - mozilla::dom::CSSValue* DoGetContain(); - mozilla::dom::CSSValue* DoGetPosition(); - mozilla::dom::CSSValue* DoGetClip(); - mozilla::dom::CSSValue* DoGetImageOrientation(); - mozilla::dom::CSSValue* DoGetWillChange(); - mozilla::dom::CSSValue* DoGetOverflow(); - mozilla::dom::CSSValue* DoGetOverflowX(); - mozilla::dom::CSSValue* DoGetOverflowY(); - mozilla::dom::CSSValue* DoGetOverflowClipBox(); - mozilla::dom::CSSValue* DoGetResize(); - mozilla::dom::CSSValue* DoGetPageBreakAfter(); - mozilla::dom::CSSValue* DoGetPageBreakBefore(); - mozilla::dom::CSSValue* DoGetPageBreakInside(); - mozilla::dom::CSSValue* DoGetTouchAction(); - mozilla::dom::CSSValue* DoGetTransform(); - mozilla::dom::CSSValue* DoGetTransformBox(); - mozilla::dom::CSSValue* DoGetTransformOrigin(); - mozilla::dom::CSSValue* DoGetPerspective(); - mozilla::dom::CSSValue* DoGetBackfaceVisibility(); - mozilla::dom::CSSValue* DoGetPerspectiveOrigin(); - mozilla::dom::CSSValue* DoGetTransformStyle(); - mozilla::dom::CSSValue* DoGetOrient(); - mozilla::dom::CSSValue* DoGetScrollBehavior(); - mozilla::dom::CSSValue* DoGetScrollSnapType(); - mozilla::dom::CSSValue* DoGetScrollSnapTypeX(); - mozilla::dom::CSSValue* DoGetScrollSnapTypeY(); - mozilla::dom::CSSValue* DoGetScrollSnapPointsX(); - mozilla::dom::CSSValue* DoGetScrollSnapPointsY(); - mozilla::dom::CSSValue* DoGetScrollSnapDestination(); - mozilla::dom::CSSValue* DoGetScrollSnapCoordinate(); + already_AddRefed<CSSValue> DoGetBinding(); + already_AddRefed<CSSValue> DoGetClear(); + already_AddRefed<CSSValue> DoGetFloat(); + already_AddRefed<CSSValue> DoGetDisplay(); + already_AddRefed<CSSValue> DoGetContain(); + already_AddRefed<CSSValue> DoGetPosition(); + already_AddRefed<CSSValue> DoGetClip(); + already_AddRefed<CSSValue> DoGetImageOrientation(); + already_AddRefed<CSSValue> DoGetWillChange(); + already_AddRefed<CSSValue> DoGetOverflow(); + already_AddRefed<CSSValue> DoGetOverflowX(); + already_AddRefed<CSSValue> DoGetOverflowY(); + already_AddRefed<CSSValue> DoGetOverflowClipBox(); + already_AddRefed<CSSValue> DoGetResize(); + already_AddRefed<CSSValue> DoGetPageBreakAfter(); + already_AddRefed<CSSValue> DoGetPageBreakBefore(); + already_AddRefed<CSSValue> DoGetPageBreakInside(); + already_AddRefed<CSSValue> DoGetTouchAction(); + already_AddRefed<CSSValue> DoGetTransform(); + already_AddRefed<CSSValue> DoGetTransformBox(); + already_AddRefed<CSSValue> DoGetTransformOrigin(); + already_AddRefed<CSSValue> DoGetPerspective(); + already_AddRefed<CSSValue> DoGetBackfaceVisibility(); + already_AddRefed<CSSValue> DoGetPerspectiveOrigin(); + already_AddRefed<CSSValue> DoGetTransformStyle(); + already_AddRefed<CSSValue> DoGetOrient(); + already_AddRefed<CSSValue> DoGetScrollBehavior(); + already_AddRefed<CSSValue> DoGetScrollSnapType(); + already_AddRefed<CSSValue> DoGetScrollSnapTypeX(); + already_AddRefed<CSSValue> DoGetScrollSnapTypeY(); + already_AddRefed<CSSValue> DoGetScrollSnapPointsX(); + already_AddRefed<CSSValue> DoGetScrollSnapPointsY(); + already_AddRefed<CSSValue> DoGetScrollSnapDestination(); + already_AddRefed<CSSValue> DoGetScrollSnapCoordinate(); /* User interface properties */ - mozilla::dom::CSSValue* DoGetCursor(); - mozilla::dom::CSSValue* DoGetForceBrokenImageIcon(); - mozilla::dom::CSSValue* DoGetIMEMode(); - mozilla::dom::CSSValue* DoGetUserFocus(); - mozilla::dom::CSSValue* DoGetUserInput(); - mozilla::dom::CSSValue* DoGetUserModify(); - mozilla::dom::CSSValue* DoGetUserSelect(); - mozilla::dom::CSSValue* DoGetWindowDragging(); + already_AddRefed<CSSValue> DoGetCursor(); + already_AddRefed<CSSValue> DoGetForceBrokenImageIcon(); + already_AddRefed<CSSValue> DoGetIMEMode(); + already_AddRefed<CSSValue> DoGetUserFocus(); + already_AddRefed<CSSValue> DoGetUserInput(); + already_AddRefed<CSSValue> DoGetUserModify(); + already_AddRefed<CSSValue> DoGetUserSelect(); + already_AddRefed<CSSValue> DoGetWindowDragging(); /* Column properties */ - mozilla::dom::CSSValue* DoGetColumnCount(); - mozilla::dom::CSSValue* DoGetColumnFill(); - mozilla::dom::CSSValue* DoGetColumnWidth(); - mozilla::dom::CSSValue* DoGetColumnGap(); - mozilla::dom::CSSValue* DoGetColumnRuleWidth(); - mozilla::dom::CSSValue* DoGetColumnRuleStyle(); - mozilla::dom::CSSValue* DoGetColumnRuleColor(); + already_AddRefed<CSSValue> DoGetColumnCount(); + already_AddRefed<CSSValue> DoGetColumnFill(); + already_AddRefed<CSSValue> DoGetColumnWidth(); + already_AddRefed<CSSValue> DoGetColumnGap(); + already_AddRefed<CSSValue> DoGetColumnRuleWidth(); + already_AddRefed<CSSValue> DoGetColumnRuleStyle(); + already_AddRefed<CSSValue> DoGetColumnRuleColor(); /* CSS Transitions */ - mozilla::dom::CSSValue* DoGetTransitionProperty(); - mozilla::dom::CSSValue* DoGetTransitionDuration(); - mozilla::dom::CSSValue* DoGetTransitionDelay(); - mozilla::dom::CSSValue* DoGetTransitionTimingFunction(); + already_AddRefed<CSSValue> DoGetTransitionProperty(); + already_AddRefed<CSSValue> DoGetTransitionDuration(); + already_AddRefed<CSSValue> DoGetTransitionDelay(); + already_AddRefed<CSSValue> DoGetTransitionTimingFunction(); /* CSS Animations */ - mozilla::dom::CSSValue* DoGetAnimationName(); - mozilla::dom::CSSValue* DoGetAnimationDuration(); - mozilla::dom::CSSValue* DoGetAnimationDelay(); - mozilla::dom::CSSValue* DoGetAnimationTimingFunction(); - mozilla::dom::CSSValue* DoGetAnimationDirection(); - mozilla::dom::CSSValue* DoGetAnimationFillMode(); - mozilla::dom::CSSValue* DoGetAnimationIterationCount(); - mozilla::dom::CSSValue* DoGetAnimationPlayState(); + already_AddRefed<CSSValue> DoGetAnimationName(); + already_AddRefed<CSSValue> DoGetAnimationDuration(); + already_AddRefed<CSSValue> DoGetAnimationDelay(); + already_AddRefed<CSSValue> DoGetAnimationTimingFunction(); + already_AddRefed<CSSValue> DoGetAnimationDirection(); + already_AddRefed<CSSValue> DoGetAnimationFillMode(); + already_AddRefed<CSSValue> DoGetAnimationIterationCount(); + already_AddRefed<CSSValue> DoGetAnimationPlayState(); /* CSS Flexbox properties */ - mozilla::dom::CSSValue* DoGetFlexBasis(); - mozilla::dom::CSSValue* DoGetFlexDirection(); - mozilla::dom::CSSValue* DoGetFlexGrow(); - mozilla::dom::CSSValue* DoGetFlexShrink(); - mozilla::dom::CSSValue* DoGetFlexWrap(); + already_AddRefed<CSSValue> DoGetFlexBasis(); + already_AddRefed<CSSValue> DoGetFlexDirection(); + already_AddRefed<CSSValue> DoGetFlexGrow(); + already_AddRefed<CSSValue> DoGetFlexShrink(); + already_AddRefed<CSSValue> DoGetFlexWrap(); /* CSS Flexbox/Grid properties */ - mozilla::dom::CSSValue* DoGetOrder(); + already_AddRefed<CSSValue> DoGetOrder(); /* CSS Box Alignment properties */ - mozilla::dom::CSSValue* DoGetAlignContent(); - mozilla::dom::CSSValue* DoGetAlignItems(); - mozilla::dom::CSSValue* DoGetAlignSelf(); - mozilla::dom::CSSValue* DoGetJustifyContent(); - mozilla::dom::CSSValue* DoGetJustifyItems(); - mozilla::dom::CSSValue* DoGetJustifySelf(); + already_AddRefed<CSSValue> DoGetAlignContent(); + already_AddRefed<CSSValue> DoGetAlignItems(); + already_AddRefed<CSSValue> DoGetAlignSelf(); + already_AddRefed<CSSValue> DoGetJustifyContent(); + already_AddRefed<CSSValue> DoGetJustifyItems(); + already_AddRefed<CSSValue> DoGetJustifySelf(); /* SVG properties */ - mozilla::dom::CSSValue* DoGetFill(); - mozilla::dom::CSSValue* DoGetStroke(); - mozilla::dom::CSSValue* DoGetMarkerEnd(); - mozilla::dom::CSSValue* DoGetMarkerMid(); - mozilla::dom::CSSValue* DoGetMarkerStart(); - mozilla::dom::CSSValue* DoGetStrokeDasharray(); + already_AddRefed<CSSValue> DoGetFill(); + already_AddRefed<CSSValue> DoGetStroke(); + already_AddRefed<CSSValue> DoGetMarkerEnd(); + already_AddRefed<CSSValue> DoGetMarkerMid(); + already_AddRefed<CSSValue> DoGetMarkerStart(); + already_AddRefed<CSSValue> DoGetStrokeDasharray(); - mozilla::dom::CSSValue* DoGetStrokeDashoffset(); - mozilla::dom::CSSValue* DoGetStrokeWidth(); - mozilla::dom::CSSValue* DoGetVectorEffect(); + already_AddRefed<CSSValue> DoGetStrokeDashoffset(); + already_AddRefed<CSSValue> DoGetStrokeWidth(); + already_AddRefed<CSSValue> DoGetVectorEffect(); - mozilla::dom::CSSValue* DoGetFillOpacity(); - mozilla::dom::CSSValue* DoGetFloodOpacity(); - mozilla::dom::CSSValue* DoGetStopOpacity(); - mozilla::dom::CSSValue* DoGetStrokeMiterlimit(); - mozilla::dom::CSSValue* DoGetStrokeOpacity(); + already_AddRefed<CSSValue> DoGetFillOpacity(); + already_AddRefed<CSSValue> DoGetFloodOpacity(); + already_AddRefed<CSSValue> DoGetStopOpacity(); + already_AddRefed<CSSValue> DoGetStrokeMiterlimit(); + already_AddRefed<CSSValue> DoGetStrokeOpacity(); - mozilla::dom::CSSValue* DoGetClipRule(); - mozilla::dom::CSSValue* DoGetFillRule(); - mozilla::dom::CSSValue* DoGetStrokeLinecap(); - mozilla::dom::CSSValue* DoGetStrokeLinejoin(); - mozilla::dom::CSSValue* DoGetTextAnchor(); + already_AddRefed<CSSValue> DoGetClipRule(); + already_AddRefed<CSSValue> DoGetFillRule(); + already_AddRefed<CSSValue> DoGetStrokeLinecap(); + already_AddRefed<CSSValue> DoGetStrokeLinejoin(); + already_AddRefed<CSSValue> DoGetTextAnchor(); - mozilla::dom::CSSValue* DoGetColorInterpolation(); - mozilla::dom::CSSValue* DoGetColorInterpolationFilters(); - mozilla::dom::CSSValue* DoGetDominantBaseline(); - mozilla::dom::CSSValue* DoGetImageRendering(); - mozilla::dom::CSSValue* DoGetShapeRendering(); - mozilla::dom::CSSValue* DoGetTextRendering(); + already_AddRefed<CSSValue> DoGetColorInterpolation(); + already_AddRefed<CSSValue> DoGetColorInterpolationFilters(); + already_AddRefed<CSSValue> DoGetDominantBaseline(); + already_AddRefed<CSSValue> DoGetImageRendering(); + already_AddRefed<CSSValue> DoGetShapeRendering(); + already_AddRefed<CSSValue> DoGetTextRendering(); - mozilla::dom::CSSValue* DoGetFloodColor(); - mozilla::dom::CSSValue* DoGetLightingColor(); - mozilla::dom::CSSValue* DoGetStopColor(); + already_AddRefed<CSSValue> DoGetFloodColor(); + already_AddRefed<CSSValue> DoGetLightingColor(); + already_AddRefed<CSSValue> DoGetStopColor(); - mozilla::dom::CSSValue* DoGetClipPath(); - mozilla::dom::CSSValue* DoGetFilter(); - mozilla::dom::CSSValue* DoGetMask(); - mozilla::dom::CSSValue* DoGetMaskType(); - mozilla::dom::CSSValue* DoGetPaintOrder(); + already_AddRefed<CSSValue> DoGetClipPath(); + already_AddRefed<CSSValue> DoGetFilter(); + already_AddRefed<CSSValue> DoGetMask(); + already_AddRefed<CSSValue> DoGetMaskType(); + already_AddRefed<CSSValue> DoGetPaintOrder(); /* Custom properties */ - mozilla::dom::CSSValue* DoGetCustomProperty(const nsAString& aPropertyName); + already_AddRefed<CSSValue> DoGetCustomProperty(const nsAString& aPropertyName); nsDOMCSSValueList* GetROCSSValueList(bool aCommaDelimited); /* Helper functions */ void SetToRGBAColor(nsROCSSPrimitiveValue* aValue, nscolor aColor); void SetValueToStyleImage(const nsStyleImage& aStyleImage, nsROCSSPrimitiveValue* aValue); void SetValueToPositionCoord( @@ -602,21 +604,21 @@ private: bool GetScrollFrameContentHeight(nscoord& aHeight); bool GetFrameBoundsWidthForTransform(nscoord &aWidth); bool GetFrameBoundsHeightForTransform(nscoord &aHeight); bool GetFrameBorderRectWidth(nscoord& aWidth); bool GetFrameBorderRectHeight(nscoord& aHeight); /* Helper functions for computing the filter property style. */ void SetCssTextToCoord(nsAString& aCssText, const nsStyleCoord& aCoord); - already_AddRefed<mozilla::dom::CSSValue> CreatePrimitiveValueForStyleFilter( + already_AddRefed<CSSValue> CreatePrimitiveValueForStyleFilter( const nsStyleFilter& aStyleFilter); // Helper function for computing basic shape styles. - mozilla::dom::CSSValue* CreatePrimitiveValueForClipPath( + already_AddRefed<CSSValue> CreatePrimitiveValueForClipPath( const nsStyleBasicShape* aStyleBasicShape, uint8_t aSizingBox); void BoxValuesToString(nsAString& aString, const nsTArray<nsStyleCoord>& aBoxValues); void BasicShapeRadiiToString(nsAString& aCssText, const nsStyleCorners& aCorners); static nsComputedStyleMap* GetComputedStyleMap();
--- a/mobile/android/base/java/org/mozilla/gecko/gfx/GLController.java +++ b/mobile/android/base/java/org/mozilla/gecko/gfx/GLController.java @@ -81,17 +81,17 @@ public class GLController extends JNIObj @WrapForJNI private native void pauseCompositor(); // UI thread resumes compositor and notifies Gecko thread; does not block UI thread. @WrapForJNI private native void syncResumeResizeCompositor(int width, int height); @WrapForJNI - /* package */ native void syncInvalidateAndScheduleComposite(); + private native void syncInvalidateAndScheduleComposite(); public GLController() { } synchronized void serverSurfaceDestroyed() { ThreadUtils.assertOnUiThread(); mServerSurfaceValid = false; @@ -282,16 +282,22 @@ public class GLController extends JNIObj // It is important to not notify Gecko until after the compositor has // been resumed, otherwise Gecko may send updates that get dropped. if (mCompositorCreated) { syncResumeResizeCompositor(width, height); mView.requestRender(); } } + /* package */ void invalidateAndScheduleComposite() { + if (mCompositorCreated) { + syncInvalidateAndScheduleComposite(); + } + } + public static class GLControllerException extends RuntimeException { public static final long serialVersionUID = 1L; GLControllerException(String e) { super(e); } } }