author | Ryan VanderMeulen <ryanvm@gmail.com> |
Mon, 23 Jun 2014 10:59:41 -0400 | |
changeset 190173 | 007a3b5039a4dbaa6ced017311d9df9220914a29 |
parent 190172 | 00681f1336d5ec9d8dc96f54cb46500d2d020990 (current diff) |
parent 190107 | 31de1a84b27f7bf1a15d3dc9ea8a01f4acd7bd75 (diff) |
child 190174 | 943bd08b116aa6a62025da75b18e68472c9c4c17 |
push id | 27002 |
push user | kwierso@gmail.com |
push date | Tue, 24 Jun 2014 00:56:44 +0000 |
treeherder | mozilla-central@fa6a7a2f476c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 33.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
|
dom/mobileconnection/tests/marionette/mobile_header.js | file | annotate | diff | comparison | revisions | |
dom/xslt/xpath/nsXPathResult.cpp | file | annotate | diff | comparison | revisions | |
dom/xslt/xpath/nsXPathResult.h | file | annotate | diff | comparison | revisions | |
layout/style/nsCSSStyleSheet.cpp | file | annotate | diff | comparison | revisions | |
layout/style/nsCSSStyleSheet.h | file | annotate | diff | comparison | revisions |
--- a/accessible/src/generic/DocAccessible.cpp +++ b/accessible/src/generic/DocAccessible.cpp @@ -1298,17 +1298,17 @@ DocAccessible::GetAccessibleByUniqueIDIn } return nullptr; } Accessible* DocAccessible::GetAccessibleOrContainer(nsINode* aNode) const { - if (!aNode || !aNode->IsInDoc()) + if (!aNode || !aNode->GetCrossShadowCurrentDoc()) return nullptr; nsINode* currNode = aNode; Accessible* accessible = nullptr; while (!(accessible = GetAccessible(currNode)) && (currNode = currNode->GetParentNode())); return accessible;
--- a/accessible/src/jsat/ContentControl.jsm +++ b/accessible/src/jsat/ContentControl.jsm @@ -70,16 +70,19 @@ this.ContentControl.prototype = { receiveMessage: function cc_receiveMessage(aMessage) { Logger.debug(() => { return ['ContentControl.receiveMessage', aMessage.name, JSON.stringify(aMessage.json)]; }); + // If we get an explicit message, we should immediately cancel any autoMove + this.cancelAutoMove(); + try { let func = this['handle' + aMessage.name.slice(9)]; // 'AccessFu:'.length if (func) { func.bind(this)(aMessage); } else { Logger.warning('ContentControl: Unhandled message:', aMessage.name); } } catch (x) { @@ -376,18 +379,17 @@ this.ContentControl.prototype = { * focus move. Default 0. * - noOpIfOnScreen: if accessible is alive and visible, don't do anything. * - forcePresent: present cursor location, whether we move or don't. * - moveToFocused: if there is a focused accessible move to that. This takes * precedence over given anchor. * - moveMethod: pivot move method to use, default is 'moveNext', */ autoMove: function cc_autoMove(aAnchor, aOptions = {}) { - let win = this.window; - win.clearTimeout(this._autoMove); + this.cancelAutoMove(); let moveFunc = () => { let vc = this.vc; let acc = aAnchor; let rule = aOptions.onScreenOnly ? TraversalRules.SimpleOnScreen : TraversalRules.Simple; let forcePresentFunc = () => { if (aOptions.forcePresent) { @@ -427,18 +429,23 @@ this.ContentControl.prototype = { }); if (!moved && !sentToChild) { forcePresentFunc(); } }; if (aOptions.delay) { - this._autoMove = win.setTimeout(moveFunc, aOptions.delay); + this._autoMove = this.window.setTimeout(moveFunc, aOptions.delay); } else { moveFunc(); } }, + cancelAutoMove: function cc_cancelAutoMove() { + this.window.clearTimeout(this._autoMove); + this._autoMove = 0; + }, + QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference, Ci.nsIMessageListener ]) };
--- a/accessible/src/windows/msaa/AccessibleWrap.h +++ b/accessible/src/windows/msaa/AccessibleWrap.h @@ -213,11 +213,12 @@ protected: } // namespace mozilla #ifdef XP_WIN // Undo the windows.h damage #undef GetMessage #undef CreateEvent #undef GetClassName #undef GetBinaryType +#undef RemoveDirectory #endif #endif
--- a/accessible/tests/mochitest/elm/test_shadowroot.html +++ b/accessible/tests/mochitest/elm/test_shadowroot.html @@ -9,32 +9,30 @@ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> <script type="application/javascript" src="../common.js"></script> <script type="application/javascript" src="../role.js"></script> <script type="application/javascript"> - SpecialPowers.setBoolPref("dom.webcomponents.enabled", true); function doTest() { testElm("component", { role: ROLE_GROUPING, children: [ { role: ROLE_PUSHBUTTON, }, { role: ROLE_LINK, }, ] }); - SpecialPowers.clearUserPref("dom.webcomponents.enabled"); SimpleTest.finish(); } SimpleTest.waitForExplicitFinish(); addA11yLoadEvent(doTest); </script> </head> <body>
--- a/accessible/tests/mochitest/hittest/a11y.ini +++ b/accessible/tests/mochitest/hittest/a11y.ini @@ -1,11 +1,12 @@ [DEFAULT] support-files = zoom_tree.xul [test_browser.html] [test_canvas_hitregion.html] skip-if = (os == "android" || appname == "b2g") [test_general.html] [test_menu.xul] +[test_shadowroot.html] [test_zoom.html] [test_zoom_text.html] [test_zoom_tree.xul]
new file mode 100644 --- /dev/null +++ b/accessible/tests/mochitest/hittest/test_shadowroot.html @@ -0,0 +1,72 @@ +<!DOCTYPE html> +<html> +<head> + <title>ShadowRoot hit tests</title> + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../layout.js"></script> + + <script type="application/javascript"> + function doTest() + { + var componentAcc = getAccessible('component1'); + testChildAtPoint(componentAcc, 1, 1, componentAcc.firstChild, + componentAcc.firstChild); + + componentAcc = getAccessible('component2'); + testChildAtPoint(componentAcc, 1, 1, componentAcc.firstChild, + componentAcc.firstChild); + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> +</head> +<body> + + <a target="_blank" + title="Test getChildAtPoint works for shadow DOM content" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=1027315"> + Mozilla Bug 1027315 + </a><br/> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + </pre> + + <div role="group" class="components" id="component1" style="display: inline-block;"> + <!-- + <div role="button" id="component-child" + style="width: 100px; height: 100px; background-color: pink;"> + </div> + --> + </div> + <div role="group" class="components" id="component2" style="display: inline-block;"> + <!-- + <button>Hello world</button> + --> + </div> + <script> + // This routine adds the comment children of each 'component' to its + // shadow root. + var components = document.querySelectorAll('.components'); + for (var i = 0; i < components.length; i++) { + var component = components[i]; + var shadow = component.createShadowRoot(); + for (var child = component.firstChild; child; child = child.nextSibling) { + if (child.nodeType === 8) + shadow.innerHTML = child.data; + } + } + </script> + +</body> +</html>
--- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -14,23 +14,23 @@ <!--original fetch url was git://github.com/apitrace/--> <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/> <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> - <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/> - <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/> <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="3326b51017252e09ccdd715dec6c5e12a7d1ecfe"/> <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/> <!-- Stock Android things --> <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/> <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/> <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/> <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/> <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/> <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/> <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -12,20 +12,20 @@ <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="cc67f31dc638c0b7edba3cf7e3d87cadf0ed52bf"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> - <project name="gaia" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/> - <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/> @@ -123,14 +123,14 @@ <project name="platform/system/security" path="system/security" revision="f48ff68fedbcdc12b570b7699745abb6e7574907"/> <project name="platform/system/vold" path="system/vold" revision="8de05d4a52b5a91e7336e6baa4592f945a6ddbea"/> <default remote="caf" revision="refs/tags/android-4.3_r2.1" sync-j="4"/> <!-- Emulator specific things --> <project name="android-development" path="development" remote="b2g" revision="dab55669da8f48b6e57df95d5af9f16b4a87b0b1"/> <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/> <project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="0e31f35a2a77301e91baa8a237aa9e9fa4076084"/> <project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/> - <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="973367035a1f2545f3dad6e40e354463dc56a7f4"/> + <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="346c7694b156a3933f3d87cbc077c657e2ce571f"/> <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="832f4acaf481a19031e479a40b03d9ce5370ddee"/> <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d0aa65b140a45016975ed0ecf35f280dd336e1d3"/> <project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/> </manifest>
--- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -10,25 +10,25 @@ <!--original fetch url was git://codeaurora.org/--> <remote fetch="https://git.mozilla.org/external/caf" name="caf"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1"> <copyfile dest="Makefile" src="core/root.mk"/> </project> - <project name="gaia" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> - <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/> + <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/> <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/> <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/> <project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
--- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -14,23 +14,23 @@ <!--original fetch url was git://github.com/apitrace/--> <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/> <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> - <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/> - <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/> <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="3326b51017252e09ccdd715dec6c5e12a7d1ecfe"/> <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/> <!-- Stock Android things --> <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/> <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/> <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/> <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/> <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/> <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/> <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -12,20 +12,20 @@ <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="cc67f31dc638c0b7edba3cf7e3d87cadf0ed52bf"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> - <project name="gaia" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/> - <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
--- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { "git_revision": "", "remote": "", "branch": "" }, - "revision": "387f4c0123a7e82eae4c83f88f73e81f907c00e2", + "revision": "aba00cfd579caaf205e05c269f0a8100f242f39c", "repo_path": "/integration/gaia-central" }
--- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -12,22 +12,22 @@ <!--original fetch url was git://github.com/apitrace/--> <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/> <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> - <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/> - <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/> <!-- Stock Android things --> <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/> <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/> <project name="platform/bootable/recovery" path="bootable/recovery" revision="746bc48f34f5060f90801925dcdd964030c1ab6d"/> <project name="platform/development" path="development" revision="2460485184bc8535440bb63876d4e63ec1b4770c"/> <project name="device/common" path="device/common" revision="0dcc1e03659db33b77392529466f9eb685cdd3c7"/> <project name="device/sample" path="device/sample" revision="68b1cb978a20806176123b959cb05d4fa8adaea4"/> <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -10,18 +10,18 @@ <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> - <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/> - <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/> <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/> <!-- Stock Android things --> <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/> <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/> <project name="platform/bootable/recovery" path="bootable/recovery" revision="575fdbf046e966a5915b1f1e800e5d6ad0ea14c0"/>
--- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -12,20 +12,20 @@ <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="cc67f31dc638c0b7edba3cf7e3d87cadf0ed52bf"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> - <project name="gaia" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/> - <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -12,22 +12,22 @@ <!--original fetch url was git://github.com/apitrace/--> <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/> <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> - <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/> - <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/> <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/> <!-- Stock Android things --> <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/> <project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/> <project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/> <project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/> <project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/> <project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
--- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -213,18 +213,20 @@ pref("app.update.showInstalledUI", false // to newer versions of installed addons that resolve them. // 1 = suppress prompting for incompatibilities only if there are VersionInfo // updates available to installed addons that resolve them, not newer // versions. pref("app.update.incompatible.mode", 0); // Whether or not to attempt using the service for updates. #ifdef MOZ_MAINTENANCE_SERVICE +#ifndef HAVE_64BIT_OS pref("app.update.service.enabled", true); #endif +#endif // Symmetric (can be overridden by individual extensions) update preferences. // e.g. // extensions.{GUID}.update.enabled // extensions.{GUID}.update.url // .. etc .. // pref("extensions.update.enabled", true);
--- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -752,23 +752,16 @@ var gBrowserInit = { gMultiProcessBrowser = window.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebNavigation) .QueryInterface(Ci.nsILoadContext) .useRemoteTabs; var mustLoadSidebar = false; - if (!gMultiProcessBrowser) { - // There is a Content:Click message manually sent from content. - Cc["@mozilla.org/eventlistenerservice;1"] - .getService(Ci.nsIEventListenerService) - .addSystemEventListener(gBrowser, "click", contentAreaClick, true); - } - gBrowser.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver, false); // Note that the XBL binding is untrusted gBrowser.addEventListener("PluginBindingAttached", gPluginHandler, true, true); gBrowser.addEventListener("PluginCrashed", gPluginHandler, true); gBrowser.addEventListener("PluginOutdated", gPluginHandler, true); gBrowser.addEventListener("PluginInstantiated", gPluginHandler, true); gBrowser.addEventListener("PluginRemoved", gPluginHandler, true); @@ -797,16 +790,25 @@ var gBrowserInit = { .getInterface(nsIWebNavigation) .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner .QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIXULWindow) .XULBrowserWindow = window.XULBrowserWindow; window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow = new nsBrowserAccess(); + if (!gMultiProcessBrowser) { + // There is a Content:Click message manually sent from content. + Cc["@mozilla.org/eventlistenerservice;1"] + .getService(Ci.nsIEventListenerService) + .addSystemEventListener(gBrowser, "click", contentAreaClick, true); + } else { + gBrowser.updateBrowserRemoteness(gBrowser.mCurrentBrowser, true); + } + // hook up UI through progress listener gBrowser.addProgressListener(window.XULBrowserWindow); gBrowser.addTabsProgressListener(window.TabsProgressListener); // setup simple gestures support gGestureSupport.init(true); // setup history swipe animation @@ -2618,17 +2620,17 @@ function onMozEnteredDomFullscreen(event function getWebNavigation() { return gBrowser.webNavigation; } function BrowserReloadWithFlags(reloadFlags) { let url = gBrowser.currentURI.spec; - if (gBrowser.updateBrowserRemoteness(gBrowser.selectedBrowser, url)) { + if (gBrowser.updateBrowserRemotenessByURL(gBrowser.selectedBrowser, url)) { // If the remoteness has changed, the new browser doesn't have any // information of what was loaded before, so we need to load the previous // URL again. gBrowser.loadURIWithFlags(url, reloadFlags); return; } /* First, we'll try to use the session history object to reload so
--- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -1369,58 +1369,67 @@ this.selectedTab = firstTabAdded; } else this.selectedBrowser.focus(); } ]]></body> </method> -#ifdef MAKE_E10S_WORK <method name="updateBrowserRemoteness"> <parameter name="aBrowser"/> - <parameter name="aURL"/> + <parameter name="aShouldBeRemote"/> <body> <![CDATA[ - let shouldBeRemote = this._shouldBrowserBeRemote(aURL); - let isRemote = aBrowser.getAttribute("remote") == "true"; - if (isRemote == shouldBeRemote) + if (isRemote == aShouldBeRemote) return false; let wasActive = document.activeElement == aBrowser; // Unhook our progress listener. let tab = this._getTabForBrowser(aBrowser); let index = tab._tPos; let filter = this.mTabFilters[index]; aBrowser.webProgress.removeProgressListener(filter); // Change the "remote" attribute. let parent = aBrowser.parentNode; parent.removeChild(aBrowser); - aBrowser.setAttribute("remote", shouldBeRemote ? "true" : "false"); + aBrowser.setAttribute("remote", aShouldBeRemote ? "true" : "false"); parent.appendChild(aBrowser); // Restore the progress listener. aBrowser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL); - if (shouldBeRemote) + if (aShouldBeRemote) tab.setAttribute("remote", "true"); else tab.removeAttribute("remote"); if (wasActive) aBrowser.focus(); return true; ]]> </body> </method> +#ifdef MAKE_E10S_WORK + <method name="updateBrowserRemotenessByURL"> + <parameter name="aBrowser"/> + <parameter name="aURL"/> + <body> + <![CDATA[ + let shouldBeRemote = this._shouldBrowserBeRemote(aURL); + return this.updateBrowserRemoteness(aBrowser, shouldBeRemote); + ]]> + </body> + </method> + <!-- Returns true if we want to load the content for this URL in a remote process. Eventually this should just check whether aURL is unprivileged. Right now, though, we would like to load some unprivileged URLs (like about:neterror) in the main process since they interact with chrome code through BrowserOnClick. --> @@ -2721,24 +2730,24 @@ <!-- throws exception for unknown schemes --> <method name="loadURI"> <parameter name="aURI"/> <parameter name="aReferrerURI"/> <parameter name="aCharset"/> <body> <![CDATA[ #ifdef MAKE_E10S_WORK - this.updateBrowserRemoteness(this.mCurrentBrowser, aURI); + this.updateBrowserRemotenessByURL(this.mCurrentBrowser, aURI); try { #endif return this.mCurrentBrowser.loadURI(aURI, aReferrerURI, aCharset); #ifdef MAKE_E10S_WORK } catch (e) { let url = this.mCurrentBrowser.currentURI.spec; - this.updateBrowserRemoteness(this.mCurrentBrowser, url); + this.updateBrowserRemotenessByURL(this.mCurrentBrowser, url); throw e; } #endif ]]> </body> </method> <!-- throws exception for unknown schemes --> @@ -2746,24 +2755,24 @@ <parameter name="aURI"/> <parameter name="aFlags"/> <parameter name="aReferrerURI"/> <parameter name="aCharset"/> <parameter name="aPostData"/> <body> <![CDATA[ #ifdef MAKE_E10S_WORK - this.updateBrowserRemoteness(this.mCurrentBrowser, aURI); + this.updateBrowserRemotenessByURL(this.mCurrentBrowser, aURI); try { #endif return this.mCurrentBrowser.loadURIWithFlags(aURI, aFlags, aReferrerURI, aCharset, aPostData); #ifdef MAKE_E10S_WORK } catch (e) { let url = this.mCurrentBrowser.currentURI.spec; - this.updateBrowserRemoteness(this.mCurrentBrowser, url); + this.updateBrowserRemotenessByURL(this.mCurrentBrowser, url); throw e; } #endif ]]> </body> </method> <method name="goHome"> @@ -3276,17 +3285,17 @@ if (!event.isTrusted) return; let browser = event.originalTarget; let title = browser.contentTitle; let uri = browser.currentURI; let icon = browser.mIconURL; - this.updateBrowserRemoteness(browser, "about:tabcrashed"); + this.updateBrowserRemotenessByURL(browser, "about:tabcrashed"); browser.setAttribute("crashedPageTitle", title); browser.docShell.displayLoadError(Cr.NS_ERROR_CONTENT_CRASHED, uri, null); browser.removeAttribute("crashedPageTitle"); let tab = this._getTabForBrowser(browser); this.setIcon(tab, icon); ]]> </handler>
--- a/browser/components/loop/content/conversation.html +++ b/browser/components/loop/content/conversation.html @@ -1,16 +1,17 @@ <!DOCTYPE html> <!-- 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/. --> <html> <head> <meta charset="utf-8"> - <title>Conversation</title> + <!-- Title is set in conversation.js --> + <title></title> <link rel="stylesheet" type="text/css" href="loop/shared/css/common.css"> <link rel="stylesheet" type="text/css" href="loop/shared/css/conversation.css"> </head> <body onload="loop.conversation.init();"> <div id="messages"></div> <div id="main"></div>
--- a/browser/components/loop/content/js/conversation.js +++ b/browser/components/loop/content/js/conversation.js @@ -3,19 +3,17 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ /* global loop:true */ var loop = loop || {}; loop.conversation = (function(OT, mozL10n) { "use strict"; - var sharedViews = loop.shared.views, - // aliasing translation function as __ for concision - __ = mozL10n.get; + var sharedViews = loop.shared.views; /** * App router. * @type {loop.desktopRouter.DesktopConversationRouter} */ var router; /** @@ -169,16 +167,18 @@ loop.conversation = (function(OT, mozL10 /** * Panel initialisation. */ function init() { // Do the initial L10n setup, we do this before anything // else to ensure the L10n environment is setup correctly. mozL10n.initialize(window.navigator.mozLoop); + document.title = mozL10n.get("incoming_call_title"); + router = new ConversationRouter({ conversation: new loop.shared.models.ConversationModel({}, {sdk: OT}), notifier: new sharedViews.NotificationListView({el: "#messages"}) }); Backbone.history.start(); } return {
--- a/browser/components/loop/test/desktop-local/conversation_test.js +++ b/browser/components/loop/test/desktop-local/conversation_test.js @@ -30,16 +30,67 @@ describe("loop.conversation", function() }; }); afterEach(function() { delete window.navigator.mozLoop; sandbox.restore(); }); + describe("#init", function() { + var conversation, oldTitle; + + beforeEach(function() { + oldTitle = document.title; + + sandbox.stub(document.mozL10n, "initialize"); + sandbox.stub(document.mozL10n, "get").returns("Fake title"); + + sandbox.stub(loop.conversation.ConversationRouter.prototype, + "initialize"); + sandbox.stub(loop.shared.models.ConversationModel.prototype, + "initialize"); + sandbox.stub(loop.shared.views.NotificationListView.prototype, + "initialize"); + + sandbox.stub(Backbone.history, "start"); + }); + + afterEach(function() { + document.title = oldTitle; + }); + + it("should initalize L10n", function() { + loop.conversation.init(); + + sinon.assert.calledOnce(document.mozL10n.initialize); + sinon.assert.calledWithExactly(document.mozL10n.initialize, + window.navigator.mozLoop); + }); + + it("should set the document title", function() { + loop.conversation.init(); + + expect(document.title).to.be.equal("Fake title"); + }); + + it("should create the router", function() { + loop.conversation.init(); + + sinon.assert.calledOnce( + loop.conversation.ConversationRouter.prototype.initialize); + }); + + it("should start Backbone history", function() { + loop.conversation.init(); + + sinon.assert.calledOnce(Backbone.history.start); + }); + }); + describe("ConversationRouter", function() { var conversation; beforeEach(function() { conversation = new loop.shared.models.ConversationModel({}, {sdk: {}}); sandbox.stub(conversation, "initiate"); });
--- a/browser/components/sessionstore/src/SessionStore.jsm +++ b/browser/components/sessionstore/src/SessionStore.jsm @@ -2529,17 +2529,17 @@ let SessionStoreInternal = { // Save the index in case we updated it above. tabData.index = activeIndex + 1; // In electrolysis, we may need to change the browser's remote // attribute so that it runs in a content process. let activePageData = tabData.entries[activeIndex] || null; let uri = activePageData ? activePageData.url || null : null; - tabbrowser.updateBrowserRemoteness(browser, uri); + tabbrowser.updateBrowserRemotenessByURL(browser, uri); // Start a new epoch and include the epoch in the restoreHistory // message. If a message is received that relates to a previous epoch, we // discard it. let epoch = this._nextRestoreEpoch++; this._browserEpochs.set(browser.permanentKey, epoch); // keep the data around to prevent dataloss in case
--- a/browser/config/mozconfigs/linux32/debug +++ b/browser/config/mozconfigs/linux32/debug @@ -1,14 +1,17 @@ ac_add_options --enable-debug ac_add_options --enable-dmd ac_add_options --enable-signmar ac_add_options --disable-unified-compilation +MOZ_AUTOMATION_TALOS_SENDCHANGE=0 +MOZ_AUTOMATION_L10N_CHECK=0 + . $topsrcdir/build/unix/mozconfig.linux32 # Needed to enable breakpad in application.ini export MOZILLA_OFFICIAL=1 #Use ccache . "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/linux64/debug +++ b/browser/config/mozconfigs/linux64/debug @@ -1,12 +1,15 @@ ac_add_options --enable-debug ac_add_options --enable-dmd ac_add_options --enable-signmar +MOZ_AUTOMATION_TALOS_SENDCHANGE=0 +MOZ_AUTOMATION_L10N_CHECK=0 + . $topsrcdir/build/unix/mozconfig.linux # Needed to enable breakpad in application.ini export MOZILLA_OFFICIAL=1 # Use ccache . "$topsrcdir/build/mozconfig.cache"
--- a/browser/config/mozconfigs/linux64/debug-static-analysis-clang +++ b/browser/config/mozconfigs/linux64/debug-static-analysis-clang @@ -1,8 +1,15 @@ +MOZ_AUTOMATION_BUILD_SYMBOLS=0 +MOZ_AUTOMATION_PACKAGE_TESTS=0 +MOZ_AUTOMATION_UNITTEST_SENDCHANGE=0 +MOZ_AUTOMATION_TALOS_SENDCHANGE=0 +MOZ_AUTOMATION_L10N_CHECK=0 +MOZ_AUTOMATION_CHECK=0 + . "$topsrcdir/build/mozconfig.common" ac_add_options --enable-debug ac_add_options --disable-unified-compilation # Use Clang as specified in manifest export CC="$topsrcdir/clang/bin/clang"
--- a/browser/config/mozconfigs/linux64/nightly-nonunified +++ b/browser/config/mozconfigs/linux64/nightly-nonunified @@ -1,3 +1,8 @@ +MOZ_AUTOMATION_UPLOAD=0 +MOZ_AUTOMATION_UNITTEST_SENDCHANGE=0 +MOZ_AUTOMATION_TALOS_SENDCHANGE=0 +MOZ_AUTOMATION_CHECK=0 + . "$topsrcdir/browser/config/mozconfigs/linux64/nightly" ac_add_options --disable-unified-compilation
--- a/browser/confvars.sh +++ b/browser/confvars.sh @@ -4,19 +4,19 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. MOZ_APP_BASENAME=Firefox MOZ_APP_VENDOR=Mozilla MOZ_UPDATER=1 MOZ_PHOENIX=1 if test "$OS_ARCH" = "WINNT"; then + MOZ_MAINTENANCE_SERVICE=1 if ! test "$HAVE_64BIT_OS"; then MOZ_VERIFY_MAR_SIGNATURE=1 - MOZ_MAINTENANCE_SERVICE=1 if test "$MOZ_UPDATE_CHANNEL" = "nightly" -o \ "$MOZ_UPDATE_CHANNEL" = "aurora" -o \ "$MOZ_UPDATE_CHANNEL" = "beta" -o \ "$MOZ_UPDATE_CHANNEL" = "release"; then if ! test "$MOZ_DEBUG"; then MOZ_STUB_INSTALLER=1 fi fi
--- a/browser/experiments/Experiments.jsm +++ b/browser/experiments/Experiments.jsm @@ -1561,17 +1561,17 @@ Experiments.ExperimentEntry.prototype = return Task.spawn(function ExperimentEntry_runFilterFunction_task() { const nullprincipal = Cc["@mozilla.org/nullprincipal;1"].createInstance(Ci.nsIPrincipal); let options = { sandboxName: "telemetry experiments jsfilter sandbox", wantComponents: false, }; - let sandbox = Cu.Sandbox(nullprincipal); + let sandbox = Cu.Sandbox(nullprincipal, options); try { Cu.evalInSandbox(jsfilter, sandbox); } catch (e) { this._log.error("runFilterFunction() - failed to eval jsfilter: " + e.message); throw ["jsfilter-evalfailed"]; } // You can't insert arbitrarily complex objects into a sandbox, so
--- a/browser/installer/windows/nsis/maintenanceservice_installer.nsi +++ b/browser/installer/windows/nsis/maintenanceservice_installer.nsi @@ -70,24 +70,21 @@ OutFile "maintenanceservice_installer.ex ; Get installation folder from registry if available InstallDirRegKey HKLM "Software\Mozilla\MaintenanceService" "" SetOverwrite on !define MaintUninstallKey \ "Software\Microsoft\Windows\CurrentVersion\Uninstall\MozillaMaintenanceService" -; The HAVE_64BIT_OS define also means that we have an x64 build, -; not just an x64 OS. -!ifdef HAVE_64BIT_OS - ; See below, we actually abort the install for x64 builds currently. - InstallDir "$PROGRAMFILES64\${MaintFullName}\" -!else - InstallDir "$PROGRAMFILES32\${MaintFullName}\" -!endif +; Always install into the 32-bit location even if we have a 64-bit build. +; This is because we use only 1 service for all Firefox channels. +; Allow either x86 and x64 builds to exist at this location, depending on +; what is the latest build. +InstallDir "$PROGRAMFILES32\${MaintFullName}\" ShowUnInstDetails nevershow ################################################################################ # Modern User Interface - MUI !define MUI_ICON setup.ico !define MUI_UNICON setup.ico !define MUI_WELCOMEPAGE_TITLE_3LINES @@ -116,23 +113,16 @@ BrandingText " " Function .onInit ; Remove the current exe directory from the search order. ; This only effects LoadLibrary calls and not implicitly loaded DLLs. System::Call 'kernel32::SetDllDirectoryW(w "")' SetSilent silent -!ifdef HAVE_64BIT_OS - ; We plan to eventually enable 64bit native builds to use the maintenance - ; service, but for the initial release, to reduce testing and development, - ; 64-bit builds will not install the maintenanceservice. - Abort -!endif - ; On Windows 2000 we do not install the maintenance service. ; We won't run this installer from the parent installer, but just in case ; someone tries to execute it on Windows 2000... ${Unless} ${AtLeastWinXP} Abort ${EndUnless} FunctionEnd @@ -200,18 +190,17 @@ Section "MaintenanceService" WriteUninstaller "$INSTDIR\Uninstall.exe" WriteRegStr HKLM "${MaintUninstallKey}" "DisplayName" "${MaintFullName}" WriteRegStr HKLM "${MaintUninstallKey}" "UninstallString" \ '"$INSTDIR\uninstall.exe"' WriteRegStr HKLM "${MaintUninstallKey}" "DisplayIcon" \ "$INSTDIR\Uninstall.exe,0" WriteRegStr HKLM "${MaintUninstallKey}" "DisplayVersion" "${AppVersion}" WriteRegStr HKLM "${MaintUninstallKey}" "Publisher" "Mozilla" - WriteRegStr HKLM "${MaintUninstallKey}" "Comments" \ - "${BrandFullName} ${AppVersion} (${ARCH} ${AB_CD})" + WriteRegStr HKLM "${MaintUninstallKey}" "Comments" "${BrandFullName}" WriteRegDWORD HKLM "${MaintUninstallKey}" "NoModify" 1 ${GetSize} "$INSTDIR" "/S=0K" $R2 $R3 $R4 WriteRegDWORD HKLM "${MaintUninstallKey}" "EstimatedSize" $R2 ; Write out that a maintenance service was attempted. ; We do this because on upgrades we will check this value and we only ; want to install once on the first upgrade to maintenance service. ; Also write out that we are currently installed, preferences will check
--- a/browser/locales/en-US/chrome/browser/loop/loop.properties +++ b/browser/locales/en-US/chrome/browser/loop/loop.properties @@ -1,16 +1,30 @@ +# 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/. + +# Panel Strings + get_link_to_share=Get a link and invite someone to talk +share_link_url=Share the link below with your friend to start your call! +do_not_disturb=Do not disturb + get_a_call_url=Get a call url new_url=New url +caller.placeholder=Identify this call + unable_retrieve_url=Sorry, we were unable to retrieve a call url. -share_link_url=Share the link below with your friend to start your call! -caller.placeholder=Identify this call -cannot_start_call_session_not_ready=Can't start call, session is not ready. -network_disconnected=The network connection terminated abruptly. -peer_ended_conversation=Your peer ended the conversation. -stop=Stop -call_has_ended=Your call has ended. -close_window=Close this window -do_not_disturb=Do not disturb + +# Conversation Window Strings + +incoming_call_title=Incoming Call… incoming_call=Incoming call accept_button=Accept decline_button=Decline +stop=Stop + +peer_ended_conversation=Your peer ended the conversation. +call_has_ended=Your call has ended. +close_window=Close this window + +cannot_start_call_session_not_ready=Can't start call, session is not ready. +network_disconnected=The network connection terminated abruptly.
--- a/browser/modules/TabCrashReporter.jsm +++ b/browser/modules/TabCrashReporter.jsm @@ -74,17 +74,17 @@ this.TabCrashReporter = { if (browser.isRemoteBrowser) continue; let doc = browser.contentDocument; if (!doc.documentURI.startsWith("about:tabcrashed")) continue; let url = browser.currentURI.spec; - window.gBrowser.updateBrowserRemoteness(browser, url); + window.gBrowser.updateBrowserRemotenessByURL(browser, url); browser.loadURIWithFlags(url, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null); } } }, onAboutTabCrashedLoad: function (aBrowser) { if (!this.childMap) return;
--- a/browser/modules/test/unit/social/head.js +++ b/browser/modules/test/unit/social/head.js @@ -80,16 +80,17 @@ function initApp() { createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9"); // prepare a blocklist file for the blocklist service var blocklistFile = gProfD.clone(); blocklistFile.append("blocklist.xml"); if (blocklistFile.exists()) blocklistFile.remove(false); var source = do_get_file("blocklist.xml"); source.copyTo(gProfD, "blocklist.xml"); + blocklistFile.lastModifiedTime = Date.now(); let internalManager = Cc["@mozilla.org/addons/integration;1"]. getService(Ci.nsIObserver). QueryInterface(Ci.nsITimerCallback); internalManager.observe(null, "addons-startup", null); }
--- a/build/autoconf/altoptions.m4 +++ b/build/autoconf/altoptions.m4 @@ -13,17 +13,16 @@ dnl Send comments, improvements, bugs to dnl MOZ_ARG_ENABLE_BOOL( NAME, HELP, IF-YES [, IF-NO [, ELSE]]) dnl MOZ_ARG_DISABLE_BOOL( NAME, HELP, IF-NO [, IF-YES [, ELSE]]) dnl MOZ_ARG_ENABLE_STRING( NAME, HELP, IF-SET [, ELSE]) dnl MOZ_ARG_ENABLE_BOOL_OR_STRING( NAME, HELP, IF-YES, IF-NO, IF-SET[, ELSE]]]) dnl MOZ_ARG_WITH_BOOL( NAME, HELP, IF-YES [, IF-NO [, ELSE]) dnl MOZ_ARG_WITHOUT_BOOL( NAME, HELP, IF-NO [, IF-YES [, ELSE]) dnl MOZ_ARG_WITH_STRING( NAME, HELP, IF-SET [, ELSE]) dnl MOZ_ARG_HEADER(Comment) -dnl MOZ_CHECK_PTHREADS( NAME, IF-YES [, ELSE ]) dnl MOZ_READ_MYCONFIG() - Read in 'myconfig.sh' file dnl MOZ_TWO_STRING_TEST(NAME, VAL, STR1, IF-STR1, STR2, IF-STR2 [, ELSE]) AC_DEFUN([MOZ_TWO_STRING_TEST], [if test "[$2]" = "[$3]"; then ifelse([$4], , :, [$4]) elif test "[$2]" = "[$5]"; then @@ -75,48 +74,15 @@ AC_DEFUN([MOZ_ARG_WITHOUT_BOOL], dnl MOZ_ARG_WITH_STRING(NAME, HELP, IF-SET [, ELSE]) AC_DEFUN([MOZ_ARG_WITH_STRING], [AC_ARG_WITH([$1], [$2], [$3], [$4])]) dnl MOZ_ARG_HEADER(Comment) dnl This is used by webconfig to group options define(MOZ_ARG_HEADER, [# $1]) -dnl -dnl Apparently, some systems cannot properly check for the pthread -dnl library unless <pthread.h> is included so we need to test -dnl using it -dnl -dnl MOZ_CHECK_PTHREADS(lib, success, failure) -AC_DEFUN([MOZ_CHECK_PTHREADS], -[ -AC_MSG_CHECKING([for pthread_create in -l$1]) -echo " - #include <pthread.h> - #include <stdlib.h> - void *foo(void *v) { int a = 1; } - int main() { - pthread_t t; - if (!pthread_create(&t, 0, &foo, 0)) { - pthread_join(t, 0); - } - exit(0); - }" > dummy.c ; - echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -l[$1] $LDFLAGS $LIBS" 1>&5; - ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -l[$1] $LDFLAGS $LIBS 2>&5; - _res=$? ; - rm -f dummy.c dummy${ac_exeext} ; - if test "$_res" = "0"; then - AC_MSG_RESULT([yes]) - [$2] - else - AC_MSG_RESULT([no]) - [$3] - fi -]) - dnl MOZ_READ_MYCONFIG() - Read in 'myconfig.sh' file AC_DEFUN([MOZ_READ_MOZCONFIG], [AC_REQUIRE([AC_INIT_BINSH])dnl # Read in '.mozconfig' script to set the initial options. # See the mozconfig2configure script for more details. _AUTOCONF_TOOLS_DIR=`dirname [$]0`/[$1]/build/autoconf . $_AUTOCONF_TOOLS_DIR/mozconfig2configure])
--- a/build/automation.py.in +++ b/build/automation.py.in @@ -469,17 +469,17 @@ class Automation(object): status = self.Process([pk12util, "-i", os.path.join(certPath, item), "-w", pwfilePath, "-d", profileDir], env = env).wait() automationutils.printstatus(status, "pk12util") os.unlink(pwfilePath) return 0 - def environment(self, env=None, xrePath=None, crashreporter=True, debugger=False, dmdPath=None): + def environment(self, env=None, xrePath=None, crashreporter=True, debugger=False, dmdPath=None, lsanPath=None): if xrePath == None: xrePath = self.DIST_BIN if env == None: env = dict(os.environ) ldLibraryPath = os.path.abspath(os.path.join(SCRIPT_DIR, xrePath)) dmdLibrary = None preloadEnvVar = None
--- a/build/automationutils.py +++ b/build/automationutils.py @@ -443,17 +443,17 @@ def parseKeyValue(strings, separator='=' def systemMemory(): """ Returns total system memory in kilobytes. Works only on unix-like platforms where `free` is in the path. """ return int(os.popen("free").readlines()[1].split()[1]) -def environment(xrePath, env=None, crashreporter=True, debugger=False, dmdPath=None): +def environment(xrePath, env=None, crashreporter=True, debugger=False, dmdPath=None, lsanPath=None): """populate OS environment variables for mochitest""" env = os.environ.copy() if env is None else env assert os.path.isabs(xrePath) ldLibraryPath = xrePath @@ -516,21 +516,40 @@ def environment(xrePath, env=None, crash log.info("TEST-UNEXPECTED-FAIL | runtests.py | Failed to find ASan symbolizer at %s", llvmsym) totalMemory = systemMemory() # Only 4 GB RAM or less available? Use custom ASan options to reduce # the amount of resources required to do the tests. Standard options # will otherwise lead to OOM conditions on the current test slaves. message = "INFO | runtests.py | ASan running in %s configuration" + asanOptions = [] if totalMemory <= 1024 * 1024 * 4: message = message % 'low-memory' - env["ASAN_OPTIONS"] = "quarantine_size=50331648:malloc_context_size=5" + asanOptions = ['quarantine_size=50331648', 'malloc_context_size=5'] else: message = message % 'default memory' + + if lsanPath: + log.info("LSan enabled.") + asanOptions.append('detect_leaks=1') + lsanOptions = ["exitcode=0"] + suppressionsFile = os.path.join(lsanPath, 'lsan_suppressions.txt') + if os.path.exists(suppressionsFile): + log.info("LSan using suppression file " + suppressionsFile) + lsanOptions.append("suppressions=" + suppressionsFile) + else: + log.info("WARNING | runtests.py | LSan suppressions file does not exist! " + suppressionsFile) + env["LSAN_OPTIONS"] = ':'.join(lsanOptions) + # Run shutdown GCs and CCs to avoid spurious leaks. + env['MOZ_CC_RUN_DURING_SHUTDOWN'] = '1' + + if len(asanOptions): + env['ASAN_OPTIONS'] = ':'.join(asanOptions) + except OSError,err: log.info("Failed determine available memory, disabling ASan low-memory configuration: %s", err.strerror) except: log.info("Failed determine available memory, disabling ASan low-memory configuration") else: log.info(message) return env @@ -673,8 +692,103 @@ class ShutdownLeaks(object): counted = set() for url in leakedWindows: if not url in counted: counts.append((url, leakedWindows.count(url))) counted.add(url) return sorted(counts, key=itemgetter(1), reverse=True) + + +class LSANLeaks(object): + """ + Parses the log when running an LSAN build, looking for interesting stack frames + in allocation stacks, and prints out reports. + """ + + def __init__(self, logger): + self.logger = logger + self.inReport = False + self.foundFrames = set([]) + self.recordMoreFrames = None + self.currStack = None + self.maxNumRecordedFrames = 4 + + # Don't various allocation-related stack frames, as they do not help much to + # distinguish different leaks. + unescapedSkipList = [ + "malloc", "js_malloc", "malloc_", "__interceptor_malloc", "moz_malloc", "moz_xmalloc", + "calloc", "js_calloc", "calloc_", "__interceptor_calloc", "moz_calloc", "moz_xcalloc", + "realloc","js_realloc", "realloc_", "__interceptor_realloc", "moz_realloc", "moz_xrealloc", + "new", + "js::MallocProvider", + ] + self.skipListRegExp = re.compile("^" + "|".join([re.escape(f) for f in unescapedSkipList]) + "$") + + self.startRegExp = re.compile("==\d+==ERROR: LeakSanitizer: detected memory leaks") + self.stackFrameRegExp = re.compile(" #\d+ 0x[0-9a-f]+ in ([^(</]+)") + self.sysLibStackFrameRegExp = re.compile(" #\d+ 0x[0-9a-f]+ \(([^+]+)\+0x[0-9a-f]+\)") + + + def log(self, line): + if re.match(self.startRegExp, line): + self.inReport = True + return + + if not self.inReport: + return + + if line.startswith("Direct leak"): + self._finishStack() + self.recordMoreFrames = True + self.currStack = [] + return + + if line.startswith("Indirect leak"): + self._finishStack() + # Only report direct leaks, in the hope that they are less flaky. + self.recordMoreFrames = False + return + + if line.startswith("SUMMARY: AddressSanitizer"): + self._finishStack() + self.inReport = False + return + + if not self.recordMoreFrames: + return + + stackFrame = re.match(self.stackFrameRegExp, line) + if stackFrame: + # Split the frame to remove any return types. + frame = stackFrame.group(1).split()[-1] + if not re.match(self.skipListRegExp, frame): + self._recordFrame(frame) + return + + sysLibStackFrame = re.match(self.sysLibStackFrameRegExp, line) + if sysLibStackFrame: + # System library stack frames will never match the skip list, + # so don't bother checking if they do. + self._recordFrame(sysLibStackFrame.group(1)) + + # If we don't match either of these, just ignore the frame. + # We'll end up with "unknown stack" if everything is ignored. + + def process(self): + for f in self.foundFrames: + self.logger("TEST-UNEXPECTED-FAIL | LeakSanitizer | leak at " + f) + + def _finishStack(self): + if self.recordMoreFrames and len(self.currStack) == 0: + self.currStack = ["unknown stack"] + if self.currStack: + self.foundFrames.add(", ".join(self.currStack)) + self.currStack = None + self.recordMoreFrames = False + self.numRecordedFrames = 0 + + def _recordFrame(self, frame): + self.currStack.append(frame) + self.numRecordedFrames += 1 + if self.numRecordedFrames >= self.maxNumRecordedFrames: + self.recordMoreFrames = False
--- a/build/gen_mach_buildprops.py +++ b/build/gen_mach_buildprops.py @@ -1,15 +1,20 @@ #!/usr/bin/python # # 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/. -import sys, os, sha, json, re +import sys +import os +import sha +import json +import re +import errno from argparse import ArgumentParser def getFileHashAndSize(filename): sha1Hash = 'UNKNOWN' size = 'UNKNOWN' try: # open in binary mode to make sure we get consistent results @@ -46,25 +51,30 @@ def getUrlProperties(filename): ('jsshellUrl', lambda m: 'jsshell-' in m and m.endswith('.zip')), ('completeMarUrl', lambda m: m.endswith('.complete.mar')), # packageUrl must be last! ('packageUrl', lambda m: True), ] url_re = re.compile(r'''^(https?://.*?\.(?:tar\.bz2|dmg|zip|apk|rpm|mar|tar\.gz))$''') properties = {} - with open(filename) as f: - for line in f: - m = url_re.match(line) - if m: - m = m.group(1) - for prop, condition in property_conditions: - if condition(m): - properties.update({prop: m}) - break + try: + with open(filename) as f: + for line in f: + m = url_re.match(line) + if m: + m = m.group(1) + for prop, condition in property_conditions: + if condition(m): + properties.update({prop: m}) + break + except IOError as e: + if e.errno != errno.ENOENT: + raise + properties = {prop: 'UNKNOWN' for prop, condition in property_conditions} return properties if __name__ == '__main__': parser = ArgumentParser(description='Generate mach_build_properties.json for automation builds.') parser.add_argument("--complete-mar-file", required=True, action="store", dest="complete_mar_file", help="Path to the complete MAR file, relative to the objdir.") parser.add_argument("--upload-output", required=True,
--- a/build/mobile/remoteautomation.py +++ b/build/mobile/remoteautomation.py @@ -43,17 +43,17 @@ class RemoteAutomation(Automation): def setProduct(self, product): self._product = product def setRemoteLog(self, logfile): self._remoteLog = logfile # Set up what we need for the remote environment - def environment(self, env=None, xrePath=None, crashreporter=True, debugger=False, dmdPath=None): + def environment(self, env=None, xrePath=None, crashreporter=True, debugger=False, dmdPath=None, lsanPath=None): # Because we are running remote, we don't want to mimic the local env # so no copying of os.environ if env is None: env = {} if dmdPath: env['DMD'] = '1' env['MOZ_REPLACE_MALLOC_LIB'] = os.path.join(dmdPath, 'libdmd.so')
--- a/build/moz-automation.mk +++ b/build/moz-automation.mk @@ -12,63 +12,67 @@ endif endif include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk # Log file from the 'make upload' step. We need this to parse out the URLs of # the uploaded files. AUTOMATION_UPLOAD_OUTPUT = $(DIST)/automation-upload.txt +# Helper variables to convert from MOZ_AUTOMATION_* variables to the +# corresponding the make target +tier_BUILD_SYMBOLS = buildsymbols +tier_CHECK = check +tier_L10N_CHECK = l10n-check +tier_PACKAGE = package +tier_PACKAGE_TESTS = package-tests +tier_UPDATE_PACKAGING = update-packaging +tier_UPLOAD_SYMBOLS = uploadsymbols +tier_UPLOAD = upload + # Automation build steps. Everything in MOZ_AUTOMATION_TIERS also gets used in # TIERS for mach display. As such, the MOZ_AUTOMATION_TIERS are roughly sorted # here in the order that they will be executed (since mach doesn't know of the # dependencies between them). - -MOZ_AUTOMATION_TIERS += package-tests -MOZ_AUTOMATION_TIERS += buildsymbols - -ifdef NIGHTLY_BUILD -MOZ_AUTOMATION_TIERS += uploadsymbols -endif - -ifdef MOZ_UPDATE_PACKAGING -MOZ_AUTOMATION_TIERS += update-packaging -automation/upload: automation/update-packaging -automation/update-packaging: automation/package -endif - -MOZ_AUTOMATION_TIERS += package -MOZ_AUTOMATION_TIERS += check - -ifndef MOZ_ASAN -MOZ_AUTOMATION_TIERS += l10n-check -automation/l10n-check: automation/package -endif - -MOZ_AUTOMATION_TIERS += upload - -automation/build: $(addprefix automation/,$(MOZ_AUTOMATION_TIERS)) - $(PYTHON) $(topsrcdir)/build/gen_mach_buildprops.py --complete-mar-file $(DIST)/$(COMPLETE_MAR) --upload-output $(AUTOMATION_UPLOAD_OUTPUT) +moz_automation_symbols = PACKAGE_TESTS BUILD_SYMBOLS UPLOAD_SYMBOLS PACKAGE UPDATE_PACKAGING CHECK L10N_CHECK UPLOAD +MOZ_AUTOMATION_TIERS := $(foreach sym,$(moz_automation_symbols),$(if $(filter 1,$(MOZ_AUTOMATION_$(sym))),$(tier_$(sym)))) # Dependencies between automation build steps automation/uploadsymbols: automation/buildsymbols +automation/update-packaging: automation/package + +automation/l10n-check: automation/package + automation/upload: automation/package automation/upload: automation/package-tests automation/upload: automation/buildsymbols +automation/upload: automation/update-packaging # automation/package and automation/check should depend on build (which is # implicit due to the way client.mk invokes automation/build), but buildsymbols # changes the binaries/libs, and that's what we package/test. automation/package: automation/buildsymbols automation/check: automation/buildsymbols +automation/build: $(addprefix automation/,$(MOZ_AUTOMATION_TIERS)) + $(PYTHON) $(topsrcdir)/build/gen_mach_buildprops.py --complete-mar-file $(DIST)/$(COMPLETE_MAR) --upload-output $(AUTOMATION_UPLOAD_OUTPUT) + # make check runs with the keep-going flag so we can see all the failures AUTOMATION_EXTRA_CMDLINE-check = -k # We need the log from make upload to grep it for urls in order to set # properties. AUTOMATION_EXTRA_CMDLINE-upload = 2>&1 | tee $(AUTOMATION_UPLOAD_OUTPUT) +# The commands only run if the corresponding MOZ_AUTOMATION_* variable is +# enabled. This means, for example, if we enable MOZ_AUTOMATION_UPLOAD, then +# 'buildsymbols' will only run if MOZ_AUTOMATION_BUILD_SYMBOLS is also set. +# However, the target automation/buildsymbols will still be executed in this +# case because it is a prerequisite of automation/upload. +define automation_commands +$(call BUILDSTATUS,TIER_START $1) +@$(MAKE) $1 $(AUTOMATION_EXTRA_CMDLINE-$1) +$(call BUILDSTATUS,TIER_FINISH $1) +endef + automation/%: - $(call BUILDSTATUS,TIER_START $*) - @$(MAKE) $* $(AUTOMATION_EXTRA_CMDLINE-$*) - $(call BUILDSTATUS,TIER_FINISH $*) + $(if $(filter $*,$(MOZ_AUTOMATION_TIERS)),$(call automation_commands,$*))
new file mode 100644 --- /dev/null +++ b/build/mozconfig.automation @@ -0,0 +1,21 @@ +# 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/. + +# Common mozconfig for automation builds. +# +# We export MOZ_AUTOMATION_* variables here to trigger various steps in +# automation builds. For example, if MOZ_AUTOMATION_PACKAGE is set, then the +# package step will run. This file contains the default settings, which can be +# overridden by setting them earlier in the appropriate mozconfig. + +mk_add_options "export MOZ_AUTOMATION_BUILD_SYMBOLS=${MOZ_AUTOMATION_BUILD_SYMBOLS-1}" +mk_add_options "export MOZ_AUTOMATION_CHECK=${MOZ_AUTOMATION_CHECK-1}" +mk_add_options "export MOZ_AUTOMATION_L10N_CHECK=${MOZ_AUTOMATION_L10N_CHECK-1}" +mk_add_options "export MOZ_AUTOMATION_PACKAGE=${MOZ_AUTOMATION_PACKAGE-1}" +mk_add_options "export MOZ_AUTOMATION_PACKAGE_TESTS=${MOZ_AUTOMATION_PACKAGE_TESTS-1}" +mk_add_options "export MOZ_AUTOMATION_TALOS_SENDCHANGE=${MOZ_AUTOMATION_TALOS_SENDCHANGE-1}" +mk_add_options "export MOZ_AUTOMATION_UNITTEST_SENDCHANGE=${MOZ_AUTOMATION_UNITTEST_SENDCHANGE-1}" +mk_add_options "export MOZ_AUTOMATION_UPDATE_PACKAGING=${MOZ_AUTOMATION_UPDATE_PACKAGING-0}" +mk_add_options "export MOZ_AUTOMATION_UPLOAD=${MOZ_AUTOMATION_UPLOAD-1}" +mk_add_options "export MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-0}"
--- a/build/mozconfig.common +++ b/build/mozconfig.common @@ -10,8 +10,10 @@ # another mozconfig file, you'll need to use mozconfig.common.override instead # of this file. mk_add_options AUTOCLOBBER=1 ac_add_options --enable-crashreporter ac_add_options --enable-release + +. "$topsrcdir/build/mozconfig.automation"
new file mode 100644 --- /dev/null +++ b/build/sanitizers/lsan_suppressions.txt @@ -0,0 +1,108 @@ +### !!! Please do not add suppressions for new leaks in Gecko code, unless they are intentional !!! + +### +### Some of these leak in every test run. +### + +# LSan runs with a shallow stack depth and no debug symbols, so some small intentional +# leaks in system libraries show up with this. You do not want this enabled +# when running locally with a deep stack, as it can catch too much. +leak:libc.so + +# nsComponentManagerImpl intentionally leaks factory entries, and probably some other stuff. +leak:nsComponentManagerImpl +# These two variants are needed when fast unwind is disabled and stack depth is limited. +leak:mozJSComponentLoader::LoadModule +leak:nsNativeModuleLoader::LoadModule + +# Bug 980109 - Freeing this properly on shutdown is hard. +leak:profiler_init + +# Bug 981220 - Pixman fails to free TLS memory. +leak:pixman_implementation_lookup_composite + +# Bug 987918 - Font shutdown leaks when CLEANUP_MEMORY is not enabled. +leak:libfontconfig.so +leak:GI___strdup +# The symbol is really __GI___strdup, but if you have the leading _, it doesn't suppress it. + + +### +### Many leaks only affect some test suites. The suite annotations are not checked. +### + +# Bug 800200 - JSD1 is leaking, but it is about to be removed, so ignore it. m4 +leak:jsd_CreateLock +leak:jsdScript::GetExecutableLines +leak:jsdService::ActivateDebugger + +# Bug 979928 - WebRTC is leaky. m2, m3 +leak:/media/mtransport/ +leak:/media/webrtc/signaling/ + +# Bug 981195 - Small leak in the parser. m4 +leak:TypeCompartment::fixObjectType + +# Bug 982111 - WebM is leaking. m1 +leak:nestegg_read_packet + +# Bug 987385 - Various plugin leaks. m3 +leak:mozilla::plugins::PPluginInstanceParent::CallNPP_HandleEvent +leak:mozilla::plugins::PPluginModuleParent::OnCallReceived + +# Bug 987925 - Small leak under PK11_ChangePW. m5 +leak:sec_asn1e_allocate_item +leak:PORT_Strdup_Util + +# Bug 1021302 - Leak of fds allocated in nsSocketTransport::BuildSocket(). m1, m5, dt, oth +leak:nsSocketTransport::BuildSocket +leak:nsServerSocket::OnSocketReady + +# Bug 1021350 - Small leak under event_base_once. m1, m4, bc3 +leak:event_base_once + +# Bug 1021854 - nsFileStreamBase::DoOpen() leaking fds. bc1, oth +leak:nsLocalFile::OpenNSPRFileDesc + +# Bug 1021932 - AllocateArrayBufferContents leaks. m1 +# Bug 1023583 - Leak of array buffer data involving web audio and XHR::OnStopRequest(). m1 +# Bug 1023585 - Leak of array buffer in JSStructuredCloneWriter::transferOwnership(). m1 +leak:AllocateArrayBufferContents + +# Bug 1022010 - Small leak under _render_glyph_outline. bc1 +leak:_render_glyph_outline + +# Bug 1022042 - compareVariants in the test plugin leaks identifiers. oth +leak:compareVariants(_NPP*, + +# Bug 1022954 - ScriptSource leaks sourceMapURL_ sometimes. dt +leak:ScriptSource::setSourceMapURL + +# Bug 1023548 - Small leak under SECITEM_AllocItem_Util. bc1, bc3 +leak:SECITEM_AllocItem_Util + +# This is a one-time leak, so it is probably okay to ignore. bc1, oth +leak:GlobalPrinters::InitializeGlobalPrinters +leak:nsPSPrinterList::GetPrinterList + +# Bug 1028456 - More leaks with _PR_Getfd, in nsLocalFile::CopyToNative and do_create. bc1, bc3 +leak:_PR_Getfd + + +### +### Leaks with system libraries in their stacks. These show up across a number of tests. +### Better symbols and disabling fast stackwalking may help diagnose these. +### + +leak:libcairo.so +leak:libdricore.so +leak:libGL.so +leak:libglib-2.0.so +leak:libp11-kit.so +leak:libpulse.so +leak:libpulsecommon-1.1.so +leak:libresolv.so +leak:libstdc++.so +leak:libXrandr.so +leak:pthread_setspecific_internal +leak:swrast_dri.so
--- a/build/unix/mozconfig.asan +++ b/build/unix/mozconfig.asan @@ -1,8 +1,14 @@ +if [ "x$IS_NIGHTLY" = "xyes" ]; then + MOZ_AUTOMATION_UPDATE_PACKAGING=1 +fi +MOZ_AUTOMATION_TALOS_SENDCHANGE=0 +MOZ_AUTOMATION_L10N_CHECK=0 + . "$topsrcdir/build/mozconfig.common" # Use Clang as specified in manifest export CC="$topsrcdir/clang/bin/clang -fgnu89-inline" export CXX="$topsrcdir/clang/bin/clang++" export LLVM_SYMBOLIZER="$topsrcdir/clang/bin/llvm-symbolizer" # Mandatory flags for ASan
--- a/build/unix/mozconfig.linux +++ b/build/unix/mozconfig.linux @@ -1,8 +1,13 @@ +if [ "x$IS_NIGHTLY" = "xyes" ]; then + MOZ_AUTOMATION_UPLOAD_SYMBOLS=1 + MOZ_AUTOMATION_UPDATE_PACKAGING=1 +fi + . "$topsrcdir/build/mozconfig.common" # some b2g desktop builds still happen on i686 machines, and the tooltool # toolchain is x86_64 only. # We also deal with valgrind builds here, they don't use tooltool manifests at # all yet. if [ -z "$no_tooltool" ] then
--- a/chrome/src/nsChromeRegistry.cpp +++ b/chrome/src/nsChromeRegistry.cpp @@ -11,30 +11,34 @@ #include "prprf.h" #include "nsCOMPtr.h" #include "nsError.h" #include "nsEscape.h" #include "nsNetUtil.h" #include "nsString.h" -#include "nsCSSStyleSheet.h" +#include "mozilla/CSSStyleSheet.h" +#include "mozilla/dom/URL.h" #include "nsIConsoleService.h" #include "nsIDocument.h" #include "nsIDOMDocument.h" #include "nsIDOMLocation.h" #include "nsIDOMWindowCollection.h" #include "nsIDOMWindow.h" #include "nsIObserverService.h" #include "nsIPresShell.h" #include "nsIScriptError.h" #include "nsIWindowMediator.h" -#include "mozilla/dom/URL.h" nsChromeRegistry* nsChromeRegistry::gChromeRegistry; + +// DO NOT use namespace mozilla; it'll break due to a naming conflict between +// mozilla::TextRange and a TextRange in OSX headers. +using mozilla::CSSStyleSheet; using mozilla::dom::IsChromeURI; //////////////////////////////////////////////////////////////////////////////// void nsChromeRegistry::LogMessage(const char* aMsg, ...) { nsCOMPtr<nsIConsoleService> console @@ -289,17 +293,17 @@ nsChromeRegistry::ConvertChromeURL(nsIUR #else path.Insert("unix/", 0); #endif } if (!baseURI) { LogMessage("No chrome package registered for chrome://%s/%s/%s", package.get(), provider.get(), path.get()); - return NS_ERROR_FAILURE; + return NS_ERROR_FILE_NOT_FOUND; } return NS_NewURI(aResult, path, nullptr, baseURI); } //////////////////////////////////////////////////////////////////////// // theme stuff @@ -410,17 +414,17 @@ nsresult nsChromeRegistry::RefreshWindow nsCOMArray<nsIStyleSheet> newAgentSheets; for (int32_t l = 0; l < agentSheets.Count(); ++l) { nsIStyleSheet *sheet = agentSheets[l]; nsIURI* uri = sheet->GetSheetURI(); if (IsChromeURI(uri)) { // Reload the sheet. - nsRefPtr<nsCSSStyleSheet> newSheet; + nsRefPtr<CSSStyleSheet> newSheet; rv = document->LoadChromeSheetSync(uri, true, getter_AddRefs(newSheet)); if (NS_FAILED(rv)) return rv; if (newSheet) { rv = newAgentSheets.AppendObject(newSheet) ? NS_OK : NS_ERROR_FAILURE; if (NS_FAILED(rv)) return rv; } } @@ -449,22 +453,22 @@ nsresult nsChromeRegistry::RefreshWindow if (!oldSheets.AppendObject(styleSheet)) { return NS_ERROR_OUT_OF_MEMORY; } } // Iterate over our old sheets and kick off a sync load of the new // sheet if and only if it's a chrome URL. for (i = 0; i < count; i++) { - nsRefPtr<nsCSSStyleSheet> sheet = do_QueryObject(oldSheets[i]); + nsRefPtr<CSSStyleSheet> sheet = do_QueryObject(oldSheets[i]); nsIURI* uri = sheet ? sheet->GetOriginalURI() : nullptr; if (uri && IsChromeURI(uri)) { // Reload the sheet. - nsRefPtr<nsCSSStyleSheet> newSheet; + nsRefPtr<CSSStyleSheet> newSheet; // XXX what about chrome sheets that have a title or are disabled? This // only works by sheer dumb luck. document->LoadChromeSheetSync(uri, false, getter_AddRefs(newSheet)); // Even if it's null, we put in in there. newSheets.AppendObject(newSheet); } else { // Just use the same sheet.
--- a/chrome/src/nsChromeRegistryChrome.cpp +++ b/chrome/src/nsChromeRegistryChrome.cpp @@ -267,17 +267,17 @@ nsChromeRegistryChrome::GetSelectedLocal if (NS_FAILED(rv)) return rv; PackageEntry* entry = static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash, & realpackage, PL_DHASH_LOOKUP)); if (PL_DHASH_ENTRY_IS_FREE(entry)) - return NS_ERROR_FAILURE; + return NS_ERROR_FILE_NOT_FOUND; aLocale = entry->locales.GetSelected(mSelectedLocale, nsProviderArray::LOCALE); if (aLocale.IsEmpty()) return NS_ERROR_FAILURE; return NS_OK; } @@ -555,17 +555,17 @@ nsresult nsChromeRegistryChrome::GetFlagsFromPackage(const nsCString& aPackage, uint32_t* aFlags) { PackageEntry* entry = static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash, & (nsACString&) aPackage, PL_DHASH_LOOKUP)); if (PL_DHASH_ENTRY_IS_FREE(entry)) - return NS_ERROR_NOT_AVAILABLE; + return NS_ERROR_FILE_NOT_FOUND; *aFlags = entry->flags; return NS_OK; } PLHashNumber nsChromeRegistryChrome::HashKey(PLDHashTable *table, const void *key) {
--- a/configure.in +++ b/configure.in @@ -2799,23 +2799,23 @@ dnl ==================================== dnl = pthread support dnl = Start by checking whether the system support pthreads dnl ======================================================== case "$target_os" in darwin*) MOZ_USE_PTHREADS=1 ;; *) - MOZ_CHECK_PTHREADS(pthreads, + AC_CHECK_LIB(pthreads, pthread_create, MOZ_USE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthreads", - MOZ_CHECK_PTHREADS(pthread, + AC_CHECK_LIB(pthread, pthread_create, MOZ_USE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthread", - MOZ_CHECK_PTHREADS(c_r, + AC_CHECK_LIB(c_r, pthread_create, MOZ_USE_PTHREADS=1 _PTHREAD_LDFLAGS="-lc_r", - MOZ_CHECK_PTHREADS(c, + AC_CHECK_LIB(c, pthread_create, MOZ_USE_PTHREADS=1 ) ) ) ) ;; esac @@ -7796,59 +7796,16 @@ if test "$SOLARIS_SUNPRO_CC"; then PROFILE_USE_LDFLAGS="-xprofile=use:$_objdir/$enable_application" fi AC_SUBST(PROFILE_GEN_CFLAGS) AC_SUBST(PROFILE_GEN_LDFLAGS) AC_SUBST(PROFILE_USE_CFLAGS) AC_SUBST(PROFILE_USE_LDFLAGS) -AC_LANG_CPLUSPLUS - -dnl ======================================================== -dnl Autoconf test for gcc 2.7.2.x (and maybe others?) so that we don't -dnl provide non-const forms of the operator== for comparing nsCOMPtrs to -dnl raw pointers in nsCOMPtr.h. (VC++ has the same bug.) -dnl ======================================================== -_SAVE_CXXFLAGS=$CXXFLAGS -CXXFLAGS="$CXXFLAGS ${_WARNINGS_CXXFLAGS}" -AC_CACHE_CHECK(for correct overload resolution with const and templates, - ac_nscap_nonconst_opeq_bug, - [AC_TRY_COMPILE([ - template <class T> - class Pointer - { - public: - T* myPtr; - }; - - template <class T, class U> - int operator==(const Pointer<T>& rhs, U* lhs) - { - return rhs.myPtr == lhs; - } - - template <class T, class U> - int operator==(const Pointer<T>& rhs, const U* lhs) - { - return rhs.myPtr == lhs; - } - ], - [ - Pointer<int> foo; - const int* bar; - return foo == bar; - ], - ac_nscap_nonconst_opeq_bug="no", - ac_nscap_nonconst_opeq_bug="yes")]) -CXXFLAGS="$_SAVE_CXXFLAGS" - -if test "$ac_nscap_nonconst_opeq_bug" = "yes" ; then - AC_DEFINE(NSCAP_DONT_PROVIDE_NONCONST_OPEQ) -fi fi # ! SKIP_COMPILER_CHECKS AC_DEFINE(CPP_THROW_NEW, [throw()]) AC_LANG_C if test "$COMPILE_ENVIRONMENT"; then MOZ_EXPAND_LIBS fi # COMPILE_ENVIRONMENT @@ -7870,17 +7827,17 @@ else if test -z "$_WIN32_MSVC"; then _USE_CPP_INCLUDE_FLAG= _DEFINES_CFLAGS='$(ACDEFINES) -D_MOZILLA_CONFIG_H_ -DMOZILLA_CLIENT' _DEFINES_CXXFLAGS='$(ACDEFINES) -D_MOZILLA_CONFIG_H_ -DMOZILLA_CLIENT' else echo '#include <stdio.h>' > dummy-hello.c changequote(,) dnl This output is localized, split at the first double space or colon and space. - _CL_PREFIX_REGEX="^\([^:]*:.*[ :] \)\(.*stdio.h\)$" + _CL_PREFIX_REGEX="^\([^:]*:.*[ :] \)\(.*\\\stdio.h\)$" CL_INCLUDES_PREFIX=`${CC} -showIncludes -c -Fonul dummy-hello.c 2>&1 | sed -ne 's/'"$_CL_PREFIX_REGEX"'/\1/p'` _CL_STDIO_PATH=`${CC} -showIncludes -c -Fonul dummy-hello.c 2>&1 | sed -ne 's/'"$_CL_PREFIX_REGEX"'/\2/p'` changequote([,]) if ! test -e "$_CL_STDIO_PATH"; then AC_MSG_ERROR([Unable to parse cl -showIncludes prefix. This compiler's locale has an unsupported formatting.]) fi if test -z "$CL_INCLUDES_PREFIX"; then AC_MSG_ERROR([Cannot find cl -showIncludes prefix.])
--- a/content/base/public/FragmentOrElement.h +++ b/content/base/public/FragmentOrElement.h @@ -119,16 +119,17 @@ public: ~nsNodeWeakReference(); // nsISupports NS_DECL_ISUPPORTS // nsIWeakReference NS_DECL_NSIWEAKREFERENCE + virtual size_t SizeOfOnlyThis(mozilla::MallocSizeOf aMallocSizeOf) const; void NoticeNodeDestruction() { mNode = nullptr; } private: nsINode* mNode;
--- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -24,17 +24,16 @@ #include "mozilla/WeakPtr.h" #include "Units.h" #include "nsExpirationTracker.h" #include "nsClassHashtable.h" class imgIRequest; class nsAString; class nsBindingManager; -class nsCSSStyleSheet; class nsIDocShell; class nsDocShell; class nsDOMNavigationTiming; class nsFrameLoader; class nsHTMLCSSStyleSheet; class nsHTMLDocument; class nsHTMLStyleSheet; class nsIAtom; @@ -78,16 +77,17 @@ class nsTextNode; class nsWindowSizes; class nsSmallVoidArray; class nsDOMCaretPosition; class nsViewportInfo; class nsIGlobalObject; struct nsCSSSelectorList; namespace mozilla { +class CSSStyleSheet; class ErrorResult; class EventStates; namespace css { class Loader; class ImageLoader; } // namespace css @@ -117,16 +117,17 @@ class NodeIterator; class ProcessingInstruction; class StyleSheetList; class SVGDocument; class Touch; class TouchList; class TreeWalker; class UndoManager; class XPathEvaluator; +class XPathResult; template<typename> class OwningNonNull; template<typename> class Sequence; template<typename, typename> class CallbackObjectHolder; typedef CallbackObjectHolder<NodeFilter, nsIDOMNodeFilter> NodeFilterHolder; } // namespace dom } // namespace mozilla @@ -774,17 +775,17 @@ public: * This function prepends the given style sheet to the document's style set * in order to make sure that it does not override user-agent style sheets * supplied by add-ons or by the app (Firefox OS or Firefox Mobile, for * example), since their sheets should override built-in sheets. * * TODO We can get rid of the whole concept of delayed loading if we fix * bug 77999. */ - virtual void EnsureOnDemandBuiltInUASheet(nsCSSStyleSheet* aSheet) = 0; + virtual void EnsureOnDemandBuiltInUASheet(mozilla::CSSStyleSheet* aSheet) = 0; /** * Get the number of (document) stylesheets * * @return the number of stylesheets * @throws no exceptions */ virtual int32_t GetNumberOfStyleSheets() const = 0; @@ -1831,17 +1832,17 @@ public: * Called by the chrome registry to load style sheets. Can be put * back there if and when when that module is merged with libgklayout. * * This always does a synchronous load. If aIsAgentSheet is true, * it also uses the system principal and enables unsafe rules. * DO NOT USE FOR UNTRUSTED CONTENT. */ virtual nsresult LoadChromeSheetSync(nsIURI* aURI, bool aIsAgentSheet, - nsCSSStyleSheet** aSheet) = 0; + mozilla::CSSStyleSheet** aSheet) = 0; /** * Returns true if the locale used for the document specifies a direction of * right to left. For chrome documents, this comes from the chrome registry. * This is used to determine the current state for the :-moz-locale-dir pseudoclass * so once can know whether a document is expected to be rendered left-to-right * or right-to-left. */ @@ -2269,20 +2270,20 @@ public: Element* GetBindingParent(nsINode& aNode); void LoadBindingDocument(const nsAString& aURI, mozilla::ErrorResult& rv); already_AddRefed<nsIDOMXPathExpression> CreateExpression(const nsAString& aExpression, nsIDOMXPathNSResolver* aResolver, mozilla::ErrorResult& rv); already_AddRefed<nsIDOMXPathNSResolver> CreateNSResolver(nsINode* aNodeResolver, mozilla::ErrorResult& rv); - already_AddRefed<nsISupports> - Evaluate(const nsAString& aExpression, nsINode* aContextNode, + already_AddRefed<mozilla::dom::XPathResult> + Evaluate(JSContext* aCx, const nsAString& aExpression, nsINode* aContextNode, nsIDOMXPathNSResolver* aResolver, uint16_t aType, - nsISupports* aResult, mozilla::ErrorResult& rv); + JS::Handle<JSObject*> aResult, mozilla::ErrorResult& rv); // Touch event handlers already on nsINode already_AddRefed<mozilla::dom::Touch> CreateTouch(nsIDOMWindow* aView, mozilla::dom::EventTarget* aTarget, int32_t aIdentifier, int32_t aPageX, int32_t aPageY, int32_t aScreenX, int32_t aScreenY, int32_t aClientX, int32_t aClientY, int32_t aRadiusX, int32_t aRadiusY, float aRotationAngle, float aForce); already_AddRefed<mozilla::dom::TouchList> CreateTouchList();
--- a/content/base/public/nsIStyleSheetLinkingElement.h +++ b/content/base/public/nsIStyleSheetLinkingElement.h @@ -11,30 +11,33 @@ class nsICSSLoaderObserver; class nsIURI; #define NS_ISTYLESHEETLINKINGELEMENT_IID \ { 0xd753c84a, 0x17fd, 0x4d5f, \ { 0xb2, 0xe9, 0x63, 0x52, 0x8c, 0x87, 0x99, 0x7a } } class nsIStyleSheet; -class nsCSSStyleSheet; + +namespace mozilla { +class CSSStyleSheet; +} // namespace mozilla class nsIStyleSheetLinkingElement : public nsISupports { public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISTYLESHEETLINKINGELEMENT_IID) /** * Used to make the association between a style sheet and * the element that linked it to the document. * * @param aStyleSheet the style sheet associated with this * element. */ - NS_IMETHOD SetStyleSheet(nsCSSStyleSheet* aStyleSheet) = 0; + NS_IMETHOD SetStyleSheet(mozilla::CSSStyleSheet* aStyleSheet) = 0; /** * Used to obtain the style sheet linked in by this element. * * @param aStyleSheet out parameter that returns the style * sheet associated with this element. */ NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aStyleSheet) = 0;
--- a/content/base/src/ChildIterator.cpp +++ b/content/base/src/ChildIterator.cpp @@ -20,29 +20,29 @@ public: : mIsContentElement(true), mContentElement(aInsertionPoint) {} MatchedNodes(XBLChildrenElement* aInsertionPoint) : mIsContentElement(false), mChildrenElement(aInsertionPoint) {} uint32_t Length() const { return mIsContentElement ? mContentElement->MatchedNodes().Length() - : mChildrenElement->mInsertedChildren.Length(); + : mChildrenElement->InsertedChildrenLength(); } nsIContent* operator[](int32_t aIndex) const { return mIsContentElement ? mContentElement->MatchedNodes()[aIndex] - : mChildrenElement->mInsertedChildren[aIndex]; + : mChildrenElement->InsertedChild(aIndex); } bool IsEmpty() const { return mIsContentElement ? mContentElement->MatchedNodes().IsEmpty() - : mChildrenElement->mInsertedChildren.IsEmpty(); + : !mChildrenElement->HasInsertedChildren(); } protected: bool mIsContentElement; union { HTMLContentElement* mContentElement; XBLChildrenElement* mChildrenElement; }; };
--- a/content/base/src/EventSource.cpp +++ b/content/base/src/EventSource.cpp @@ -1231,25 +1231,21 @@ EventSource::DispatchAllMessageEvents() mGoingToDispatchAllMessages = false; nsresult rv = CheckInnerWindowCorrectness(); if (NS_FAILED(rv)) { return; } - // We need a parent object so that we can enter its compartment. - nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(GetParentObject()); - if (NS_WARN_IF(!parentObject)) { + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.InitUsingWin(GetOwner()))) { return; } - - AutoJSAPI jsapi; JSContext* cx = jsapi.cx(); - JSAutoCompartment ac(cx, parentObject->GetGlobalJSObject()); while (mMessagesToDispatch.GetSize() > 0) { nsAutoPtr<Message> message(static_cast<Message*>(mMessagesToDispatch.PopFront())); // Now we can turn our string into a jsval JS::Rooted<JS::Value> jsData(cx); {
--- a/content/base/src/FragmentOrElement.cpp +++ b/content/base/src/FragmentOrElement.cpp @@ -495,16 +495,22 @@ nsNodeWeakReference::~nsNodeWeakReferenc NS_IMETHODIMP nsNodeWeakReference::QueryReferent(const nsIID& aIID, void** aInstancePtr) { return mNode ? mNode->QueryInterface(aIID, aInstancePtr) : NS_ERROR_NULL_POINTER; } +size_t +nsNodeWeakReference::SizeOfOnlyThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + return aMallocSizeOf(this); +} + NS_IMPL_CYCLE_COLLECTION(nsNodeSupportsWeakRefTearoff, mNode) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsNodeSupportsWeakRefTearoff) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_END_AGGREGATED(mNode) NS_IMPL_CYCLE_COLLECTING_ADDREF(nsNodeSupportsWeakRefTearoff)
--- a/content/base/src/ShadowRoot.cpp +++ b/content/base/src/ShadowRoot.cpp @@ -132,17 +132,17 @@ ShadowRoot::StyleSheetChanged() if (shell) { OwnerDoc()->BeginUpdate(UPDATE_STYLE); shell->RecordShadowStyleChange(this); OwnerDoc()->EndUpdate(UPDATE_STYLE); } } void -ShadowRoot::InsertSheet(nsCSSStyleSheet* aSheet, +ShadowRoot::InsertSheet(CSSStyleSheet* aSheet, nsIContent* aLinkingContent) { nsCOMPtr<nsIStyleSheetLinkingElement> linkingElement = do_QueryInterface(aLinkingContent); MOZ_ASSERT(linkingElement, "The only styles in a ShadowRoot should come " "from <style>."); linkingElement->SetStyleSheet(aSheet); // This sets the ownerNode on the sheet @@ -163,17 +163,17 @@ ShadowRoot::InsertSheet(nsCSSStyleSheet* } if (aSheet->IsApplicable()) { StyleSheetChanged(); } } void -ShadowRoot::RemoveSheet(nsCSSStyleSheet* aSheet) +ShadowRoot::RemoveSheet(CSSStyleSheet* aSheet) { mProtoBinding->RemoveStyleSheet(aSheet); if (aSheet->IsApplicable()) { StyleSheetChanged(); } } @@ -714,17 +714,17 @@ ShadowRootStyleSheetList::ShadowRootStyl MOZ_COUNT_CTOR(ShadowRootStyleSheetList); } ShadowRootStyleSheetList::~ShadowRootStyleSheetList() { MOZ_COUNT_DTOR(ShadowRootStyleSheetList); } -nsCSSStyleSheet* +CSSStyleSheet* ShadowRootStyleSheetList::IndexedGetter(uint32_t aIndex, bool& aFound) { aFound = aIndex < mShadowRoot->mProtoBinding->SheetCount(); if (!aFound) { return nullptr; }
--- a/content/base/src/ShadowRoot.h +++ b/content/base/src/ShadowRoot.h @@ -43,18 +43,18 @@ public: NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED ShadowRoot(nsIContent* aContent, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, nsXBLPrototypeBinding* aProtoBinding); virtual ~ShadowRoot(); void AddToIdTable(Element* aElement, nsIAtom* aId); void RemoveFromIdTable(Element* aElement, nsIAtom* aId); - void InsertSheet(nsCSSStyleSheet* aSheet, nsIContent* aLinkingContent); - void RemoveSheet(nsCSSStyleSheet* aSheet); + void InsertSheet(CSSStyleSheet* aSheet, nsIContent* aLinkingContent); + void RemoveSheet(CSSStyleSheet* aSheet); bool ApplyAuthorStyles(); void SetApplyAuthorStyles(bool aApplyAuthorStyles); StyleSheetList* StyleSheets(); HTMLShadowElement* GetShadowElement() { return mShadowElement; } /** * Sets the current shadow insertion point where the older * ShadowRoot will be projected. @@ -182,17 +182,17 @@ public: NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ShadowRootStyleSheetList, StyleSheetList) virtual nsINode* GetParentObject() const MOZ_OVERRIDE { return mShadowRoot; } virtual uint32_t Length() MOZ_OVERRIDE; - virtual nsCSSStyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) MOZ_OVERRIDE; + virtual CSSStyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) MOZ_OVERRIDE; protected: nsRefPtr<ShadowRoot> mShadowRoot; }; } // namespace dom } // namespace mozilla
--- a/content/base/src/StyleSheetList.cpp +++ b/content/base/src/StyleSheetList.cpp @@ -1,17 +1,17 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/dom/StyleSheetList.h" +#include "mozilla/CSSStyleSheet.h" #include "mozilla/dom/StyleSheetListBinding.h" -#include "nsCSSStyleSheet.h" namespace mozilla { namespace dom { NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(StyleSheetList) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(StyleSheetList) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
--- a/content/base/src/StyleSheetList.h +++ b/content/base/src/StyleSheetList.h @@ -4,20 +4,21 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_StyleSheetList_h #define mozilla_dom_StyleSheetList_h #include "nsIDOMStyleSheetList.h" #include "nsWrapperCache.h" -class nsCSSStyleSheet; class nsINode; namespace mozilla { +class CSSStyleSheet; + namespace dom { class StyleSheetList : public nsIDOMStyleSheetList , public nsWrapperCache { public: StyleSheetList() { @@ -29,18 +30,18 @@ public: NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(StyleSheetList) NS_DECL_NSIDOMSTYLESHEETLIST virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE MOZ_FINAL; virtual nsINode* GetParentObject() const = 0; virtual uint32_t Length() = 0; - virtual nsCSSStyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) = 0; - nsCSSStyleSheet* Item(uint32_t aIndex) + virtual CSSStyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) = 0; + CSSStyleSheet* Item(uint32_t aIndex) { bool dummy = false; return IndexedGetter(aIndex, dummy); } }; } // namespace dom } // namespace mozilla
--- a/content/base/src/WebSocket.cpp +++ b/content/base/src/WebSocket.cpp @@ -860,24 +860,21 @@ WebSocket::CreateAndDispatchMessageEvent bool isBinary) { NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread"); nsresult rv = CheckInnerWindowCorrectness(); if (NS_FAILED(rv)) return NS_OK; - nsCOMPtr<nsIGlobalObject> globalObject = do_QueryInterface(GetOwner()); - if (NS_WARN_IF(!globalObject)) { + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.InitUsingWin(GetOwner()))) { return NS_ERROR_FAILURE; } - - AutoJSAPI jsapi; JSContext* cx = jsapi.cx(); - JSAutoCompartment ac(cx, globalObject->GetGlobalJSObject()); // Create appropriate JS object for message JS::Rooted<JS::Value> jsData(cx); if (isBinary) { if (mBinaryType == dom::BinaryType::Blob) { rv = nsContentUtils::CreateBlobBuffer(cx, aData, &jsData); NS_ENSURE_SUCCESS(rv, rv); } else if (mBinaryType == dom::BinaryType::Arraybuffer) {
--- a/content/base/src/nsContentSink.cpp +++ b/content/base/src/nsContentSink.cpp @@ -202,17 +202,17 @@ nsContentSink::Init(nsIDocument* aDoc, mDynamicLowerValue = sEnablePerfMode == 1; FavorPerformanceHint(!mDynamicLowerValue, 0); } return NS_OK; } NS_IMETHODIMP -nsContentSink::StyleSheetLoaded(nsCSSStyleSheet* aSheet, +nsContentSink::StyleSheetLoaded(CSSStyleSheet* aSheet, bool aWasAlternate, nsresult aStatus) { NS_ASSERTION(!mRunsToCompletion, "How come a fragment parser observed sheets?"); if (!aWasAlternate) { NS_ASSERTION(mPendingSheetCount > 0, "How'd that happen?"); --mPendingSheetCount;
--- a/content/base/src/nsContentSink.h +++ b/content/base/src/nsContentSink.h @@ -81,17 +81,18 @@ class nsContentSink : public nsICSSLoade { NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsContentSink, nsICSSLoaderObserver) // nsITimerCallback NS_DECL_NSITIMERCALLBACK // nsICSSLoaderObserver - NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet, bool aWasAlternate, + NS_IMETHOD StyleSheetLoaded(mozilla::CSSStyleSheet* aSheet, + bool aWasAlternate, nsresult aStatus) MOZ_OVERRIDE; virtual nsresult ProcessMETATag(nsIContent* aContent); // nsIContentSink implementation helpers nsresult WillParseImpl(void); nsresult WillInterruptImpl(void); nsresult WillResumeImpl(void);
--- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -6406,25 +6406,22 @@ nsContentUtils::GetContentSecurityPolicy } // static bool nsContentUtils::IsPatternMatching(nsAString& aValue, nsAString& aPattern, nsIDocument* aDocument) { NS_ASSERTION(aDocument, "aDocument should be a valid pointer (not null)"); - nsCOMPtr<nsIGlobalObject> globalObject = - do_QueryInterface(aDocument->GetWindow()); - if (NS_WARN_IF(!globalObject)) { - return true; - } AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.InitUsingWin(aDocument->GetWindow()))) { + return true; + } JSContext* cx = jsapi.cx(); - JSAutoCompartment ac(cx, globalObject->GetGlobalJSObject()); // The pattern has to match the entire value. aPattern.Insert(NS_LITERAL_STRING("^(?:"), 0); aPattern.AppendLiteral(")$"); JS::Rooted<JSObject*> re(cx, JS_NewUCRegExpObjectNoStatics(cx, static_cast<jschar*>(aPattern.BeginWriting()),
--- a/content/base/src/nsDOMDataChannel.cpp +++ b/content/base/src/nsDOMDataChannel.cpp @@ -378,24 +378,21 @@ nsDOMDataChannel::DoOnMessageAvailable(c LOG(("DoOnMessageAvailable%s\n",aBinary ? ((mBinaryType == DC_BINARY_TYPE_BLOB) ? " (blob)" : " (binary)") : "")); nsresult rv = CheckInnerWindowCorrectness(); if (NS_FAILED(rv)) { return NS_OK; } - nsCOMPtr<nsIGlobalObject> globalObject = do_QueryInterface(GetOwner()); - if (NS_WARN_IF(!globalObject)) { + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.InitUsingWin(GetOwner()))) { return NS_ERROR_FAILURE; } - - AutoJSAPI jsapi; JSContext* cx = jsapi.cx(); - JSAutoCompartment ac(cx, globalObject->GetGlobalJSObject()); JS::Rooted<JS::Value> jsData(cx); if (aBinary) { if (mBinaryType == DC_BINARY_TYPE_BLOB) { rv = nsContentUtils::CreateBlobBuffer(cx, aData, &jsData); NS_ENSURE_SUCCESS(rv, rv); } else if (mBinaryType == DC_BINARY_TYPE_ARRAYBUFFER) {
--- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -213,16 +213,17 @@ #include "nsIEditor.h" #include "nsIDOMCSSStyleRule.h" #include "mozilla/css/Rule.h" #include "nsIDOMLocation.h" #include "nsIHttpChannelInternal.h" #include "nsISecurityConsoleMessage.h" #include "nsCharSeparatedTokenizer.h" #include "mozilla/dom/XPathEvaluator.h" +#include "mozilla/dom/XPathResult.h" #include "nsIDocumentEncoder.h" #include "nsIDocumentActivity.h" #include "nsIStructuredCloneContainer.h" #include "nsIMutableArray.h" #include "nsContentPermissionHelper.h" #include "mozilla/dom/DOMStringList.h" #include "nsWindowMemoryReporter.h" @@ -756,29 +757,29 @@ nsDOMStyleSheetList::Length() nsCOMPtr<nsIDOMStyleSheet> domss(do_QueryInterface(sheet)); NS_ASSERTION(domss, "All \"normal\" sheets implement nsIDOMStyleSheet"); } #endif } return mLength; } -nsCSSStyleSheet* +CSSStyleSheet* nsDOMStyleSheetList::IndexedGetter(uint32_t aIndex, bool& aFound) { if (!mDocument || aIndex >= (uint32_t)mDocument->GetNumberOfStyleSheets()) { aFound = false; return nullptr; } aFound = true; nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(aIndex); NS_ASSERTION(sheet, "Must have a sheet"); - return static_cast<nsCSSStyleSheet*>(sheet); + return static_cast<CSSStyleSheet*>(sheet); } void nsDOMStyleSheetList::NodeWillBeDestroyed(const nsINode *aNode) { mDocument = nullptr; } @@ -3965,29 +3966,29 @@ nsDocument::RemoveChildAt(uint32_t aInde DestroyElementMaps(); } doRemoveChildAt(aIndex, aNotify, oldKid, mChildren); mCachedRootElement = nullptr; } void -nsDocument::EnsureOnDemandBuiltInUASheet(nsCSSStyleSheet* aSheet) +nsDocument::EnsureOnDemandBuiltInUASheet(CSSStyleSheet* aSheet) { // Contains() takes nsISupport*, so annoyingly we have to cast here if (mOnDemandBuiltInUASheets.Contains(static_cast<nsIStyleSheet*>(aSheet))) { return; } BeginUpdate(UPDATE_STYLE); AddOnDemandBuiltInUASheet(aSheet); EndUpdate(UPDATE_STYLE); } void -nsDocument::AddOnDemandBuiltInUASheet(nsCSSStyleSheet* aSheet) +nsDocument::AddOnDemandBuiltInUASheet(CSSStyleSheet* aSheet) { // Contains() takes nsISupport*, so annoyingly we have to cast here MOZ_ASSERT(!mOnDemandBuiltInUASheets.Contains(static_cast<nsIStyleSheet*>(aSheet))); // Prepend here so that we store the sheets in mOnDemandBuiltInUASheets in // the same order that they should end up in the style set. mOnDemandBuiltInUASheets.InsertElementAt(0, aSheet); @@ -4275,17 +4276,17 @@ nsDocument::LoadAdditionalStyleSheet(add // Checking if we have loaded this one already. if (FindSheet(mAdditionalSheets[aType], aSheetURI) >= 0) return NS_ERROR_INVALID_ARG; // Loading the sheet sync. nsRefPtr<mozilla::css::Loader> loader = new mozilla::css::Loader(); - nsRefPtr<nsCSSStyleSheet> sheet; + nsRefPtr<CSSStyleSheet> sheet; nsresult rv = loader->LoadSheetSync(aSheetURI, aType == eAgentSheet, true, getter_AddRefs(sheet)); NS_ENSURE_SUCCESS(rv, rv); mAdditionalSheets[aType].AppendObject(sheet); sheet->SetOwningDocument(this); MOZ_ASSERT(sheet->IsApplicable()); @@ -9326,17 +9327,17 @@ namespace { /** * Stub for LoadSheet(), since all we want is to get the sheet into * the CSSLoader's style cache */ class StubCSSLoaderObserver MOZ_FINAL : public nsICSSLoaderObserver { public: NS_IMETHOD - StyleSheetLoaded(nsCSSStyleSheet*, bool, nsresult) + StyleSheetLoaded(CSSStyleSheet*, bool, nsresult) { return NS_OK; } NS_DECL_ISUPPORTS }; NS_IMPL_ISUPPORTS(StubCSSLoaderObserver, nsICSSLoaderObserver) } @@ -9352,17 +9353,17 @@ nsDocument::PreloadStyle(nsIURI* uri, co CSSLoader()->LoadSheet(uri, NodePrincipal(), NS_LossyConvertUTF16toASCII(charset), obs, Element::StringToCORSMode(aCrossOriginAttr)); } nsresult nsDocument::LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet, - nsCSSStyleSheet** sheet) + CSSStyleSheet** sheet) { return CSSLoader()->LoadSheetSync(uri, isAgentSheet, isAgentSheet, sheet); } class nsDelayedEventDispatcher : public nsRunnable { public: nsDelayedEventDispatcher(nsTArray<nsCOMPtr<nsIDocument> >& aDocuments) @@ -9701,37 +9702,37 @@ nsIDocument::CreateStaticClone(nsIDocShe clonedDoc = static_cast<nsDocument*>(tmp.get()); if (IsStaticDocument()) { clonedDoc->mOriginalDocument = mOriginalDocument; } else { clonedDoc->mOriginalDocument = this; } int32_t sheetsCount = GetNumberOfStyleSheets(); for (int32_t i = 0; i < sheetsCount; ++i) { - nsRefPtr<nsCSSStyleSheet> sheet = do_QueryObject(GetStyleSheetAt(i)); + nsRefPtr<CSSStyleSheet> sheet = do_QueryObject(GetStyleSheetAt(i)); if (sheet) { if (sheet->IsApplicable()) { - nsRefPtr<nsCSSStyleSheet> clonedSheet = + nsRefPtr<CSSStyleSheet> clonedSheet = sheet->Clone(nullptr, nullptr, clonedDoc, nullptr); NS_WARN_IF_FALSE(clonedSheet, "Cloning a stylesheet didn't work!"); if (clonedSheet) { clonedDoc->AddStyleSheet(clonedSheet); } } } } sheetsCount = thisAsDoc->mOnDemandBuiltInUASheets.Count(); // Iterate backwards to maintain order for (int32_t i = sheetsCount - 1; i >= 0; --i) { - nsRefPtr<nsCSSStyleSheet> sheet = + nsRefPtr<CSSStyleSheet> sheet = do_QueryObject(thisAsDoc->mOnDemandBuiltInUASheets[i]); if (sheet) { if (sheet->IsApplicable()) { - nsRefPtr<nsCSSStyleSheet> clonedSheet = + nsRefPtr<CSSStyleSheet> clonedSheet = sheet->Clone(nullptr, nullptr, clonedDoc, nullptr); NS_WARN_IF_FALSE(clonedSheet, "Cloning a stylesheet didn't work!"); if (clonedSheet) { clonedDoc->AddOnDemandBuiltInUASheet(clonedSheet); } } } } @@ -12099,23 +12100,24 @@ nsIDocument::CreateExpression(const nsAS already_AddRefed<nsIDOMXPathNSResolver> nsIDocument::CreateNSResolver(nsINode* aNodeResolver, ErrorResult& rv) { return XPathEvaluator()->CreateNSResolver(aNodeResolver, rv); } -already_AddRefed<nsISupports> -nsIDocument::Evaluate(const nsAString& aExpression, nsINode* aContextNode, - nsIDOMXPathNSResolver* aResolver, uint16_t aType, - nsISupports* aResult, ErrorResult& rv) -{ - return XPathEvaluator()->Evaluate(aExpression, aContextNode, aResolver, aType, - aResult, rv); +already_AddRefed<XPathResult> +nsIDocument::Evaluate(JSContext* aCx, const nsAString& aExpression, + nsINode* aContextNode, nsIDOMXPathNSResolver* aResolver, + uint16_t aType, JS::Handle<JSObject*> aResult, + ErrorResult& rv) +{ + return XPathEvaluator()->Evaluate(aCx, aExpression, aContextNode, aResolver, + aType, aResult, rv); } NS_IMETHODIMP nsDocument::CreateExpression(const nsAString& aExpression, nsIDOMXPathNSResolver* aResolver, nsIDOMXPathExpression** aResult) { return XPathEvaluator()->CreateExpression(aExpression, aResolver, aResult);
--- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -452,17 +452,18 @@ public: NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED virtual nsINode* GetParentObject() const MOZ_OVERRIDE { return mDocument; } virtual uint32_t Length() MOZ_OVERRIDE; - virtual nsCSSStyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) MOZ_OVERRIDE; + virtual mozilla::CSSStyleSheet* + IndexedGetter(uint32_t aIndex, bool& aFound) MOZ_OVERRIDE; protected: int32_t mLength; nsIDocument* mDocument; }; class nsOnloadBlocker MOZ_FINAL : public nsIRequest { @@ -775,17 +776,17 @@ public: virtual mozilla::dom::AnimationTimeline* Timeline() MOZ_OVERRIDE; virtual nsresult SetSubDocumentFor(Element* aContent, nsIDocument* aSubDoc) MOZ_OVERRIDE; virtual nsIDocument* GetSubDocumentFor(nsIContent* aContent) const MOZ_OVERRIDE; virtual Element* FindContentForSubDocument(nsIDocument *aDocument) const MOZ_OVERRIDE; virtual Element* GetRootElementInternal() const MOZ_OVERRIDE; - virtual void EnsureOnDemandBuiltInUASheet(nsCSSStyleSheet* aSheet) MOZ_OVERRIDE; + virtual void EnsureOnDemandBuiltInUASheet(mozilla::CSSStyleSheet* aSheet) MOZ_OVERRIDE; /** * Get the (document) style sheets owned by this document. * These are ordered, highest priority last */ virtual int32_t GetNumberOfStyleSheets() const MOZ_OVERRIDE; virtual nsIStyleSheet* GetStyleSheetAt(int32_t aIndex) const MOZ_OVERRIDE; virtual int32_t GetIndexOfStyleSheet(nsIStyleSheet* aSheet) const MOZ_OVERRIDE; @@ -927,17 +928,17 @@ public: // for radio group nsRadioGroupStruct* GetRadioGroup(const nsAString& aName) const; nsRadioGroupStruct* GetOrCreateRadioGroup(const nsAString& aName); virtual nsViewportInfo GetViewportInfo(const mozilla::ScreenIntSize& aDisplaySize) MOZ_OVERRIDE; private: - void AddOnDemandBuiltInUASheet(nsCSSStyleSheet* aSheet); + void AddOnDemandBuiltInUASheet(mozilla::CSSStyleSheet* aSheet); nsRadioGroupStruct* GetRadioGroupInternal(const nsAString& aName) const; void SendToConsole(nsCOMArray<nsISecurityConsoleMessage>& aMessages); public: // nsIDOMNode NS_FORWARD_NSIDOMNODE_TO_NSINODE_OVERRIDABLE // nsIDOMDocument @@ -1075,17 +1076,17 @@ public: virtual void MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr) MOZ_OVERRIDE; virtual void PreloadStyle(nsIURI* uri, const nsAString& charset, const nsAString& aCrossOriginAttr) MOZ_OVERRIDE; virtual nsresult LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet, - nsCSSStyleSheet** sheet) MOZ_OVERRIDE; + mozilla::CSSStyleSheet** sheet) MOZ_OVERRIDE; virtual nsISupports* GetCurrentContentSink() MOZ_OVERRIDE; virtual mozilla::EventStates GetDocumentState() MOZ_OVERRIDE; virtual void RegisterHostObjectUri(const nsACString& aUri) MOZ_OVERRIDE; virtual void UnregisterHostObjectUri(const nsACString& aUri) MOZ_OVERRIDE;
--- a/content/base/src/nsFrameLoader.cpp +++ b/content/base/src/nsFrameLoader.cpp @@ -2064,24 +2064,33 @@ nsFrameLoader::TryRemoteBrowser() return false; } nsCOMPtr<nsPIDOMWindow> parentWin = doc->GetWindow(); if (!parentWin) { return false; } - nsCOMPtr<nsIDocShellTreeItem> parentAsItem(parentWin->GetDocShell()); - if (!parentAsItem) { + nsCOMPtr<nsIDocShell> parentDocShell = parentWin->GetDocShell(); + if (!parentDocShell) { return false; } + TabParent* openingTab = static_cast<TabParent*>(parentDocShell->GetOpener()); + ContentParent* openerContentParent = nullptr; + + if (openingTab && + openingTab->Manager() && + openingTab->Manager()->IsContentParent()) { + openerContentParent = openingTab->Manager()->AsContentParent(); + } + // <iframe mozbrowser> gets to skip these checks. if (!OwnerIsBrowserOrAppFrame()) { - if (parentAsItem->ItemType() != nsIDocShellTreeItem::typeChrome) { + if (parentDocShell->ItemType() != nsIDocShellTreeItem::typeChrome) { return false; } if (!mOwnerContent->IsXUL()) { return false; } nsAutoString value; @@ -2091,17 +2100,17 @@ nsFrameLoader::TryRemoteBrowser() !StringBeginsWith(value, NS_LITERAL_STRING("content-"), nsCaseInsensitiveStringComparator())) { return false; } } uint32_t chromeFlags = 0; nsCOMPtr<nsIDocShellTreeOwner> parentOwner; - if (NS_FAILED(parentAsItem->GetTreeOwner(getter_AddRefs(parentOwner))) || + if (NS_FAILED(parentDocShell->GetTreeOwner(getter_AddRefs(parentOwner))) || !parentOwner) { return false; } nsCOMPtr<nsIXULWindow> window(do_GetInterface(parentOwner)); if (window && NS_FAILED(window->GetChromeFlags(&chromeFlags))) { return false; } @@ -2128,21 +2137,21 @@ nsFrameLoader::TryRemoteBrowser() // The |else| above is unnecessary; OwnerIsBrowserFrame() implies !ownApp. rv = context.SetTabContextForBrowserFrame(containingApp, scrollingBehavior); } else { rv = context.SetTabContextForNormalFrame(scrollingBehavior); } NS_ENSURE_TRUE(rv, false); nsCOMPtr<Element> ownerElement = mOwnerContent; - mRemoteBrowser = ContentParent::CreateBrowserOrApp(context, ownerElement); + mRemoteBrowser = ContentParent::CreateBrowserOrApp(context, ownerElement, openerContentParent); if (mRemoteBrowser) { mChildID = mRemoteBrowser->Manager()->ChildID(); nsCOMPtr<nsIDocShellTreeItem> rootItem; - parentAsItem->GetRootTreeItem(getter_AddRefs(rootItem)); + parentDocShell->GetRootTreeItem(getter_AddRefs(rootItem)); nsCOMPtr<nsIDOMWindow> rootWin = rootItem->GetWindow(); nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(rootWin); if (rootChromeWin) { nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin; rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin)); mRemoteBrowser->SetBrowserDOMWindow(browserDOMWin); } @@ -2150,16 +2159,17 @@ nsFrameLoader::TryRemoteBrowser() mContentParent = mRemoteBrowser->Manager(); if (mOwnerContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::mozpasspointerevents, nsGkAtoms::_true, eCaseMatters)) { unused << mRemoteBrowser->SendSetUpdateHitRegion(true); } + parentDocShell->SetOpenedRemote(mRemoteBrowser); } return true; } mozilla::dom::PBrowserParent* nsFrameLoader::GetRemoteBrowser() { return mRemoteBrowser;
--- a/content/base/src/nsScriptLoader.cpp +++ b/content/base/src/nsScriptLoader.cpp @@ -882,26 +882,23 @@ nsScriptLoader::AttemptAsyncScriptParse( return NS_ERROR_FAILURE; } nsCOMPtr<nsIScriptGlobalObject> globalObject = GetScriptGlobalObject(); if (!globalObject) { return NS_ERROR_FAILURE; } - nsCOMPtr<nsIScriptContext> context = globalObject->GetScriptContext(); - if (!context) { + AutoJSAPI jsapi; + if (!jsapi.InitWithLegacyErrorReporting(globalObject)) { return NS_ERROR_FAILURE; } - AutoJSAPIWithErrorsReportedToWindow jsapi(context); JSContext* cx = jsapi.cx(); JS::Rooted<JSObject*> global(cx, globalObject->GetGlobalJSObject()); - JSAutoCompartment ac(cx, global); - JS::CompileOptions options(cx); FillCompileOptionsForRequest(aRequest, global, &options); if (!JS::CanCompileOffThread(cx, options, aRequest->mScriptTextLength)) { return NS_ERROR_FAILURE; } nsRefPtr<NotifyOffThreadScriptLoadCompletedRunnable> runnable =
--- a/content/base/src/nsStyleLinkElement.cpp +++ b/content/base/src/nsStyleLinkElement.cpp @@ -7,22 +7,22 @@ /* * A base class which implements nsIStyleSheetLinkingElement and can * be subclassed by various content nodes that want to load * stylesheets (<style>, <link>, processing instructions, etc). */ #include "nsStyleLinkElement.h" +#include "mozilla/CSSStyleSheet.h" #include "mozilla/css/Loader.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/FragmentOrElement.h" #include "mozilla/dom/ShadowRoot.h" #include "mozilla/Preferences.h" -#include "nsCSSStyleSheet.h" #include "nsIContent.h" #include "nsIDocument.h" #include "nsIDOMComment.h" #include "nsIDOMNode.h" #include "nsIDOMStyleSheet.h" #include "nsNetUtil.h" #include "nsUnicharUtils.h" #include "nsCRT.h" @@ -55,17 +55,17 @@ nsStyleLinkElement::Unlink() void nsStyleLinkElement::Traverse(nsCycleCollectionTraversalCallback &cb) { nsStyleLinkElement* tmp = this; NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheet); } NS_IMETHODIMP -nsStyleLinkElement::SetStyleSheet(nsCSSStyleSheet* aStyleSheet) +nsStyleLinkElement::SetStyleSheet(CSSStyleSheet* aStyleSheet) { if (mStyleSheet) { mStyleSheet->SetOwningNode(nullptr); } mStyleSheet = aStyleSheet; if (mStyleSheet) { nsCOMPtr<nsINode> node = do_QueryObject(this); @@ -257,17 +257,17 @@ UpdateIsElementInStyleScopeFlagOnSubtree n = n->GetNextNode(aElement); } } } static Element* GetScopeElement(nsIStyleSheet* aSheet) { - nsRefPtr<nsCSSStyleSheet> cssStyleSheet = do_QueryObject(aSheet); + nsRefPtr<CSSStyleSheet> cssStyleSheet = do_QueryObject(aSheet); if (!cssStyleSheet) { return nullptr; } return cssStyleSheet->GetScopeElement(); } nsresult
--- a/content/base/src/nsStyleLinkElement.h +++ b/content/base/src/nsStyleLinkElement.h @@ -9,21 +9,21 @@ * be subclassed by various content nodes that want to load * stylesheets (<style>, <link>, processing instructions, etc). */ #ifndef nsStyleLinkElement_h___ #define nsStyleLinkElement_h___ #include "mozilla/Attributes.h" +#include "mozilla/CORSMode.h" +#include "mozilla/CSSStyleSheet.h" #include "nsCOMPtr.h" #include "nsIStyleSheetLinkingElement.h" -#include "nsCSSStyleSheet.h" #include "nsTArray.h" -#include "mozilla/CORSMode.h" class nsIDocument; class nsIURI; namespace mozilla { namespace dom { class ShadowRoot; } // namespace dom @@ -32,20 +32,20 @@ class ShadowRoot; class nsStyleLinkElement : public nsIStyleSheetLinkingElement { public: nsStyleLinkElement(); virtual ~nsStyleLinkElement(); NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) MOZ_OVERRIDE = 0; - nsCSSStyleSheet* GetSheet() const { return mStyleSheet; } + mozilla::CSSStyleSheet* GetSheet() const { return mStyleSheet; } // nsIStyleSheetLinkingElement - NS_IMETHOD SetStyleSheet(nsCSSStyleSheet* aStyleSheet) MOZ_OVERRIDE; + NS_IMETHOD SetStyleSheet(mozilla::CSSStyleSheet* aStyleSheet) MOZ_OVERRIDE; NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aStyleSheet) MOZ_OVERRIDE; NS_IMETHOD InitStyleLinkElement(bool aDontLoadStyle) MOZ_OVERRIDE; NS_IMETHOD UpdateStyleSheet(nsICSSLoaderObserver* aObserver, bool* aWillNotify, bool* aIsAlternate) MOZ_OVERRIDE; NS_IMETHOD SetEnableUpdates(bool aEnableUpdates) MOZ_OVERRIDE; NS_IMETHOD GetCharset(nsAString& aCharset) MOZ_OVERRIDE; @@ -117,17 +117,17 @@ private: */ nsresult DoUpdateStyleSheet(nsIDocument* aOldDocument, mozilla::dom::ShadowRoot* aOldShadowRoot, nsICSSLoaderObserver* aObserver, bool* aWillNotify, bool* aIsAlternate, bool aForceUpdate); - nsRefPtr<nsCSSStyleSheet> mStyleSheet; + nsRefPtr<mozilla::CSSStyleSheet> mStyleSheet; protected: bool mDontLoadStyle; bool mUpdatesEnabled; uint32_t mLineNumber; }; #endif /* nsStyleLinkElement_h___ */
--- a/content/base/src/nsTreeSanitizer.cpp +++ b/content/base/src/nsTreeSanitizer.cpp @@ -1,24 +1,24 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set sw=2 ts=2 et tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "mozilla/ArrayUtils.h" +#include "nsTreeSanitizer.h" -#include "nsTreeSanitizer.h" -#include "nsCSSParser.h" -#include "nsCSSProperty.h" +#include "mozilla/ArrayUtils.h" +#include "mozilla/CSSStyleSheet.h" #include "mozilla/css/Declaration.h" #include "mozilla/css/StyleRule.h" #include "mozilla/css/Rule.h" +#include "nsCSSParser.h" +#include "nsCSSProperty.h" #include "nsUnicharInputStream.h" -#include "nsCSSStyleSheet.h" #include "nsIDOMCSSRule.h" #include "nsAttrName.h" #include "nsIScriptSecurityManager.h" #include "nsNetUtil.h" #include "nsComponentManagerUtils.h" #include "nsNullPrincipal.h" #include "nsContentUtils.h" #include "nsIParserUtils.h" @@ -1093,17 +1093,17 @@ nsTreeSanitizer::SanitizeStyleSheet(cons nsIURI* aBaseURI) { nsresult rv; aSanitized.Truncate(); // aSanitized will hold the permitted CSS text. // -moz-binding is blacklisted. bool didSanitize = false; // Create a sheet to hold the parsed CSS - nsRefPtr<nsCSSStyleSheet> sheet = new nsCSSStyleSheet(CORS_NONE); + nsRefPtr<CSSStyleSheet> sheet = new CSSStyleSheet(CORS_NONE); sheet->SetURIs(aDocument->GetDocumentURI(), nullptr, aBaseURI); sheet->SetPrincipal(aDocument->NodePrincipal()); // Create the CSS parser, and parse the CSS text. nsCSSParser parser(nullptr, sheet); rv = parser.ParseSheet(aOriginal, aDocument->GetDocumentURI(), aBaseURI, aDocument->NodePrincipal(), 0, false); NS_ENSURE_SUCCESS(rv, true); // Mark the sheet as complete.
--- a/content/canvas/src/CanvasRenderingContext2D.cpp +++ b/content/canvas/src/CanvasRenderingContext2D.cpp @@ -2320,17 +2320,16 @@ CanvasRenderingContext2D::SetFont(const gfxFontStyle style(fontStyle->mFont.style, fontStyle->mFont.weight, fontStyle->mFont.stretch, NSAppUnitsToFloatPixels(fontStyle->mSize, float(aupcp)), language, fontStyle->mFont.sizeAdjust, fontStyle->mFont.systemFont, printerFont, - fontStyle->mFont.variant == NS_STYLE_FONT_VARIANT_SMALL_CAPS, fontStyle->mFont.synthesis & NS_FONT_SYNTHESIS_WEIGHT, fontStyle->mFont.synthesis & NS_FONT_SYNTHESIS_STYLE, fontStyle->mFont.languageOverride); fontStyle->mFont.AddFontFeaturesToStyle(&style); nsPresContext *c = presShell->GetPresContext(); CurrentState().fontGroup =
--- a/content/canvas/src/ImageEncoder.cpp +++ b/content/canvas/src/ImageEncoder.cpp @@ -258,16 +258,20 @@ ImageEncoder::ExtractDataInternal(const const nsAString& aOptions, uint8_t* aImageBuffer, int32_t aFormat, const nsIntSize aSize, nsICanvasRenderingContextInternal* aContext, nsIInputStream** aStream, imgIEncoder* aEncoder) { + if (aSize.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + nsCOMPtr<nsIInputStream> imgStream; // get image bytes nsresult rv; if (aImageBuffer) { rv = ImageEncoder::GetInputStream( aSize.width, aSize.height,
--- a/content/canvas/src/WebGLElementArrayCache.cpp +++ b/content/canvas/src/WebGLElementArrayCache.cpp @@ -2,16 +2,17 @@ /* 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 "WebGLElementArrayCache.h" #include "mozilla/Assertions.h" #include "mozilla/MemoryReporting.h" +#include "mozilla/MathAlgorithms.h" #include <cstdlib> #include <cstring> #include <limits> #include <algorithm> namespace mozilla { @@ -288,26 +289,16 @@ public: } // walk up 1 level firstTreeIndex = ParentNode(firstTreeIndex); lastTreeIndex = ParentNode(lastTreeIndex); } } - template<typename U> - static U NextPowerOfTwo(U x) { - U result = 1; - while (result < x) - result <<= 1; - MOZ_ASSERT(result >= x); - MOZ_ASSERT((result & (result - 1)) == 0); - return result; - } - // Updates the tree from the parent's buffer contents. Fallible, as it // may have to resize the tree storage. bool Update(size_t firstByte, size_t lastByte); size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { return aMallocSizeOf(this) + mTreeData.SizeOfExcludingThis(aMallocSizeOf); } @@ -360,17 +351,17 @@ bool WebGLElementArrayCacheTree<T>::Upda // it would just be equal to // // ceil(numberOfElements / sElementsPerLeaf) // // The way we implement this (division+ceil) operation in integer arithmetic // is as follows: size_t numLeavesNonPOT = (numberOfElements + sElementsPerLeaf - 1) / sElementsPerLeaf; // It only remains to round that up to the next power of two: - requiredNumLeaves = NextPowerOfTwo(numLeavesNonPOT); + requiredNumLeaves = RoundUpPow2(numLeavesNonPOT); } // Step #0: if needed, resize our tree data storage. if (requiredNumLeaves != NumLeaves()) { // see class comment for why we the tree storage size is 2 * numLeaves if (!mTreeData.SetLength(2 * requiredNumLeaves)) { mTreeData.SetLength(0); return false;
--- a/content/html/content/src/HTMLLinkElement.cpp +++ b/content/html/content/src/HTMLLinkElement.cpp @@ -76,35 +76,34 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement) NS_IMPL_ELEMENT_CLONE(HTMLLinkElement) bool HTMLLinkElement::Disabled() { - nsCSSStyleSheet* ss = GetSheet(); + CSSStyleSheet* ss = GetSheet(); return ss && ss->Disabled(); } NS_IMETHODIMP HTMLLinkElement::GetMozDisabled(bool* aDisabled) { *aDisabled = Disabled(); return NS_OK; } void HTMLLinkElement::SetDisabled(bool aDisabled) { - nsCSSStyleSheet* ss = GetSheet(); + CSSStyleSheet* ss = GetSheet(); if (ss) { ss->SetDisabled(aDisabled); } - } NS_IMETHODIMP HTMLLinkElement::SetMozDisabled(bool aDisabled) { SetDisabled(aDisabled); return NS_OK; }
--- a/content/html/content/src/HTMLStyleElement.cpp +++ b/content/html/content/src/HTMLStyleElement.cpp @@ -64,31 +64,31 @@ HTMLStyleElement::GetMozDisabled(bool* a *aDisabled = Disabled(); return NS_OK; } bool HTMLStyleElement::Disabled() { - nsCSSStyleSheet* ss = GetSheet(); + CSSStyleSheet* ss = GetSheet(); return ss && ss->Disabled(); } NS_IMETHODIMP HTMLStyleElement::SetMozDisabled(bool aDisabled) { SetDisabled(aDisabled); return NS_OK; } void HTMLStyleElement::SetDisabled(bool aDisabled) { - nsCSSStyleSheet* ss = GetSheet(); + CSSStyleSheet* ss = GetSheet(); if (ss) { ss->SetDisabled(aDisabled); } } NS_IMPL_STRING_ATTR(HTMLStyleElement, Media, media) NS_IMPL_BOOL_ATTR(HTMLStyleElement, Scoped, scoped) NS_IMPL_STRING_ATTR(HTMLStyleElement, Type, type)
--- a/content/html/content/test/test_bug389797.html +++ b/content/html/content/test/test_bug389797.html @@ -185,16 +185,21 @@ HTML_TAG("object", "Object", [], HTML_TAG("ol", "OList"); HTML_TAG("optgroup", "OptGroup"); HTML_TAG("option", "Option"); HTML_TAG("p", "Paragraph"); HTML_TAG("param", "Param"); HTML_TAG("plaintext", ""); HTML_TAG("pre", "Pre"); HTML_TAG("q", "Quote"); +HTML_TAG("rb", ""); +HTML_TAG("rp", ""); +HTML_TAG("rt", ""); +HTML_TAG("rtc", ""); +HTML_TAG("ruby", ""); HTML_TAG("s", ""); HTML_TAG("samp", ""); HTML_TAG("script", "Script", [ "nsIScriptLoaderObserver" ], []); HTML_TAG("section", "") HTML_TAG("select", "Select", ["nsIDOMHTMLSelectElement"]); HTML_TAG("small", ""); HTML_TAG("span", "Span"); HTML_TAG("strike", "");
--- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -2751,17 +2751,17 @@ nsHTMLDocument::EditingStateChanged() nsCOMArray<nsIStyleSheet> agentSheets; rv = presShell->GetAgentStyleSheets(agentSheets); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIURI> uri; rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_STRING("resource://gre/res/contenteditable.css")); NS_ENSURE_SUCCESS(rv, rv); - nsRefPtr<nsCSSStyleSheet> sheet; + nsRefPtr<CSSStyleSheet> sheet; rv = LoadChromeSheetSync(uri, true, getter_AddRefs(sheet)); NS_ENSURE_TRUE(sheet, rv); bool result = agentSheets.AppendObject(sheet); NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY); // Should we update the editable state of all the nodes in the document? We // need to do this when the designMode value changes, as that overrides
--- a/content/media/AudioNodeEngine.h +++ b/content/media/AudioNodeEngine.h @@ -355,18 +355,20 @@ public: { return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); } void SizeOfIncludingThis(MallocSizeOf aMallocSizeOf, AudioNodeSizes& aUsage) const { aUsage.mEngine = SizeOfIncludingThis(aMallocSizeOf); - aUsage.mDomNode = mNode->SizeOfIncludingThis(aMallocSizeOf); - aUsage.mNodeType = mNode->NodeType(); + if (HasNode()) { + aUsage.mDomNode = mNode->SizeOfIncludingThis(aMallocSizeOf); + aUsage.mNodeType = mNode->NodeType(); + } } private: dom::AudioNode* mNode; Mutex mNodeMutex; const uint16_t mInputCount; const uint16_t mOutputCount; };
--- a/content/media/MediaDecoder.cpp +++ b/content/media/MediaDecoder.cpp @@ -424,16 +424,17 @@ MediaDecoder::MediaDecoder() : mIsDormant(false), mIsExitingDormant(false), mPlayState(PLAY_STATE_PAUSED), mNextState(PLAY_STATE_PAUSED), mCalledResourceLoaded(false), mIgnoreProgressData(false), mInfiniteStream(false), mOwner(nullptr), + mPlaybackStatistics(new MediaChannelStatistics()), mPinnedForSeek(false), mShuttingDown(false), mPausedForPlaybackRateNull(false), mMinimizePreroll(false) { MOZ_COUNT_CTOR(MediaDecoder); MOZ_ASSERT(NS_IsMainThread()); MediaMemoryTracker::AddMediaDecoder(this); @@ -935,17 +936,17 @@ double MediaDecoder::ComputePlaybackRate GetReentrantMonitor().AssertCurrentThreadIn(); MOZ_ASSERT(NS_IsMainThread() || OnStateMachineThread() || OnDecodeThread()); int64_t length = mResource ? mResource->GetLength() : -1; if (mDuration >= 0 && length >= 0) { *aReliable = true; return length * static_cast<double>(USECS_PER_S) / mDuration; } - return mPlaybackStatistics.GetRateAtLastStop(aReliable); + return mPlaybackStatistics->GetRateAtLastStop(aReliable); } void MediaDecoder::UpdatePlaybackRate() { MOZ_ASSERT(NS_IsMainThread() || OnStateMachineThread()); GetReentrantMonitor().AssertCurrentThreadIn(); if (!mResource) return; @@ -1027,17 +1028,17 @@ void MediaDecoder::NotifyBytesConsumed(i } ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); MOZ_ASSERT(mDecoderStateMachine); if (mIgnoreProgressData) { return; } if (aOffset >= mDecoderPosition) { - mPlaybackStatistics.AddBytes(aBytes); + mPlaybackStatistics->AddBytes(aBytes); } mDecoderPosition = aOffset + aBytes; } void MediaDecoder::UpdateReadyStateForData() { MOZ_ASSERT(NS_IsMainThread()); if (!mOwner || mShuttingDown || !mDecoderStateMachine)
--- a/content/media/MediaDecoder.h +++ b/content/media/MediaDecoder.h @@ -713,24 +713,24 @@ public: // Something has changed that could affect the computed playback rate, // so recompute it. The monitor must be held. virtual void UpdatePlaybackRate(); // Used to estimate rates of data passing through the decoder's channel. // Records activity stopping on the channel. The monitor must be held. virtual void NotifyPlaybackStarted() { GetReentrantMonitor().AssertCurrentThreadIn(); - mPlaybackStatistics.Start(); + mPlaybackStatistics->Start(); } // Used to estimate rates of data passing through the decoder's channel. // Records activity stopping on the channel. The monitor must be held. virtual void NotifyPlaybackStopped() { GetReentrantMonitor().AssertCurrentThreadIn(); - mPlaybackStatistics.Stop(); + mPlaybackStatistics->Stop(); } // The actual playback rate computation. The monitor must be held. virtual double ComputePlaybackRate(bool* aReliable); // Return true when the media is same-origin with the element. The monitor // must be held. bool IsSameOriginMedia(); @@ -1189,17 +1189,17 @@ protected: // when data is arriving slower than PROGRESS_MS. A value of null indicates // that a stall event has already fired and not to fire another one until // more data is received. Read/Write from the main thread only. TimeStamp mDataTime; // Data needed to estimate playback data rate. The timeline used for // this estimate is "decode time" (where the "current time" is the // time of the last decoded video frame). - MediaChannelStatistics mPlaybackStatistics; + nsRefPtr<MediaChannelStatistics> mPlaybackStatistics; // True when our media stream has been pinned. We pin the stream // while seeking. bool mPinnedForSeek; // True if the decoder is being shutdown. At this point all events that // are currently queued need to return immediately to prevent javascript // being run that operates on the element and decoder during shutdown.
--- a/content/media/MediaDecoderReader.h +++ b/content/media/MediaDecoderReader.h @@ -16,34 +16,27 @@ namespace mozilla { namespace dom { class TimeRanges; } class RequestSampleCallback; class MediaDecoderReader; -template <> -struct HasDangerousPublicDestructor<MediaDecoderReader> -{ - static const bool value = true; -}; - // Encapsulates the decoding and reading of media data. Reading can either // synchronous and done on the calling "decode" thread, or asynchronous and // performed on a background thread, with the result being returned by // callback. Never hold the decoder monitor when calling into this class. // Unless otherwise specified, methods and fields of this class can only // be accessed on the decode task queue. class MediaDecoderReader { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReader) MediaDecoderReader(AbstractMediaDecoder* aDecoder); - virtual ~MediaDecoderReader(); // Initializes the reader, returns NS_OK on success, or NS_ERROR_FAILURE // on failure. virtual nsresult Init(MediaDecoderReader* aCloneDonor) = 0; // True if this reader is waiting media resource allocation virtual bool IsWaitingMediaResources() { return false; } // True when this reader need to become dormant state @@ -176,16 +169,17 @@ public: } AudioData* DecodeToFirstAudioData(); VideoData* DecodeToFirstVideoData(); MediaInfo GetMediaInfo() { return mInfo; } protected: + virtual ~MediaDecoderReader(); // Overrides of this function should decodes an unspecified amount of // audio data, enqueuing the audio data in mAudioQueue. Returns true // when there's more audio to decode, false if the audio is finished, // end of file has been reached, or an un-recoverable read error has // occured. This function blocks until the decode is complete. virtual bool DecodeAudioData() { return false;
--- a/content/media/MediaResource.h +++ b/content/media/MediaResource.h @@ -33,22 +33,16 @@ static const int64_t RELIABLE_DATA_THRES class nsIHttpChannel; class nsIPrincipal; namespace mozilla { class MediaDecoder; class MediaChannelStatistics; -template<> -struct HasDangerousPublicDestructor<MediaChannelStatistics> -{ - static const bool value = true; -}; - /** * This class is useful for estimating rates of data passing through * some channel. The idea is that activity on the channel "starts" * and "stops" over time. At certain times data passes through the * channel (usually while the channel is active; data passing through * an inactive channel is ignored). The GetRate() function computes * an estimate of the "current rate" of the channel, which is some * kind of average of the data passing through over the time the @@ -114,16 +108,17 @@ public: double seconds = time.ToSeconds(); *aReliable = (seconds >= 3.0) || (mAccumulatedBytes >= RELIABLE_DATA_THRESHOLD); if (seconds <= 0.0) return 0.0; return static_cast<double>(mAccumulatedBytes)/seconds; } private: + ~MediaChannelStatistics() {} int64_t mAccumulatedBytes; TimeDuration mAccumulatedTime; TimeStamp mLastStartTime; bool mIsStarted; }; // Forward declaration for use in MediaByteRange. class TimestampedMediaByteRange;
--- a/content/media/MediaStreamGraph.cpp +++ b/content/media/MediaStreamGraph.cpp @@ -2781,17 +2781,18 @@ MediaStreamGraphImpl::CollectReports(nsI rv = aHandleReport->Callback(EmptyCString(), _path, \ KIND_HEAP, UNITS_BYTES, _amount, \ NS_LITERAL_CSTRING(_desc), aData); \ NS_ENSURE_SUCCESS(rv, rv); \ } while (0) for (size_t i = 0; i < mAudioStreamSizes.Length(); i++) { const AudioNodeSizes& usage = mAudioStreamSizes[i]; - const char* const nodeType = usage.mNodeType.get(); + const char* const nodeType = usage.mNodeType.IsEmpty() ? + "<unknown>" : usage.mNodeType.get(); nsPrintfCString domNodePath("explicit/webaudio/audio-node/%s/dom-nodes", nodeType); REPORT(domNodePath, usage.mDomNode, "Memory used by AudioNode DOM objects (Web Audio)."); nsPrintfCString enginePath("explicit/webaudio/audio-node/%s/engine-objects", nodeType);
--- a/content/media/MediaStreamGraph.h +++ b/content/media/MediaStreamGraph.h @@ -227,16 +227,17 @@ public: virtual void NotifyMainThreadStateChanged() = 0; }; /** * Helper struct used to keep track of memory usage by AudioNodes. */ struct AudioNodeSizes { + AudioNodeSizes() : mDomNode(0), mStream(0), mEngine(0), mNodeType() {} size_t mDomNode; size_t mStream; size_t mEngine; nsCString mNodeType; }; class MediaStreamGraphImpl; class SourceMediaStream;
--- a/content/media/fmp4/ffmpeg/FFmpegDataDecoder.cpp +++ b/content/media/fmp4/ffmpeg/FFmpegDataDecoder.cpp @@ -82,16 +82,19 @@ FFmpegDataDecoder::Init() mCodecContext.opaque = this; // FFmpeg takes this as a suggestion for what format to use for audio samples. mCodecContext.request_sample_fmt = AV_SAMPLE_FMT_FLT; // FFmpeg will call back to this to negotiate a video pixel format. mCodecContext.get_format = ChoosePixelFormat; + mCodecContext.extradata = mExtraData.begin(); + mCodecContext.extradata_size = mExtraData.length(); + AVDictionary* opts = nullptr; if (avcodec_open2(&mCodecContext, codec, &opts) < 0) { NS_WARNING("Couldn't initialise ffmpeg decoder"); return NS_ERROR_FAILURE; } if (mCodecContext.codec_type == AVMEDIA_TYPE_AUDIO && mCodecContext.sample_fmt != AV_SAMPLE_FMT_FLT &&
--- a/content/media/fmp4/ffmpeg/FFmpegDataDecoder.h +++ b/content/media/fmp4/ffmpeg/FFmpegDataDecoder.h @@ -5,16 +5,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef __FFmpegDataDecoder_h__ #define __FFmpegDataDecoder_h__ #include "FFmpegDecoderModule.h" #include "FFmpegRuntimeLinker.h" #include "FFmpegCompat.h" +#include "mozilla/Vector.h" namespace mozilla { class FFmpegDataDecoder : public MediaDataDecoder { public: FFmpegDataDecoder(MediaTaskQueue* aTaskQueue, AVCodecID aCodecID); @@ -26,16 +27,17 @@ public: virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) = 0; virtual nsresult Flush() MOZ_OVERRIDE; virtual nsresult Drain() = 0; virtual nsresult Shutdown() MOZ_OVERRIDE; protected: MediaTaskQueue* mTaskQueue; AVCodecContext mCodecContext; + Vector<uint8_t> mExtraData; private: static bool sFFmpegInitDone; AVCodecID mCodecID; }; } // namespace mozilla
--- a/content/media/fmp4/ffmpeg/FFmpegH264Decoder.cpp +++ b/content/media/fmp4/ffmpeg/FFmpegH264Decoder.cpp @@ -28,16 +28,17 @@ FFmpegH264Decoder::FFmpegH264Decoder( MediaTaskQueue* aTaskQueue, MediaDataDecoderCallback* aCallback, const mp4_demuxer::VideoDecoderConfig &aConfig, ImageContainer* aImageContainer) : FFmpegDataDecoder(aTaskQueue, AV_CODEC_ID_H264) , mCallback(aCallback) , mImageContainer(aImageContainer) { MOZ_COUNT_CTOR(FFmpegH264Decoder); + mExtraData.append(aConfig.extra_data.begin(), aConfig.extra_data.length()); } nsresult FFmpegH264Decoder::Init() { nsresult rv = FFmpegDataDecoder::Init(); NS_ENSURE_SUCCESS(rv, rv);
--- a/content/media/fmp4/wmf/WMFAudioOutputSource.cpp +++ b/content/media/fmp4/wmf/WMFAudioOutputSource.cpp @@ -1,15 +1,16 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* 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 "WMFAudioOutputSource.h" +#include "mp4_demuxer/DecoderData.h" #include "VideoUtils.h" #include "WMFUtils.h" #include "nsTArray.h" #include "prlog.h" #ifdef PR_LOGGING PRLogModuleInfo* GetDemuxerLog(); @@ -123,16 +124,24 @@ WMFAudioOutputSource::Init() NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); mDecoder = decoder; return decoder.forget(); } HRESULT +WMFAudioOutputSource::Input(mp4_demuxer::MP4Sample* aSample) +{ + const uint8_t* data = reinterpret_cast<const uint8_t*>(aSample->data); + uint32_t length = aSample->size; + return mDecoder->Input(data, length, aSample->composition_timestamp); +} + +HRESULT WMFAudioOutputSource::Output(int64_t aStreamOffset, nsAutoPtr<MediaData>& aOutData) { aOutData = nullptr; RefPtr<IMFSample> sample; HRESULT hr = mDecoder->Output(&sample); if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { return MF_E_TRANSFORM_NEED_MORE_INPUT;
--- a/content/media/fmp4/wmf/WMFAudioOutputSource.h +++ b/content/media/fmp4/wmf/WMFAudioOutputSource.h @@ -17,16 +17,18 @@ namespace mozilla { class WMFAudioOutputSource : public WMFOutputSource { public: WMFAudioOutputSource(const mp4_demuxer::AudioDecoderConfig& aConfig); ~WMFAudioOutputSource(); virtual TemporaryRef<MFTDecoder> Init() MOZ_OVERRIDE; + virtual HRESULT Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE; + // Note WMF's AAC decoder sometimes output negatively timestamped samples, // presumably they're the preroll samples, and we strip them. We may return // a null aOutput in this case. virtual HRESULT Output(int64_t aStreamOffset, nsAutoPtr<MediaData>& aOutput) MOZ_OVERRIDE; private: // IMFTransform wrapper that performs the decoding.
--- a/content/media/fmp4/wmf/WMFDecoderModule.cpp +++ b/content/media/fmp4/wmf/WMFDecoderModule.cpp @@ -65,17 +65,18 @@ WMFDecoderModule::Shutdown() MediaDataDecoder* WMFDecoderModule::CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConfig, mozilla::layers::LayersBackend aLayersBackend, mozilla::layers::ImageContainer* aImageContainer, MediaTaskQueue* aVideoTaskQueue, MediaDataDecoderCallback* aCallback) { - return new WMFMediaDataDecoder(new WMFVideoOutputSource(aLayersBackend, + return new WMFMediaDataDecoder(new WMFVideoOutputSource(aConfig, + aLayersBackend, aImageContainer, sDXVAEnabled), aVideoTaskQueue, aCallback); } MediaDataDecoder* WMFDecoderModule::CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
--- a/content/media/fmp4/wmf/WMFMediaDataDecoder.cpp +++ b/content/media/fmp4/wmf/WMFMediaDataDecoder.cpp @@ -62,21 +62,19 @@ WMFMediaDataDecoder::Input(mp4_demuxer:: &WMFMediaDataDecoder::ProcessDecode, nsAutoPtr<mp4_demuxer::MP4Sample>(aSample))); return NS_OK; } void WMFMediaDataDecoder::ProcessDecode(mp4_demuxer::MP4Sample* aSample) { - const uint8_t* data = reinterpret_cast<const uint8_t*>(aSample->data); - uint32_t length = aSample->size; - HRESULT hr = mDecoder->Input(data, length, aSample->composition_timestamp); + HRESULT hr = mSource->Input(aSample); if (FAILED(hr)) { - NS_WARNING("WMFAudioDecoder failed to input data"); + NS_WARNING("WMFOutputSource rejected sample"); mCallback->Error(); return; } mLastStreamOffset = aSample->byte_offset; ProcessOutput(); }
--- a/content/media/fmp4/wmf/WMFMediaDataDecoder.h +++ b/content/media/fmp4/wmf/WMFMediaDataDecoder.h @@ -8,29 +8,36 @@ #define WMFMediaDataDecoder_h_ #include "WMF.h" #include "MP4Reader.h" #include "MFTDecoder.h" #include "mozilla/RefPtr.h" +class mp4_demuxer::MP4Sample; + namespace mozilla { // Encapsulates the initialization of the MFTDecoder appropriate for decoding // a given stream, and the process of converting the IMFSample produced // by the MFT into a MediaData object. class WMFOutputSource { public: virtual ~WMFOutputSource() {} // Creates an initializs the MFTDecoder. // Returns nullptr on failure. virtual TemporaryRef<MFTDecoder> Init() = 0; + // Submit a compressed sample for decoding. + // This should forward to the MFTDecoder after performing + // any required sample formatting. + virtual HRESULT Input(mp4_demuxer::MP4Sample* aSample) = 0; + // Produces decoded output, if possible. Blocks until output can be produced, // or until no more is able to be produced. // Returns S_OK on success, or MF_E_TRANSFORM_NEED_MORE_INPUT if there's not // enough data to produce more output. If this returns a failure code other // than MF_E_TRANSFORM_NEED_MORE_INPUT, an error will be reported to the // MP4Reader. virtual HRESULT Output(int64_t aStreamOffset, nsAutoPtr<MediaData>& aOutput) = 0;
--- a/content/media/fmp4/wmf/WMFVideoOutputSource.cpp +++ b/content/media/fmp4/wmf/WMFVideoOutputSource.cpp @@ -8,16 +8,18 @@ #include "MediaDecoderReader.h" #include "WMFUtils.h" #include "ImageContainer.h" #include "VideoUtils.h" #include "DXVA2Manager.h" #include "nsThreadUtils.h" #include "Layers.h" #include "mozilla/layers/LayersTypes.h" +#include "mp4_demuxer/AnnexB.h" +#include "mp4_demuxer/DecoderData.h" #include "prlog.h" #include "gfx2DGlue.h" #ifdef PR_LOGGING PRLogModuleInfo* GetDemuxerLog(); #define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__)) #else #define LOG(...) @@ -25,22 +27,25 @@ PRLogModuleInfo* GetDemuxerLog(); using mozilla::gfx::ToIntRect; using mozilla::layers::Image; using mozilla::layers::LayerManager; using mozilla::layers::LayersBackend; namespace mozilla { -WMFVideoOutputSource::WMFVideoOutputSource(mozilla::layers::LayersBackend aLayersBackend, - mozilla::layers::ImageContainer* aImageContainer, - bool aDXVAEnabled) +WMFVideoOutputSource::WMFVideoOutputSource( + const mp4_demuxer::VideoDecoderConfig& aConfig, + mozilla::layers::LayersBackend aLayersBackend, + mozilla::layers::ImageContainer* aImageContainer, + bool aDXVAEnabled) : mVideoStride(0) , mVideoWidth(0) , mVideoHeight(0) + , mConfig(aConfig) , mImageContainer(aImageContainer) , mDXVAEnabled(aDXVAEnabled) , mLayersBackend(aLayersBackend) , mUseHwAccel(false) { NS_ASSERTION(!NS_IsMainThread(), "Should not be on main thread."); MOZ_ASSERT(mImageContainer); MOZ_COUNT_CTOR(WMFVideoOutputSource); @@ -134,16 +139,27 @@ WMFVideoOutputSource::Init() mDecoder = decoder; LOG("Video Decoder initialized, Using DXVA: %s", (mUseHwAccel ? "Yes" : "No")); return decoder.forget(); } HRESULT +WMFVideoOutputSource::Input(mp4_demuxer::MP4Sample* aSample) +{ + // We must prepare samples in AVC Annex B. + mp4_demuxer::AnnexB::ConvertSample(aSample, mConfig.annex_b); + // Forward sample data to the decoder. + const uint8_t* data = reinterpret_cast<const uint8_t*>(aSample->data); + uint32_t length = aSample->size; + return mDecoder->Input(data, length, aSample->composition_timestamp); +} + +HRESULT WMFVideoOutputSource::ConfigureVideoFrameGeometry() { RefPtr<IMFMediaType> mediaType; HRESULT hr = mDecoder->GetOutputMediaType(mediaType); NS_ENSURE_TRUE(SUCCEEDED(hr), hr); // Verify that the video subtype is what we expect it to be. // When using hardware acceleration/DXVA2 the video format should
--- a/content/media/fmp4/wmf/WMFVideoOutputSource.h +++ b/content/media/fmp4/wmf/WMFVideoOutputSource.h @@ -15,23 +15,26 @@ #include "mozilla/RefPtr.h" namespace mozilla { class DXVA2Manager; class WMFVideoOutputSource : public WMFOutputSource { public: - WMFVideoOutputSource(mozilla::layers::LayersBackend aLayersBackend, + WMFVideoOutputSource(const mp4_demuxer::VideoDecoderConfig& aConfig, + mozilla::layers::LayersBackend aLayersBackend, mozilla::layers::ImageContainer* aImageContainer, bool aDXVAEnabled); ~WMFVideoOutputSource(); virtual TemporaryRef<MFTDecoder> Init() MOZ_OVERRIDE; + virtual HRESULT Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE; + virtual HRESULT Output(int64_t aStreamOffset, nsAutoPtr<MediaData>& aOutput) MOZ_OVERRIDE; private: bool InitializeDXVA(); HRESULT ConfigureVideoFrameGeometry(); @@ -46,16 +49,18 @@ private: // Video frame geometry. VideoInfo mVideoInfo; uint32_t mVideoStride; uint32_t mVideoWidth; uint32_t mVideoHeight; nsIntRect mPictureRegion; + const mp4_demuxer::VideoDecoderConfig& mConfig; + RefPtr<MFTDecoder> mDecoder; RefPtr<layers::ImageContainer> mImageContainer; nsAutoPtr<DXVA2Manager> mDXVA2Manager; RefPtr<MediaTaskQueue> mTaskQueue; MediaDataDecoderCallback* mCallback; const bool mDXVAEnabled; const layers::LayersBackend mLayersBackend;
--- a/content/media/mediasource/MediaSource.h +++ b/content/media/mediasource/MediaSource.h @@ -9,17 +9,16 @@ #include "MediaSourceDecoder.h" #include "js/RootingAPI.h" #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/DOMEventTargetHelper.h" #include "mozilla/dom/MediaSourceBinding.h" #include "mozilla/Monitor.h" -#include "nsAutoPtr.h" #include "nsCOMPtr.h" #include "nsCycleCollectionNoteChild.h" #include "nsCycleCollectionParticipant.h" #include "nsID.h" #include "nsISupports.h" #include "nscore.h" struct JSContext;
--- a/content/media/mediasource/MediaSourceDecoder.cpp +++ b/content/media/mediasource/MediaSourceDecoder.cpp @@ -9,16 +9,17 @@ #include "AbstractMediaDecoder.h" #include "MediaDecoderReader.h" #include "MediaDecoderStateMachine.h" #include "mozilla/Assertions.h" #include "mozilla/FloatingPoint.h" #include "mozilla/dom/HTMLMediaElement.h" #include "mozilla/dom/TimeRanges.h" #include "mozilla/mozalloc.h" +#include "nsAutoPtr.h" #include "nsISupports.h" #include "nsIThread.h" #include "prlog.h" #include "MediaSource.h" #include "SubBufferDecoder.h" #include "SourceBufferResource.h" #include "SourceBufferList.h" #include "VideoUtils.h" @@ -409,31 +410,31 @@ MediaSourceReader::InitializePendingDeco already_AddRefed<SubBufferDecoder> MediaSourceReader::CreateSubDecoder(const nsACString& aType, MediaSourceDecoder* aParentDecoder, MediaTaskQueue* aTaskQueue) { // XXX: Why/when is mDecoder null here, since it should be equal to aParentDecoder?! nsRefPtr<SubBufferDecoder> decoder = new SubBufferDecoder(new SourceBufferResource(nullptr, aType), aParentDecoder); - nsAutoPtr<MediaDecoderReader> reader(DecoderTraits::CreateReader(aType, decoder)); + nsRefPtr<MediaDecoderReader> reader(DecoderTraits::CreateReader(aType, decoder)); if (!reader) { return nullptr; } // Set a callback on the subreader that forwards calls to this reader. // This reader will then forward them onto the state machine via this // reader's callback. RefPtr<MediaDataDecodedListener<MediaSourceReader>> callback = new MediaDataDecodedListener<MediaSourceReader>(this, aTaskQueue); reader->SetCallback(callback); reader->SetTaskQueue(aTaskQueue); reader->Init(nullptr); ReentrantMonitorAutoEnter mon(aParentDecoder->GetReentrantMonitor()); MSE_DEBUG("Registered subdecoder %p subreader %p", decoder.get(), reader.get()); - decoder->SetReader(reader.forget()); + decoder->SetReader(reader); mPendingDecoders.AppendElement(decoder); if (NS_FAILED(static_cast<MediaSourceDecoder*>(mDecoder)->EnqueueDecoderInitialization())) { MSE_DEBUG("%p: Failed to enqueue decoder initialization task", this); return nullptr; } mDecoder->NotifyWaitingForResourcesStatusChanged(); return decoder.forget(); }
--- a/content/media/mediasource/SourceBufferList.h +++ b/content/media/mediasource/SourceBufferList.h @@ -7,17 +7,16 @@ #ifndef mozilla_dom_SourceBufferList_h_ #define mozilla_dom_SourceBufferList_h_ #include "SourceBuffer.h" #include "js/RootingAPI.h" #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/DOMEventTargetHelper.h" -#include "nsAutoPtr.h" #include "nsCycleCollectionNoteChild.h" #include "nsCycleCollectionParticipant.h" #include "nsISupports.h" #include "nsTArray.h" struct JSContext; class JSObject;
--- a/content/media/mediasource/SubBufferDecoder.h +++ b/content/media/mediasource/SubBufferDecoder.h @@ -81,16 +81,16 @@ public: void SetMediaStartTime(int64_t aMediaStartTime) { mMediaStartTime = aMediaStartTime; } private: MediaSourceDecoder* mParentDecoder; - nsAutoPtr<MediaDecoderReader> mReader; + nsRefPtr<MediaDecoderReader> mReader; int64_t mMediaDuration; int64_t mMediaStartTime; }; } // namespace mozilla #endif /* MOZILLA_SUBBUFFERDECODER_H_ */
--- a/content/media/plugins/MediaResourceServer.cpp +++ b/content/media/plugins/MediaResourceServer.cpp @@ -1,15 +1,16 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* 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 "mozilla/Assertions.h" #include "mozilla/Base64.h" +#include "mozilla/IntegerPrintfMacros.h" #include "nsThreadUtils.h" #include "nsIServiceManager.h" #include "nsISocketTransport.h" #include "nsIOutputStream.h" #include "nsIInputStream.h" #include "nsIRandomGenerator.h" #include "nsReadLine.h" #include "nsNetCID.h" @@ -223,17 +224,17 @@ ServeResourceEvent::Run() { // the end of the resource and the client is informed of this via // the content-range header. NS_NAMED_LITERAL_CSTRING(byteRange, "Range: bytes="); const char* s = strstr(line.get(), byteRange.get()); if (s) { start = strtoll(s+byteRange.Length(), nullptr, 10); // Clamp 'start' to be between 0 and the resource length. - start = std::max(0ll, std::min(resource->GetLength(), start)); + start = std::max(int64_t(0), std::min(resource->GetLength(), start)); } } // HTTP response to use if this is a non byte range request const char* response_normal = "HTTP/1.1 200 OK\r\n"; // HTTP response to use if this is a byte range request const char* response_range = "HTTP/1.1 206 Partial Content\r\n"; @@ -263,28 +264,29 @@ ServeResourceEvent::Run() { nsAutoArrayPtr<char> b(new char[buffer_size]); // If we know the length of the resource, send a Content-Length header. int64_t contentlength = resource->GetLength() - start; if (contentlength > 0) { static_assert (buffer_size > 1024, "buffer_size must be large enough " "to hold response headers"); - snprintf(b, buffer_size, "Content-Length: %lld\r\n", contentlength); + snprintf(b, buffer_size, "Content-Length: %" PRId64 "\r\n", contentlength); rv = WriteAll(b, strlen(b)); if (NS_FAILED(rv)) { Shutdown(); return NS_OK; } } // If the request was a byte range request, respond with a Content-Range // header which details the extent of the data returned. if (start > 0) { static_assert (buffer_size > 1024, "buffer_size must be large enough " "to hold response headers"); - snprintf(b, buffer_size, "Content-Range: bytes %lld-%lld/%lld\r\n", + snprintf(b, buffer_size, "Content-Range: " + "bytes %" PRId64 "-%" PRId64 "/%" PRId64 "\r\n", start, resource->GetLength() - 1, resource->GetLength()); rv = WriteAll(b, strlen(b)); if (NS_FAILED(rv)) { Shutdown(); return NS_OK; } } rv = WriteAll(response_end, strlen(response_end)); if (NS_FAILED(rv)) { Shutdown(); return NS_OK; }
--- a/content/media/webaudio/AudioContext.cpp +++ b/content/media/webaudio/AudioContext.cpp @@ -432,16 +432,17 @@ AudioContext::Listener() } void AudioContext::DecodeAudioData(const ArrayBuffer& aBuffer, DecodeSuccessCallback& aSuccessCallback, const Optional<OwningNonNull<DecodeErrorCallback> >& aFailureCallback) { AutoJSAPI jsapi; + jsapi.Init(); JSContext* cx = jsapi.cx(); JSAutoCompartment ac(cx, aBuffer.Obj()); aBuffer.ComputeLengthAndData(); // Neuter the array buffer size_t length = aBuffer.Length(); JS::RootedObject obj(cx, aBuffer.Obj());
--- a/content/media/webaudio/AudioDestinationNode.cpp +++ b/content/media/webaudio/AudioDestinationNode.cpp @@ -121,25 +121,21 @@ public: void FireOfflineCompletionEvent(AudioDestinationNode* aNode) { AudioContext* context = aNode->Context(); context->Shutdown(); // Shutdown drops self reference, but the context is still referenced by aNode, // which is strongly referenced by the runnable that called // AudioDestinationNode::FireOfflineCompletionEvent. - // We need the global for the context so that we can enter its compartment. - JSObject* global = context->GetGlobalJSObject(); - if (NS_WARN_IF(!global)) { + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.InitUsingWin(aNode->GetOwner()))) { return; } - - AutoJSAPI jsapi; JSContext* cx = jsapi.cx(); - JSAutoCompartment ac(cx, global); // Create the input buffer ErrorResult rv; nsRefPtr<AudioBuffer> renderedBuffer = AudioBuffer::Create(context, mInputChannels.Length(), mLength, mSampleRate, cx, rv); if (rv.Failed()) { return;
--- a/content/media/webaudio/AudioProcessingEvent.cpp +++ b/content/media/webaudio/AudioProcessingEvent.cpp @@ -36,26 +36,22 @@ AudioProcessingEvent::WrapObject(JSConte { return AudioProcessingEventBinding::Wrap(aCx, this); } already_AddRefed<AudioBuffer> AudioProcessingEvent::LazilyCreateBuffer(uint32_t aNumberOfChannels, ErrorResult& aRv) { - // We need the global for the context so that we can enter its compartment. - JSObject* global = mNode->Context()->GetGlobalJSObject(); - if (NS_WARN_IF(!global)) { + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.InitUsingWin(mNode->GetOwner()))) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; } - - AutoJSAPI jsapi; JSContext* cx = jsapi.cx(); - JSAutoCompartment ac(cx, global); nsRefPtr<AudioBuffer> buffer = AudioBuffer::Create(mNode->Context(), aNumberOfChannels, mNode->BufferSize(), mNode->Context()->SampleRate(), cx, aRv); MOZ_ASSERT(buffer || aRv.ErrorCode() == NS_ERROR_OUT_OF_MEMORY); return buffer.forget(); }
--- a/content/media/webaudio/MediaBufferDecoder.cpp +++ b/content/media/webaudio/MediaBufferDecoder.cpp @@ -11,16 +11,17 @@ #include <speex/speex_resampler.h> #include "nsXPCOMCIDInternal.h" #include "nsComponentManagerUtils.h" #include "MediaDecoderReader.h" #include "BufferMediaResource.h" #include "DecoderTraits.h" #include "AudioContext.h" #include "AudioBuffer.h" +#include "nsAutoPtr.h" #include "nsIScriptObjectPrincipal.h" #include "nsIScriptError.h" #include "nsMimeTypes.h" #include "WebAudioUtils.h" namespace mozilla { NS_IMPL_CYCLE_COLLECTION_CLASS(WebAudioDecodeJob) @@ -146,17 +147,17 @@ private: nsCString mContentType; uint8_t* mBuffer; uint32_t mLength; WebAudioDecodeJob& mDecodeJob; PhaseEnum mPhase; nsCOMPtr<nsIThreadPool> mThreadPool; nsCOMPtr<nsIPrincipal> mPrincipal; nsRefPtr<BufferDecoder> mBufferDecoder; - nsAutoPtr<MediaDecoderReader> mDecoderReader; + nsRefPtr<MediaDecoderReader> mDecoderReader; }; NS_IMETHODIMP MediaDecodeTask::Run() { MOZ_ASSERT(mBufferDecoder); MOZ_ASSERT(mDecoderReader); switch (mPhase) { @@ -407,25 +408,21 @@ MediaDecodeTask::CallbackTheResult() } bool WebAudioDecodeJob::AllocateBuffer() { MOZ_ASSERT(!mOutput); MOZ_ASSERT(NS_IsMainThread()); - // We need the global for the context so that we can enter its compartment. - JSObject* global = mContext->GetGlobalJSObject(); - if (NS_WARN_IF(!global)) { + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.InitUsingWin(mContext->GetOwner()))) { return false; } - - AutoJSAPI jsapi; JSContext* cx = jsapi.cx(); - JSAutoCompartment ac(cx, global); // Now create the AudioBuffer ErrorResult rv; mOutput = AudioBuffer::Create(mContext, mChannelBuffers.Length(), mWriteIndex, mContext->SampleRate(), cx, rv); if (rv.Failed()) { return false; } @@ -445,25 +442,27 @@ MediaBufferDecoder::AsyncDecodeMedia(con // Do not attempt to decode the media if we were not successful at sniffing // the content type. if (!*aContentType || strcmp(aContentType, APPLICATION_OCTET_STREAM) == 0) { nsCOMPtr<nsIRunnable> event = new ReportResultTask(aDecodeJob, &WebAudioDecodeJob::OnFailure, WebAudioDecodeJob::UnknownContent); + JS_free(nullptr, aBuffer); NS_DispatchToMainThread(event); return; } if (!EnsureThreadPoolInitialized()) { nsCOMPtr<nsIRunnable> event = new ReportResultTask(aDecodeJob, &WebAudioDecodeJob::OnFailure, WebAudioDecodeJob::UnknownError); + JS_free(nullptr, aBuffer); NS_DispatchToMainThread(event); return; } MOZ_ASSERT(mThreadPool); nsRefPtr<MediaDecodeTask> task = new MediaDecodeTask(aContentType, aBuffer, aLength, aDecodeJob, mThreadPool);
--- a/content/media/webaudio/MediaBufferDecoder.h +++ b/content/media/webaudio/MediaBufferDecoder.h @@ -4,17 +4,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef MediaBufferDecoder_h_ #define MediaBufferDecoder_h_ #include "nsWrapperCache.h" #include "nsCOMPtr.h" -#include "nsAutoPtr.h" #include "nsIThreadPool.h" #include "nsString.h" #include "nsTArray.h" #include "mozilla/dom/TypedArray.h" #include "mozilla/MemoryReporting.h" namespace mozilla {
--- a/content/media/webaudio/ScriptProcessorNode.cpp +++ b/content/media/webaudio/ScriptProcessorNode.cpp @@ -397,25 +397,21 @@ private: // this function. MutexAutoLock lock(mStream->Engine()->NodeMutex()); node = static_cast<ScriptProcessorNode*>(mStream->Engine()->Node()); } if (!node || !node->Context()) { return NS_OK; } - // Get the global for the context so that we can enter its compartment. - JSObject* global = node->Context()->GetGlobalJSObject(); - if (NS_WARN_IF(!global)) { + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.InitUsingWin(node->GetOwner()))) { return NS_OK; } - - AutoJSAPI jsapi; JSContext* cx = jsapi.cx(); - JSAutoCompartment ac(cx, global); // Create the input buffer nsRefPtr<AudioBuffer> inputBuffer; if (!mNullInput) { ErrorResult rv; inputBuffer = AudioBuffer::Create(node->Context(), mInputChannels.Length(), node->BufferSize(),
--- a/content/media/webrtc/LoadManager.cpp +++ b/content/media/webrtc/LoadManager.cpp @@ -35,25 +35,25 @@ namespace mozilla { NS_IMPL_ISUPPORTS(LoadManagerSingleton, nsIObserver) LoadManagerSingleton::LoadManagerSingleton(int aLoadMeasurementInterval, int aAveragingMeasurements, float aHighLoadThreshold, float aLowLoadThreshold) - : mLoadSum(0.0f), + : mLock("LoadManager"), + mCurrentState(webrtc::kLoadNormal), + mOveruseActive(false), + mLoadSum(0.0f), mLoadSumMeasurements(0), - mOveruseActive(false), mLoadMeasurementInterval(aLoadMeasurementInterval), mAveragingMeasurements(aAveragingMeasurements), mHighLoadThreshold(aHighLoadThreshold), - mLowLoadThreshold(aLowLoadThreshold), - mCurrentState(webrtc::kLoadNormal), - mLock("LoadManager") + mLowLoadThreshold(aLowLoadThreshold) { #if defined(PR_LOGGING) if (!gLoadManagerLog) gLoadManagerLog = PR_NewLogModule("LoadManager"); #endif LOG(("LoadManager - Initializing (%dms x %d, %f, %f)", mLoadMeasurementInterval, mAveragingMeasurements, mHighLoadThreshold, mLowLoadThreshold));
--- a/content/media/webrtc/LoadManager.h +++ b/content/media/webrtc/LoadManager.h @@ -49,18 +49,18 @@ private: float aHighLoadThreshold, float aLowLoadThreshold); ~LoadManagerSingleton(); void LoadHasChanged(); nsRefPtr<LoadMonitor> mLoadMonitor; - // This protexts access to the mObservers list, the current state, pretty much all - // the other members (below) + // This protects access to the mObservers list, the current state, and + // pretty much all the other members (below). Mutex mLock; nsTArray<webrtc::CPULoadStateObserver*> mObservers; webrtc::CPULoadState mCurrentState; // Set when overuse was signaled to us, and hasn't been un-signaled yet. bool mOveruseActive; float mLoadSum; int mLoadSumMeasurements; // Load measurement settings
--- a/content/media/webrtc/LoadManagerFactory.cpp +++ b/content/media/webrtc/LoadManagerFactory.cpp @@ -24,19 +24,19 @@ LoadManagerSingleton::Get() { if (!sSingleton) { MOZ_ASSERT(NS_IsMainThread()); int loadMeasurementInterval = mozilla::Preferences::GetInt("media.navigator.load_adapt.measure_interval", 1000); int averagingSeconds = mozilla::Preferences::GetInt("media.navigator.load_adapt.avg_seconds", 3); float highLoadThreshold = - mozilla::Preferences::GetFloat("media.navigator.load_adapt.high_load", 0.90); + mozilla::Preferences::GetFloat("media.navigator.load_adapt.high_load", 0.90f); float lowLoadThreshold = - mozilla::Preferences::GetFloat("media.navigator.load_adapt.low_load", 0.40); + mozilla::Preferences::GetFloat("media.navigator.load_adapt.low_load", 0.40f); sSingleton = new LoadManagerSingleton(loadMeasurementInterval, averagingSeconds, highLoadThreshold, lowLoadThreshold); nsCOMPtr<nsIObserverService> obs = services::GetObserverService(); if (obs) {
--- a/content/media/webrtc/MediaEngineWebRTC.h +++ b/content/media/webrtc/MediaEngineWebRTC.h @@ -262,23 +262,23 @@ private: }; class MediaEngineWebRTCAudioSource : public MediaEngineAudioSource, public webrtc::VoEMediaProcess { public: MediaEngineWebRTCAudioSource(webrtc::VoiceEngine* aVoiceEnginePtr, int aIndex, const char* name, const char* uuid) - : mVoiceEngine(aVoiceEnginePtr) + : mSamples(0) + , mVoiceEngine(aVoiceEnginePtr) , mMonitor("WebRTCMic.Monitor") , mCapIndex(aIndex) , mChannel(-1) , mInitDone(false) , mStarted(false) - , mSamples(0) , mEchoOn(false), mAgcOn(false), mNoiseOn(false) , mEchoCancel(webrtc::kEcDefault) , mAGC(webrtc::kAgcDefault) , mNoiseSuppress(webrtc::kNsDefault) , mPlayoutDelay(0) , mNullTransport(nullptr) { MOZ_ASSERT(aVoiceEnginePtr); mState = kReleased; @@ -314,16 +314,23 @@ public: // VoEMediaProcess. void Process(int channel, webrtc::ProcessingTypes type, int16_t audio10ms[], int length, int samplingFreq, bool isStereo); NS_DECL_THREADSAFE_ISUPPORTS +protected: + // mSamples is an int to avoid conversions when comparing/etc to + // samplingFreq & length. Making mSamples protected instead of private is a + // silly way to avoid -Wunused-private-field warnings when PR_LOGGING is not + // #defined. mSamples is not actually expected to be used by a derived class. + int mSamples; + private: static const unsigned int KMaxDeviceNameLength = 128; static const unsigned int KMaxUniqueIdLength = 256; void Init(); void Shutdown(); webrtc::VoiceEngine* mVoiceEngine; @@ -339,17 +346,16 @@ private: Monitor mMonitor; nsTArray<SourceMediaStream *> mSources; // When this goes empty, we shut down HW int mCapIndex; int mChannel; TrackID mTrackID; bool mInitDone; bool mStarted; - int mSamples; // int to avoid conversions when comparing/etc to samplingFreq & length nsString mDeviceName; nsString mDeviceUUID; bool mEchoOn, mAgcOn, mNoiseOn; webrtc::EcModes mEchoCancel; webrtc::AgcModes mAGC; webrtc::NsModes mNoiseSuppress;
--- a/content/media/webrtc/PeerIdentity.cpp +++ b/content/media/webrtc/PeerIdentity.cpp @@ -1,16 +1,17 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: sw=2 ts=2 sts=2 expandtab * 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 "PeerIdentity.h" +#include "mozilla/DebugOnly.h" #include "nsCOMPtr.h" #include "nsIIDNService.h" #include "nsNetCID.h" #include "nsServiceManagerUtils.h" namespace mozilla { bool @@ -71,14 +72,14 @@ PeerIdentity::GetHost(const nsAString& a } } /* static */ void PeerIdentity::GetNormalizedHost(const nsCOMPtr<nsIIDNService>& aIdnService, const nsAString& aHost, nsACString& aNormalizedHost) { - nsCString chost = NS_ConvertUTF16toUTF8(aHost); - nsresult rv = aIdnService->ConvertUTF8toACE(chost, aNormalizedHost); - NS_WARN_IF(NS_FAILED(rv)); + const nsCString chost = NS_ConvertUTF16toUTF8(aHost); + DebugOnly<nsresult> rv = aIdnService->ConvertUTF8toACE(chost, aNormalizedHost); + NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to convert UTF-8 host to ASCII"); } } /* namespace mozilla */
--- a/content/media/webrtc/moz.build +++ b/content/media/webrtc/moz.build @@ -52,8 +52,16 @@ EXPORTS.mozilla += [ 'PeerIdentity.h', ] include('/ipc/chromium/chromium-config.mozbuild') FINAL_LIBRARY = 'gklayout' if CONFIG['OS_ARCH'] == 'WINNT': DEFINES['NOMINMAX'] = True + + +if CONFIG['_MSC_VER']: + CXXFLAGS += [ + '-wd4275', # non dll-interface class used as base for dll-interface class + ] + +FAIL_ON_WARNINGS = True
--- a/content/svg/document/src/SVGDocument.cpp +++ b/content/svg/document/src/SVGDocument.cpp @@ -138,29 +138,29 @@ SVGDocument::EnsureNonSVGUserAgentStyleS catMan->GetCategoryEntry("agent-style-sheets", name.get(), getter_Copies(spec)); mozilla::css::Loader* cssLoader = CSSLoader(); if (cssLoader->GetEnabled()) { nsCOMPtr<nsIURI> uri; NS_NewURI(getter_AddRefs(uri), spec); if (uri) { - nsRefPtr<nsCSSStyleSheet> cssSheet; + nsRefPtr<CSSStyleSheet> cssSheet; cssLoader->LoadSheetSync(uri, true, true, getter_AddRefs(cssSheet)); if (cssSheet) { EnsureOnDemandBuiltInUASheet(cssSheet); } } } } } } } - nsCSSStyleSheet* sheet = nsLayoutStylesheetCache::NumberControlSheet(); + CSSStyleSheet* sheet = nsLayoutStylesheetCache::NumberControlSheet(); if (sheet) { // number-control.css can be behind a pref EnsureOnDemandBuiltInUASheet(sheet); } EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::FormsSheet()); EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::CounterStylesSheet()); EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::HTMLSheet()); EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::UASheet());
--- a/content/test/unit/test_range.js +++ b/content/test/unit/test_range.js @@ -132,17 +132,16 @@ function evalXPathInDocumentFragment(aCo targetType, filter); var targetNode = walker.nextNode(); do_check_neq(targetNode, null); // Apply our remaining xpath to the found node. var expr = aContextNode.ownerDocument.createExpression(realPath, null); var result = expr.evaluate(targetNode, UNORDERED_TYPE, null); - do_check_true(result instanceof C_i.nsIDOMXPathResult); return result.singleNodeValue; } /** * Get a DOM range corresponding to the test's source node. * * @param aSourceNode <source/> element with range information. * @param aFragment DocumentFragment generated with getFragment().
--- a/content/xml/document/src/nsXMLContentSink.cpp +++ b/content/xml/document/src/nsXMLContentSink.cpp @@ -15,17 +15,17 @@ #include "nsNetUtil.h" #include "nsIDocShell.h" #include "nsIStyleSheetLinkingElement.h" #include "nsIDOMComment.h" #include "nsIDOMCDATASection.h" #include "DocumentType.h" #include "nsHTMLParts.h" #include "nsCRT.h" -#include "nsCSSStyleSheet.h" +#include "mozilla/CSSStyleSheet.h" #include "mozilla/css/Loader.h" #include "nsGkAtoms.h" #include "nsContentUtils.h" #include "nsIScriptContext.h" #include "nsNameSpaceManager.h" #include "nsIServiceManager.h" #include "nsIScriptSecurityManager.h" #include "nsIContentViewer.h" @@ -58,16 +58,17 @@ #include "nsHtml5SVGLoadDispatcher.h" #include "nsTextNode.h" #include "mozilla/dom/CDATASection.h" #include "mozilla/dom/Comment.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/HTMLTemplateElement.h" #include "mozilla/dom/ProcessingInstruction.h" +using namespace mozilla; using namespace mozilla::dom; // XXX Open Issues: // 1) what's not allowed - We need to figure out which HTML tags // (prefixed with a HTML namespace qualifier) are explicitly not // allowed (if any). // 2) factoring code with nsHTMLContentSink - There's some amount of // common code between this and the HTML content sink. This will @@ -409,17 +410,17 @@ nsXMLContentSink::OnTransformDone(nsresu ScrollToRef(); originalDocument->EndLoad(); return NS_OK; } NS_IMETHODIMP -nsXMLContentSink::StyleSheetLoaded(nsCSSStyleSheet* aSheet, +nsXMLContentSink::StyleSheetLoaded(CSSStyleSheet* aSheet, bool aWasAlternate, nsresult aStatus) { if (!mPrettyPrinting) { return nsContentSink::StyleSheetLoaded(aSheet, aWasAlternate, aStatus); } if (!mDocument->CSSLoader()->HasPendingLoads()) {
--- a/content/xml/document/src/nsXMLContentSink.h +++ b/content/xml/document/src/nsXMLContentSink.h @@ -78,17 +78,18 @@ public: virtual bool IsScriptExecuting() MOZ_OVERRIDE; virtual void ContinueInterruptedParsingAsync() MOZ_OVERRIDE; // nsITransformObserver NS_IMETHOD OnDocumentCreated(nsIDocument *aResultDocument) MOZ_OVERRIDE; NS_IMETHOD OnTransformDone(nsresult aResult, nsIDocument *aResultDocument) MOZ_OVERRIDE; // nsICSSLoaderObserver - NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet, bool aWasAlternate, + NS_IMETHOD StyleSheetLoaded(mozilla::CSSStyleSheet* aSheet, + bool aWasAlternate, nsresult aStatus) MOZ_OVERRIDE; static bool ParsePIData(const nsString &aData, nsString &aHref, nsString &aTitle, nsString &aMedia, bool &aIsAlternate); protected: nsIParser* GetParser();
--- a/content/xul/document/src/XULDocument.cpp +++ b/content/xul/document/src/XULDocument.cpp @@ -66,27 +66,28 @@ #include "nsIScriptGlobalObject.h" #include "nsIScriptSecurityManager.h" #include "nsNodeInfoManager.h" #include "nsContentCreatorFunctions.h" #include "nsContentUtils.h" #include "nsIParser.h" #include "nsCharsetSource.h" #include "nsIParserService.h" -#include "nsCSSStyleSheet.h" +#include "mozilla/CSSStyleSheet.h" #include "mozilla/css/Loader.h" #include "nsIScriptError.h" #include "nsIStyleSheetLinkingElement.h" #include "nsIObserverService.h" #include "nsNodeUtils.h" #include "nsIDocShellTreeOwner.h" #include "nsIXULWindow.h" #include "nsXULPopupManager.h" #include "nsCCUncollectableMarker.h" #include "nsURILoader.h" +#include "mozilla/AddonPathService.h" #include "mozilla/BasicEvents.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/NodeInfoInlines.h" #include "mozilla/dom/ProcessingInstruction.h" #include "mozilla/dom/XULDocumentBinding.h" #include "mozilla/EventDispatcher.h" #include "mozilla/Preferences.h" #include "nsTextNode.h" @@ -3283,17 +3284,17 @@ XULDocument::DoneWalking() } } } return NS_OK; } NS_IMETHODIMP -XULDocument::StyleSheetLoaded(nsCSSStyleSheet* aSheet, +XULDocument::StyleSheetLoaded(CSSStyleSheet* aSheet, bool aWasAlternate, nsresult aStatus) { if (!aWasAlternate) { // Don't care about when alternate sheets finish loading NS_ASSERTION(mPendingSheets > 0, "Unexpected StyleSheetLoaded notification"); @@ -3686,19 +3687,24 @@ XULDocument::ExecuteScript(nsIScriptCont return NS_ERROR_NULL_POINTER; NS_ENSURE_TRUE(mScriptGlobalObject, NS_ERROR_NOT_INITIALIZED); // Execute the precompiled script with the given version nsAutoMicroTask mt; JSContext *cx = aContext->GetNativeContext(); AutoCxPusher pusher(cx); - JS::Rooted<JSObject*> global(cx, mScriptGlobalObject->GetGlobalJSObject()); + JS::Rooted<JSObject*> baseGlobal(cx, mScriptGlobalObject->GetGlobalJSObject()); + NS_ENSURE_TRUE(baseGlobal, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(nsContentUtils::GetSecurityManager()->ScriptAllowed(baseGlobal), NS_OK); + + JSAddonId *addonId = MapURIToAddonID(mCurrentPrototype->GetURI()); + JS::Rooted<JSObject*> global(cx, xpc::GetAddonScope(cx, baseGlobal, addonId)); NS_ENSURE_TRUE(global, NS_ERROR_FAILURE); - NS_ENSURE_TRUE(nsContentUtils::GetSecurityManager()->ScriptAllowed(global), NS_OK); + JS::ExposeObjectToActiveJS(global); xpc_UnmarkGrayScript(aScriptObject); JSAutoCompartment ac(cx, global); // The script is in the compilation scope. Clone it into the target scope // and execute it. if (!JS::CloneAndExecuteScript(cx, global, aScriptObject)) nsJSUtils::ReportPendingException(cx); @@ -3934,17 +3940,17 @@ XULDocument::AddPrototypeSheets() { nsresult rv; const nsCOMArray<nsIURI>& sheets = mCurrentPrototype->GetStyleSheetReferences(); for (int32_t i = 0; i < sheets.Count(); i++) { nsCOMPtr<nsIURI> uri = sheets[i]; - nsRefPtr<nsCSSStyleSheet> incompleteSheet; + nsRefPtr<CSSStyleSheet> incompleteSheet; rv = CSSLoader()->LoadSheet(uri, mCurrentPrototype->DocumentPrincipal(), EmptyCString(), this, getter_AddRefs(incompleteSheet)); // XXXldb We need to prevent bogus sheets from being held in the // prototype's list, but until then, don't propagate the failure // from LoadSheet (and thus exit the loop).
--- a/content/xul/document/src/XULDocument.h +++ b/content/xul/document/src/XULDocument.h @@ -158,17 +158,17 @@ public: // nsDocument interface overrides virtual Element* GetElementById(const nsAString & elementId) MOZ_OVERRIDE; // nsIDOMXULDocument interface NS_DECL_NSIDOMXULDOCUMENT // nsICSSLoaderObserver - NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet, + NS_IMETHOD StyleSheetLoaded(CSSStyleSheet* aSheet, bool aWasAlternate, nsresult aStatus) MOZ_OVERRIDE; virtual void EndUpdate(nsUpdateType aUpdateType) MOZ_OVERRIDE; virtual bool IsDocumentRightToLeft() MOZ_OVERRIDE; virtual void ResetDocumentDirection() MOZ_OVERRIDE; @@ -331,17 +331,17 @@ protected: */ bool mRestrictPersistence; nsTHashtable<nsStringHashKey> mPersistenceIds; /** * An array of style sheets, that will be added (preserving order) to the * document after all of them are loaded (in DoneWalking). */ - nsTArray<nsRefPtr<nsCSSStyleSheet> > mOverlaySheets; + nsTArray<nsRefPtr<CSSStyleSheet>> mOverlaySheets; nsCOMPtr<nsIDOMXULCommandDispatcher> mCommandDispatcher; // [OWNER] of the focus tracker // Maintains the template builders that have been attached to // content elements typedef nsInterfaceHashtable<nsISupportsHashKey, nsIXULTemplateBuilder> BuilderTable; BuilderTable* mTemplateBuilderTable;
--- a/content/xul/document/src/nsXULPrototypeCache.cpp +++ b/content/xul/document/src/nsXULPrototypeCache.cpp @@ -2,33 +2,33 @@ /* 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 "nsXULPrototypeCache.h" #include "plstr.h" #include "nsXULPrototypeDocument.h" -#include "nsCSSStyleSheet.h" #include "nsIServiceManager.h" #include "nsIURI.h" #include "nsIChromeRegistry.h" #include "nsIFile.h" #include "nsIObjectInputStream.h" #include "nsIObjectOutputStream.h" #include "nsIObserverService.h" #include "nsIStringStream.h" #include "nsIStorageStream.h" #include "nsNetUtil.h" #include "nsAppDirectoryServiceDefs.h" #include "js/TracingAPI.h" +#include "mozilla/CSSStyleSheet.h" #include "mozilla/Preferences.h" #include "mozilla/scache/StartupCache.h" #include "mozilla/scache/StartupCacheUtils.h" #include "mozilla/Telemetry.h" using namespace mozilla; using namespace mozilla::scache; @@ -167,17 +167,17 @@ nsXULPrototypeCache::PutPrototype(nsXULP nsCOMPtr<nsIURI> uri = aDocument->GetURI(); // Put() releases any old value and addrefs the new one mPrototypeTable.Put(uri, aDocument); return NS_OK; } nsresult -nsXULPrototypeCache::PutStyleSheet(nsCSSStyleSheet* aStyleSheet) +nsXULPrototypeCache::PutStyleSheet(CSSStyleSheet* aStyleSheet) { nsIURI* uri = aStyleSheet->GetSheetURI(); mStyleSheetTable.Put(uri, aStyleSheet); return NS_OK; } @@ -234,17 +234,17 @@ FlushSkinXBL(nsIURI* aKey, nsRefPtr<nsXB if (!strncmp(str.get(), "/skin", 5)) { ret = PL_DHASH_REMOVE; } return ret; } static PLDHashOperator -FlushSkinSheets(nsIURI* aKey, nsRefPtr<nsCSSStyleSheet>& aSheet, void* aClosure) +FlushSkinSheets(nsIURI* aKey, nsRefPtr<CSSStyleSheet>& aSheet, void* aClosure) { nsAutoCString str; aSheet->GetSheetURI()->GetPath(str); PLDHashOperator ret = PL_DHASH_NEXT; if (!strncmp(str.get(), "/skin", 5)) { // This is a skin binding. Add the key to the list.
--- a/content/xul/document/src/nsXULPrototypeCache.h +++ b/content/xul/document/src/nsXULPrototypeCache.h @@ -14,17 +14,19 @@ #include "nsRefPtrHashtable.h" #include "nsURIHashKey.h" #include "nsXULPrototypeDocument.h" #include "nsIInputStream.h" #include "nsIStorageStream.h" #include "mozilla/scache/StartupCache.h" -class nsCSSStyleSheet; +namespace mozilla { +class CSSStyleSheet; +} // namespace mozilla /** * The XUL prototype cache can be used to store and retrieve shared data for * XUL documents, style sheets, XBL, and scripts. * * The cache has two levels: * 1. In-memory hashtables * 2. The on-disk cache file. @@ -67,25 +69,25 @@ public: return mXBLDocTable.GetWeak(aURL); } nsresult PutXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo); /** * Get a style sheet by URI. If the style sheet is not in the cache, * returns nullptr. */ - nsCSSStyleSheet* GetStyleSheet(nsIURI* aURI) { + mozilla::CSSStyleSheet* GetStyleSheet(nsIURI* aURI) { return mStyleSheetTable.GetWeak(aURI); } /** * Store a style sheet in the cache. The key, style sheet's URI is obtained * from the style sheet itself. */ - nsresult PutStyleSheet(nsCSSStyleSheet* aStyleSheet); + nsresult PutStyleSheet(mozilla::CSSStyleSheet* aStyleSheet); /** * Write the XUL prototype document to a cache file. The proto must be * fully loaded. */ nsresult WritePrototype(nsXULPrototypeDocument* aPrototypeDocument); /** @@ -116,17 +118,17 @@ protected: nsXULPrototypeCache(); virtual ~nsXULPrototypeCache(); static nsXULPrototypeCache* sInstance; void FlushSkinFiles(); nsRefPtrHashtable<nsURIHashKey,nsXULPrototypeDocument> mPrototypeTable; // owns the prototypes - nsRefPtrHashtable<nsURIHashKey,nsCSSStyleSheet> mStyleSheetTable; + nsRefPtrHashtable<nsURIHashKey,mozilla::CSSStyleSheet> mStyleSheetTable; nsJSThingHashtable<nsURIHashKey, JSScript*> mScriptTable; nsRefPtrHashtable<nsURIHashKey,nsXBLDocumentInfo> mXBLDocTable; nsTHashtable<nsURIHashKey> mCacheURITable; nsInterfaceHashtable<nsURIHashKey, nsIStorageStream> mOutputStreamTable; nsInterfaceHashtable<nsURIHashKey, nsIObjectInputStream> mInputStreamTable;
--- a/content/xul/templates/src/nsXMLBinding.cpp +++ b/content/xul/templates/src/nsXMLBinding.cpp @@ -1,16 +1,21 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsXULTemplateQueryProcessorXML.h" #include "nsXULTemplateResultXML.h" #include "nsXMLBinding.h" +#include "mozilla/ErrorResult.h" +#include "mozilla/dom/XPathResult.h" + +using namespace mozilla; +using namespace mozilla::dom; NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(nsXMLBindingSet) NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(nsXMLBindingSet) NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLBindingSet) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXMLBindingSet) nsXMLBinding* binding = tmp->mFirst; @@ -78,66 +83,70 @@ nsXMLBindingSet::LookupTargetIndex(nsIAt idx++; binding = binding->mNext; } *aBinding = nullptr; return -1; } -void +XPathResult* nsXMLBindingValues::GetAssignmentFor(nsXULTemplateResultXML* aResult, nsXMLBinding* aBinding, int32_t aIndex, - uint16_t aType, - nsIDOMXPathResult** aValue) + uint16_t aType) { - *aValue = mValues.SafeObjectAt(aIndex); - - if (!*aValue) { - nsCOMPtr<nsIDOMNode> contextNode; - aResult->GetNode(getter_AddRefs(contextNode)); - if (contextNode) { - nsCOMPtr<nsISupports> resultsupports; - aBinding->mExpr->Evaluate(contextNode, aType, - nullptr, getter_AddRefs(resultsupports)); - - nsCOMPtr<nsIDOMXPathResult> result = do_QueryInterface(resultsupports); - if (result && mValues.ReplaceObjectAt(result, aIndex)) - *aValue = result; - } + XPathResult* value = mValues.SafeElementAt(aIndex); + if (value) { + return value; } - NS_IF_ADDREF(*aValue); + nsCOMPtr<nsIDOMNode> contextNode; + aResult->GetNode(getter_AddRefs(contextNode)); + if (!contextNode) { + return nullptr; + } + + mValues.EnsureLengthAtLeast(aIndex + 1); + + nsCOMPtr<nsISupports> resultsupports; + aBinding->mExpr->Evaluate(contextNode, aType, + nullptr, getter_AddRefs(resultsupports)); + + mValues.ReplaceElementAt(aIndex, XPathResult::FromSupports(resultsupports)); + + return mValues[aIndex]; } void nsXMLBindingValues::GetNodeAssignmentFor(nsXULTemplateResultXML* aResult, nsXMLBinding* aBinding, int32_t aIndex, nsIDOMNode** aNode) { - nsCOMPtr<nsIDOMXPathResult> result; - GetAssignmentFor(aResult, aBinding, aIndex, - nsIDOMXPathResult::FIRST_ORDERED_NODE_TYPE, - getter_AddRefs(result)); + XPathResult* result = GetAssignmentFor(aResult, aBinding, aIndex, + XPathResult::FIRST_ORDERED_NODE_TYPE); - if (result) - result->GetSingleNodeValue(aNode); - else + nsINode* node; + ErrorResult rv; + if (result && (node = result->GetSingleNodeValue(rv))) { + CallQueryInterface(node, aNode); + } else { *aNode = nullptr; + } } void nsXMLBindingValues::GetStringAssignmentFor(nsXULTemplateResultXML* aResult, nsXMLBinding* aBinding, int32_t aIndex, nsAString& aValue) { - nsCOMPtr<nsIDOMXPathResult> result; - GetAssignmentFor(aResult, aBinding, aIndex, - nsIDOMXPathResult::STRING_TYPE, getter_AddRefs(result)); + XPathResult* result = GetAssignmentFor(aResult, aBinding, aIndex, + XPathResult::STRING_TYPE); - if (result) - result->GetStringValue(aValue); - else + if (result) { + ErrorResult rv; + result->GetStringValue(aValue, rv); + } else { aValue.Truncate(); + } }
--- a/content/xul/templates/src/nsXMLBinding.h +++ b/content/xul/templates/src/nsXMLBinding.h @@ -8,16 +8,21 @@ #include "nsAutoPtr.h" #include "nsIAtom.h" #include "nsCycleCollectionParticipant.h" #include "mozilla/Attributes.h" class nsXULTemplateResultXML; class nsXMLBindingValues; +namespace mozilla { +namespace dom { +class XPathResult; +} +} /** * Classes related to storing bindings for XML handling. */ /** * a <binding> description */ @@ -87,17 +92,17 @@ protected: // the binding set nsRefPtr<nsXMLBindingSet> mBindings; /** * A set of values for variable bindings. To look up a binding value, * scan through the binding set in mBindings for the right target atom. * Its index will correspond to the index in this array. */ - nsCOMArray<nsIDOMXPathResult> mValues; + nsTArray<nsRefPtr<mozilla::dom::XPathResult> > mValues; public: nsXMLBindingValues() { MOZ_COUNT_CTOR(nsXMLBindingValues); } ~nsXMLBindingValues() { MOZ_COUNT_DTOR(nsXMLBindingValues); } nsXMLBindingSet* GetBindingSet() { return mBindings; } @@ -112,24 +117,22 @@ public: /** * Retrieve the assignment for a particular variable * * aResult the result generated from the template * aBinding the binding looked up using LookupTargetIndex * aIndex the index of the assignment to retrieve * aType the type of result expected - * aValue the value of the assignment */ - void + mozilla::dom::XPathResult* GetAssignmentFor(nsXULTemplateResultXML* aResult, nsXMLBinding* aBinding, int32_t idx, - uint16_t type, - nsIDOMXPathResult** aValue); + uint16_t type); void GetNodeAssignmentFor(nsXULTemplateResultXML* aResult, nsXMLBinding* aBinding, int32_t idx, nsIDOMNode** aValue); void
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp +++ b/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp @@ -21,47 +21,48 @@ #include "nsPIDOMWindow.h" #include "nsXULContentUtils.h" #include "nsXMLHttpRequest.h" #include "nsXULTemplateQueryProcessorXML.h" #include "nsXULTemplateResultXML.h" #include "nsXULSortService.h" +using namespace mozilla; using namespace mozilla::dom; NS_IMPL_ISUPPORTS(nsXMLQuery, nsXMLQuery) //---------------------------------------------------------------------- // // nsXULTemplateResultSetXML // NS_IMPL_ISUPPORTS(nsXULTemplateResultSetXML, nsISimpleEnumerator) NS_IMETHODIMP nsXULTemplateResultSetXML::HasMoreElements(bool *aResult) { // if GetSnapshotLength failed, then the return type was not a set of // nodes, so just return false in this case. - uint32_t length; - if (NS_SUCCEEDED(mResults->GetSnapshotLength(&length))) - *aResult = (mPosition < length); - else - *aResult = false; - + ErrorResult rv; + uint32_t length = mResults->GetSnapshotLength(rv); + *aResult = !rv.Failed() && mPosition < length; return NS_OK; } NS_IMETHODIMP nsXULTemplateResultSetXML::GetNext(nsISupports **aResult) { - nsCOMPtr<nsIDOMNode> node; - nsresult rv = mResults->SnapshotItem(mPosition, getter_AddRefs(node)); - NS_ENSURE_SUCCESS(rv, rv); + ErrorResult rv; + nsCOMPtr<nsIDOMNode> node = + do_QueryInterface(mResults->SnapshotItem(mPosition, rv)); + if (rv.Failed()) { + return rv.ErrorCode(); + } nsXULTemplateResultXML* result = new nsXULTemplateResultXML(mQuery, node, mBindingSet); NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY); ++mPosition; *aResult = result; NS_ADDREF(result); @@ -326,23 +327,21 @@ nsXULTemplateQueryProcessorXML::Generate context = mRoot; nsIDOMXPathExpression* expr = xmlquery->GetResultsExpression(); if (!expr) return NS_ERROR_FAILURE; nsCOMPtr<nsISupports> exprsupportsresults; nsresult rv = expr->Evaluate(context, - nsIDOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, + XPathResult::ORDERED_NODE_SNAPSHOT_TYPE, nullptr, getter_AddRefs(exprsupportsresults)); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr<nsIDOMXPathResult> exprresults = - do_QueryInterface(exprsupportsresults); - + XPathResult* exprresults = XPathResult::FromSupports(exprsupportsresults); nsXULTemplateResultSetXML* results = new nsXULTemplateResultSetXML(xmlquery, exprresults, xmlquery->GetBindingSet()); NS_ENSURE_TRUE(results, NS_ERROR_OUT_OF_MEMORY); *aResults = results; NS_ADDREF(*aResults);
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorXML.h +++ b/content/xul/templates/src/nsXULTemplateQueryProcessorXML.h @@ -12,21 +12,21 @@ #include "nsISimpleEnumerator.h" #include "nsString.h" #include "nsCOMArray.h" #include "nsRefPtrHashtable.h" #include "nsIDOMElement.h" #include "nsIDOMEventListener.h" #include "nsIDOMXPathExpression.h" #include "nsIDOMXPathEvaluator.h" -#include "nsIDOMXPathResult.h" #include "nsXMLBinding.h" #include "nsCycleCollectionParticipant.h" #include "nsIXMLHttpRequest.h" #include "mozilla/Attributes.h" +#include "mozilla/dom/XPathResult.h" class nsXULTemplateQueryProcessorXML; #define NS_IXMLQUERY_IID \ {0x0358d692, 0xccce, 0x4a97, \ { 0xb2, 0x51, 0xba, 0x8f, 0x17, 0x0f, 0x3b, 0x6f }} class nsXMLQuery MOZ_FINAL : public nsISupports @@ -86,31 +86,31 @@ private: // reference back to the query nsCOMPtr<nsXMLQuery> mQuery; // the binding set created from <assign> nodes nsRefPtr<nsXMLBindingSet> mBindingSet; // set of results contained in this enumerator - nsCOMPtr<nsIDOMXPathResult> mResults; + nsRefPtr<mozilla::dom::XPathResult> mResults; // current position within the list of results uint32_t mPosition; public: // nsISupports interface NS_DECL_ISUPPORTS // nsISimpleEnumerator interface NS_DECL_NSISIMPLEENUMERATOR nsXULTemplateResultSetXML(nsXMLQuery* aQuery, - nsIDOMXPathResult* aResults, + mozilla::dom::XPathResult* aResults, nsXMLBindingSet* aBindingSet) : mQuery(aQuery), mBindingSet(aBindingSet), mResults(aResults), mPosition(0) {} };
--- a/dom/apps/src/Webapps.jsm +++ b/dom/apps/src/Webapps.jsm @@ -947,17 +947,17 @@ this.DOMApplicationRegistry = { // If we can't load the manifest, we probably have a corrupted // registry. We delete the app since we can't do anything with it. delete this.webapps[aResult.id]; return; } let localeManifest = new ManifestHelper(manifest, app.origin); - app.name = localeManifest.name; + app.name = manifest.name; app.csp = manifest.csp || ""; app.role = localeManifest.role; if (app.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) { app.redirects = this.sanitizeRedirects(manifest.redirects); } this._registerSystemMessages(manifest, app); this._registerInterAppConnections(manifest, app); appsToRegister.push({ manifest: manifest, app: app }); @@ -1311,16 +1311,22 @@ this.DOMApplicationRegistry = { } else if (download.channel) { try { download.channel.cancel(Cr.NS_BINDING_ABORTED); } catch(e) { } } else { return; } + // Ensure we don't send additional errors for this download + app.isCanceling = true; + + // Ensure this app can be downloaded again after canceling + app.downloading = false; + this._saveApps().then(() => { this.broadcastMessage("Webapps:UpdateState", { app: { progress: 0, installState: download.previousState, downloading: false }, error: error, @@ -1334,16 +1340,17 @@ this.DOMApplicationRegistry = { AppDownloadManager.remove(aManifestURL); }, startDownload: Task.async(function*(aManifestURL) { debug("startDownload for " + aManifestURL); let id = this._appIdForManifestURL(aManifestURL); let app = this.webapps[id]; + if (!app) { debug("startDownload: No app found for " + aManifestURL); throw new Error("NO_SUCH_APP"); } if (app.downloading) { debug("app is already downloading. Ignoring."); throw new Error("APP_IS_DOWNLOADING"); @@ -1959,17 +1966,17 @@ this.DOMApplicationRegistry = { origin: aApp.origin, manifestURL: aData.manifestURL }, true); } this.updateDataStore(this.webapps[aId].localId, aApp.origin, aApp.manifestURL, aApp.manifest); - aApp.name = manifest.name; + aApp.name = aNewManifest.name; aApp.csp = manifest.csp || ""; aApp.role = manifest.role || ""; aApp.updateTime = Date.now(); } else { manifest = new ManifestHelper(aOldManifest, aApp.origin); } // Update the registry. @@ -2324,45 +2331,45 @@ this.DOMApplicationRegistry = { app.id = aId; app.installTime = Date.now(); app.lastUpdateCheck = Date.now(); return app; }, - _cloneApp: function(aData, aNewApp, aManifest, aId, aLocalId) { + _cloneApp: function(aData, aNewApp, aLocaleManifest, aManifest, aId, aLocalId) { let appObject = AppsUtils.cloneAppObject(aNewApp); appObject.appStatus = aNewApp.appStatus || Ci.nsIPrincipal.APP_STATUS_INSTALLED; - if (aManifest.appcache_path) { + if (aLocaleManifest.appcache_path) { appObject.installState = "pending"; appObject.downloadAvailable = true; appObject.downloading = true; appObject.downloadSize = 0; appObject.readyToApplyDownload = false; - } else if (aManifest.package_path) { + } else if (aLocaleManifest.package_path) { appObject.installState = "pending"; appObject.downloadAvailable = true; appObject.downloading = true; - appObject.downloadSize = aManifest.size; + appObject.downloadSize = aLocaleManifest.size; appObject.readyToApplyDownload = false; } else { appObject.installState = "installed"; appObject.downloadAvailable = false; appObject.downloading = false; appObject.readyToApplyDownload = false; } appObject.localId = aLocalId; appObject.basePath = OS.Path.dirname(this.appsFile); appObject.name = aManifest.name; - appObject.csp = aManifest.csp || ""; - appObject.role = aManifest.role || ""; + appObject.csp = aLocaleManifest.csp || ""; + appObject.role = aLocaleManifest.role; appObject.installerAppId = aData.appId; appObject.installerIsBrowser = aData.isBrowser; return appObject; }, _writeManifestFile: function(aId, aIsPackage, aJsonManifest) { debug("_writeManifestFile"); @@ -2470,17 +2477,17 @@ this.DOMApplicationRegistry = { let app = this._setupApp(aData, id); let jsonManifest = aData.isPackage ? app.updateManifest : app.manifest; yield this._writeManifestFile(id, aData.isPackage, jsonManifest); debug("app.origin: " + app.origin); let manifest = new ManifestHelper(jsonManifest, app.origin); - let appObject = this._cloneApp(aData, app, manifest, id, localId); + let appObject = this._cloneApp(aData, app, manifest, jsonManifest, id, localId); this.webapps[id] = appObject; // For package apps, the permissions are not in the mini-manifest, so // don't update the permissions yet. if (!aData.isPackage) { if (supportUseCurrentProfile()) { PermissionsInstaller.installPermissions( @@ -2765,16 +2772,24 @@ this.DOMApplicationRegistry = { // We determine the app's 'installState' according to its previous // state. Cancelled download should remain as 'pending'. Successfully // installed apps should morph to 'updating'. oldApp.installState = aIsUpdate ? "updating" : "pending"; // initialize the progress to 0 right now oldApp.progress = 0; + // Save the current state of the app to handle cases where we may be + // retrying a past download. + yield DOMApplicationRegistry._saveApps(); + DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", { + app: oldApp, + manifestURL: aNewApp.manifestURL + }); + let zipFile = yield this._getPackage(requestChannel, id, oldApp, aNewApp); let hash = yield this._computeFileHash(zipFile.path); let responseStatus = requestChannel.responseStatus; let oldPackage = (responseStatus == 304 || hash == oldApp.packageHash); if (oldPackage) { debug("package's etag or hash unchanged; sending 'applied' event"); @@ -4078,26 +4093,34 @@ AppcacheObserver.prototype = { eventType: ["downloadsuccess", "downloadapplied"], manifestURL: app.manifestURL }); } let setError = function appObs_setError(aError) { debug("Offlinecache setError to " + aError); app.downloading = false; + mustSave = true; + + // If we are canceling the download, we already send a DOWNLOAD_CANCELED + // error. + if (app.isCanceling) { + delete app.isCanceling; + return; + } + DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", { app: app, error: aError, manifestURL: app.manifestURL }); DOMApplicationRegistry.broadcastMessage("Webapps:FireEvent", { eventType: "downloaderror", manifestURL: app.manifestURL }); - mustSave = true; } switch (aState) { case Ci.nsIOfflineCacheUpdateObserver.STATE_ERROR: aUpdate.removeObserver(this); AppDownloadManager.remove(app.manifestURL); setError("APP_CACHE_DOWNLOAD_ERROR"); break;
--- a/dom/archivereader/ArchiveRequest.cpp +++ b/dom/archivereader/ArchiveRequest.cpp @@ -126,29 +126,22 @@ ArchiveRequest::ReaderReady(nsTArray<nsC { if (NS_FAILED(aStatus)) { FireError(aStatus); return NS_OK; } nsresult rv; - nsCOMPtr<nsIGlobalObject> globalObject = do_QueryInterface(GetOwner()); - if (NS_WARN_IF(!globalObject)) { + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.InitUsingWin(GetOwner()))) { return NS_ERROR_UNEXPECTED; } - - AutoJSAPI jsapi; JSContext* cx = jsapi.cx(); - JS::Rooted<JSObject*> global(cx, globalObject->GetGlobalJSObject()); - NS_ASSERTION(global, "Failed to get global object!"); - - JSAutoCompartment ac(cx, global); - JS::Rooted<JS::Value> result(cx); switch (mOperation) { case GetFilenames: rv = GetFilenamesResult(cx, result.address(), aFileList); break; case GetFile: rv = GetFileResult(cx, &result, aFileList);
--- a/dom/base/Console.cpp +++ b/dom/base/Console.cpp @@ -319,27 +319,28 @@ private: RunConsole() MOZ_OVERRIDE { // Walk up to our containing page WorkerPrivate* wp = mWorkerPrivate; while (wp->GetParent()) { wp = wp->GetParent(); } - AutoJSAPI jsapi; - JSContext* cx = jsapi.cx(); - ClearException ce(cx); - nsPIDOMWindow* window = wp->GetWindow(); NS_ENSURE_TRUE_VOID(window); nsRefPtr<nsGlobalWindow> win = static_cast<nsGlobalWindow*>(window); NS_ENSURE_TRUE_VOID(win); - JSAutoCompartment ac(cx, win->GetWrapperPreserveColor()); + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.Init(win))) { + return; + } + JSContext* cx = jsapi.cx(); + ClearException ce(cx); ErrorResult error; nsRefPtr<Console> console = win->GetConsole(error); if (error.Failed()) { NS_WARNING("Failed to get console from the window."); return; } @@ -431,27 +432,28 @@ private: RunConsole() MOZ_OVERRIDE { // Walk up to our containing page WorkerPrivate* wp = mWorkerPrivate; while (wp->GetParent()) { wp = wp->GetParent(); } - AutoJSAPI jsapi; - JSContext* cx = jsapi.cx(); - ClearException ce(cx); - nsPIDOMWindow* window = wp->GetWindow(); NS_ENSURE_TRUE_VOID(window); nsRefPtr<nsGlobalWindow> win = static_cast<nsGlobalWindow*>(window); NS_ENSURE_TRUE_VOID(win); - JSAutoCompartment ac(cx, win->GetWrapperPreserveColor()); + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.Init(win))) { + return; + } + JSContext* cx = jsapi.cx(); + ClearException ce(cx); ErrorResult error; nsRefPtr<Console> console = win->GetConsole(error); if (error.Failed()) { NS_WARNING("Failed to get console from the window."); return; }
--- a/dom/base/MessagePort.cpp +++ b/dom/base/MessagePort.cpp @@ -267,24 +267,21 @@ PopulateMessagePortList(MessagePortBase* return PL_DHASH_NEXT; } NS_IMETHODIMP PostMessageRunnable::Run() { MOZ_ASSERT(mPort); - nsCOMPtr<nsIGlobalObject> globalObject = do_QueryInterface(mPort->GetOwner()); - if (NS_WARN_IF(!globalObject)) { + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.Init(mPort->GetParentObject()))) { return NS_ERROR_UNEXPECTED; } - - AutoJSAPI jsapi; JSContext* cx = jsapi.cx(); - JSAutoCompartment ac(cx, globalObject->GetGlobalJSObject()); // Deserialize the structured clone data JS::Rooted<JS::Value> messageData(cx); StructuredCloneInfo scInfo; scInfo.mEvent = this; scInfo.mPort = mPort; if (!mBuffer.read(cx, &messageData, &kPostMessageCallbacks, &scInfo)) {
--- a/dom/base/ScriptSettings.cpp +++ b/dom/base/ScriptSettings.cpp @@ -9,16 +9,18 @@ #include "mozilla/Assertions.h" #include "jsapi.h" #include "xpcpublic.h" #include "nsIGlobalObject.h" #include "nsIScriptGlobalObject.h" #include "nsIScriptContext.h" #include "nsContentUtils.h" +#include "nsGlobalWindow.h" +#include "nsPIDOMWindow.h" #include "nsTArray.h" #include "nsJSUtils.h" namespace mozilla { namespace dom { static mozilla::ThreadLocal<ScriptSettingsStackEntry*> sScriptSettingsTLS; @@ -216,57 +218,110 @@ FindJSContext(nsIGlobalObject* aGlobalOb } if (!cx) { cx = nsContentUtils::GetSafeJSContext(); } return cx; } AutoJSAPI::AutoJSAPI() - : mCx(nsContentUtils::GetDefaultJSContextForThread()) + : mCx(nullptr) { - if (NS_IsMainThread()) { - mCxPusher.construct(mCx); - } - - // Leave the cx in a null compartment. - mNullAc.construct(mCx); } -AutoJSAPI::AutoJSAPI(JSContext *aCx, bool aIsMainThread, bool aSkipNullAc) - : mCx(aCx) +void +AutoJSAPI::InitInternal(JSObject* aGlobal, JSContext* aCx, bool aIsMainThread) { - MOZ_ASSERT_IF(aIsMainThread, NS_IsMainThread()); + mCx = aCx; if (aIsMainThread) { mCxPusher.construct(mCx); } - // In general we want to leave the cx in a null compartment, but we let - // subclasses skip this if they plan to immediately enter a compartment. - if (!aSkipNullAc) { - mNullAc.construct(mCx); - } + mAutoNullableCompartment.construct(mCx, aGlobal); +} + +AutoJSAPI::AutoJSAPI(nsIGlobalObject* aGlobalObject, + bool aIsMainThread, + JSContext* aCx) +{ + MOZ_ASSERT(aGlobalObject); + MOZ_ASSERT(aGlobalObject->GetGlobalJSObject(), "Must have a JS global"); + MOZ_ASSERT(aCx); + MOZ_ASSERT_IF(aIsMainThread, NS_IsMainThread()); + + InitInternal(aGlobalObject->GetGlobalJSObject(), aCx, aIsMainThread); +} + +void +AutoJSAPI::Init() +{ + MOZ_ASSERT(!mCx, "An AutoJSAPI should only be initialised once"); + + InitInternal(/* aGlobal */ nullptr, + nsContentUtils::GetDefaultJSContextForThread(), + NS_IsMainThread()); } -AutoJSAPIWithErrorsReportedToWindow::AutoJSAPIWithErrorsReportedToWindow(nsIScriptContext* aScx) - : AutoJSAPI(aScx->GetNativeContext(), /* aIsMainThread = */ true) +bool +AutoJSAPI::Init(nsIGlobalObject* aGlobalObject, JSContext* aCx) { + MOZ_ASSERT(!mCx, "An AutoJSAPI should only be initialised once"); + MOZ_ASSERT(aCx); + + if (NS_WARN_IF(!aGlobalObject)) { + return false; + } + + JSObject* global = aGlobalObject->GetGlobalJSObject(); + if (NS_WARN_IF(!global)) { + return false; + } + + InitInternal(global, aCx, NS_IsMainThread()); + return true; +} + +bool +AutoJSAPI::Init(nsIGlobalObject* aGlobalObject) +{ + return Init(aGlobalObject, nsContentUtils::GetDefaultJSContextForThread()); } -AutoJSAPIWithErrorsReportedToWindow::AutoJSAPIWithErrorsReportedToWindow(nsIGlobalObject* aGlobalObject) - : AutoJSAPI(FindJSContext(aGlobalObject), /* aIsMainThread = */ true) +bool +AutoJSAPI::InitWithLegacyErrorReporting(nsIGlobalObject* aGlobalObject) +{ + MOZ_ASSERT(NS_IsMainThread()); + + return Init(aGlobalObject, FindJSContext(aGlobalObject)); +} + +bool +AutoJSAPI::InitUsingWin(nsPIDOMWindow* aWindow, JSContext* aCx) { + return Init(static_cast<nsGlobalWindow*>(aWindow), aCx); +} + +bool +AutoJSAPI::InitUsingWin(nsPIDOMWindow* aWindow) +{ + return Init(static_cast<nsGlobalWindow*>(aWindow)); +} + +bool +AutoJSAPI::InitWithLegacyErrorReportingUsingWin(nsPIDOMWindow* aWindow) +{ + return InitWithLegacyErrorReporting(static_cast<nsGlobalWindow*>(aWindow)); } AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject, bool aIsMainThread, JSContext* aCx) - : AutoJSAPI(aCx ? aCx : FindJSContext(aGlobalObject), aIsMainThread, /* aSkipNullAc = */ true) + : AutoJSAPI(aGlobalObject, aIsMainThread, + aCx ? aCx : FindJSContext(aGlobalObject)) , ScriptSettingsStackEntry(aGlobalObject, /* aCandidate = */ true) - , mAc(cx(), aGlobalObject->GetGlobalJSObject()) , mWebIDLCallerPrincipal(nullptr) { MOZ_ASSERT(aGlobalObject); MOZ_ASSERT_IF(!aCx, aIsMainThread); // cx is mandatory off-main-thread. MOZ_ASSERT_IF(aCx && aIsMainThread, aCx == FindJSContext(aGlobalObject)); } AutoIncumbentScript::AutoIncumbentScript(nsIGlobalObject* aGlobalObject)
--- a/dom/base/ScriptSettings.h +++ b/dom/base/ScriptSettings.h @@ -11,17 +11,17 @@ #include "nsCxPusher.h" #include "MainThreadUtils.h" #include "nsIGlobalObject.h" #include "nsIPrincipal.h" #include "mozilla/Maybe.h" -class nsIGlobalObject; +class nsPIDOMWindow; namespace mozilla { namespace dom { /* * System-wide setup/teardown routines. Init and Destroy should be invoked * once each, at startup and shutdown (respectively). */ @@ -87,22 +87,24 @@ private: ScriptSettingsStackEntry *mOlder; }; /* * For any interaction with JSAPI, an AutoJSAPI (or one of its subclasses) * must be on the stack. * * This base class should be instantiated as-is when the caller wants to use - * JSAPI but doesn't expect to run script. Its current duties are as-follows: + * JSAPI but doesn't expect to run script. The caller must then call one of its + * Init functions before being able to access the JSContext through cx(). + * Its current duties are as-follows (see individual Init comments for details): * * * Grabbing an appropriate JSContext, and, on the main thread, pushing it onto * the JSContext stack. - * * Entering a null compartment, so that the consumer is forced to select a - * compartment to enter before manipulating objects. + * * Entering an initial (possibly null) compartment, to ensure that the + * previously entered compartment for that JSContext is not used by mistake. * * Additionally, the following duties are planned, but not yet implemented: * * * De-poisoning the JSRuntime to allow manipulation of JSAPI. We can't * actually implement this poisoning until all the JSContext pushing in the * system goes through AutoJSAPI (see bug 951991). For now, this de-poisoning * effectively corresponds to having a non-null cx on the stack. * * Reporting any exceptions left on the JSRuntime, unless the caller steals @@ -116,47 +118,74 @@ private: * should be used, which does additional manipulation of the script settings * stack. In bug 991758, we'll add hard invariants to SpiderMonkey, such that * any attempt to run script without an AutoEntryScript on the stack will * fail. This prevents system code from accidentally triggering script * execution at inopportune moments via surreptitious getters and proxies. */ class AutoJSAPI { public: - // Public constructor for use when the base class is constructed as-is. It - // uses the SafeJSContext (or worker equivalent), and enters a null - // compartment. + // Trivial constructor. One of the Init functions must be called before + // accessing the JSContext through cx(). AutoJSAPI(); - JSContext* cx() const { return mCx; } + + // This uses the SafeJSContext (or worker equivalent), and enters a null + // compartment, so that the consumer is forced to select a compartment to + // enter before manipulating objects. + void Init(); + + // This uses the SafeJSContext (or worker equivalent), and enters the + // compartment of aGlobalObject. + // If aGlobalObject or its associated JS global are null then it returns + // false and use of cx() will cause an assertion. + bool Init(nsIGlobalObject* aGlobalObject); + + // Unsurprisingly, this uses aCx and enters the compartment of aGlobalObject. + // If aGlobalObject or its associated JS global are null then it returns + // false and use of cx() will cause an assertion. + // If aCx is null it will cause an assertion. + bool Init(nsIGlobalObject* aGlobalObject, JSContext* aCx); + + // This may only be used on the main thread. + // This attempts to use the JSContext associated with aGlobalObject, otherwise + // it uses the SafeJSContext. It then enters the compartment of aGlobalObject. + // This means that existing error reporting mechanisms that use the JSContext + // to find the JSErrorReporter should still work as before. + // We should be able to remove this around bug 981198. + // If aGlobalObject or its associated JS global are null then it returns + // false and use of cx() will cause an assertion. + bool InitWithLegacyErrorReporting(nsIGlobalObject* aGlobalObject); + + // Convenience functions to take an nsPIDOMWindow*, when it is more easily + // available than an nsIGlobalObject. + bool InitUsingWin(nsPIDOMWindow* aWindow); + bool InitUsingWin(nsPIDOMWindow* aWindow, JSContext* aCx); + bool InitWithLegacyErrorReportingUsingWin(nsPIDOMWindow* aWindow); + + JSContext* cx() const { + MOZ_ASSERT(mCx, "Must call Init before using an AutoJSAPI"); + return mCx; + } bool CxPusherIsStackTop() { return mCxPusher.ref().IsStackTop(); } protected: // Protected constructor, allowing subclasses to specify a particular cx to - // be used. - AutoJSAPI(JSContext *aCx, bool aIsMainThread, bool aSkipNullAC = false); + // be used. This constructor initialises the AutoJSAPI, so Init must NOT be + // called on subclasses that use this. + // If aGlobalObject, its associated JS global or aCx are null this will cause + // an assertion, as will setting aIsMainThread incorrectly. + AutoJSAPI(nsIGlobalObject* aGlobalObject, bool aIsMainThread, JSContext* aCx); private: mozilla::Maybe<AutoCxPusher> mCxPusher; - mozilla::Maybe<JSAutoNullCompartment> mNullAc; + mozilla::Maybe<JSAutoNullableCompartment> mAutoNullableCompartment; JSContext *mCx; -}; -// Note - the ideal way to implement this is with an accessor on AutoJSAPI -// that lets us select the error reporting target. But at present, -// implementing it that way would require us to destroy and reconstruct -// mCxPusher, which is pretty wasteful. So we do this for now, since it should -// be pretty easy to switch things over later. -// -// This should only be used on the main thread. -class AutoJSAPIWithErrorsReportedToWindow : public AutoJSAPI { - public: - AutoJSAPIWithErrorsReportedToWindow(nsIScriptContext* aScx); - // Equivalent to AutoJSAPI if aGlobal is not a Window. - AutoJSAPIWithErrorsReportedToWindow(nsIGlobalObject* aGlobalObject); + void InitInternal(JSObject* aGlobal, JSContext* aCx, bool aIsMainThread); }; /* * A class that represents a new script entry point. */ class AutoEntryScript : public AutoJSAPI, protected ScriptSettingsStackEntry { public: @@ -165,17 +194,16 @@ public: // Note: aCx is mandatory off-main-thread. JSContext* aCx = nullptr); void SetWebIDLCallerPrincipal(nsIPrincipal *aPrincipal) { mWebIDLCallerPrincipal = aPrincipal; } private: - JSAutoCompartment mAc; // It's safe to make this a weak pointer, since it's the subject principal // when we go on the stack, so can't go away until after we're gone. In // particular, this is only used from the CallSetup constructor, and only in // the aIsJSImplementedWebIDL case. And in that case, the subject principal // is the principal of the callee function that is part of the CallArgs just a // bit up the stack, and which will outlive us. So we know the principal // can't go away until then either. nsIPrincipal* mWebIDLCallerPrincipal;
--- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -109,17 +109,16 @@ #include "nsITreeContentView.h" #include "nsITreeView.h" #include "nsIXULTemplateBuilder.h" #include "nsITreeColumns.h" #endif #include "nsIDOMXPathExpression.h" #include "nsIDOMNSXPathExpression.h" #include "nsIDOMXPathNSResolver.h" -#include "nsIDOMXPathResult.h" // Storage includes #include "nsIDOMStorage.h" #include "nsPIDOMStorage.h" // Drag and drop #include "nsIDOMFile.h" #include "nsDOMBlobBuilder.h" // nsDOMMultipartFile @@ -345,18 +344,16 @@ static nsDOMClassInfoData sClassInfoData NS_DEFINE_CLASSINFO_DATA(XSLTProcessor, nsDOMGenericSH, DOM_DEFAULT_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(XPathExpression, nsDOMGenericSH, DOM_DEFAULT_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(XPathNSResolver, nsDOMGenericSH, DOM_DEFAULT_SCRIPTABLE_FLAGS) - NS_DEFINE_CLASSINFO_DATA(XPathResult, nsDOMGenericSH, - DOM_DEFAULT_SCRIPTABLE_FLAGS) // WhatWG Storage // mrbkap says we don't need WANT_ADDPROPERTY on Storage objects // since a call to addProperty() is always followed by a call to // setProperty(), except in the case when a getter or setter is set // for a property. But we don't care about getters or setters here. NS_DEFINE_CLASSINFO_DATA(Storage, nsStorage2SH, @@ -953,20 +950,16 @@ nsDOMClassInfo::Init() DOM_CLASSINFO_MAP_ENTRY(nsIDOMXPathExpression) DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSXPathExpression) DOM_CLASSINFO_MAP_END DOM_CLASSINFO_MAP_BEGIN(XPathNSResolver, nsIDOMXPathNSResolver) DOM_CLASSINFO_MAP_ENTRY(nsIDOMXPathNSResolver) DOM_CLASSINFO_MAP_END - DOM_CLASSINFO_MAP_BEGIN(XPathResult, nsIDOMXPathResult) - DOM_CLASSINFO_MAP_ENTRY(nsIDOMXPathResult) - DOM_CLASSINFO_MAP_END - DOM_CLASSINFO_MAP_BEGIN(Storage, nsIDOMStorage) DOM_CLASSINFO_MAP_ENTRY(nsIDOMStorage) DOM_CLASSINFO_MAP_END DOM_CLASSINFO_MAP_BEGIN(Blob, nsIDOMBlob) DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlob) DOM_CLASSINFO_MAP_END
--- a/dom/base/nsDOMClassInfoClasses.h +++ b/dom/base/nsDOMClassInfoClasses.h @@ -43,17 +43,16 @@ DOMCI_CLASS(CSSMozDocumentRule) DOMCI_CLASS(CSSSupportsRule) // XSLTProcessor DOMCI_CLASS(XSLTProcessor) // DOM Level 3 XPath objects DOMCI_CLASS(XPathExpression) DOMCI_CLASS(XPathNSResolver) -DOMCI_CLASS(XPathResult) // WhatWG WebApps Objects DOMCI_CLASS(Storage) DOMCI_CLASS(Blob) DOMCI_CLASS(File) // DOM modal content window class, almost identical to Window
--- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -2354,16 +2354,17 @@ nsGlobalWindow::SetNewDocument(nsIDocume // clear smartcard events, our document has gone away. if (mCrypto && XRE_GetProcessType() != GeckoProcessType_Content) { nsresult rv = mCrypto->SetEnableSmartCardEvents(false); NS_ENSURE_SUCCESS(rv, rv); } #endif AutoJSAPI jsapi; + jsapi.Init(); JSContext *cx = jsapi.cx(); if (!mDoc) { // First document load. // Get our private root. If it is equal to us, then we need to // attach our global key bindings that handles browser scrolling // and other browser commands. @@ -8000,16 +8001,17 @@ NS_IMETHODIMP PostMessageEvent::Run() { NS_ABORT_IF_FALSE(mTargetWindow->IsOuterWindow(), "should have been passed an outer window!"); NS_ABORT_IF_FALSE(!mSource || mSource->IsOuterWindow(), "should have been passed an outer window!"); AutoJSAPI jsapi; + jsapi.Init(); JSContext* cx = jsapi.cx(); // If we bailed before this point we're going to leak mMessage, but // that's probably better than crashing. nsRefPtr<nsGlobalWindow> targetWindow; if (mTargetWindow->IsClosedOrClosing() || !(targetWindow = mTargetWindow->GetCurrentInnerWindowInternal()) ||
--- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -1590,16 +1590,17 @@ static const JSFunctionSpec JProfFunctio #endif /* defined(MOZ_JPROF) */ nsresult nsJSContext::InitClasses(JS::Handle<JSObject*> aGlobalObj) { JSOptionChangedCallback(js_options_dot_str, this); AutoJSAPI jsapi; + jsapi.Init(); JSContext* cx = jsapi.cx(); JSAutoCompartment ac(cx, aGlobalObj); // Attempt to initialize profiling functions ::JS_DefineProfilingFunctions(cx, aGlobalObj); #ifdef NS_TRACE_MALLOC if (nsContentUtils::IsCallerChrome()) {
--- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -258,17 +258,17 @@ DOMInterfaces = { 'resultNotAddRefed': ['getRGBColorValue', 'getRectValue'] }, 'CSSStyleDeclaration': { 'nativeType': 'nsICSSDeclaration' }, 'CSSStyleSheet': { - 'nativeType': 'nsCSSStyleSheet', + 'nativeType': 'mozilla::CSSStyleSheet', 'binaryNames': { 'ownerRule': 'DOMOwnerRule' }, }, 'CSSValue': { 'concrete': False }, 'CSSValueList': { @@ -1061,17 +1061,17 @@ DOMInterfaces = { 'workers': True, }, 'SourceBufferList': { 'resultNotAddRefed': [ '__indexedGetter' ], }, 'StyleSheet': { - 'nativeType': 'nsCSSStyleSheet', + 'nativeType': 'mozilla::CSSStyleSheet', }, 'SVGAnimatedLengthList': { 'nativeType': 'mozilla::DOMSVGAnimatedLengthList', 'headerFile': 'DOMSVGAnimatedLengthList.h', }, 'SVGAnimatedNumberList': { @@ -1654,16 +1654,20 @@ DOMInterfaces = { 'XMLStylesheetProcessingInstruction': { 'resultNotAddRefed': [ 'sheet' ] }, 'XPathEvaluator': { 'wrapperCache': False }, +'XPathResult': { + 'resultNotAddRefed': ['singleNodeValue', 'iterateNext', 'snapshotItem'] +}, + 'XULDocument': { 'headerFile': 'XULDocument.h' }, 'XULElement': { 'nativeType': 'nsXULElement', 'resultNotAddRefed': [ 'controllers', 'style' ] }, @@ -1991,12 +1995,11 @@ addExternalIface('OutputStream', nativeT notflattened=True) addExternalIface('Principal', nativeType='nsIPrincipal', headerFile='nsIPrincipal.h', notflattened=True) addExternalIface('StackFrame', nativeType='nsIStackFrame', headerFile='nsIException.h', notflattened=True) addExternalIface('URI', nativeType='nsIURI', headerFile='nsIURI.h', notflattened=True) addExternalIface('UserDataHandler') -addExternalIface('XPathResult', nativeType='nsISupports') addExternalIface('XPathExpression') addExternalIface('XPathNSResolver') addExternalIface('XULCommandDispatcher')
--- a/dom/bluetooth2/BluetoothAdapter.cpp +++ b/dom/bluetooth2/BluetoothAdapter.cpp @@ -694,17 +694,20 @@ BluetoothAdapter::EnableDisable(bool aEn promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR); return promise.forget(); } methodName.AssignLiteral("Disable"); mState = BluetoothAdapterState::Disabling; } nsTArray<nsString> types; - types.AppendElement(NS_LITERAL_STRING("State")); + BT_APPEND_ENUM_STRING(types, + BluetoothAdapterAttribute, + BluetoothAdapterAttribute::State); + DispatchAttributeEvent(types); nsRefPtr<BluetoothReplyRunnable> result = new BluetoothVoidReplyRunnable(nullptr, /* DOMRequest */ promise, methodName); if(NS_FAILED(bs->EnableDisable(aEnable, result))) { @@ -787,17 +790,17 @@ BluetoothAdapter::HandlePropertyChanged( if (type == BluetoothAdapterAttribute::Unknown) { SetPropertyByValue(arr[i]); continue; } // BluetoothAdapterAttribute properties if (IsAdapterAttributeChanged(type, arr[i].value())) { SetPropertyByValue(arr[i]); - types.AppendElement(arr[i].name()); + BT_APPEND_ENUM_STRING(types, BluetoothAdapterAttribute, type); } } DispatchAttributeEvent(types); } void BluetoothAdapter::DispatchAttributeEvent(const nsTArray<nsString>& aTypes)
--- a/dom/bluetooth2/BluetoothCommon.h +++ b/dom/bluetooth2/BluetoothCommon.h @@ -78,16 +78,28 @@ extern bool gBluetoothDebugFlag; do { \ if (!BroadcastSystemMessage(type, parameters)) { \ BT_WARNING("Failed to broadcast [%s]", \ NS_ConvertUTF16toUTF8(type).get()); \ return; \ } \ } while(0) +/** + * Convert an enum value to string then append it to an array. + */ +#define BT_APPEND_ENUM_STRING(array, enumType, enumValue) \ + do { \ + uint32_t index = uint32_t(enumValue); \ + nsAutoString name; \ + name.AssignASCII(enumType##Values::strings[index].value, \ + enumType##Values::strings[index].length); \ + array.AppendElement(name); \ + } while(0) \ + #define BEGIN_BLUETOOTH_NAMESPACE \ namespace mozilla { namespace dom { namespace bluetooth { #define END_BLUETOOTH_NAMESPACE \ } /* namespace bluetooth */ } /* namespace dom */ } /* namespace mozilla */ #define USING_BLUETOOTH_NAMESPACE \ using namespace mozilla::dom::bluetooth; #define KEY_LOCAL_AGENT "/B2G/bluetooth/agent"
--- a/dom/bluetooth2/BluetoothManager.cpp +++ b/dom/bluetooth2/BluetoothManager.cpp @@ -255,17 +255,19 @@ BluetoothManager::DispatchAttributeEvent NS_ENSURE_TRUE_VOID(global); JS::Rooted<JSObject*> scope(cx, global->GetGlobalJSObject()); NS_ENSURE_TRUE_VOID(scope); JSAutoCompartment ac(cx, scope); nsTArray<nsString> types; - types.AppendElement(NS_LITERAL_STRING("DefaultAdapter")); + BT_APPEND_ENUM_STRING(types, + BluetoothManagerAttribute, + BluetoothManagerAttribute::DefaultAdapter); if (!ToJSValue(cx, types, &value)) { JS_ClearPendingException(cx); return; } // Notify application of default adapter change RootedDictionary<BluetoothAttributeEventInit> init(cx);
--- a/dom/browser-element/BrowserElementParent.jsm +++ b/dom/browser-element/BrowserElementParent.jsm @@ -60,20 +60,16 @@ function visibilityChangeHandler(e) { } this.BrowserElementParentBuilder = { create: function create(frameLoader, hasRemoteFrame, isPendingFrame) { return new BrowserElementParent(frameLoader, hasRemoteFrame); } } - -// The active input method iframe. -let activeInputFrame = null; - function BrowserElementParent(frameLoader, hasRemoteFrame, isPendingFrame) { debug("Creating new BrowserElementParent object for " + frameLoader); this._domRequestCounter = 0; this._pendingDOMRequests = {}; this._pendingSetInputMethodActive = []; this._hasRemoteFrame = hasRemoteFrame; this._nextPaintListeners = []; @@ -108,22 +104,17 @@ function BrowserElementParent(frameLoade if (self._isAlive()) { fn.apply(self, arguments); } }; }; let defineDOMRequestMethod = function(domName, msgName) { XPCNativeWrapper.unwrap(self._frameElement)[domName] = function() { - if (!self._mm) { - return self._queueDOMRequest; - } - if (self._isAlive()) { - return self._sendDOMRequest(msgName); - } + return self._sendDOMRequest(msgName); }; } // Define methods on the frame element. defineNoReturnMethod('setVisible', this._setVisible); defineDOMRequestMethod('getVisible', 'get-visible'); defineNoReturnMethod('sendMouseEvent', this._sendMouseEvent); @@ -337,23 +328,16 @@ BrowserElementParent.prototype = { return false; } return true; }, _recvHello: function() { debug("recvHello"); - this._ready = true; - - // Handle pending SetInputMethodActive request. - while (this._pendingSetInputMethodActive.length > 0) { - this._setInputMethodActive(this._pendingSetInputMethodActive.shift()); - } - // Inform our child if our owner element's document is invisible. Note // that we must do so here, rather than in the BrowserElementParent // constructor, because the BrowserElementChild may not be initialized when // we run our constructor. if (this._window.document.hidden) { this._ownerVisibilityChange(); } @@ -477,60 +461,46 @@ BrowserElementParent.prototype = { } return new this._window.Event('mozbrowser' + evtName, { bubbles: true, cancelable: cancelable }); }, /** - * If remote frame haven't been set up, we enqueue a function that get a - * DOMRequest until the remote frame is ready and return another DOMRequest - * to caller. When we get the real DOMRequest, we will help forward the - * success/error callback to the DOMRequest that caller got. - */ - _queueDOMRequest: function(msgName, args) { - if (!this._pendingAPICalls) { - return; - } - - let req = Services.DOMRequest.createRequest(this._window); - let self = this; - let getRealDOMRequest = function() { - let realReq = self._sendDOMRequest(msgName, args); - realReq.onsuccess = function(v) { - Services.DOMRequest.fireSuccess(req, v); - }; - realReq.onerror = function(v) { - Services.DOMRequest.fireError(req, v); - }; - }; - this._pendingAPICalls.push(getRealDOMRequest); - return req; - }, - - /** * Kick off a DOMRequest in the child process. * * We'll fire an event called |msgName| on the child process, passing along * an object with two fields: * * - id: the ID of this request. * - arg: arguments to pass to the child along with this request. * * We expect the child to pass the ID back to us upon completion of the * request. See _gotDOMRequestResult. */ _sendDOMRequest: function(msgName, args) { let id = 'req_' + this._domRequestCounter++; let req = Services.DOMRequest.createRequest(this._window); - if (this._sendAsyncMsg(msgName, {id: id, args: args})) { - this._pendingDOMRequests[id] = req; + let self = this; + let send = function() { + if (!self._isAlive()) { + return; + } + if (self._sendAsyncMsg(msgName, {id: id, args: args})) { + self._pendingDOMRequests[id] = req; + } else { + Services.DOMRequest.fireErrorAsync(req, "fail"); + } + }; + if (this._mm) { + send(); } else { - Services.DOMRequest.fireErrorAsync(req, "fail"); + // Child haven't been loaded. + this._pendingAPICalls.push(send); } return req; }, /** * Called when the child process finishes handling a DOMRequest. data.json * must have the fields [id, successRv], if the DOMRequest was successful, or * [id, errorMsg], if the request was not successful. @@ -726,23 +696,16 @@ BrowserElementParent.prototype = { let height = parseInt(_height); let mimeType = (typeof _mimeType === 'string') ? _mimeType.trim().toLowerCase() : 'image/jpeg'; if (isNaN(width) || isNaN(height) || width < 0 || height < 0) { throw Components.Exception("Invalid argument", Cr.NS_ERROR_INVALID_ARG); } - if (!this._mm) { - // Child haven't been loaded. - return this._queueDOMRequest('get-screenshot', - {width: width, height: height, - mimeType: mimeType}); - } - return this._sendDOMRequest('get-screenshot', {width: width, height: height, mimeType: mimeType}); }, _recvNextPaint: function(data) { let listeners = this._nextPaintListeners; this._nextPaintListeners = []; @@ -795,60 +758,18 @@ BrowserElementParent.prototype = { }, _setInputMethodActive: function(isActive) { if (typeof isActive !== 'boolean') { throw Components.Exception("Invalid argument", Cr.NS_ERROR_INVALID_ARG); } - // Wait until browserElementChild is initialized. - if (!this._ready) { - this._pendingSetInputMethodActive.push(isActive); - return; - } - - let req = Services.DOMRequest.createRequest(this._window); - - // Deactivate the old input method if needed. - if (activeInputFrame && isActive) { - if (Cu.isDeadWrapper(activeInputFrame)) { - // If the activeInputFrame is already a dead object, - // we should simply set it to null directly. - activeInputFrame = null; - this._sendSetInputMethodActiveDOMRequest(req, isActive); - return req; - } - - let reqOld = XPCNativeWrapper.unwrap(activeInputFrame) - .setInputMethodActive(false); - - // We wan't to continue regardless whether this req succeeded - reqOld.onsuccess = reqOld.onerror = function() { - activeInputFrame = null; - this._sendSetInputMethodActiveDOMRequest(req, isActive); - }.bind(this); - } else { - this._sendSetInputMethodActiveDOMRequest(req, isActive); - } - return req; - }, - - _sendSetInputMethodActiveDOMRequest: function(req, isActive) { - let id = 'req_' + this._domRequestCounter++; - let data = { - id : id, - args: { isActive: isActive } - }; - if (this._sendAsyncMsg('set-input-method-active', data)) { - activeInputFrame = this._frameElement; - this._pendingDOMRequests[id] = req; - } else { - Services.DOMRequest.fireErrorAsync(req, 'fail'); - } + return this._sendDOMRequest('set-input-method-active', + {isActive: isActive}); }, _fireKeyEvent: function(data) { let evt = this._window.document.createEvent("KeyboardEvent"); evt.initKeyEvent(data.json.type, true, true, this._window, false, false, false, false, // modifiers data.json.keyCode, data.json.charCode);
--- a/dom/browser-element/mochitest/browserElement_SetInputMethodActive.js +++ b/dom/browser-element/mochitest/browserElement_SetInputMethodActive.js @@ -167,16 +167,23 @@ function next(msg) { // Do nothing and wait for the input to show up in input frame. break; case 2: is(from, 'input', 'Message sequence unexpected (2).'); is(value, '#0hello', 'Failed to get correct input from the first iframe.'); + let req0 = gFrames[0].setInputMethodActive(false); + req0.onsuccess = function() { + ok(true, 'setInputMethodActive succeeded (0).'); + }; + req0.onerror = function() { + ok(false, 'setInputMethodActive failed (0): ' + this.error.name); + }; let req1 = gFrames[1].setInputMethodActive(true); req1.onsuccess = function() { ok(true, 'setInputMethodActive succeeded (1).'); }; req1.onerror = function() { ok(false, 'setInputMethodActive failed (1): ' + this.error.name); }; break;
--- a/dom/camera/CameraPreferences.cpp +++ b/dom/camera/CameraPreferences.cpp @@ -1,15 +1,16 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "CameraPreferences.h" #include "CameraCommon.h" +#include "mozilla/ArrayUtils.h" #include "mozilla/Monitor.h" #include "mozilla/StaticPtr.h" #include "mozilla/Preferences.h" using namespace mozilla; /* statics */ static StaticAutoPtr<Monitor> sPrefMonitor;
--- a/dom/crypto/WebCryptoTask.cpp +++ b/dom/crypto/WebCryptoTask.cpp @@ -261,16 +261,20 @@ public: AesCbcParams params; nsresult rv = Coerce(aCx, params, aAlgorithm); if (NS_FAILED(rv) || !params.mIv.WasPassed()) { mEarlyRv = NS_ERROR_DOM_INVALID_ACCESS_ERR; return; } ATTEMPT_BUFFER_INIT(mIv, params.mIv.Value()) + if (mIv.Length() != 16) { + mEarlyRv = NS_ERROR_DOM_DATA_ERR; + return; + } } else if (algName.EqualsLiteral(WEBCRYPTO_ALG_AES_CTR)) { mMechanism = CKM_AES_CTR; telemetryAlg = TA_AES_CTR; AesCtrParams params; nsresult rv = Coerce(aCx, params, aAlgorithm); if (NS_FAILED(rv) || !params.mCounter.WasPassed() || !params.mLength.WasPassed()) { mEarlyRv = NS_ERROR_DOM_SYNTAX_ERR; @@ -1160,21 +1164,27 @@ public: hashName.Assign(hashAlg.mName.Value()); } if (params.mLength.WasPassed()) { mLength = params.mLength.Value(); } else { KeyAlgorithm hashAlg(global, hashName); switch (hashAlg.Mechanism()) { - case CKM_SHA_1: mLength = 128; break; - case CKM_SHA256: mLength = 256; break; - case CKM_SHA384: mLength = 384; break; - case CKM_SHA512: mLength = 512; break; - default: mLength = 0; break; + case CKM_SHA_1: + case CKM_SHA256: + mLength = 512; + break; + case CKM_SHA384: + case CKM_SHA512: + mLength = 1024; + break; + default: + mLength = 0; + break; } } if (mLength == 0) { mEarlyRv = NS_ERROR_DOM_DATA_ERR; return; }
--- a/dom/crypto/test/tests.js +++ b/dom/crypto/test/tests.js @@ -327,17 +327,32 @@ TestArray.addTest( // ----------------------------------------------------------------------------- TestArray.addTest( "Generate a 256-bit HMAC-SHA-256 key without specifying a key length", function() { var that = this; var alg = { name: "HMAC", hash: {name: "SHA-256"} }; crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then( complete(that, function(x) { - return hasKeyFields(x) && x.algorithm.length == 256; + return hasKeyFields(x) && x.algorithm.length == 512; + }), + error(that) + ); + } +); + +// ----------------------------------------------------------------------------- +TestArray.addTest( + "Generate a 256-bit HMAC-SHA-512 key without specifying a key length", + function() { + var that = this; + var alg = { name: "HMAC", hash: {name: "SHA-512"} }; + crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then( + complete(that, function(x) { + return hasKeyFields(x) && x.algorithm.length == 1024; }), error(that) ); } ); // ----------------------------------------------------------------------------- TestArray.addTest( @@ -455,16 +470,46 @@ TestArray.addTest( memcmp_complete(that, tv.aes_cbc_enc.result), error(that) ); } ); // ----------------------------------------------------------------------------- TestArray.addTest( + "AES-CBC encrypt with wrong IV size", + function () { + var that = this; + + function encrypt(x, iv) { + console.log(x); + return crypto.subtle.encrypt( + { name: "AES-CBC", iv: iv }, + x, tv.aes_cbc_enc.data); + } + + function doEncrypt(x) { + return encrypt(x, new Uint8Array(15)) + .then( + null, + function () { return encrypt(new Uint8Array(17)); } + ); + } + + crypto.subtle.importKey("raw", tv.aes_cbc_enc.key, "AES-CBC", false, ['encrypt']) + .then(doEncrypt) + .then( + error(that), + complete(that) + ); + } +); + +// ----------------------------------------------------------------------------- +TestArray.addTest( "AES-CBC decrypt", function () { var that = this; function doDecrypt(x) { return crypto.subtle.decrypt( { name: "AES-CBC", iv: tv.aes_cbc_dec.iv }, x, tv.aes_cbc_dec.data); @@ -476,16 +521,45 @@ TestArray.addTest( memcmp_complete(that, tv.aes_cbc_dec.result), error(that) ); } ); // ----------------------------------------------------------------------------- TestArray.addTest( + "AES-CBC decrypt with wrong IV size", + function () { + var that = this; + + function decrypt(x, iv) { + return crypto.subtle.decrypt( + { name: "AES-CBC", iv: iv }, + x, tv.aes_cbc_dec.data); + } + + function doDecrypt(x) { + return decrypt(x, new Uint8Array(15)) + .then( + null, + function () { return decrypt(x, new Uint8Array(17)); } + ); + } + + crypto.subtle.importKey("raw", tv.aes_cbc_dec.key, "AES-CBC", false, ['decrypt']) + .then(doDecrypt) + .then( + error(that), + complete(that) + ); + } +); + +// ----------------------------------------------------------------------------- +TestArray.addTest( "AES-CTR encryption", function () { var that = this; function doEncrypt(x) { return crypto.subtle.encrypt( { name: "AES-CTR", counter: tv.aes_ctr_enc.iv, length: 32 }, x, tv.aes_ctr_enc.data); @@ -497,16 +571,45 @@ TestArray.addTest( memcmp_complete(that, tv.aes_ctr_enc.result), error(that) ); } ); // ----------------------------------------------------------------------------- TestArray.addTest( + "AES-CTR encryption with wrong IV size", + function () { + var that = this; + + function encrypt(x, iv) { + return crypto.subtle.encrypt( + { name: "AES-CTR", counter: iv, length: 32 }, + x, tv.aes_ctr_enc.data); + } + + function doEncrypt(x) { + return encrypt(x, new Uint8Array(15)) + .then( + null, + function () { return encrypt(x, new Uint8Array(17)); } + ); + } + + crypto.subtle.importKey("raw", tv.aes_ctr_enc.key, "AES-CTR", false, ['encrypt']) + .then(doEncrypt) + .then( + error(that), + complete(that) + ); + } +); + +// ----------------------------------------------------------------------------- +TestArray.addTest( "AES-CTR decryption", function () { var that = this; function doDecrypt(x) { return crypto.subtle.decrypt( { name: "AES-CTR", counter: tv.aes_ctr_dec.iv, length: 32 }, x, tv.aes_ctr_dec.data); @@ -518,16 +621,45 @@ TestArray.addTest( memcmp_complete(that, tv.aes_ctr_dec.result), error(that) ); } ); // ----------------------------------------------------------------------------- TestArray.addTest( + "AES-CTR decryption with wrong IV size", + function () { + var that = this; + + function doDecrypt(x, iv) { + return crypto.subtle.decrypt( + { name: "AES-CTR", counter: iv, length: 32 }, + x, tv.aes_ctr_dec.data); + } + + function decrypt(x) { + return decrypt(x, new Uint8Array(15)) + .then( + null, + function () { return decrypt(x, new Uint8Array(17)); } + ); + } + + crypto.subtle.importKey("raw", tv.aes_ctr_dec.key, "AES-CTR", false, ['decrypt']) + .then(doDecrypt) + .then( + error(that), + complete(that) + ); + } +); + +// ----------------------------------------------------------------------------- +TestArray.addTest( "AES-GCM encryption", function () { var that = this; function doEncrypt(x) { return crypto.subtle.encrypt( { name: "AES-GCM",
--- a/dom/devicestorage/nsDeviceStorage.cpp +++ b/dom/devicestorage/nsDeviceStorage.cpp @@ -1719,25 +1719,21 @@ nsIFileToJsval(nsPIDOMWindow* aWindow, D return InterfaceToJsval(aWindow, blob, &NS_GET_IID(nsIDOMBlob)); } JS::Value StringToJsval(nsPIDOMWindow* aWindow, nsAString& aString) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aWindow); - JSObject* global = - static_cast<nsGlobalWindow*>(aWindow)->GetWrapperPreserveColor(); - if (NS_WARN_IF(!global)) { + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.InitUsingWin(aWindow))) { return JSVAL_NULL; } - - AutoJSAPI jsapi; JSContext* cx = jsapi.cx(); - JSAutoCompartment ac(cx, global); JS::Rooted<JS::Value> result(cx); if (!xpc::StringToJsval(cx, aString, &result)) { return JSVAL_NULL; } return result; }
--- a/dom/events/EventListenerManager.cpp +++ b/dom/events/EventListenerManager.cpp @@ -1,16 +1,17 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // Microsoft's API Name hackery sucks #undef CreateEvent +#include "mozilla/AddonPathService.h" #include "mozilla/BasicEvents.h" #include "mozilla/CycleCollectedJSRuntime.h" #include "mozilla/EventDispatcher.h" #include "mozilla/EventListenerManager.h" #ifdef MOZ_B2G #include "mozilla/Hal.h" #endif // #ifdef MOZ_B2G #include "mozilla/HalSensor.h" @@ -769,22 +770,22 @@ EventListenerManager::CompileEventHandle "What is there to compile?"); nsresult result = NS_OK; nsCOMPtr<nsIDocument> doc; nsCOMPtr<nsIScriptGlobalObject> global = GetScriptGlobalAndDocument(getter_AddRefs(doc)); NS_ENSURE_STATE(global); - nsIScriptContext* context = global->GetScriptContext(); - NS_ENSURE_STATE(context); - // Activate JSAPI, and make sure that exceptions are reported on the right // Window. - AutoJSAPIWithErrorsReportedToWindow jsapi(context); + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(global))) { + return NS_ERROR_UNEXPECTED; + } JSContext* cx = jsapi.cx(); nsCOMPtr<nsIAtom> typeAtom = aListener->mTypeAtom; nsIAtom* attrName = typeAtom; // Flag us as not a string so we don't keep trying to compile strings which // can't be compiled. aListener->mHandlerIsString = false; @@ -837,32 +838,45 @@ EventListenerManager::CompileEventHandle nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mTarget); uint32_t argCount; const char **argNames; nsContentUtils::GetEventArgNames(aElement->GetNameSpaceID(), typeAtom, win, &argCount, &argNames); + JSAddonId *addonId = MapURIToAddonID(uri); + // Wrap the event target, so that we can use it as the scope for the event // handler. Note that mTarget is different from aElement in the <body> case, // where mTarget is a Window. // // The wrapScope doesn't really matter here, because the target will create // its reflector in the proper scope, and then we'll enter that compartment. - JS::Rooted<JSObject*> wrapScope(cx, context->GetWindowProxy()); + JS::Rooted<JSObject*> wrapScope(cx, global->GetGlobalJSObject()); JS::Rooted<JS::Value> v(cx); { JSAutoCompartment ac(cx, wrapScope); nsresult rv = nsContentUtils::WrapNative(cx, mTarget, &v, /* aAllowWrapping = */ false); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } + if (addonId) { + JS::Rooted<JSObject*> vObj(cx, &v.toObject()); + JS::Rooted<JSObject*> addonScope(cx, xpc::GetAddonScope(cx, vObj, addonId)); + if (!addonScope) { + return NS_ERROR_FAILURE; + } + JSAutoCompartment ac(cx, addonScope); + if (!JS_WrapValue(cx, &v)) { + return NS_ERROR_FAILURE; + } + } JS::Rooted<JSObject*> target(cx, &v.toObject()); JSAutoCompartment ac(cx, target); nsDependentAtomString str(attrName); // Most of our names are short enough that we don't even have to malloc // the JS string stuff, so don't worry about playing games with // refcounting XPCOM stringbuffers. JS::Rooted<JSString*> jsStr(cx, JS_NewUCStringCopyN(cx,
--- a/dom/icc/src/Icc.cpp +++ b/dom/icc/src/Icc.cpp @@ -43,23 +43,21 @@ nsresult Icc::NotifyEvent(const nsAString& aName) { return DispatchTrustedEvent(aName); } nsresult Icc::NotifyStkEvent(const nsAString& aName, const nsAString& aMessage) { - nsresult rv; - nsIScriptContext* sc = GetContextForEventHandlers(&rv); - NS_ENSURE_SUCCESS(rv, rv); - - AutoJSAPIWithErrorsReportedToWindow jsapi(sc); + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReportingUsingWin(GetOwner()))) { + return NS_ERROR_UNEXPECTED; + } JSContext* cx = jsapi.cx(); - JSAutoCompartment ac(cx, sc->GetWindowProxyPreserveColor()); JS::Rooted<JS::Value> value(cx); if (!aMessage.IsEmpty()) { nsCOMPtr<nsIJSON> json(new nsJSON()); nsresult rv = json->DecodeToJSVal(aMessage, cx, &value); NS_ENSURE_SUCCESS(rv, rv); } else { value = JS::NullValue();
--- a/dom/imptests/failures/editing/conformancetest/test_runtest.html.json +++ b/dom/imptests/failures/editing/conformancetest/test_runtest.html.json @@ -3867,19 +3867,16 @@ "[[\"stylewithcss\",\"false\"],[\"defaultparagraphseparator\",\"p\"],[\"inserthorizontalrule\",\"\"]] \"<p>foo<b>b[a]r</b>baz</p>\" queryCommandValue(\"defaultparagraphseparator\") before":true, "[[\"stylewithcss\",\"false\"],[\"defaultparagraphseparator\",\"p\"],[\"inserthorizontalrule\",\"\"]] \"<p>foo<b>b[a]r</b>baz</p>\" queryCommandValue(\"defaultparagraphseparator\") after":true, "[[\"inserthorizontalrule\",\"\"]] \"<address>foo[bar]baz</address>\" compare innerHTML":true, "[[\"inserthorizontalrule\",\"\"]] \"<bdi>foo[bar]baz</bdi>\" compare innerHTML":true, "[[\"inserthorizontalrule\",\"\"]] \"<blink>foo[bar]baz</blink>\" compare innerHTML":true, "[[\"inserthorizontalrule\",\"\"]] \"<table><caption>foo[bar]baz</caption><tr><td>quz</table>\": execCommand(\"inserthorizontalrule\", false, \"\") return value":true, "[[\"inserthorizontalrule\",\"\"]] \"<table><caption>foo[bar]baz</caption><tr><td>quz</table>\" compare innerHTML":true, "[[\"inserthorizontalrule\",\"\"]] \"<dl><dt>foo[bar]baz</dt></dl>\" compare innerHTML":true, - "[[\"inserthorizontalrule\",\"\"]] \"<ruby>foo[bar]baz<rt>quz</rt></ruby>\" compare innerHTML":true, - "[[\"inserthorizontalrule\",\"\"]] \"<ruby>foo<rt>bar[baz]quz</rt></ruby>\" compare innerHTML":true, - "[[\"inserthorizontalrule\",\"\"]] \"<ruby>foo<rp>bar[baz]quz</rp><rt>qoz</rt><rp>qiz</rp></ruby>\" compare innerHTML":true, "[[\"inserthorizontalrule\",\"\"]] \"fo[o<span contenteditable=false>bar</span>b]az\" compare innerHTML":true, "[[\"stylewithcss\",\"true\"],[\"inserthtml\",\"ab<b>c</b>d\"]] \"[foo<span style=color:#aBcDeF>bar]</span>baz\" compare innerHTML":true, "[[\"stylewithcss\",\"false\"],[\"inserthtml\",\"ab<b>c</b>d\"]] \"[foo<span style=color:#aBcDeF>bar]</span>baz\" compare innerHTML":true, "[[\"stylewithcss\",\"true\"],[\"inserthtml\",\"ab<b>c</b>d\"]] \"{foo<span style=color:#aBcDeF>bar}</span>baz\" compare innerHTML":true, "[[\"stylewithcss\",\"false\"],[\"inserthtml\",\"ab<b>c</b>d\"]] \"{foo<span style=color:#aBcDeF>bar}</span>baz\" compare innerHTML":true, "[[\"stylewithcss\",\"true\"],[\"inserthtml\",\"ab<b>c</b>d\"]] \"foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz\" compare innerHTML":true, "[[\"stylewithcss\",\"false\"],[\"inserthtml\",\"ab<b>c</b>d\"]] \"foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz\" compare innerHTML":true, "[[\"inserthtml\",\"\"]] \"foo[bar]baz\": execCommand(\"inserthtml\", false, \"\") return value":true,
--- a/dom/interfaces/xpath/nsIDOMNSXPathExpression.idl +++ b/dom/interfaces/xpath/nsIDOMNSXPathExpression.idl @@ -1,16 +1,15 @@ /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "domstubs.idl" -interface nsIDOMXPathResult; interface XPathException; /** * Interface for Mozilla specific XPathExpression functions. */ [scriptable, uuid(ce600ca8-e98a-4419-ad61-2f6d0cb0ecc8)] interface nsIDOMNSXPathExpression : nsISupports {
--- a/dom/interfaces/xpath/nsIDOMXPathEvaluator.idl +++ b/dom/interfaces/xpath/nsIDOMXPathEvaluator.idl @@ -5,17 +5,16 @@ /** * Corresponds to http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020208 */ #include "domstubs.idl" interface nsIDOMXPathNSResolver; -interface nsIDOMXPathResult; interface nsIDOMXPathExpression; interface XPathException; [uuid(75506f8a-b504-11d5-a7f2-ca108ab8b6fc)] interface nsIDOMXPathEvaluator : nsISupports { nsIDOMXPathExpression createExpression(in DOMString expression, in nsIDOMXPathNSResolver resolver)
--- a/dom/interfaces/xpath/nsIDOMXPathExpression.idl +++ b/dom/interfaces/xpath/nsIDOMXPathExpression.idl @@ -4,17 +4,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** * Corresponds to http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020208 */ #include "domstubs.idl" -interface nsIDOMXPathResult; interface XPathException; [scriptable, uuid(75506f82-b504-11d5-a7f2-ca108ab8b6fc)] interface nsIDOMXPathExpression : nsISupports { nsISupports evaluate(in nsIDOMNode contextNode, in unsigned short type, in nsISupports result)
--- a/dom/interfaces/xpath/nsIDOMXPathResult.idl +++ b/dom/interfaces/xpath/nsIDOMXPathResult.idl @@ -2,50 +2,25 @@ /* 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/. */ /** * Corresponds to http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020208 */ -#include "domstubs.idl" +#include "nsISupports.idl" -interface XPathException; - -[scriptable, uuid(75506f84-b504-11d5-a7f2-ca108ab8b6fc)] +[uuid(75506f84-b504-11d5-a7f2-ca108ab8b6fc)] interface nsIDOMXPathResult : nsISupports { // XPathResultType const unsigned short ANY_TYPE = 0; const unsigned short NUMBER_TYPE = 1; const unsigned short STRING_TYPE = 2; const unsigned short BOOLEAN_TYPE = 3; const unsigned short UNORDERED_NODE_ITERATOR_TYPE = 4; const unsigned short ORDERED_NODE_ITERATOR_TYPE = 5; const unsigned short UNORDERED_NODE_SNAPSHOT_TYPE = 6; const unsigned short ORDERED_NODE_SNAPSHOT_TYPE = 7; const unsigned short ANY_UNORDERED_NODE_TYPE = 8; const unsigned short FIRST_ORDERED_NODE_TYPE = 9; - - readonly attribute unsigned short resultType; - readonly attribute double numberValue; - // raises(XPathException) on retrieval - - readonly attribute DOMString stringValue; - // raises(XPathException) on retrieval - - readonly attribute boolean booleanValue; - // raises(XPathException) on retrieval - - readonly attribute nsIDOMNode singleNodeValue; - // raises(XPathException) on retrieval - - readonly attribute boolean invalidIteratorState; - readonly attribute unsigned long snapshotLength; - // raises(XPathException) on retrieval - - nsIDOMNode iterateNext() - raises(XPathException, - DOMException); - nsIDOMNode snapshotItem(in unsigned long index) - raises(XPathException); };
--- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -826,17 +826,18 @@ ContentParent::AnswerBridgeToChildProces // You can't bridge to a process you didn't open! KillHard(); return false; } } /*static*/ TabParent* ContentParent::CreateBrowserOrApp(const TabContext& aContext, - Element* aFrameElement) + Element* aFrameElement, + ContentParent* aOpenerContentParent) { if (!sCanLaunchSubprocesses) { return nullptr; } ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement); if (aContext.IsBrowserElement() || !aContext.HasOwnApp()) { @@ -858,19 +859,22 @@ ContentParent::CreateBrowserOrApp(const if (!child->CallBridgeToChildProcess(id)) { return nullptr; } ContentBridgeParent* parent = child->GetLastBridge(); parent->SetChildID(id); parent->SetIsForApp(isForApp); parent->SetIsForBrowser(isForBrowser); constructorSender = parent; - } else if (nsRefPtr<ContentParent> cp = - GetNewOrUsed(aContext.IsBrowserElement(), initialPriority)) { - constructorSender = cp; + } else { + if (aOpenerContentParent) { + constructorSender = aOpenerContentParent; + } else { + constructorSender = GetNewOrUsed(aContext.IsBrowserElement(), initialPriority); + } } if (constructorSender) { uint32_t chromeFlags = 0; // Propagate the private-browsing status of the element's parent // docshell to the remote docshell, via the chrome flags. nsCOMPtr<Element> frameElement = do_QueryInterface(aFrameElement); MOZ_ASSERT(frameElement);
--- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -110,17 +110,18 @@ public: /** * Get or create a content process for the given TabContext. aFrameElement * should be the frame/iframe element with which this process will * associated. */ static TabParent* CreateBrowserOrApp(const TabContext& aContext, - Element* aFrameElement); + Element* aFrameElement, + ContentParent* aOpenerContentParent); static void GetAll(nsTArray<ContentParent*>& aArray); static void GetAllEvenIfDead(nsTArray<ContentParent*>& aArray); static bool IgnoreIPCPrincipal(); virtual bool RecvCreateChildProcess(const IPCTabContext& aContext, const hal::ProcessPriority& aPriority,
--- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -89,17 +89,25 @@ parent: /** * When child sends this message, parent should move focus to * the next or previous focusable element. */ MoveFocus(bool forward); Event(RemoteDOMEvent aEvent); - intr CreateWindow() returns (PBrowser window); + intr CreateWindow(uint32_t aChromeFlags, + bool aCalledFromJS, + bool aPositionSpecified, + bool aSizeSpecified, + nsString aURI, + nsString aName, + nsString aFeatures, + nsString aBaseURI) + returns (bool windowIsNew, PBrowser window); sync SyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows, Principal aPrincipal) returns (nsString[] retval); rpc RpcMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows, Principal aPrincipal) returns (nsString[] retval);
--- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -37,19 +37,21 @@ #include "nsEmbedCID.h" #include <algorithm> #ifdef MOZ_CRASHREPORTER #include "nsExceptionHandler.h" #endif #include "nsFilePickerProxy.h" #include "mozilla/dom/Element.h" #include "nsIBaseWindow.h" +#include "nsIBrowserDOMWindow.h" #include "nsICachedFileDescriptorListener.h" #include "nsIDocumentInlines.h" #include "nsIDocShellTreeOwner.h" +#include "nsIDOMChromeWindow.h" #include "nsIDOMEvent.h" #include "nsIDOMWindow.h" #include "nsIDOMWindowUtils.h" #include "nsIDocShell.h" #include "nsIURI.h" #include "nsIURIFixup.h" #include "nsCDefaultURIFixup.h" #include "nsIWebBrowser.h" @@ -59,16 +61,17 @@ #include "nsIXULRuntime.h" #include "nsInterfaceHashtable.h" #include "nsPIDOMWindow.h" #include "nsPIWindowRoot.h" #include "nsLayoutUtils.h" #include "nsPrintfCString.h" #include "nsThreadUtils.h" #include "nsWeakReference.h" +#include "nsWindowWatcher.h" #include "PermissionMessageUtils.h" #include "PCOMContentPermissionRequestChild.h" #include "PuppetWidget.h" #include "StructuredCloneUtils.h" #include "nsViewportInfo.h" #include "JavaScriptChild.h" #include "nsILoadContext.h" #include "ipc/nsGUIEventIPC.h" @@ -1225,23 +1228,78 @@ TabChild::ProvideWindow(nsIDOMWindow* aP // Note that BrowserFrameProvideWindow may return NS_ERROR_ABORT if the // open window call was canceled. It's important that we pass this error // code back to our caller. return BrowserFrameProvideWindow(aParent, aURI, aName, aFeatures, aWindowIsNew, aReturn); } - // Otherwise, create a new top-level window. + int32_t openLocation = + nsWindowWatcher::GetWindowOpenLocation(aParent, aChromeFlags, aCalledFromJS, + aPositionSpecified, aSizeSpecified); + + // If it turns out we're opening in the current browser, just hand over the + // current browser's docshell. + if (openLocation == nsIBrowserDOMWindow::OPEN_CURRENTWINDOW) { + nsCOMPtr<nsIWebBrowser> browser = do_GetInterface(WebNavigation()); + *aWindowIsNew = false; + return browser->GetContentDOMWindow(aReturn); + } + + // Otherwise, we're opening a new tab or a new window. We have to contact + // TabParent in order to do either. + PBrowserChild* newChild; - if (!CallCreateWindow(&newChild)) { + + nsAutoCString uriString; + if (aURI) { + aURI->GetSpec(uriString); + } + + nsCOMPtr<nsIDOMDocument> domDoc; + aParent->GetDocument(getter_AddRefs(domDoc)); + if (!domDoc) { + NS_ERROR("Could retrieve document from nsIBaseWindow"); + return NS_ERROR_FAILURE; + } + + nsCOMPtr<nsIDocument> doc; + doc = do_QueryInterface(domDoc); + if (!doc) { + NS_ERROR("Document from nsIBaseWindow didn't QI to nsIDocument"); + return NS_ERROR_FAILURE; + } + + nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI(); + if (!baseURI) { + NS_ERROR("nsIDocument didn't return a base URI"); + return NS_ERROR_FAILURE; + } + + nsAutoCString baseURIString; + baseURI->GetSpec(baseURIString); + + nsAutoString nameString; + nameString.Assign(aName); + nsAutoCString features; + + // We can assume that if content is requesting to open a window from a remote + // tab, then we want to enforce that the new window is also a remote tab. + features.Assign(aFeatures); + features.Append(",remote"); + + if (!CallCreateWindow(aChromeFlags, aCalledFromJS, aPositionSpecified, + aSizeSpecified, NS_ConvertUTF8toUTF16(uriString), + nameString, NS_ConvertUTF8toUTF16(features), + NS_ConvertUTF8toUTF16(baseURIString), + aWindowIsNew, &newChild)) { return NS_ERROR_NOT_AVAILABLE; } - *aWindowIsNew = true; nsCOMPtr<nsIDOMWindow> win = do_GetInterface(static_cast<TabChild*>(newChild)->WebNavigation()); win.forget(aReturn); return NS_OK; } nsresult TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
--- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -39,25 +39,28 @@ #include "nsIDOMElement.h" #include "nsIDOMEvent.h" #include "nsIDOMWindow.h" #include "nsIDOMWindowUtils.h" #include "nsIInterfaceRequestorUtils.h" #include "nsIPromptFactory.h" #include "nsIURI.h" #include "nsIWebBrowserChrome.h" +#include "nsIWindowCreator2.h" #include "nsIXULBrowserWindow.h" #include "nsIXULWindow.h" #include "nsViewManager.h" #include "nsIWidget.h" #include "nsIWindowWatcher.h" #include "nsPIDOMWindow.h" +#include "nsPIWindowWatcher.h" #include "nsPrintfCString.h" #include "nsServiceManagerUtils.h" #include "nsThreadUtils.h" +#include "nsWindowWatcher.h" #include "private/pprio.h" #include "PermissionMessageUtils.h" #include "StructuredCloneUtils.h" #include "ColorPickerParent.h" #include "JavaScriptParent.h" #include "FilePickerParent.h" #include "TabChild.h" #include "LoadContext.h" @@ -383,45 +386,105 @@ TabParent::RecvEvent(const RemoteDOMEven event->SetOwner(target); bool dummy; target->DispatchEvent(event, &dummy); return true; } bool -TabParent::AnswerCreateWindow(PBrowserParent** retval) +TabParent::AnswerCreateWindow(const uint32_t& aChromeFlags, + const bool& aCalledFromJS, + const bool& aPositionSpecified, + const bool& aSizeSpecified, + const nsString& aURI, + const nsString& aName, + const nsString& aFeatures, + const nsString& aBaseURI, + bool* aWindowIsNew, + PBrowserParent** aRetVal) { - if (!mBrowserDOMWindow) { - return false; - } + if (IsBrowserOrApp()) { + return false; + } + + nsresult rv; + nsCOMPtr<nsPIWindowWatcher> pwwatch = + do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, false); - // Only non-app, non-browser processes may call CreateWindow. - if (IsBrowserOrApp()) { - return false; - } + nsCOMPtr<nsIContent> frame(do_QueryInterface(mFrameElement)); + NS_ENSURE_TRUE(frame, false); + + nsCOMPtr<nsIDOMWindow> parent = do_QueryInterface(frame->OwnerDoc()->GetWindow()); + NS_ENSURE_TRUE(parent, false); + + int32_t openLocation = + nsWindowWatcher::GetWindowOpenLocation(parent, aChromeFlags, aCalledFromJS, + aPositionSpecified, aSizeSpecified); - // Get a new rendering area from the browserDOMWin. We don't want - // to be starting any loads here, so get it with a null URI. + MOZ_ASSERT(openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB || + openLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW); + + *aWindowIsNew = true; + + // Opening new tabs is the easy case... + if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) { + NS_ENSURE_TRUE(mBrowserDOMWindow, false); + nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner; mBrowserDOMWindow->OpenURIInFrame(nullptr, nullptr, nsIBrowserDOMWindow::OPEN_NEWTAB, nsIBrowserDOMWindow::OPEN_NEW, getter_AddRefs(frameLoaderOwner)); - if (!frameLoaderOwner) { - return false; - } + NS_ENSURE_TRUE(frameLoaderOwner, false); nsRefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader(); - if (!frameLoader) { - return false; - } + NS_ENSURE_TRUE(frameLoader, false); + + *aRetVal = frameLoader->GetRemoteBrowser(); + return true; + } + + // WindowWatcher is going to expect a valid URI to open a window + // to. If it can't find one, it's going to attempt to figure one + // out on its own, which is problematic because it can't access + // the document for the remote browser we're opening. Luckily, + // TabChild has sent us a baseURI with which we can ensure that + // the URI we pass to WindowWatcher is valid. + nsCOMPtr<nsIURI> baseURI; + rv = NS_NewURI(getter_AddRefs(baseURI), aBaseURI); + NS_ENSURE_SUCCESS(rv, false); + + nsCOMPtr<nsIURI> finalURI; + rv = NS_NewURI(getter_AddRefs(finalURI), NS_ConvertUTF16toUTF8(aURI).get(), baseURI); + NS_ENSURE_SUCCESS(rv, false); - *retval = frameLoader->GetRemoteBrowser(); - return true; + nsAutoCString finalURIString; + finalURI->GetSpec(finalURIString); + + nsCOMPtr<nsIDOMWindow> window; + + rv = pwwatch->OpenWindow2(parent, finalURIString.get(), + NS_ConvertUTF16toUTF8(aName).get(), + NS_ConvertUTF16toUTF8(aFeatures).get(), aCalledFromJS, + false, false, this, nullptr, getter_AddRefs(window)); + NS_ENSURE_SUCCESS(rv, false); + + nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(window); + NS_ENSURE_TRUE(pwindow, false); + + nsRefPtr<nsIDocShell> newDocShell = pwindow->GetDocShell(); + NS_ENSURE_TRUE(newDocShell, false); + + nsCOMPtr<nsITabParent> newRemoteTab = newDocShell->GetOpenedRemote(); + NS_ENSURE_TRUE(newRemoteTab, false); + + *aRetVal = static_cast<TabParent*>(newRemoteTab.get()); + return true; } void TabParent::LoadURL(nsIURI* aURI) { MOZ_ASSERT(aURI); if (mIsDestroyed) {
--- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -122,17 +122,26 @@ public: TextureFactoryIdentifier* aFactoryIdentifier, uint64_t* aLayersId, bool* aSuccess) MOZ_OVERRIDE; virtual bool RecvBrowserFrameOpenWindow(PBrowserParent* aOpener, const nsString& aURL, const nsString& aName, const nsString& aFeatures, bool* aOutWindowOpened) MOZ_OVERRIDE; - virtual bool AnswerCreateWindow(PBrowserParent** retval) MOZ_OVERRIDE; + virtual bool AnswerCreateWindow(const uint32_t& aChromeFlags, + const bool& aCalledFromJS, + const bool& aPositionSpecified, + const bool& aSizeSpecified, + const nsString& aURI, + const nsString& aName, + const nsString& aFeatures, + const nsString& aBaseURI, + bool* aWindowIsNew, + PBrowserParent** aRetVal) MOZ_OVERRIDE; virtual bool RecvSyncMessage(const nsString& aMessage, const ClonedMessageData& aData, const InfallibleTArray<CpowEntry>& aCpows, const IPC::Principal& aPrincipal, InfallibleTArray<nsString>* aJSONRetVal) MOZ_OVERRIDE; virtual bool AnswerRpcMessage(const nsString& aMessage, const ClonedMessageData& aData, const InfallibleTArray<CpowEntry>& aCpows,
--- a/dom/mobileconnection/tests/marionette/head.js +++ b/dom/mobileconnection/tests/marionette/head.js @@ -561,29 +561,77 @@ function sendMMI(aMmi) { return wrapDomRequestAsPromise(request) .then(null, () => { throw request.error }); } /** * Query current voice privacy mode. * * Fulfill params: - A boolean indicates the current voice privacy mode. + * A boolean indicates the current voice privacy mode. * Reject params: * 'RadioNotAvailable', 'RequestNotSupported', or 'GenericFailure'. * * @return A deferred promise. */ function getVoicePrivacyMode() { let request = mobileConnection.getVoicePrivacyMode(); return wrapDomRequestAsPromise(request) .then(() => request.result, () => { throw request.error }); } /** + * Configures call barring options. + * + * Fulfill params: (none) + * Reject params: + * 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter' or + * 'GenericFailure'. + * + * @return A deferred promise. + */ + function setCallBarringOption(aOptions) { + let request = mobileConnection.setCallBarringOption(aOptions); + return wrapDomRequestAsPromise(request) + .then(null, () => { throw request.error }); +} + +/** + * Queries current call barring status. + * + * Fulfill params: + * An object contains call barring status. + * Reject params: + * 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter' or + * 'GenericFailure'. + * + * @return A deferred promise. + */ + function getCallBarringOption(aOptions) { + let request = mobileConnection.getCallBarringOption(aOptions); + return wrapDomRequestAsPromise(request) + .then(() => request.result, () => { throw request.error }); +} + +/** + * Change call barring facility password. + * + * Fulfill params: (none) + * Reject params: + * 'RadioNotAvailable', 'RequestNotSupported', or 'GenericFailure'. + * + * @return A deferred promise. + */ + function changeCallBarringPassword(aOptions) { + let request = mobileConnection.changeCallBarringPassword(aOptions); + return wrapDomRequestAsPromise(request) + .then(null, () => { throw request.error }); +} + +/** * Set data connection enabling state and wait for "datachange" event. * * Resolve if data connection state changed to the expected one. Never reject. * * Fulfill params: (none) * * @param aEnabled * A boolean state. @@ -954,16 +1002,104 @@ function setEmulatorOperatorNamesAndWait if (aWaitData) { promises.push(waitForManagerEvent("datachange")); } promises.push(setEmulatorOperatorNames(aOperator, aLongName, aShortName, aMcc, aMnc)); return Promise.all(promises); } +/** + * Set GSM signal strength. + * + * Fulfill params: (none) + * Reject params: (none) + * + * @param aRssi + * + * @return A deferred promise. + */ +function setEmulatorGsmSignalStrength(aRssi) { + let cmd = "gsm signal " + aRssi; + return runEmulatorCmdSafe(cmd); +} + +/** + * Set emulator GSM signal strength and wait for voice and/or data state change. + * + * Fulfill params: (none) + * + * @param aRssi + * @param aWaitVoice [optional] + * A boolean value. Default true. + * @param aWaitData [optional] + * A boolean value. Default false. + * + * @return A deferred promise. + */ +function setEmulatorGsmSignalStrengthAndWait(aRssi, + aWaitVoice = true, + aWaitData = false) { + let promises = []; + if (aWaitVoice) { + promises.push(waitForManagerEvent("voicechange")); + } + if (aWaitData) { + promises.push(waitForManagerEvent("datachange")); + } + promises.push(setEmulatorGsmSignalStrength(aRssi)); + return Promise.all(promises); +} + +/** + * Set LTE signal strength. + * + * Fulfill params: (none) + * Reject params: (none) + * + * @param aRxlev + * @param aRsrp + * @param aRssnr + * + * @return A deferred promise. + */ +function setEmulatorLteSignalStrength(aRxlev, aRsrp, aRssnr) { + let cmd = "gsm lte_signal " + aRxlev + " " + aRsrp + " " + aRssnr; + return runEmulatorCmdSafe(cmd); +} + +/** + * Set emulator LTE signal strength and wait for voice and/or data state change. + * + * Fulfill params: (none) + * + * @param aRxlev + * @param aRsrp + * @param aRssnr + * @param aWaitVoice [optional] + * A boolean value. Default true. + * @param aWaitData [optional] + * A boolean value. Default false. + * + * @return A deferred promise. + */ +function setEmulatorLteSignalStrengthAndWait(aRxlev, aRsrp, aRssnr, + aWaitVoice = true, + aWaitData = false) { + let promises = []; + if (aWaitVoice) { + promises.push(waitForManagerEvent("voicechange")); + } + if (aWaitData) { + promises.push(waitForManagerEvent("datachange")); + } + promises.push(setEmulatorLteSignalStrength(aRxlev, aRsrp, aRssnr)); + return Promise.all(promises); +} + let _networkManager; /** * Get internal NetworkManager service. */ function getNetworkManager() { if (!_networkManager) { _networkManager = Cc["@mozilla.org/network/manager;1"]
deleted file mode 100644 --- a/dom/mobileconnection/tests/marionette/mobile_header.js +++ /dev/null @@ -1,60 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -SpecialPowers.addPermission("mobileconnection", true, document); - -// In single sim scenario, there is only one mobileConnection, we can always use -// the first instance. -let mobileConnection = window.navigator.mozMobileConnections[0]; -ok(mobileConnection instanceof MozMobileConnection, - "mobileConnection is instanceof " + mobileConnection.constructor); - -let _pendingEmulatorCmdCount = 0; - -/* Remove permission and execute finish() */ -let cleanUp = function() { - waitFor(function() { - SpecialPowers.removePermission("mobileconnection", document); - finish(); - }, function() { - return _pendingEmulatorCmdCount === 0; - }); -}; - -/* Helper for tasks */ -let taskHelper = { - tasks: [], - - push: function(task) { - this.tasks.push(task); - }, - - runNext: function() { - let task = this.tasks.shift(); - if (!task) { - cleanUp(); - return; - } - - if (typeof task === "function") { - task(); - } - }, -}; - -/* Helper for emulator console command */ -let emulatorHelper = { - sendCommand: function(cmd, callback) { - _pendingEmulatorCmdCount++; - runEmulatorCmd(cmd, function(results) { - _pendingEmulatorCmdCount--; - - let result = results[results.length - 1]; - is(result, "OK", "'"+ cmd +"' returns '" + result + "'"); - - if (callback && typeof callback === "function") { - callback(results); - } - }); - }, -};
--- a/dom/mobileconnection/tests/marionette/test_call_barring_change_password.js +++ b/dom/mobileconnection/tests/marionette/test_call_barring_change_password.js @@ -1,63 +1,50 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = "head.js"; -SpecialPowers.addPermission("mobileconnection", true, document); +const TEST_DATA = [ + // [<pin>, <new pin>, <expected error>] -// Permission changes can't change existing Navigator.prototype -// objects, so grab our objects from a new Navigator -let ifr = document.createElement("iframe"); -let connection; -ifr.onload = function() { - connection = ifr.contentWindow.navigator.mozMobileConnections[0]; + // Test passing an invalid pin or newPin. + [null, "0000", "InvalidPassword"], + ["0000", null, "InvalidPassword"], + [null, null, "InvalidPassword"], - ok(connection instanceof ifr.contentWindow.MozMobileConnection, - "connection is instanceof " + connection.constructor); - - setTimeout(testChangeCallBarringPasswordWithFailure, 0); -}; -document.body.appendChild(ifr); + // Test passing mismatched newPin. + ["000", "0000", "InvalidPassword"], + ["00000", "1111", "InvalidPassword"], + ["abcd", "efgh", "InvalidPassword"], -function testChangeCallBarringPasswordWithFailure() { - // Incorrect parameters, expect onerror callback. - let options = [ - {pin: null, newPin: '0000'}, - {pin: '0000', newPin: null}, - {pin: null, newPin: null}, - {pin: '000', newPin: '0000'}, - {pin: '00000', newPin: '1111'}, - {pin: 'abcd', newPin: 'efgh'}, - ]; + // TODO: Bug 906603 - B2G RIL: Support Change Call Barring Password on Emulator. + // Currently emulator doesn't support REQUEST_CHANGE_BARRING_PASSWORD, so we + // expect to get a 'RequestNotSupported' error here. + ["1234", "1234", "RequestNotSupported"] +]; - function do_test() { - for (let i = 0; i < options.length; i++) { - let request = connection.changeCallBarringPassword(options[i]); +function testChangeCallBarringPassword(aPin, aNewPin, aExpectedError) { + log("Test changing call barring password to " + aPin + "/" + aNewPin); - request.onsuccess = function() { - ok(false, 'Unexpected result.'); - setTimeout(cleanUp , 0); - }; - - request.onerror = function() { - ok(request.error.name === 'InvalidPassword', 'InvalidPassword'); - if (i >= options.length) { - setTimeout(testChangeCallBarringPasswordWithSuccess, 0); - } - }; - } - } - - do_test(); + let options = { + pin: aPin, + newPin: aNewPin + }; + return changeCallBarringPassword(options) + .then(function resolve() { + ok(!aExpectedError, "changeCallBarringPassword success"); + }, function reject(aError) { + is(aError.name, aExpectedError, "failed to changeCallBarringPassword"); + }); } -function testChangeCallBarringPasswordWithSuccess() { - // TODO: Bug 906603 - B2G RIL: Support Change Call Barring Password on - // Emulator. - setTimeout(cleanUp , 0); -} - -function cleanUp() { - SpecialPowers.removePermission("mobileconnection", document); - finish(); -} +// Start tests +startTestCommon(function() { + let promise = Promise.resolve(); + for (let i = 0; i < TEST_DATA.length; i++) { + let data = TEST_DATA[i]; + promise = + promise.then(() => testChangeCallBarringPassword(data[0], data[1], data[2])); + } + return promise; +});
--- a/dom/mobileconnection/tests/marionette/test_call_barring_get_option.js +++ b/dom/mobileconnection/tests/marionette/test_call_barring_get_option.js @@ -1,39 +1,74 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ MARIONETTE_TIMEOUT = 60000; - -SpecialPowers.addPermission("mobileconnection", true, document); - -// Permission changes can't change existing Navigator.prototype -// objects, so grab our objects from a new Navigator -let ifr = document.createElement("iframe"); -let connection; -ifr.onload = function() { - connection = ifr.contentWindow.navigator.mozMobileConnections[0]; - - ok(connection instanceof ifr.contentWindow.MozMobileConnection, - "connection is instanceof " + connection.constructor); +MARIONETTE_HEAD_JS = "head.js"; - testGetCallBarringOption(); -}; -document.body.appendChild(ifr); +const TEST_DATA = [ + // Test passing invalid program. + { + options: { + program: 5, /* Invalid program */ + serviceClass: 0 + }, + expectedError: "InvalidParameter" + }, { + options: { + program: null, + serviceClass: 0 + }, + expectedError: "InvalidParameter" + }, { + options: { + /* Undefined program */ + serviceClass: 0 + }, + expectedError: "InvalidParameter" + }, + // Test passing invalid serviceClass. + { + options: { + program: MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING, + serviceClass: null + }, + expectedError: "InvalidParameter" + }, { + options: { + program: MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING, + /* Undefined serviceClass */ + }, + expectedError: "InvalidParameter" + }, + // TODO: Bug 1027546 - [B2G][Emulator] Support call barring + // Currently emulator doesn't support call barring, so we expect to get a + // 'RequestNotSupported' error here. + { + options: { + program: MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING, + serviceClass: 0 + }, + expectedError: "RequestNotSupported" + } +]; -function testGetCallBarringOption() { - let option = {'program': 0, 'password': '', 'serviceClass': 0}; - let request = connection.getCallBarringOption(option); - request.onsuccess = function() { - ok(request.result); - ok('enabled' in request.result, 'should have "enabled" field'); - cleanUp(); - }; - request.onerror = function() { - // Call barring is not supported by current emulator. - cleanUp(); - }; +function testGetCallBarringOption(aOptions, aExpectedError) { + log("Test getting call barring to " + JSON.stringify(aOptions)); + + return getCallBarringOption(aOptions) + .then(function resolve(aResult) { + ok(false, "should not success"); + }, function reject(aError) { + is(aError.name, aExpectedError, "failed to getCallBarringOption"); + }); } -function cleanUp() { - SpecialPowers.removePermission("mobileconnection", document); - finish(); -} +// Start tests +startTestCommon(function() { + let promise = Promise.resolve(); + for (let i = 0; i < TEST_DATA.length; i++) { + let data = TEST_DATA[i]; + promise = promise.then(() => testGetCallBarringOption(data.options, + data.expectedError)); + } + return promise; +});
--- a/dom/mobileconnection/tests/marionette/test_call_barring_set_error.js +++ b/dom/mobileconnection/tests/marionette/test_call_barring_set_error.js @@ -1,74 +1,122 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ MARIONETTE_TIMEOUT = 60000; - -SpecialPowers.addPermission("mobileconnection", true, document); - -// Permission changes can't change existing Navigator.prototype -// objects, so grab our objects from a new Navigator -let ifr = document.createElement("iframe"); -let connection; -ifr.onload = function() { - connection = ifr.contentWindow.navigator.mozMobileConnections[0]; - - ok(connection instanceof ifr.contentWindow.MozMobileConnection, - "connection is instanceof " + connection.constructor); +MARIONETTE_HEAD_JS = "head.js"; - nextTest(); -}; -document.body.appendChild(ifr); - -let caseId = 0; -let options = [ - buildOption(5, true, '0000', 0), // invalid program. - - // test null. - buildOption(null, true, '0000', 0), - buildOption(0, null, '0000', 0), - buildOption(0, true, null, 0), - buildOption(0, true, '0000', null), - - // test undefined. - {'enabled': true, 'password': '0000', 'serviceClass': 0}, - {'program': 0, 'password': '0000', 'serviceClass': 0}, - {'program': 0, 'enabled': true, 'serviceClass': 0}, - {'program': 0, 'enabled': true, 'password': '0000'}, +const TEST_DATA = [ + // Test passing invalid program. + { + options: { + "program": 5, /* Invalid program */ + "enabled": true, + "password": "0000", + "serviceClass": 0 + }, + expectedError: "InvalidParameter" + }, { + options: { + "program": null, + "enabled": true, + "password": "0000", + "serviceClass": 0 + }, + expectedError: "InvalidParameter" + }, { + options: { + /* Undefined program */ + "enabled": true, + "password": "0000", + "serviceClass": 0 + }, + expectedError: "InvalidParameter" + }, + // Test passing invalid enabled. + { + options: { + "program": MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING, + "enabled": null, + "password": "0000", + "serviceClass": 0 + }, + expectedError: "InvalidParameter" + }, { + options: { + "program": MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING, + /* Undefined enabled */ + "password": "0000", + "serviceClass": 0 + }, + expectedError: "InvalidParameter" + }, + // Test passing invalid password. + { + options: { + "program": MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING, + "enabled": true, + "password": null, + "serviceClass": 0 + }, + expectedError: "InvalidParameter" + }, { + options: { + "program": MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING, + "enabled": true, + /* Undefined password */ + "serviceClass": 0 + }, + expectedError: "InvalidParameter" + }, + // Test passing invalid serviceClass. + { + options: { + "program": MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING, + "enabled": true, + "password": "0000", + "serviceClass": null + }, + expectedError: "InvalidParameter" + }, { + options: { + "program": MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING, + "enabled": true, + "password": "0000", + /* Undefined serviceClass */ + }, + expectedError: "InvalidParameter" + }, + // TODO: Bug 1027546 - [B2G][Emulator] Support call barring + // Currently emulator doesn't support call barring, so we expect to get a + // 'RequestNotSupported' error here. + { + options: { + "program": MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING, + "enabled": true, + "password": "0000", + "serviceClass": 0 + }, + expectedError: "RequestNotSupported" + } ]; -function buildOption(program, enabled, password, serviceClass) { - return { - 'program': program, - 'enabled': enabled, - 'password': password, - 'serviceClass': serviceClass - }; +function testSetCallBarringOption(aOptions, aExpectedError) { + log("Test setting call barring to " + JSON.stringify(aOptions)); + + return setCallBarringOption(aOptions) + .then(function resolve() { + ok(false, "changeCallBarringPassword success"); + }, function reject(aError) { + is(aError.name, aExpectedError, "failed to changeCallBarringPassword"); + }); } -function testSetCallBarringOptionError(option) { - let request = connection.setCallBarringOption(option); - request.onsuccess = function() { - ok(false, - 'should not fire onsuccess for invaild call barring option: ' - + JSON.stringify(option)); - }; - request.onerror = function(event) { - is(event.target.error.name, 'InvalidParameter', JSON.stringify(option)); - nextTest(); - }; -} - -function nextTest() { - if (caseId >= options.length) { - cleanUp(); - } else { - let option = options[caseId++]; - log('test for ' + JSON.stringify(option)); - testSetCallBarringOptionError(option); +// Start tests +startTestCommon(function() { + let promise = Promise.resolve(); + for (let i = 0; i < TEST_DATA.length; i++) { + let data = TEST_DATA[i]; + promise = promise.then(() => testSetCallBarringOption(data.options, + data.expectedError)); } -} - -function cleanUp() { - SpecialPowers.removePermission("mobileconnection", document); - finish(); -} + return promise; +});
--- a/dom/mobileconnection/tests/marionette/test_mobile_icc_change.js +++ b/dom/mobileconnection/tests/marionette/test_mobile_icc_change.js @@ -1,84 +1,33 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ -MARIONETTE_TIMEOUT = 30000; - -SpecialPowers.addPermission("mobileconnection", true, document); +MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = "head.js"; -// Permission changes can't change existing Navigator.prototype -// objects, so grab our objects from a new Navigator -let ifr = document.createElement("iframe"); -let connection; -ifr.onload = function() { - connection = ifr.contentWindow.navigator.mozMobileConnections[0]; - ok(connection instanceof ifr.contentWindow.MozMobileConnection, - "connection is instanceof " + connection.constructor); - - // The emulator's hard coded iccid value. - // See it here {B2G_HOME}/external/qemu/telephony/sim_card.c. - is(connection.iccId, 89014103211118510720); +// The emulator's hard coded iccid value. +const ICCID = "89014103211118510720"; - runNextTest(); -}; -document.body.appendChild(ifr); - -function waitForIccChange(callback) { - connection.addEventListener("iccchange", function handler() { - connection.removeEventListener("iccchange", handler); - callback(); - }); -} +function setRadioEnabledAndWaitIccChange(aEnabled) { + let promises = []; + promises.push(waitForManagerEvent("iccchange")); + promises.push(setRadioEnabled(aEnabled)); -function setRadioEnabled(enabled) { - let request = connection.setRadioEnabled(enabled); - - request.onsuccess = function onsuccess() { - log('setRadioEnabled: ' + enabled); - }; - - request.onerror = function onerror() { - ok(false, "setRadioEnabled should be ok"); - }; + return Promise.all(promises); } -function testIccChangeOnRadioPowerOff() { - // Turn off radio - setRadioEnabled(false); - - waitForIccChange(function() { - is(connection.iccId, null); - runNextTest(); - }); -} - -function testIccChangeOnRadioPowerOn() { - // Turn on radio - setRadioEnabled(true); - - waitForIccChange(function() { - // The emulator's hard coded iccid value. - is(connection.iccId, 89014103211118510720); - runNextTest(); - }); -} +// Start tests +startTestCommon(function() { + log("Test initial iccId"); + is(mobileConnection.iccId, ICCID); -let tests = [ - testIccChangeOnRadioPowerOff, - testIccChangeOnRadioPowerOn -]; + return setRadioEnabledAndWaitIccChange(false) + .then(() => { + is(mobileConnection.iccId, null); + }) -function runNextTest() { - let test = tests.shift(); - if (!test) { - cleanUp(); - return; - } - - test(); -} - -function cleanUp() { - SpecialPowers.removePermission("mobileconnection", document); - - finish(); -} + // Restore radio state. + .then(() => setRadioEnabledAndWaitIccChange(true)) + .then(() => { + is(mobileConnection.iccId, ICCID); + }); +});
--- a/dom/mobileconnection/tests/marionette/test_mobile_last_known_network.js +++ b/dom/mobileconnection/tests/marionette/test_mobile_last_known_network.js @@ -1,47 +1,13 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ -MARIONETTE_TIMEOUT = 30000; - -SpecialPowers.addPermission("mobilenetwork", true, document); - -let connection = navigator.mozMobileConnections[0]; -ok(connection instanceof MozMobileConnection, - "connection is instanceof " + connection.constructor); - +MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = "head.js"; -function testLastKnownNetwork() { - log("testLastKnownNetwork: " + connection.lastKnownNetwork); +// Start tests +startTestCommon(function() { // The emulator's hard coded operatoer's mcc and mnc codes. - is(connection.lastKnownNetwork, "310-260"); - runNextTest(); -} - -function testLastKnownHomeNetwork() { - log("testLastKnownHomeNetwork: " + connection.lastKnownHomeNetwork); + is(mobileConnection.lastKnownNetwork, "310-260"); // The emulator's hard coded icc's mcc and mnc codes. - is(connection.lastKnownHomeNetwork, "310-260"); - runNextTest(); -} - -let tests = [ - testLastKnownNetwork, - testLastKnownHomeNetwork -]; - -function runNextTest() { - let test = tests.shift(); - if (!test) { - cleanUp(); - return; - } - - test(); -} - -function cleanUp() { - SpecialPowers.removePermission("mobilenetwork", document); - finish(); -} - -runNextTest(); + is(mobileConnection.lastKnownHomeNetwork, "310-260"); +});
--- a/dom/mobileconnection/tests/marionette/test_mobile_set_radio.js +++ b/dom/mobileconnection/tests/marionette/test_mobile_set_radio.js @@ -1,168 +1,41 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ MARIONETTE_TIMEOUT = 60000; - -const DATA_KEY = "ril.data.enabled"; -const APN_KEY = "ril.data.apnSettings"; - -let Promise = SpecialPowers.Cu.import("resource://gre/modules/Promise.jsm").Promise; +MARIONETTE_HEAD_JS = "head.js"; -SpecialPowers.setBoolPref("dom.mozSettings.enabled", true); -SpecialPowers.addPermission("mobileconnection", true, document); -SpecialPowers.addPermission("settings-read", true, document); -SpecialPowers.addPermission("settings-write", true, document); - -let settings = window.navigator.mozSettings; -let connection = window.navigator.mozMobileConnections[0]; -ok(connection instanceof MozMobileConnection, - "connection is instanceof " + connection.constructor); - -function setSetting(key, value) { - let deferred = Promise.defer(); +// Start tests +startTestCommon(function() { - let setLock = settings.createLock(); - let obj = {}; - obj[key] = value; + let origApnSettings; + return getDataApnSettings() + .then(value => { + origApnSettings = value; + }) - let setReq = setLock.set(obj); - setReq.addEventListener("success", function onSetSuccess() { - ok(true, "set '" + key + "' to " + obj[key]); - deferred.resolve(); - }); - setReq.addEventListener("error", function onSetError() { - ok(false, "cannot set '" + key + "'"); - deferred.reject(); - }); + // Test disabling/enabling radio power. + .then(() => setRadioEnabledAndWait(false)) + .then(() => setRadioEnabledAndWait(true)) - return deferred.promise; -} - -function setEmulatorAPN() { - let apn = - [ - [ + // Test disabling radio when data is connected. + .then(() => { + let apnSettings = [[ {"carrier":"T-Mobile US", "apn":"epc.tmobile.com", "mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc", - "types":["default","supl","mms"]} - ] - ]; - return setSetting(APN_KEY, apn); -} - -function enableData() { - log("Turn data on."); - - let deferred = Promise.defer(); - - connection.addEventListener("datachange", function ondatachange() { - if (connection.data.connected === true) { - connection.removeEventListener("datachange", ondatachange); - log("mobileConnection.data.connected is now '" - + connection.data.connected + "'."); - deferred.resolve(); - } - }); - - setEmulatorAPN() - .then(() => setSetting(DATA_KEY, true)); - - return deferred.promise; -} - -function receivedPending(received, pending, nextAction) { - let index = pending.indexOf(received); - if (index != -1) { - pending.splice(index, 1); - } - if (pending.length === 0) { - nextAction(); - } -} - -function waitRadioState(state) { - let deferred = Promise.defer(); - - waitFor(function() { - deferred.resolve(); - }, function() { - return connection.radioState == state; - }); - - return deferred.promise; -} - -function setRadioEnabled(enabled, transientState, finalState) { - log("setRadioEnabled to " + enabled); - - let deferred = Promise.defer(); - let done = function() { - deferred.resolve(); - }; - - let pending = ["onradiostatechange", "onsuccess"]; - - let receivedTransient = false; - connection.onradiostatechange = function() { - let state = connection.radioState; - log("Received 'radiostatechange' event, radioState: " + state); - - if (state == transientState) { - receivedTransient = true; - } else if (state == finalState) { - ok(receivedTransient); - receivedPending("onradiostatechange", pending, done); - } - }; - - let req = connection.setRadioEnabled(enabled); - - req.onsuccess = function() { - log("setRadioEnabled success"); - receivedPending("onsuccess", pending, done); - }; - - req.onerror = function() { - ok(false, "setRadioEnabled should not fail"); - deferred.reject(); - }; - - return deferred.promise; -} - -function testSwitchRadio() { - log("= testSwitchRadio ="); - return waitRadioState("enabled") - .then(setRadioEnabled.bind(null, false, "disabling", "disabled")) - .then(setRadioEnabled.bind(null, true, "enabling", "enabled")); -} - -function testDisableRadioWhenDataConnected() { - log("= testDisableRadioWhenDataConnected ="); - return waitRadioState("enabled") - .then(enableData) - .then(setRadioEnabled.bind(null, false, "disabling", "disabled")) + "types":["default","supl","mms"]}]]; + return setDataApnSettings(apnSettings); + }) + .then(() => setDataEnabledAndWait(true)) + .then(() => setRadioEnabledAndWait(false)) .then(() => { // Data should be disconnected. - is(connection.data.connected, false); + is(mobileConnection.data.connected, false); }) - .then(setRadioEnabled.bind(null, true, "enabling", "enabled")) - // Disable data - .then(setSetting.bind(null, DATA_KEY, false)); -} -function cleanUp() { - SpecialPowers.removePermission("mobileconnection", document); - SpecialPowers.removePermission("settings-write", document); - SpecialPowers.removePermission("settings-read", document); - SpecialPowers.clearUserPref("dom.mozSettings.enabled"); - finish(); -} + // Restore test environment. + .then(() => setDataApnSettings(origApnSettings)) + .then(() => setDataEnabled(false)) + .then(() => setRadioEnabledAndWait(true)); -testSwitchRadio() - .then(testDisableRadioWhenDataConnected) - .then(null, () => { - ok(false, "promise reject somewhere"); - }) - .then(cleanUp); +}, ["settings-read", "settings-write"]);
--- a/dom/mobileconnection/tests/marionette/test_mobile_signal_strength.js +++ b/dom/mobileconnection/tests/marionette/test_mobile_signal_strength.js @@ -1,132 +1,98 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ -MARIONETTE_TIMEOUT = 30000; -MARIONETTE_HEAD_JS = "mobile_header.js"; +MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = "head.js"; -/* Emulator command for GSM/UMTS signal strength */ -function setEmulatorGsmSignalStrength(rssi) { - emulatorHelper.sendCommand("gsm signal " + rssi); -} +// Emulator uses rssi = 7 as default value. +const DEFAULT_RSSI = 7; -/* Emulator command for LTE signal strength */ -function setEmulatorLteSignalStrength(rxlev, rsrp, rssnr) { - let lteSignal = rxlev + " " + rsrp + " " + rssnr; - emulatorHelper.sendCommand("gsm lte_signal " + lteSignal); -} +const TEST_DATA = [ + // All invalid case. + { + input: { + rxlev: 99, + rsrp: 65535, + rssnr: 65535 + }, + expect: { + signalStrength: null, + relSignalStrength: null + } + }, + // Valid rxlev with max value. + { + input: { + rxlev: 63, + rsrp: 65535, + rssnr: 65535 + }, + expect: { + signalStrength: -48, + relSignalStrength: 100 + } + }, + // Valid rxlev. + { + input: { + rxlev: 12, + rsrp: 65535, + rssnr: 65535 + }, + expect: { + signalStrength: -99, + relSignalStrength: 100 + } + }, + // Valid rxlev with min value. + { + input: { + rxlev: 0, + rsrp: 65535, + rssnr: 65535 + }, + expect: { + signalStrength: -111, + relSignalStrength: 0 + } + } +]; -function waitForVoiceChangeEvent(callback) { - mobileConnection.addEventListener("voicechange", function onvoicechange() { - mobileConnection.removeEventListener("voicechange", onvoicechange); - - if (callback && typeof callback === "function") { - callback(); - } - }); -} - -/* Test Initial Signal Strength Info */ -taskHelper.push(function testInitialSignalStrengthInfo() { +function testInitialSignalStrengthInfo() { log("Test initial signal strength info"); let voice = mobileConnection.voice; // Android emulator initializes the signal strength to -99 dBm is(voice.signalStrength, -99, "check voice.signalStrength"); is(voice.relSignalStrength, 44, "check voice.relSignalStrength"); - - taskHelper.runNext(); -}); +} -/* Test Unsolicited Signal Strength Events for LTE */ -taskHelper.push(function testLteSignalStrength() { - // Set emulator's LTE signal strength and wait for 'onvoicechange' event. - function doTestLteSignalStrength(input, expect, callback) { - log("Test LTE signal info with data : " + JSON.stringify(input)); +function testLteSignalStrength(aInput, aExpect) { + log("Test setting LTE signal strength to " + JSON.stringify(aInput)); - waitForVoiceChangeEvent(function() { + return setEmulatorLteSignalStrengthAndWait(aInput.rxlev, aInput.rsrp, aInput.rssnr) + .then(() => { let voice = mobileConnection.voice; - is(voice.signalStrength, expect.signalStrength, + is(voice.signalStrength, aExpect.signalStrength, "check voice.signalStrength"); - is(voice.relSignalStrength, expect.relSignalStrength, + is(voice.relSignalStrength, aExpect.relSignalStrength, "check voice.relSignalStrength"); + }); +} - if (callback && typeof callback === "function") { - callback(); - } - }); +// Start tests +startTestCommon(function() { + // Test initial status + testInitialSignalStrengthInfo(); - setEmulatorLteSignalStrength(input.rxlev, input.rsrp, input.rssnr); + // Test Unsolicited Signal Strength Events for LTE + let promise = Promise.resolve(); + for (let i = 0; i < TEST_DATA.length; i++) { + let data = TEST_DATA[i]; + promise = promise.then(() => testLteSignalStrength(data.input, + data.expect)); } - let testData = [ - // All invalid case. - {input: { - rxlev: 99, - rsrp: 65535, - rssnr: 65535}, - expect: { - signalStrength: null, - relSignalStrength: null} - }, - // Valid rxlev with max value. - {input: { - rxlev: 63, - rsrp: 65535, - rssnr: 65535}, - expect: { - signalStrength: -48, - relSignalStrength: 100} - }, - // Valid rxlev. - {input: { - rxlev: 12, - rsrp: 65535, - rssnr: 65535}, - expect: { - signalStrength: -99, - relSignalStrength: 100} - }, - // Valid rxlev with min value. - {input: { - rxlev: 0, - rsrp: 65535, - rssnr: 65535}, - expect: { - signalStrength: -111, - relSignalStrength: 0} - } - ]; - - // Run all test data. - (function do_call() { - let next = testData.shift(); - if (!next) { - taskHelper.runNext(); - return; - } - doTestLteSignalStrength(next.input, next.expect, do_call); - })(); + // Reset Signal Strength Info to default + return promise.then(() => setEmulatorGsmSignalStrengthAndWait(DEFAULT_RSSI)); }); - -/* Reset Signal Strength Info to default, and finsih the test */ -taskHelper.push(function testResetSignalStrengthInfo() { - // Reset emulator's signal strength and wait for 'onvoicechange' event. - function doResetSignalStrength(rssi) { - waitForVoiceChangeEvent(function() { - let voice = mobileConnection.voice; - is(voice.signalStrength, -99, "check voice.signalStrength"); - is(voice.relSignalStrength, 44, "check voice.relSignalStrength"); - - taskHelper.runNext(); - }); - - setEmulatorGsmSignalStrength(rssi); - } - - // Emulator uses rssi = 7 as default value, and we need to reset it after - // finishing test in case other test cases need those values for testing. - doResetSignalStrength(7); -}); - -// Start test -taskHelper.runNext();
--- a/dom/tests/browser/browser.ini +++ b/dom/tests/browser/browser.ini @@ -16,16 +16,21 @@ support-files = [browser_autofocus_background.js] [browser_autofocus_preference.js] [browser_bug396843.js] [browser_focus_steal_from_chrome.js] [browser_focus_steal_from_chrome_during_mousedown.js] [browser_frame_elements.js] [browser_geolocation_privatebrowsing_perwindowpb.js] [browser_localStorage_privatestorageevent.js] +[browser_test_new_window_from_content.js] +skip-if = (toolkit == 'android' || buildapp == 'b2g') +support-files = + test_new_window_from_content_child.html + test_new_window_from_content_child.js [browser_webapps_permissions.js] # TODO: Re-enable permissions tests on Mac, bug 795334 skip-if = buildapp != "b2g" support-files = test-webapp.webapp test-webapp-reinstall.webapp test-webapp-original.webapp test-webapps-permissions.html
new file mode 100644 --- /dev/null +++ b/dom/tests/browser/browser_test_new_window_from_content.js @@ -0,0 +1,340 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* + We have three ways for content to open new windows: + 1) window.open (with the default features) + 2) window.open (with non-default features) + 3) target="_blank" in <a> tags + + We also have two prefs that modify our window opening behaviours: + + 1) browser.link.open_newwindow + + This has a numeric value that allows us to set our window-opening behaviours from + content in three ways: + 1) Open links that would normally open a new window in the current tab + 2) Open links that would normally open a new window in a new window + 3) Open links that would normally open a new window in a new tab (default) + + 2) browser.link.open_newwindow.restriction + + This has a numeric value that allows us to fine tune the browser.link.open_newwindow + pref so that it can discriminate between different techniques for opening windows. + + 0) All things that open windows should behave according to browser.link.open_newwindow. + 1) No things that open windows should behave according to browser.link.open_newwindow + (essentially rendering browser.link.open_newwindow inert). + 2) Most things that open windows should behave according to browser.link.open_newwindow, + _except_ for window.open calls with the "feature" parameter. This will open in a new + window regardless of what browser.link.open_newwindow is set at. (default) + + This file attempts to test each window opening technique against all possible settings for + each preference. +*/ + +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/Promise.jsm"); +Cu.import("resource://gre/modules/Task.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; +const kContentDoc = "http://www.example.com/browser/dom/tests/browser/test_new_window_from_content_child.html"; +const kContentScript = "chrome://mochitests/content/browser/dom/tests/browser/test_new_window_from_content_child.js"; +const kNewWindowPrefKey = "browser.link.open_newwindow"; +const kNewWindowRestrictionPrefKey = "browser.link.open_newwindow.restriction"; +const kSameTab = "same tab"; +const kNewWin = "new window"; +const kNewTab = "new tab"; + +// The following "matrices" represent the result of content attempting to +// open a window with window.open with the default feature set. The key of +// the kWinOpenDefault object represents the value of browser.link.open_newwindow. +// The value for each key is an array that represents the result (either opening +// the link in the same tab, a new window, or a new tab), where the index of each +// result maps to the browser.link.open_newwindow.restriction pref. I've tried +// to illustrate this more clearly in the kWinOpenDefault object. +const kWinOpenDefault = { +// open_newwindow.restriction +// 0 1 2 +// open_newwindow + 1: [kSameTab, kNewWin, kSameTab], + 2: [kNewWin, kNewWin, kNewWin], + 3: [kNewTab, kNewWin, kNewTab], +}; + +const kWinOpenNonDefault = { + 1: [kSameTab, kNewWin, kNewWin], + 2: [kNewWin, kNewWin, kNewWin], + 3: [kNewTab, kNewWin, kNewWin], +}; + +const kTargetBlank = { + 1: [kSameTab, kSameTab, kSameTab], + 2: [kNewWin, kNewWin, kNewWin], + 3: [kNewTab, kNewTab, kNewTab], +}; + +// We'll be changing these preferences a lot, so we'll stash their original +// values and make sure we restore them at the end of the test. +let originalNewWindowPref = Services.prefs.getIntPref(kNewWindowPrefKey); +let originalNewWindowRestrictionPref = + Services.prefs.getIntPref(kNewWindowRestrictionPrefKey); + +registerCleanupFunction(function() { + Services.prefs.setIntPref(kNewWindowPrefKey, originalNewWindowPref); + Services.prefs.setIntPref(kNewWindowRestrictionPrefKey, + originalNewWindowRestrictionPref); + // If there are any content tabs leftover, make sure they're not going to + // block exiting with onbeforeunload. + for (let tab of gBrowser.tabs) { + let browser = gBrowser.getBrowserForTab(tab); + if (browser.contentDocument.location == kContentDoc) { + closeTab(tab); + } + } +}); + +/** + * WindowOpenListener is a very simple nsIWindowMediatorListener that + * listens for a new window opening to aExpectedURI. It has two Promises + * attached to it - openPromise and closePromise. As you'd expect, + * openPromise resolves when the window is opened, and closePromise + * resolves if and when a window with the same URI closes. There is + * no attempt to make sure that it's the same window opening and + * closing - we just use the URI. + * + * @param aExpectedURI the URI to watch for in a new window. + * @return nsIWindowMediatorListener + */ +function WindowOpenListener(aExpectedURI) { + this._openDeferred = Promise.defer(); + this._closeDeferred = Promise.defer(); + this._expectedURI = aExpectedURI; +} + +WindowOpenListener.prototype = { + get openPromise() { + return this._openDeferred.promise; + }, + + get closePromise() { + return this._closeDeferred.promise; + }, + + onOpenWindow: function(aXULWindow) { + let domWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindow); + let location = domWindow.document.location; + if (location == this._expectedURI) { + let deferred = this._openDeferred; + domWindow.addEventListener("load", function onWindowLoad() { + domWindow.removeEventListener("load", onWindowLoad); + deferred.resolve(domWindow); + }) + } + }, + + onCloseWindow: function(aXULWindow) { + this._closeDeferred.resolve(); + }, + onWindowTitleChange: function(aXULWindow, aNewTitle) {}, + + QueryInterface: XPCOMUtils.generateQI([Ci.nsIWindowMediatorListener]) +}; + +/** + * Adds the testing tab, and injects our frame script which + * allows us to send click events to links and other things. + * + * @return a Promise that resolves once the tab is loaded and ready. + */ +function loadAndSelectTestTab() { + let tab = gBrowser.addTab(kContentDoc); + gBrowser.selectedTab = tab; + + let browser = gBrowser.getBrowserForTab(tab); + + // Bug 687194 - Mochitest registers its chrome URLs after browser + // initialization, so the content processes don't pick them up. That + // means we can't load our frame script from its chrome URI, because + // the content process won't be able to find it. + // + // Instead, we resolve the chrome URI for the script to a file URI, which + // we can then pass to the content process, which it is able to find. + let registry = Cc['@mozilla.org/chrome/chrome-registry;1'].getService(Ci.nsIChromeRegistry); + let fileURI = registry.convertChromeURL(Services.io.newURI(kContentScript, null, null)).spec; + browser.messageManager.loadFrameScript(fileURI, false); + + let deferred = Promise.defer(); + browser.addEventListener("DOMContentLoaded", function onBrowserLoad(aEvent) { + browser.removeEventListener("DOMContentLoaded", onBrowserLoad); + deferred.resolve(tab); + }); + + return deferred.promise; +} + +/** + * Clears the onbeforeunload event handler from the testing tab, + * and then closes the tab. + * + * @param aTab the testing tab to close. + * @param a Promise that resolves once the tab has been closed. + */ +function closeTab(aTab) { + let deferred = Promise.defer(); + let browserMM = gBrowser.getBrowserForTab(aTab).messageManager; + browserMM.sendAsyncMessage("TEST:allow-unload"); + browserMM.addMessageListener("TEST:allow-unload:done", function(aMessage) { + gBrowser.removeTab(aTab); + deferred.resolve(); + }) + return deferred.promise; +} + +/** + * Sends a click event on some item into a tab. + * + * @param aTab the tab to send the click event to + * @param aItemId the item within the tab content to click. + */ +function clickInTab(aTab, aItemId) { + let browserMM = gBrowser.getBrowserForTab(aTab).messageManager; + browserMM.sendAsyncMessage("TEST:click-item", { + details: aItemId, + }); +} + +/** + * For some expectation when a link is clicked, creates and + * returns a Promise that resolves when that expectation is + * fulfilled. For example, aExpectation might be kSameTab, which + * will cause this function to return a Promise that resolves when + * the current tab attempts to browse to about:blank. + * + * This function also takes care of cleaning up once the result has + * occurred - for example, if a new window was opened, this function + * closes it before resolving. + * + * @param aTab the tab with the test document + * @param aExpectation one of kSameTab, kNewWin, or kNewTab. + * @return a Promise that resolves when the expectation is fulfilled, + * and cleaned up after. + */ +function prepareForResult(aTab, aExpectation) { + let deferred = Promise.defer(); + let browser = gBrowser.getBrowserForTab(aTab); + + switch(aExpectation) { + case kSameTab: + // We expect about:blank to be loaded in the current tab. In order + // to prevent us needing to reload the document and content script + // after browsing away, we'll detect the attempt by using onbeforeunload, + // and then cancel the unload. It's a hack, but it's also a pretty + // cheap way of detecting when we're browsing away in the test tab. + // The onbeforeunload event handler is set in the content script automatically. + browser.addEventListener("DOMWillOpenModalDialog", function onModalDialog() { + browser.removeEventListener("DOMWillOpenModalDialog", onModalDialog, true); + executeSoon(() => { + let stack = browser.parentNode; + let dialogs = stack.getElementsByTagNameNS(kXULNS, "tabmodalprompt"); + dialogs[0].ui.button1.click() + deferred.resolve(); + }) + }, true); + break; + case kNewWin: + let listener = new WindowOpenListener("about:blank"); + Services.wm.addListener(listener); + + info("Waiting for a new about:blank window"); + listener.openPromise.then(function(aWindow) { + info("Got the new about:blank window - closing it."); + executeSoon(() => { + aWindow.close(); + }); + listener.closePromise.then(() => { + info("New about:blank window closed!"); + Services.wm.removeListener(listener); + deferred.resolve(); + }); + }); + break; + case kNewTab: + gBrowser.tabContainer.addEventListener("TabOpen", function onTabOpen(aEvent) { + let newTab = aEvent.target; + let newBrowser = gBrowser.getBrowserForTab(newTab); + if (newBrowser.contentDocument.location.href == "about:blank") { + gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen); + executeSoon(() => { + gBrowser.removeTab(newTab); + deferred.resolve(); + }) + } + }) + break; + default: + ok(false, "prepareForResult can't handle an expectation of " + aExpectation) + return; + } + + return deferred.promise; +} + +/** + * Ensure that clicks on a link with ID aLinkID cause us to + * perform as specified in the supplied aMatrix (kWinOpenDefault, + * for example). + * + * @param aLinkId the id of the link within the testing page to test. + * @param aMatrix a testing matrix for the + * browser.link.open_newwindow and browser.link.open_newwindow.restriction + * prefs to test against. See kWinOpenDefault for an example. + */ +function testLinkWithMatrix(aLinkId, aMatrix) { + return Task.spawn(function* () { + let tab = yield loadAndSelectTestTab(); + // This nested for-loop is unravelling the matrix const + // we set up, and gives us three things through each tick + // of the inner loop: + // 1) newWindowPref: a browser.link.open_newwindow pref to try + // 2) newWindowRestPref: a browser.link.open_newwindow.restriction pref to try + // 3) expectation: what we expect the click outcome on this link to be, + // which will either be kSameTab, kNewWin or kNewTab. + + for (let newWindowPref in aMatrix) { + let expectations = aMatrix[newWindowPref]; + for (let i = 0; i < expectations.length; ++i) { + let newWindowRestPref = i; + let expectation = expectations[i]; + + Services.prefs.setIntPref("browser.link.open_newwindow", newWindowPref); + Services.prefs.setIntPref("browser.link.open_newwindow.restriction", newWindowRestPref); + info("Clicking on " + aLinkId); + info("Testing with browser.link.open_newwindow = " + newWindowPref + " and " + + "browser.link.open_newwindow.restriction = " + newWindowRestPref); + info("Expecting: " + expectation); + let resultPromise = prepareForResult(tab, expectation); + clickInTab(tab, aLinkId); + yield resultPromise; + ok(true, "Got expectation: " + expectation); + } + } + yield closeTab(tab); + }); +} + +add_task(function* test_window_open_with_defaults() { + yield testLinkWithMatrix("winOpenDefault", kWinOpenDefault); +}); + +add_task(function* test_window_open_with_non_defaults() { + yield testLinkWithMatrix("winOpenNonDefault", kWinOpenNonDefault); +}); + +add_task(function* test_target__blank() { + yield testLinkWithMatrix("targetBlank", kTargetBlank); +});
new file mode 100644 --- /dev/null +++ b/dom/tests/browser/test_new_window_from_content_child.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<head> + <meta charset="utf-8"> + <title>Test popup window opening behaviour</title> +</head> +<body> + <p><a id="winOpenDefault" href="#" onclick="return openWindow();">Open a new window via window.open with default features.</a></p> + <p><a id="winOpenNonDefault" href="#" onclick="return openWindow('resizable=no, toolbar=no, scrollbars=no, menubar=no, status=no, directories=no, height=100, width=500');">Open a new window via window.open with non-default features.</a></p> + <p><a id="targetBlank" href="about:blank" target="_blank">Open a new window via target="_blank".</a></p> +</body> +</html> + +<script> +function openWindow(aFeatures="") { + window.open("about:blank", "_blank", aFeatures); + return false; +} + +window.onbeforeunload = function(aEvent) { + return "We should not browse away from this document."; +} + +</script> \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/dom/tests/browser/test_new_window_from_content_child.js @@ -0,0 +1,19 @@ +// A hacky mechanism for catching and detecting that we're attempting +// to browse away is by setting the onbeforeunload event handler. We +// detect this dialog opening in the parent test script, and dismiss +// it. + +function handleClickItem(aMessage) { + let itemId = aMessage.data.details; + content.console.log("Getting item with ID: " + itemId); + let item = content.document.getElementById(itemId); + item.click(); +} + +function handleAllowUnload(aMessage) { + content.onbeforeunload = null; + sendSyncMessage("TEST:allow-unload:done"); +} + +addMessageListener("TEST:click-item", handleClickItem); +addMessageListener("TEST:allow-unload", handleAllowUnload); \ No newline at end of file
--- a/dom/webidl/XPathEvaluator.webidl +++ b/dom/webidl/XPathEvaluator.webidl @@ -1,23 +1,22 @@ /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ interface XPathExpression; interface XPathNSResolver; -interface XPathResult; [Constructor] interface XPathEvaluator { // Based on nsIDOMXPathEvaluator [NewObject, Throws] XPathExpression createExpression(DOMString expression, XPathNSResolver? resolver); [NewObject, Throws] XPathNSResolver createNSResolver(Node? nodeResolver); [Throws] XPathResult evaluate(DOMString expression, Node? contextNode, XPathNSResolver? resolver, unsigned short type, - XPathResult? result); + object? result); };
new file mode 100644 --- /dev/null +++ b/dom/webidl/XPathResult.webidl @@ -0,0 +1,38 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Corresponds to http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020208 + */ + +interface XPathResult { + // XPathResultType + const unsigned short ANY_TYPE = 0; + const unsigned short NUMBER_TYPE = 1; + const unsigned short STRING_TYPE = 2; + const unsigned short BOOLEAN_TYPE = 3; + const unsigned short UNORDERED_NODE_ITERATOR_TYPE = 4; + const unsigned short ORDERED_NODE_ITERATOR_TYPE = 5; + const unsigned short UNORDERED_NODE_SNAPSHOT_TYPE = 6; + const unsigned short ORDERED_NODE_SNAPSHOT_TYPE = 7; + const unsigned short ANY_UNORDERED_NODE_TYPE = 8; + const unsigned short FIRST_ORDERED_NODE_TYPE = 9; + + readonly attribute unsigned short resultType; + [Throws] + readonly attribute double numberValue; + [Throws] + readonly attribute DOMString stringValue; + [Throws] + readonly attribute boolean booleanValue; + [Throws] + readonly attribute Node? singleNodeValue; + readonly attribute boolean invalidIteratorState; + [Throws] + readonly attribute unsigned long snapshotLength; + [Throws] + Node? iterateNext(); + [Throws] + Node? snapshotItem(unsigned long index); +};
--- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -474,16 +474,17 @@ WEBIDL_FILES = [ 'WorkerNavigator.webidl', 'XMLDocument.webidl', 'XMLHttpRequest.webidl', 'XMLHttpRequestEventTarget.webidl', 'XMLHttpRequestUpload.webidl', 'XMLSerializer.webidl', 'XMLStylesheetProcessingInstruction.webidl', 'XPathEvaluator.webidl', + 'XPathResult.webidl', 'XULCommandEvent.webidl', 'XULDocument.webidl', 'XULElement.webidl', ] if CONFIG['MOZ_AUDIO_CHANNEL_MANAGER']: WEBIDL_FILES += [ 'AudioChannelManager.webidl',
--- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -3130,20 +3130,21 @@ WorkerPrivateParent<Derived>::BroadcastE for (size_t index = 0; index < sharedWorkers.Length(); index++) { nsRefPtr<SharedWorker>& sharedWorker = sharedWorkers[index]; // May be null. nsPIDOMWindow* window = sharedWorker->GetOwner(); size_t actionsIndex = windowActions.LastIndexOf(WindowAction(window)); - nsIGlobalObject* global = sharedWorker->GetParentObject(); - AutoJSAPIWithErrorsReportedToWindow jsapi(global); + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReportingUsingWin(sharedWorker->GetOwner()))) { + continue; + } JSContext* cx = jsapi.cx(); - JSAutoCompartment ac(cx, global->GetGlobalJSObject()); RootedDictionary<ErrorEventInit> errorInit(aCx); errorInit.mBubbles = false; errorInit.mCancelable = true; errorInit.mMessage = aMessage; errorInit.mFilename = aFilename; errorInit.mLineno = aLineNumber; errorInit.mColno = aColumnNumber;
--- a/dom/xbl/XBLChildrenElement.cpp +++ b/dom/xbl/XBLChildrenElement.cpp @@ -98,18 +98,18 @@ nsAnonymousContentList::GetLength(uint32 } uint32_t count = 0; for (nsIContent* child = mParent->GetFirstChild(); child; child = child->GetNextSibling()) { if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) { XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child); - if (!point->mInsertedChildren.IsEmpty()) { - count += point->mInsertedChildren.Length(); + if (point->HasInsertedChildren()) { + count += point->InsertedChildrenLength(); } else { count += point->GetChildCount(); } } else { ++count; } @@ -139,21 +139,21 @@ nsAnonymousContentList::Item(uint32_t aI } uint32_t remIndex = aIndex; for (nsIContent* child = mParent->GetFirstChild(); child; child = child->GetNextSibling()) { if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) { XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child); - if (!point->mInsertedChildren.IsEmpty()) { - if (remIndex < point->mInsertedChildren.Length()) { - return point->mInsertedChildren[remIndex]; + if (point->HasInsertedChildren()) { + if (remIndex < point->InsertedChildrenLength()) { + return point->InsertedChild(remIndex); } - remIndex -= point->mInsertedChildren.Length(); + remIndex -= point->InsertedChildrenLength(); } else { if (remIndex < point->GetChildCount()) { return point->GetChildAt(remIndex); } remIndex -= point->GetChildCount(); } } @@ -174,33 +174,33 @@ nsAnonymousContentList::IndexOf(nsIConte NS_ASSERTION(!aContent->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL), "Looking for insertion point"); if (!mParent) { return -1; } - size_t index = 0; + int32_t index = 0; for (nsIContent* child = mParent->GetFirstChild(); child; child = child->GetNextSibling()) { if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) { XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child); - if (!point->mInsertedChildren.IsEmpty()) { - size_t insIndex = point->mInsertedChildren.IndexOf(aContent); - if (insIndex != point->mInsertedChildren.NoIndex) { + if (point->HasInsertedChildren()) { + int32_t insIndex = point->IndexOfInsertedChild(aContent); + if (insIndex != -1) { return index + insIndex; } - index += point->mInsertedChildren.Length(); + index += point->InsertedChildrenLength(); } else { int32_t insIndex = point->IndexOf(aContent); if (insIndex != -1) { - return index + (size_t)insIndex; + return index + insIndex; } index += point->GetChildCount(); } } else { if (child == aContent) { return index; }
--- a/dom/xbl/XBLChildrenElement.h +++ b/dom/xbl/XBLChildrenElement.h @@ -17,18 +17,16 @@ class nsAnonymousContentList; namespace mozilla { namespace dom { class ExplicitChildIterator; class XBLChildrenElement : public nsXMLElement { public: - friend class mozilla::dom::ExplicitChildIterator; - friend class nsAnonymousContentList; XBLChildrenElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo) : nsXMLElement(aNodeInfo) { } XBLChildrenElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) : nsXMLElement(aNodeInfo) { } @@ -110,39 +108,40 @@ public: return mInsertedChildren.Length(); } bool HasInsertedChildren() { return !mInsertedChildren.IsEmpty(); } - enum { - NoIndex = uint32_t(-1) - }; - uint32_t IndexOfInsertedChild(nsIContent* aChild) + int32_t IndexOfInsertedChild(nsIContent* aChild) { return mInsertedChildren.IndexOf(aChild); } bool Includes(nsIContent* aChild) { NS_ASSERTION(!mIncludes.IsEmpty(), "Shouldn't check for includes on default insertion point"); return mIncludes.Contains(aChild->Tag()); } bool IsDefaultInsertion() { return mIncludes.IsEmpty(); } - nsTArray<nsIContent*> mInsertedChildren; + nsIContent* InsertedChild(uint32_t aIndex) + { + return mInsertedChildren[aIndex]; + } private: + nsTArray<nsIContent*> mInsertedChildren; // WEAK nsTArray<nsCOMPtr<nsIAtom> > mIncludes; }; } // namespace dom } // namespace mozilla class nsAnonymousContentList : public nsINodeList {
--- a/dom/xbl/nsBindingManager.cpp +++ b/dom/xbl/nsBindingManager.cpp @@ -808,51 +808,51 @@ nsBindingManager::MediumFeaturesChanged( set->EnumerateEntries(EnumMediumFeaturesChanged, &data); return NS_OK; } static PLDHashOperator EnumAppendAllSheets(nsRefPtrHashKey<nsIContent> *aKey, void* aClosure) { nsIContent *boundContent = aKey->GetKey(); - nsTArray<nsCSSStyleSheet*>* array = - static_cast<nsTArray<nsCSSStyleSheet*>*>(aClosure); + nsTArray<CSSStyleSheet*>* array = + static_cast<nsTArray<CSSStyleSheet*>*>(aClosure); for (nsXBLBinding *binding = boundContent->GetXBLBinding(); binding; binding = binding->GetBaseBinding()) { binding->PrototypeBinding()->AppendStyleSheetsTo(*array); } return PL_DHASH_NEXT; } void -nsBindingManager::AppendAllSheets(nsTArray<nsCSSStyleSheet*>& aArray) +nsBindingManager::AppendAllSheets(nsTArray<CSSStyleSheet*>& aArray) { if (mBoundContentSet) { mBoundContentSet->EnumerateEntries(EnumAppendAllSheets, &aArray); } } static void InsertAppendedContent(XBLChildrenElement* aPoint, nsIContent* aFirstNewContent) { - size_t insertionIndex; + int32_t insertionIndex; if (nsIContent* prevSibling = aFirstNewContent->GetPreviousSibling()) { // If we have a previous sibling, then it must already be in aPoint. Find // it and insert after it. insertionIndex = aPoint->IndexOfInsertedChild(prevSibling); - MOZ_ASSERT(insertionIndex != aPoint->NoIndex); + MOZ_ASSERT(insertionIndex != -1); // Our insertion index is one after our previous sibling's index. ++insertionIndex; } else { // Otherwise, we append. // TODO This is wrong for nested insertion points. In that case, we need to // keep track of the right index to insert into. - insertionIndex = aPoint->mInsertedChildren.Length(); + insertionIndex = aPoint->InsertedChildrenLength(); } // Do the inserting. for (nsIContent* currentChild = aFirstNewContent; currentChild; currentChild = currentChild->GetNextSibling()) { aPoint->InsertInsertedChildAt(currentChild, insertionIndex++); } @@ -1072,25 +1072,25 @@ nsBindingManager::HandleChildInsertion(n if (!point) { break; } // Insert the child into the proper insertion point. // TODO If there were multiple insertion points, this approximation can be // wrong. We need to re-run the distribution algorithm. In the meantime, // this should work well enough. - size_t index = aAppend ? point->mInsertedChildren.Length() : 0; + uint32_t index = aAppend ? point->InsertedChildrenLength() : 0; for (nsIContent* currentSibling = aChild->GetPreviousSibling(); currentSibling; currentSibling = currentSibling->GetPreviousSibling()) { // If we find one of our previous siblings in the insertion point, the // index following it is the correct insertion point. Otherwise, we guess // based on whether we're appending or inserting. - size_t pointIndex = point->IndexOfInsertedChild(currentSibling); - if (pointIndex != point->NoIndex) { + int32_t pointIndex = point->IndexOfInsertedChild(currentSibling); + if (pointIndex != -1) { index = pointIndex + 1; break; } } point->InsertInsertedChildAt(aChild, index); nsIContent* newParent = point->GetParent();
--- a/dom/xbl/nsBindingManager.h +++ b/dom/xbl/nsBindingManager.h @@ -25,17 +25,20 @@ class nsIDocument; class nsIURI; class nsXBLDocumentInfo; class nsIStreamListener; class nsStyleSet; class nsXBLBinding; template<class E> class nsRefPtr; typedef nsTArray<nsRefPtr<nsXBLBinding> > nsBindingList; class nsIPrincipal; -class nsCSSStyleSheet; + +namespace mozilla { +class CSSStyleSheet; +} // namespace mozilla class nsBindingManager MOZ_FINAL : public nsStubMutationObserver { public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED @@ -111,17 +114,17 @@ public: /** * Do any processing that needs to happen as a result of a change in * the characteristics of the medium, and return whether this rule * processor's rules have changed (e.g., because of media queries). */ nsresult MediumFeaturesChanged(nsPresContext* aPresContext, bool* aRulesChanged); - void AppendAllSheets(nsTArray<nsCSSStyleSheet*>& aArray); + void AppendAllSheets(nsTArray<mozilla::CSSStyleSheet*>& aArray); void Traverse(nsIContent *aContent, nsCycleCollectionTraversalCallback &cb); NS_DECL_CYCLE_COLLECTION_CLASS(nsBindingManager) // Notify the binding manager when an outermost update begins and // ends. The end method can execute script.
--- a/dom/xbl/nsXBLBinding.cpp +++ b/dom/xbl/nsXBLBinding.cpp @@ -697,17 +697,17 @@ static void UpdateInsertionParent(XBLChildrenElement* aPoint, nsIContent* aOldBoundElement) { if (aPoint->IsDefaultInsertion()) { return; } for (size_t i = 0; i < aPoint->InsertedChildrenLength(); ++i) { - nsIContent* child = aPoint->mInsertedChildren[i]; + nsIContent* child = aPoint->InsertedChild(i); MOZ_ASSERT(child->GetParentNode()); // Here, we're iterating children that we inserted. There are two cases: // either |child| is an explicit child of |aOldBoundElement| and is no // longer inserted anywhere or it's a child of a <children> element // parented to |aOldBoundElement|. In the former case, the child is no // longer inserted anywhere, so we set its insertion parent to null. In the
--- a/dom/xbl/nsXBLPrototypeBinding.cpp +++ b/dom/xbl/nsXBLPrototypeBinding.cpp @@ -1681,40 +1681,40 @@ void nsXBLPrototypeBinding::EnsureResources() { if (!mResources) { mResources = new nsXBLPrototypeResources(this); } } void -nsXBLPrototypeBinding::AppendStyleSheet(nsCSSStyleSheet* aSheet) +nsXBLPrototypeBinding::AppendStyleSheet(CSSStyleSheet* aSheet) { EnsureResources(); mResources->AppendStyleSheet(aSheet); } void -nsXBLPrototypeBinding::RemoveStyleSheet(nsCSSStyleSheet* aSheet) +nsXBLPrototypeBinding::RemoveStyleSheet(CSSStyleSheet* aSheet) { if (!mResources) { MOZ_ASSERT(false, "Trying to remove a sheet that does not exist."); return; } mResources->RemoveStyleSheet(aSheet); } void -nsXBLPrototypeBinding::InsertStyleSheetAt(size_t aIndex, nsCSSStyleSheet* aSheet) +nsXBLPrototypeBinding::InsertStyleSheetAt(size_t aIndex, CSSStyleSheet* aSheet) { EnsureResources(); mResources->InsertStyleSheetAt(aIndex, aSheet); } -nsCSSStyleSheet* +CSSStyleSheet* nsXBLPrototypeBinding::StyleSheetAt(size_t aIndex) const { MOZ_ASSERT(mResources); return mResources->StyleSheetAt(aIndex); } size_t nsXBLPrototypeBinding::SheetCount() const @@ -1725,14 +1725,14 @@ nsXBLPrototypeBinding::SheetCount() cons bool nsXBLPrototypeBinding::HasStyleSheets() const { return mResources && mResources->HasStyleSheets(); } void nsXBLPrototypeBinding::AppendStyleSheetsTo( - nsTArray<nsCSSStyleSheet*>& aResult) const + nsTArray<CSSStyleSheet*>& aResult) const { if (mResources) { mResources->AppendStyleSheetsTo(aResult); } }
--- a/dom/xbl/nsXBLPrototypeBinding.h +++ b/dom/xbl/nsXBLPrototypeBinding.h @@ -20,16 +20,20 @@ class nsIAtom; class nsIContent; class nsIDocument; class nsXBLAttributeEntry; class nsXBLBinding; class nsXBLProtoImplField; +namespace mozilla { +class CSSStyleSheet; +} // namespace mozilla + // *********************************************************************/ // The XBLPrototypeBinding class // Instances of this class are owned by the nsXBLDocumentInfo object returned // by XBLDocumentInfo(). Consumers who want to refcount things should refcount // that. class nsXBLPrototypeBinding MOZ_FINAL { @@ -108,23 +112,23 @@ public: void SetBasePrototype(nsXBLPrototypeBinding* aBinding); nsXBLPrototypeBinding* GetBasePrototype() { return mBaseBinding; } nsXBLDocumentInfo* XBLDocumentInfo() const { return mXBLDocInfoWeak; } bool IsChrome() { return mXBLDocInfoWeak->IsChrome(); } void SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent); - void AppendStyleSheet(nsCSSStyleSheet* aSheet); - void RemoveStyleSheet(nsCSSStyleSheet* aSheet); - void InsertStyleSheetAt(size_t aIndex, nsCSSStyleSheet* aSheet); - nsCSSStyleSheet* StyleSheetAt(size_t aIndex) const; + void AppendStyleSheet(mozilla::CSSStyleSheet* aSheet); + void RemoveStyleSheet(mozilla::CSSStyleSheet* aSheet); + void InsertStyleSheetAt(size_t aIndex, mozilla::CSSStyleSheet* aSheet); + mozilla::CSSStyleSheet* StyleSheetAt(size_t aIndex) const; size_t SheetCount() const; bool HasStyleSheets() const; - void AppendStyleSheetsTo(nsTArray<nsCSSStyleSheet*>& aResult) const; + void AppendStyleSheetsTo(nsTArray<mozilla::CSSStyleSheet*>& aResult) const; nsIStyleRuleProcessor* GetRuleProcessor(); nsresult FlushSkinSheets(); nsIAtom* GetBaseTag(int32_t* aNamespaceID); void SetBaseTag(int32_t aNamespaceID, nsIAtom* aTag);
--- a/dom/xbl/nsXBLPrototypeResources.cpp +++ b/dom/xbl/nsXBLPrototypeResources.cpp @@ -75,28 +75,28 @@ nsXBLPrototypeResources::FlushSkinSheets return NS_OK; } // We have scoped stylesheets. Reload any chrome stylesheets we // encounter. (If they aren't skin sheets, it doesn't matter, since // they'll still be in the chrome cache. mRuleProcessor = nullptr; - nsTArray<nsRefPtr<nsCSSStyleSheet>> oldSheets; + nsTArray<nsRefPtr<CSSStyleSheet>> oldSheets; oldSheets.SwapElements(mStyleSheetList); mozilla::css::Loader* cssLoader = doc->CSSLoader(); for (size_t i = 0, count = oldSheets.Length(); i < count; ++i) { - nsCSSStyleSheet* oldSheet = oldSheets[i]; + CSSStyleSheet* oldSheet = oldSheets[i]; nsIURI* uri = oldSheet->GetSheetURI(); - nsRefPtr<nsCSSStyleSheet> newSheet; + nsRefPtr<CSSStyleSheet> newSheet; if (IsChromeURI(uri)) { if (NS_FAILED(cssLoader->LoadSheetSync(uri, getter_AddRefs(newSheet)))) continue; } else { newSheet = oldSheet; } @@ -133,35 +133,35 @@ void nsXBLPrototypeResources::GatherRuleProcessor() { mRuleProcessor = new nsCSSRuleProcessor(mStyleSheetList, nsStyleSet::eDocSheet, nullptr); } void -nsXBLPrototypeResources::AppendStyleSheet(nsCSSStyleSheet* aSheet) +nsXBLPrototypeResources::AppendStyleSheet(CSSStyleSheet* aSheet) { mStyleSheetList.AppendElement(aSheet); } void -nsXBLPrototypeResources::RemoveStyleSheet(nsCSSStyleSheet* aSheet) +nsXBLPrototypeResources::RemoveStyleSheet(CSSStyleSheet* aSheet) { DebugOnly<bool> found = mStyleSheetList.RemoveElement(aSheet); MOZ_ASSERT(found, "Trying to remove a sheet that does not exist."); } void -nsXBLPrototypeResources::InsertStyleSheetAt(size_t aIndex, nsCSSStyleSheet* aSheet) +nsXBLPrototypeResources::InsertStyleSheetAt(size_t aIndex, CSSStyleSheet* aSheet) { mStyleSheetList.InsertElementAt(aIndex, aSheet); } -nsCSSStyleSheet* +CSSStyleSheet* nsXBLPrototypeResources::StyleSheetAt(size_t aIndex) const { return mStyleSheetList[aIndex]; } size_t nsXBLPrototypeResources::SheetCount() const { @@ -171,12 +171,12 @@ nsXBLPrototypeResources::SheetCount() co bool nsXBLPrototypeResources::HasStyleSheets() const { return !mStyleSheetList.IsEmpty(); } void nsXBLPrototypeResources::AppendStyleSheetsTo( - nsTArray<nsCSSStyleSheet*>& aResult) const + nsTArray<CSSStyleSheet*>& aResult) const { aResult.AppendElements(mStyleSheetList); }
--- a/dom/xbl/nsXBLPrototypeResources.h +++ b/dom/xbl/nsXBLPrototypeResources.h @@ -5,22 +5,25 @@ #ifndef nsXBLPrototypeResources_h__ #define nsXBLPrototypeResources_h__ #include "nsAutoPtr.h" #include "nsICSSLoaderObserver.h" class nsCSSRuleProcessor; -class nsCSSStyleSheet; class nsIAtom; class nsIContent; class nsXBLPrototypeBinding; class nsXBLResourceLoader; +namespace mozilla { +class CSSStyleSheet; +} // namespace mozilla + // *********************************************************************/ // The XBLPrototypeResources class class nsXBLPrototypeResources { public: nsXBLPrototypeResources(nsXBLPrototypeBinding* aBinding); ~nsXBLPrototypeResources(); @@ -31,37 +34,37 @@ public: nsresult FlushSkinSheets(); nsresult Write(nsIObjectOutputStream* aStream); void Traverse(nsCycleCollectionTraversalCallback &cb) const; void ClearLoader(); - void AppendStyleSheet(nsCSSStyleSheet* aSheet); - void RemoveStyleSheet(nsCSSStyleSheet* aSheet); - void InsertStyleSheetAt(size_t aIndex, nsCSSStyleSheet* aSheet); - nsCSSStyleSheet* StyleSheetAt(size_t aIndex) const; + void AppendStyleSheet(mozilla::CSSStyleSheet* aSheet); + void RemoveStyleSheet(mozilla::CSSStyleSheet* aSheet); + void InsertStyleSheetAt(size_t aIndex, mozilla::CSSStyleSheet* aSheet); + mozilla::CSSStyleSheet* StyleSheetAt(size_t aIndex) const; size_t SheetCount() const; bool HasStyleSheets() const; - void AppendStyleSheetsTo(nsTArray<nsCSSStyleSheet*>& aResult) const; + void AppendStyleSheetsTo(nsTArray<mozilla::CSSStyleSheet*>& aResult) const; /** * Recreates mRuleProcessor to represent the current list of style sheets * stored in mStyleSheetList. (Named GatherRuleProcessor to parallel * nsStyleSet::GatherRuleProcessors.) */ void GatherRuleProcessor(); nsCSSRuleProcessor* GetRuleProcessor() const { return mRuleProcessor; } private: // A loader object. Exists only long enough to load resources, and then it dies. nsRefPtr<nsXBLResourceLoader> mLoader; // A list of loaded stylesheets for this binding. - nsTArray<nsRefPtr<nsCSSStyleSheet>> mStyleSheetList; + nsTArray<nsRefPtr<mozilla::CSSStyleSheet>> mStyleSheetList; // The list of stylesheets converted to a rule processor. nsRefPtr<nsCSSRuleProcessor> mRuleProcessor; }; #endif
--- a/dom/xbl/nsXBLResourceLoader.cpp +++ b/dom/xbl/nsXBLResourceLoader.cpp @@ -1,39 +1,41 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsTArray.h" #include "nsString.h" -#include "nsCSSStyleSheet.h" #include "nsIStyleRuleProcessor.h" #include "nsIDocument.h" #include "nsIContent.h" #include "nsIPresShell.h" #include "nsXBLService.h" #include "nsIServiceManager.h" #include "nsXBLResourceLoader.h" #include "nsXBLPrototypeResources.h" #include "nsIDocumentObserver.h" #include "imgILoader.h" #include "imgRequestProxy.h" +#include "mozilla/CSSStyleSheet.h" #include "mozilla/css/Loader.h" #include "nsIURI.h" #include "nsNetUtil.h" #include "nsGkAtoms.h" #include "nsFrameManager.h" #include "nsStyleContext.h" #include "nsXBLPrototypeBinding.h" #include "nsCSSRuleProcessor.h" #include "nsContentUtils.h" #include "nsStyleSet.h" #include "nsIScriptSecurityManager.h" +using namespace mozilla; + NS_IMPL_CYCLE_COLLECTION(nsXBLResourceLoader, mBoundElements) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXBLResourceLoader) NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXBLResourceLoader) @@ -130,17 +132,17 @@ nsXBLResourceLoader::LoadResources(bool* bool chrome; nsresult rv; if (NS_SUCCEEDED(url->SchemeIs("chrome", &chrome)) && chrome) { rv = nsContentUtils::GetSecurityManager()-> CheckLoadURIWithPrincipal(docPrincipal, url, nsIScriptSecurityManager::ALLOW_CHROME); if (NS_SUCCEEDED(rv)) { - nsRefPtr<nsCSSStyleSheet> sheet; + nsRefPtr<CSSStyleSheet> sheet; rv = cssLoader->LoadSheetSync(url, getter_AddRefs(sheet)); NS_ASSERTION(NS_SUCCEEDED(rv), "Load failed!!!"); if (NS_SUCCEEDED(rv)) { rv = StyleSheetLoaded(sheet, false, NS_OK); NS_ASSERTION(NS_SUCCEEDED(rv), "Processing the style sheet failed!!!"); } } @@ -159,17 +161,17 @@ nsXBLResourceLoader::LoadResources(bool* // Destroy our resource list. delete mResourceList; mResourceList = nullptr; } // nsICSSLoaderObserver NS_IMETHODIMP -nsXBLResourceLoader::StyleSheetLoaded(nsCSSStyleSheet* aSheet, +nsXBLResourceLoader::StyleSheetLoaded(CSSStyleSheet* aSheet, bool aWasAlternate, nsresult aStatus) { if (!mResources) { // Our resources got destroyed -- just bail out return NS_OK; }
--- a/dom/xbl/nsXBLResourceLoader.h +++ b/dom/xbl/nsXBLResourceLoader.h @@ -24,17 +24,18 @@ class nsIObjectOutputStream; class nsXBLResourceLoader : public nsICSSLoaderObserver { public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_CLASS(nsXBLResourceLoader) // nsICSSLoaderObserver - NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet, bool aWasAlternate, + NS_IMETHOD StyleSheetLoaded(mozilla::CSSStyleSheet* aSheet, + bool aWasAlternate, nsresult aStatus) MOZ_OVERRIDE; void LoadResources(bool* aResult); void AddResource(nsIAtom* aResourceType, const nsAString& aSrc); void AddResourceListener(nsIContent* aElement); nsXBLResourceLoader(nsXBLPrototypeBinding* aBinding, nsXBLPrototypeResources* aResources);
--- a/dom/xslt/tests/mochitest/test_bug319374.xhtml +++ b/dom/xslt/tests/mochitest/test_bug319374.xhtml @@ -34,18 +34,17 @@ https://bugzilla.mozilla.org/show_bug.cg function getAnonymousNodes(e) { return SpecialPowers.wrap(document).getAnonymousNodes(e); } try { var xp = new XPathEvaluator(); var result = xp.evaluate("*", document.getElementById('content'), null, - SpecialPowers.Ci.nsIDOMXPathResult. - UNORDERED_NODE_ITERATOR_TYPE, + XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null); var res = null; while (res = result.iterateNext()) { ++counter; var anon = getAnonymousNodes(res); anon[0].removeChild(anon[0].firstChild); // Removing a child node anon[0].removeAttribute("attr1"); // Removing an attribute anon[1].firstChild.data = "anon text changed" // Modifying text data @@ -64,36 +63,34 @@ https://bugzilla.mozilla.org/show_bug.cg var anonAttr2 = getAnonymousNodes(document.getElementById('content'). lastChild)[0].getAttributeNode('attr'); var resultAttr = null; try { var xp2 = SpecialPowers.wrap(xp).evaluate(".", anonAttr1, null, - SpecialPowers.Ci.nsIDOMXPathResult. - UNORDERED_NODE_ITERATOR_TYPE, + XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null); // Attribute changing in a different anonymous tree. anonAttr2.value = "foo"; resultAttr = xp2.iterateNext(); ok(SpecialPowers.compare(resultAttr, anonAttr1), "XPathEvaluator returned wrong attribute!") } catch (e) { ok(false, e); } // Test 3: If the anonymous tree in which context node is in is modified, // XPath result should throw when iterateNext() is called. resultAttr = null; try { var xp3 = xp.evaluate(".", anonAttr1, null, - SpecialPowers.Ci.nsIDOMXPathResult. - UNORDERED_NODE_ITERATOR_TYPE, + XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null); // Attribute changing in the same anonymous tree. anonAttr1.ownerElement.setAttribute("foo", "bar"); resultAttr = xp3.iterateNext(); ok(resultAttr == anonAttr1, "XPathEvaluator should have thrown an exception!") } catch (e) { ok(true, e);
--- a/dom/xslt/xpath/XPathEvaluator.cpp +++ b/dom/xslt/xpath/XPathEvaluator.cpp @@ -4,28 +4,29 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/dom/XPathEvaluator.h" #include "mozilla/Move.h" #include "nsCOMPtr.h" #include "nsIAtom.h" #include "nsXPathExpression.h" #include "nsXPathNSResolver.h" -#include "nsXPathResult.h" +#include "XPathResult.h" #include "nsContentCID.h" #include "txExpr.h" #include "txExprParser.h" #include "nsError.h" #include "txURIUtils.h" #include "nsIDocument.h" #include "nsIDOMDocument.h" #include "nsDOMString.h" #include "nsNameSpaceManager.h" #include "nsContentUtils.h" #include "mozilla/dom/XPathEvaluatorBinding.h" +#include "mozilla/dom/BindingUtils.h" extern nsresult TX_ResolveFunctionCallXPCOM(const nsCString &aContractID, int32_t aNamespaceID, nsIAtom *aName, nsISupports *aState, FunctionCall **aFunction); namespace mozilla { namespace dom { @@ -169,26 +170,28 @@ XPathEvaluator::CreateNSResolver(nsINode ErrorResult& rv) { nsCOMPtr<nsIDOMNode> nodeResolver = do_QueryInterface(aNodeResolver); nsCOMPtr<nsIDOMXPathNSResolver> res; rv = CreateNSResolver(nodeResolver, getter_AddRefs(res)); return res.forget(); } -already_AddRefed<nsISupports> -XPathEvaluator::Evaluate(const nsAString& aExpression, nsINode* aContextNode, +already_AddRefed<XPathResult> +XPathEvaluator::Evaluate(JSContext* aCx, const nsAString& aExpression, + nsINode* aContextNode, nsIDOMXPathNSResolver* aResolver, uint16_t aType, - nsISupports* aResult, ErrorResult& rv) + JS::Handle<JSObject*> aResult, ErrorResult& rv) { nsCOMPtr<nsIDOMNode> contextNode = do_QueryInterface(aContextNode); nsCOMPtr<nsISupports> res; rv = Evaluate(aExpression, contextNode, aResolver, aType, - aResult, getter_AddRefs(res)); - return res.forget(); + aResult ? UnwrapDOMObjectToISupports(aResult) : nullptr, + getter_AddRefs(res)); + return res.forget().downcast<nsIXPathResult>().downcast<XPathResult>(); } /* * Implementation of txIParseContext private to XPathEvaluator, based on a * nsIDOMXPathNSResolver */
--- a/dom/xslt/xpath/XPathEvaluator.h +++ b/dom/xslt/xpath/XPathEvaluator.h @@ -16,16 +16,17 @@ class nsINode; class txResultRecycler; namespace mozilla { namespace dom { class GlobalObject; +class XPathResult; /** * A class for evaluating an XPath expression string */ class XPathEvaluator MOZ_FINAL : public nsIDOMXPathEvaluator { public: XPathEvaluator(nsIDocument* aDocument = nullptr); @@ -45,20 +46,21 @@ public: static already_AddRefed<XPathEvaluator> Constructor(const GlobalObject& aGlobal, ErrorResult& rv); already_AddRefed<nsIDOMXPathExpression> CreateExpression(const nsAString& aExpression, nsIDOMXPathNSResolver* aResolver, ErrorResult& rv); already_AddRefed<nsIDOMXPathNSResolver> CreateNSResolver(nsINode* aNodeResolver, ErrorResult& rv); - already_AddRefed<nsISupports> - Evaluate(const nsAString& aExpression, nsINode* aContextNode, - nsIDOMXPathNSResolver* aResolver, uint16_t aType, - nsISupports* aResult, ErrorResult& rv); + already_AddRefed<XPathResult> + Evaluate(JSContext* aCx, const nsAString& aExpression, + nsINode* aContextNode, nsIDOMXPathNSResolver* aResolver, + uint16_t aType, JS::Handle<JSObject*> aResult, + ErrorResult& rv); private: nsWeakPtr mDocument; nsRefPtr<txResultRecycler> mRecycler; }; inline nsISupports* ToSupports(XPathEvaluator* e) {
rename from dom/xslt/xpath/nsXPathResult.cpp rename to dom/xslt/xpath/XPathResult.cpp --- a/dom/xslt/xpath/nsXPathResult.cpp +++ b/dom/xslt/xpath/XPathResult.cpp @@ -1,267 +1,184 @@ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* 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 "nsXPathResult.h" +#include "XPathResult.h" #include "txExprResult.h" #include "txNodeSet.h" #include "nsError.h" #include "mozilla/dom/Attr.h" #include "mozilla/dom/Element.h" #include "nsDOMClassInfoID.h" #include "nsIDOMNode.h" #include "nsIDOMDocument.h" #include "nsDOMString.h" #include "txXPathTreeWalker.h" #include "nsCycleCollectionParticipant.h" +#include "mozilla/dom/XPathResultBinding.h" -using namespace mozilla::dom; +namespace mozilla { +namespace dom { -nsXPathResult::nsXPathResult() : mDocument(nullptr), - mCurrentPos(0), - mResultType(ANY_TYPE), - mInvalidIteratorState(true), - mBooleanResult(false), - mNumberResult(0) +XPathResult::XPathResult(nsINode* aParent) + : mParent(aParent), + mDocument(nullptr), + mCurrentPos(0), + mResultType(ANY_TYPE), + mInvalidIteratorState(true), + mBooleanResult(false), + mNumberResult(0) { + SetIsDOMBinding(); } -nsXPathResult::nsXPathResult(const nsXPathResult &aResult) - : mResult(aResult.mResult), +XPathResult::XPathResult(const XPathResult &aResult) + : mParent(aResult.mParent), + mResult(aResult.mResult), mResultNodes(aResult.mResultNodes), mDocument(aResult.mDocument), + mContextNode(aResult.mContextNode), mCurrentPos(0), mResultType(aResult.mResultType), - mContextNode(aResult.mContextNode), mInvalidIteratorState(aResult.mInvalidIteratorState) { + SetIsDOMBinding(); if (mDocument) { mDocument->AddMutationObserver(this); } } -nsXPathResult::~nsXPathResult() +XPathResult::~XPathResult() { RemoveObserver(); } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsXPathResult) +NS_IMPL_CYCLE_COLLECTION_CLASS(XPathResult) -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXPathResult) +NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(XPathResult) +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XPathResult) + NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER + NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent) { tmp->RemoveObserver(); } NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument) NS_IMPL_CYCLE_COLLECTION_UNLINK_END -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXPathResult) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(XPathResult) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResultNodes) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END -NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXPathResult) -NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXPathResult) +NS_IMPL_CYCLE_COLLECTING_ADDREF(XPathResult) +NS_IMPL_CYCLE_COLLECTING_RELEASE(XPathResult) -DOMCI_DATA(XPathResult, nsXPathResult) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXPathResult) - NS_INTERFACE_MAP_ENTRY(nsIDOMXPathResult) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XPathResult) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_ENTRY(nsIMutationObserver) NS_INTERFACE_MAP_ENTRY(nsIXPathResult) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMXPathResult) - NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XPathResult) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPathResult) NS_INTERFACE_MAP_END +JSObject* +XPathResult::WrapObject(JSContext* aCx) +{ + return XPathResultBinding::Wrap(aCx, this); +} + void -nsXPathResult::RemoveObserver() +XPathResult::RemoveObserver() { if (mDocument) { mDocument->RemoveMutationObserver(this); } } -NS_IMETHODIMP -nsXPathResult::GetResultType(uint16_t *aResultType) -{ - *aResultType = mResultType; - - return NS_OK; -} - -NS_IMETHODIMP -nsXPathResult::GetNumberValue(double *aNumberValue) -{ - if (mResultType != NUMBER_TYPE) { - return NS_ERROR_DOM_TYPE_ERR; - } - - *aNumberValue = mNumberResult; - - return NS_OK; -} - -NS_IMETHODIMP -nsXPathResult::GetStringValue(nsAString &aStringValue) -{ - if (mResultType != STRING_TYPE) { - return NS_ERROR_DOM_TYPE_ERR; - } - - aStringValue = mStringResult; - - return NS_OK; -} - -NS_IMETHODIMP -nsXPathResult::GetBooleanValue(bool *aBooleanValue) -{ - if (mResultType != BOOLEAN_TYPE) { - return NS_ERROR_DOM_TYPE_ERR; - } - - *aBooleanValue = mBooleanResult; - - return NS_OK; -} - -NS_IMETHODIMP -nsXPathResult::GetSingleNodeValue(nsIDOMNode **aSingleNodeValue) -{ - if (!isNode()) { - return NS_ERROR_DOM_TYPE_ERR; - } - - if (mResultNodes.Count() > 0) { - NS_ADDREF(*aSingleNodeValue = mResultNodes[0]); - } - else { - *aSingleNodeValue = nullptr; - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXPathResult::GetInvalidIteratorState(bool *aInvalidIteratorState) -{ - *aInvalidIteratorState = isIterator() && mInvalidIteratorState; - - return NS_OK; -} - -NS_IMETHODIMP -nsXPathResult::GetSnapshotLength(uint32_t *aSnapshotLength) -{ - if (!isSnapshot()) { - return NS_ERROR_DOM_TYPE_ERR; - } - - *aSnapshotLength = (uint32_t)mResultNodes.Count(); - - return NS_OK; -} - -NS_IMETHODIMP -nsXPathResult::IterateNext(nsIDOMNode **aResult) +nsINode* +XPathResult::IterateNext(ErrorResult& aRv) { if (!isIterator()) { - return NS_ERROR_DOM_TYPE_ERR; + aRv.Throw(NS_ERROR_DOM_TYPE_ERR); + return nullptr; } if (mDocument) { mDocument->FlushPendingNotifications(Flush_Content); } if (mInvalidIteratorState) { - return NS_ERROR_DOM_INVALID_STATE_ERR; - } - - if (mCurrentPos < (uint32_t)mResultNodes.Count()) { - NS_ADDREF(*aResult = mResultNodes[mCurrentPos++]); - } - else { - *aResult = nullptr; + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; } - return NS_OK; -} - -NS_IMETHODIMP -nsXPathResult::SnapshotItem(uint32_t aIndex, nsIDOMNode **aResult) -{ - if (!isSnapshot()) { - return NS_ERROR_DOM_TYPE_ERR; - } - - NS_IF_ADDREF(*aResult = mResultNodes.SafeObjectAt(aIndex)); - - return NS_OK; + return mResultNodes.SafeObjectAt(mCurrentPos++); } void -nsXPathResult::NodeWillBeDestroyed(const nsINode* aNode) +XPathResult::NodeWillBeDestroyed(const nsINode* aNode) { nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this); // Set to null to avoid unregistring unnecessarily mDocument = nullptr; Invalidate(aNode->IsNodeOfType(nsINode::eCONTENT) ? static_cast<const nsIContent*>(aNode) : nullptr); } void -nsXPathResult::CharacterDataChanged(nsIDocument* aDocument, - nsIContent *aContent, - CharacterDataChangeInfo* aInfo) +XPathResult::CharacterDataChanged(nsIDocument* aDocument, + nsIContent *aContent, + CharacterDataChangeInfo* aInfo) { Invalidate(aContent); } void -nsXPathResult::AttributeChanged(nsIDocument* aDocument, - Element* aElement, - int32_t aNameSpaceID, - nsIAtom* aAttribute, - int32_t aModType) +XPathResult::AttributeChanged(nsIDocument* aDocument, + Element* aElement, + int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) { Invalidate(aElement); } void -nsXPathResult::ContentAppended(nsIDocument* aDocument, - nsIContent* aContainer, - nsIContent* aFirstNewContent, - int32_t aNewIndexInContainer) +XPathResult::ContentAppended(nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aFirstNewContent, + int32_t aNewIndexInContainer) { Invalidate(aContainer); } void -nsXPathResult::ContentInserted(nsIDocument* aDocument, - nsIContent* aContainer, - nsIContent* aChild, - int32_t aIndexInContainer) +XPathResult::ContentInserted(nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + int32_t aIndexInContainer) { Invalidate(aContainer); } void -nsXPathResult::ContentRemoved(nsIDocument* aDocument, - nsIContent* aContainer, - nsIContent* aChild, - int32_t aIndexInContainer, - nsIContent* aPreviousSibling) +XPathResult::ContentRemoved(nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + int32_t aIndexInContainer, + nsIContent* aPreviousSibling) { Invalidate(aContainer); } nsresult -nsXPathResult::SetExprResult(txAExprResult* aExprResult, uint16_t aResultType, - nsINode* aContextNode) +XPathResult::SetExprResult(txAExprResult* aExprResult, uint16_t aResultType, + nsINode* aContextNode) { MOZ_ASSERT(aExprResult); if ((isSnapshot(aResultType) || isIterator(aResultType) || isNode(aResultType)) && aExprResult->getResultType() != txAExprResult::NODESET) { // The DOM spec doesn't really say what should happen when reusing an // XPathResult and an error is thrown. Let's not touch the XPathResult @@ -300,59 +217,48 @@ nsXPathResult::SetExprResult(txAExprResu default: { MOZ_ASSERT(isNode() || isIterator() || isSnapshot()); } } if (aExprResult->getResultType() == txAExprResult::NODESET) { txNodeSet *nodeSet = static_cast<txNodeSet*>(aExprResult); - nsCOMPtr<nsIDOMNode> node; int32_t i, count = nodeSet->size(); for (i = 0; i < count; ++i) { - txXPathNativeNode::getNode(nodeSet->get(i), getter_AddRefs(node)); - if (node) { - mResultNodes.AppendObject(node); - } + nsINode* node = txXP