mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
1e0f6191a6
@ -117,7 +117,7 @@ function checkDebuggerPort() {
|
||||
function initResponsiveDesign() {
|
||||
Cu.import('resource:///modules/devtools/responsivedesign.jsm');
|
||||
ResponsiveUIManager.on('on', function(event, {tab:tab}) {
|
||||
let responsive = tab.__responsiveUI;
|
||||
let responsive = ResponsiveUIManager.getResponsiveUIForTab(tab);
|
||||
let document = tab.ownerDocument;
|
||||
|
||||
// Only tweak reponsive mode for shell.html tabs.
|
||||
@ -137,7 +137,7 @@ function initResponsiveDesign() {
|
||||
}, true);
|
||||
|
||||
// Enable touch events
|
||||
browserWindow.gBrowser.selectedTab.__responsiveUI.enableTouch();
|
||||
responsive.enableTouch();
|
||||
});
|
||||
|
||||
// Automatically toggle responsive design mode
|
||||
|
@ -148,7 +148,8 @@ window.addEventListener('ContentStart', function() {
|
||||
let chromewidth = window.outerWidth - window.innerWidth;
|
||||
let chromeheight = window.outerHeight - window.innerHeight + controlsHeight;
|
||||
if (isMulet) {
|
||||
let responsive = browserWindow.gBrowser.selectedTab.__responsiveUI;
|
||||
let tab = browserWindow.gBrowser.selectedTab;
|
||||
let responsive = ResponsiveUIManager.getResponsiveUIForTab(tab);
|
||||
responsive.setSize((Math.round(width * scale) + 16*2),
|
||||
(Math.round(height * scale) + controlsHeight + 61));
|
||||
} else {
|
||||
|
@ -35,9 +35,9 @@ var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptS
|
||||
let permissionSpecificChecker = {};
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this,
|
||||
"AudioManager",
|
||||
"@mozilla.org/telephony/audiomanager;1",
|
||||
"nsIAudioManager");
|
||||
"TelephonyService",
|
||||
"@mozilla.org/telephony/telephonyservice;1",
|
||||
"nsITelephonyService");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
|
||||
"resource://gre/modules/SystemAppProxy.jsm");
|
||||
@ -455,12 +455,29 @@ ContentPermissionPrompt.prototype = {
|
||||
(function() {
|
||||
// Do not allow GetUserMedia while in call.
|
||||
permissionSpecificChecker["audio-capture"] = function(request) {
|
||||
if (AudioManager.phoneState === Ci.nsIAudioManager.PHONE_STATE_IN_CALL) {
|
||||
request.cancel();
|
||||
return true;
|
||||
} else {
|
||||
let forbid = false;
|
||||
|
||||
try {
|
||||
// nsITelephonyService.enumerateCalls is synchronous.
|
||||
TelephonyService.enumerateCalls({
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyListener]),
|
||||
enumerateCallStateComplete: function() {},
|
||||
enumerateCallState: function(callInfo) {
|
||||
if (callInfo.callState == Ci.nsITelephonyService.CALL_STATE_CONNECTED) {
|
||||
forbid = true;
|
||||
}
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
// No restriction if Telephony service doesn't exist.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (forbid) {
|
||||
request.cancel();
|
||||
}
|
||||
|
||||
return forbid;
|
||||
};
|
||||
})();
|
||||
|
||||
|
@ -12,15 +12,15 @@
|
||||
<!--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="e0c735ec89df011ea7dd435087a9045ecff9ff9e">
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5e98dc164b17fd6decb48a9eaddef0e55b82e249"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e45c5dbdcfc2d598c889dfbea72fa11157422afe"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="320dad6b787c296ba701bca8377f71ab5fd72ee8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<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="fe91ec3af5396edab45b15e546e21613785724b5"/>
|
||||
@ -116,7 +116,7 @@
|
||||
<project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="f7d9bf71cf6693474f3f2a81a4ba62c0fc5646aa"/>
|
||||
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="cfcef469537869947abb9aa1d656774cc2678d4c"/>
|
||||
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
|
||||
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="bdc5a9f9602652c3c2626e020da03674a2c2e1b6"/>
|
||||
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="8a05fd72770a3b1fc23f3216a45318ad393fc4ca"/>
|
||||
<project name="platform/system/extras" path="system/extras" revision="10e78a05252b3de785f88c2d0b9ea8a428009c50"/>
|
||||
<project name="platform/system/media" path="system/media" revision="7ff72c2ea2496fa50b5e8a915e56e901c3ccd240"/>
|
||||
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="fe95bc6f83af5c18a73aa86c96e7fa7f79b91477"/>
|
||||
|
@ -19,9 +19,9 @@
|
||||
<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="5e98dc164b17fd6decb48a9eaddef0e55b82e249"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="320dad6b787c296ba701bca8377f71ab5fd72ee8"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e45c5dbdcfc2d598c889dfbea72fa11157422afe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
|
@ -15,10 +15,10 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="0e94c080bee081a50aa2097527b0b40852f9143f">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5e98dc164b17fd6decb48a9eaddef0e55b82e249"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="320dad6b787c296ba701bca8377f71ab5fd72ee8"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e45c5dbdcfc2d598c889dfbea72fa11157422afe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="fe91ec3af5396edab45b15e546e21613785724b5"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
@ -118,7 +118,7 @@
|
||||
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="842e33e43a55ea44833b9e23e4d180fa17c843af"/>
|
||||
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5db24726f0f42124304195a6bdea129039eeeaeb"/>
|
||||
<project name="platform/system/bluetooth" path="system/bluetooth" revision="930ae098543881f47eac054677726ee4b998b2f8"/>
|
||||
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="bdc5a9f9602652c3c2626e020da03674a2c2e1b6"/>
|
||||
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="8a05fd72770a3b1fc23f3216a45318ad393fc4ca"/>
|
||||
<project name="platform_system_core" path="system/core" remote="b2g" revision="542d1f59dc331b472307e5bd043101d14d5a3a3e"/>
|
||||
<project name="platform/system/extras" path="system/extras" revision="18c1180e848e7ab8691940481f5c1c8d22c37b3e"/>
|
||||
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="fe95bc6f83af5c18a73aa86c96e7fa7f79b91477"/>
|
||||
|
@ -12,15 +12,15 @@
|
||||
<!--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="e0c735ec89df011ea7dd435087a9045ecff9ff9e">
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5e98dc164b17fd6decb48a9eaddef0e55b82e249"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e45c5dbdcfc2d598c889dfbea72fa11157422afe"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="320dad6b787c296ba701bca8377f71ab5fd72ee8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<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="fe91ec3af5396edab45b15e546e21613785724b5"/>
|
||||
@ -116,7 +116,7 @@
|
||||
<project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="f7d9bf71cf6693474f3f2a81a4ba62c0fc5646aa"/>
|
||||
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="b562b01c93de9578d5db537b6a602a38e1aaa0ce"/>
|
||||
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="387f03e815f57d536dd922706db1622bddba8d81"/>
|
||||
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="bdc5a9f9602652c3c2626e020da03674a2c2e1b6"/>
|
||||
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="8a05fd72770a3b1fc23f3216a45318ad393fc4ca"/>
|
||||
<project name="platform/system/extras" path="system/extras" revision="5356165f67f4a81c2ef28671c13697f1657590df"/>
|
||||
<project name="platform/system/media" path="system/media" revision="be0e2fe59a8043fa5200f75697df9220a99abe9d"/>
|
||||
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="fe95bc6f83af5c18a73aa86c96e7fa7f79b91477"/>
|
||||
@ -129,7 +129,7 @@
|
||||
<default remote="caf" revision="refs/tags/android-4.4.2_r1" sync-j="4"/>
|
||||
<!-- Emulator specific things -->
|
||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="72ffdf71c68a96309212eb13d63560d66db14c9e"/>
|
||||
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="c0e0019a6ec1a6199a9c7bc4ace041259f3b8512"/>
|
||||
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="f5f7fa2fc26b96d2cbd0af4569c0036fe034bb43"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="a510f2d2d579e76421b0c84cd225c249b2da6f8a"/>
|
||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="694cecf256122d0cb3b6a1a4efb4b5c7401db223"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="97d63c256a047b491565d624aea1dd5f1f8593ea"/>
|
||||
|
@ -19,9 +19,9 @@
|
||||
<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="5e98dc164b17fd6decb48a9eaddef0e55b82e249"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="320dad6b787c296ba701bca8377f71ab5fd72ee8"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e45c5dbdcfc2d598c889dfbea72fa11157422afe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
|
@ -12,15 +12,15 @@
|
||||
<!--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="e0c735ec89df011ea7dd435087a9045ecff9ff9e">
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5e98dc164b17fd6decb48a9eaddef0e55b82e249"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e45c5dbdcfc2d598c889dfbea72fa11157422afe"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="320dad6b787c296ba701bca8377f71ab5fd72ee8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<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="fe91ec3af5396edab45b15e546e21613785724b5"/>
|
||||
@ -111,7 +111,7 @@
|
||||
<project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="f7d9bf71cf6693474f3f2a81a4ba62c0fc5646aa"/>
|
||||
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="69d524e80cdf3981006627c65ac85f3a871238a3"/>
|
||||
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
|
||||
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="bdc5a9f9602652c3c2626e020da03674a2c2e1b6"/>
|
||||
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="8a05fd72770a3b1fc23f3216a45318ad393fc4ca"/>
|
||||
<project name="platform/system/extras" path="system/extras" revision="576f57b6510de59c08568b53c0fb60588be8689e"/>
|
||||
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="fe95bc6f83af5c18a73aa86c96e7fa7f79b91477"/>
|
||||
<project name="platform/system/netd" path="system/netd" revision="a6531f7befb49b1c81bc0de7e51c5482b308e1c5"/>
|
||||
|
@ -17,8 +17,8 @@
|
||||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5e98dc164b17fd6decb48a9eaddef0e55b82e249"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="320dad6b787c296ba701bca8377f71ab5fd72ee8"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e45c5dbdcfc2d598c889dfbea72fa11157422afe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="fe91ec3af5396edab45b15e546e21613785724b5"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"git": {
|
||||
"git_revision": "5e98dc164b17fd6decb48a9eaddef0e55b82e249",
|
||||
"git_revision": "e45c5dbdcfc2d598c889dfbea72fa11157422afe",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "d60b9f55a77aa72606acb397b3770adc1bcf5110",
|
||||
"revision": "ecc956a2747963c2db6edf513cd3a8a75ca8884a",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
@ -17,8 +17,8 @@
|
||||
<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="5e98dc164b17fd6decb48a9eaddef0e55b82e249"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="320dad6b787c296ba701bca8377f71ab5fd72ee8"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e45c5dbdcfc2d598c889dfbea72fa11157422afe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="fe91ec3af5396edab45b15e546e21613785724b5"/>
|
||||
|
@ -15,9 +15,9 @@
|
||||
<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="5e98dc164b17fd6decb48a9eaddef0e55b82e249"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="320dad6b787c296ba701bca8377f71ab5fd72ee8"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e45c5dbdcfc2d598c889dfbea72fa11157422afe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
|
||||
|
@ -15,10 +15,10 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="0e94c080bee081a50aa2097527b0b40852f9143f">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5e98dc164b17fd6decb48a9eaddef0e55b82e249"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="320dad6b787c296ba701bca8377f71ab5fd72ee8"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e45c5dbdcfc2d598c889dfbea72fa11157422afe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="fe91ec3af5396edab45b15e546e21613785724b5"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
@ -118,7 +118,7 @@
|
||||
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="842e33e43a55ea44833b9e23e4d180fa17c843af"/>
|
||||
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5db24726f0f42124304195a6bdea129039eeeaeb"/>
|
||||
<project name="platform/system/bluetooth" path="system/bluetooth" revision="930ae098543881f47eac054677726ee4b998b2f8"/>
|
||||
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="bdc5a9f9602652c3c2626e020da03674a2c2e1b6"/>
|
||||
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="8a05fd72770a3b1fc23f3216a45318ad393fc4ca"/>
|
||||
<project name="platform_system_core" path="system/core" remote="b2g" revision="542d1f59dc331b472307e5bd043101d14d5a3a3e"/>
|
||||
<project name="platform/system/extras" path="system/extras" revision="18c1180e848e7ab8691940481f5c1c8d22c37b3e"/>
|
||||
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="fe95bc6f83af5c18a73aa86c96e7fa7f79b91477"/>
|
||||
|
@ -17,9 +17,9 @@
|
||||
<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="5e98dc164b17fd6decb48a9eaddef0e55b82e249"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="320dad6b787c296ba701bca8377f71ab5fd72ee8"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e45c5dbdcfc2d598c889dfbea72fa11157422afe"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="fe91ec3af5396edab45b15e546e21613785724b5"/>
|
||||
|
@ -260,6 +260,7 @@ let MozLoopServiceInternal = {
|
||||
*/
|
||||
setError: function(errorType, error, actionCallback = null) {
|
||||
log.debug("setError", errorType, error);
|
||||
log.trace();
|
||||
let messageString, detailsString, detailsButtonLabelString, detailsButtonCallback;
|
||||
const NETWORK_ERRORS = [
|
||||
Cr.NS_ERROR_CONNECTION_REFUSED,
|
||||
@ -300,15 +301,24 @@ let MozLoopServiceInternal = {
|
||||
}
|
||||
|
||||
error.friendlyMessage = this.localizedStrings.get(messageString);
|
||||
error.friendlyDetails = detailsString ?
|
||||
this.localizedStrings.get(detailsString) :
|
||||
null;
|
||||
|
||||
// Default to the generic "retry_button" text even though the button won't be shown if
|
||||
// error.friendlyDetails is null.
|
||||
error.friendlyDetailsButtonLabel = detailsButtonLabelString ?
|
||||
this.localizedStrings.get(detailsButtonLabelString) :
|
||||
null;
|
||||
this.localizedStrings.get("retry_button");
|
||||
|
||||
error.friendlyDetailsButtonCallback = actionCallback || detailsButtonCallback || null;
|
||||
|
||||
if (detailsString) {
|
||||
error.friendlyDetails = this.localizedStrings.get(detailsString);
|
||||
} else if (error.friendlyDetailsButtonCallback) {
|
||||
// If we have a retry callback but no details use the generic try again string.
|
||||
error.friendlyDetails = this.localizedStrings.get("generic_failure_no_reason2");
|
||||
} else {
|
||||
error.friendlyDetails = null;
|
||||
}
|
||||
|
||||
gErrors.set(errorType, error);
|
||||
this.notifyStatusChanged();
|
||||
},
|
||||
@ -1219,7 +1229,8 @@ this.MozLoopService = {
|
||||
deferredInitialization.resolve("initialized to logged-in status");
|
||||
}, error => {
|
||||
log.debug("MozLoopService: error logging in using cached auth token");
|
||||
MozLoopServiceInternal.setError("login", error);
|
||||
let retryFunc = () => MozLoopServiceInternal.promiseRegisteredWithServers(LOOP_SESSION_TYPE.FXA);
|
||||
MozLoopServiceInternal.setError("login", error, retryFunc);
|
||||
deferredInitialization.reject("error logging in using cached auth token");
|
||||
});
|
||||
yield completedPromise;
|
||||
@ -1421,27 +1432,17 @@ this.MozLoopService = {
|
||||
MozLoopServiceInternal.clearError("profile");
|
||||
return MozLoopServiceInternal.fxAOAuthTokenData;
|
||||
});
|
||||
}).then(tokenData => {
|
||||
let client = new FxAccountsProfileClient({
|
||||
serverURL: gFxAOAuthClient.parameters.profile_uri,
|
||||
token: tokenData.access_token
|
||||
});
|
||||
client.fetchProfile().then(result => {
|
||||
MozLoopServiceInternal.fxAOAuthProfile = result;
|
||||
}, error => {
|
||||
log.error("Failed to retrieve profile", error);
|
||||
this.setError("profile", error);
|
||||
MozLoopServiceInternal.fxAOAuthProfile = null;
|
||||
MozLoopServiceInternal.notifyStatusChanged();
|
||||
});
|
||||
}).then(Task.async(function* fetchProfile(tokenData) {
|
||||
yield MozLoopService.fetchFxAProfile(tokenData);
|
||||
return tokenData;
|
||||
}).catch(error => {
|
||||
})).catch(error => {
|
||||
MozLoopServiceInternal.fxAOAuthTokenData = null;
|
||||
MozLoopServiceInternal.fxAOAuthProfile = null;
|
||||
MozLoopServiceInternal.deferredRegistrations.delete(LOOP_SESSION_TYPE.FXA);
|
||||
throw error;
|
||||
}).catch((error) => {
|
||||
MozLoopServiceInternal.setError("login", error);
|
||||
MozLoopServiceInternal.setError("login", error,
|
||||
() => MozLoopService.logInToFxA());
|
||||
// Re-throw for testing
|
||||
throw error;
|
||||
});
|
||||
@ -1485,6 +1486,30 @@ this.MozLoopService = {
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Fetch/update the FxA Profile for the logged in user.
|
||||
*
|
||||
* @return {Promise} resolving if the profile information was succesfully retrieved
|
||||
* rejecting if the profile information couldn't be retrieved.
|
||||
* A profile error is registered.
|
||||
**/
|
||||
fetchFxAProfile: function() {
|
||||
log.debug("fetchFxAProfile");
|
||||
let client = new FxAccountsProfileClient({
|
||||
serverURL: gFxAOAuthClient.parameters.profile_uri,
|
||||
token: MozLoopServiceInternal.fxAOAuthTokenData.access_token
|
||||
});
|
||||
return client.fetchProfile().then(result => {
|
||||
MozLoopServiceInternal.fxAOAuthProfile = result;
|
||||
MozLoopServiceInternal.clearError("profile");
|
||||
}, error => {
|
||||
log.error("Failed to retrieve profile", error, this.fetchFxAProfile.bind(this));
|
||||
MozLoopServiceInternal.setError("profile", error);
|
||||
MozLoopServiceInternal.fxAOAuthProfile = null;
|
||||
MozLoopServiceInternal.notifyStatusChanged();
|
||||
});
|
||||
},
|
||||
|
||||
openFxASettings: Task.async(function() {
|
||||
try {
|
||||
let fxAOAuthClient = yield MozLoopServiceInternal.promiseFxAOAuthClient();
|
||||
|
@ -296,8 +296,9 @@ add_task(function* basicAuthorizationAndRegistration() {
|
||||
is(loopButton.getAttribute("state"), "", "state of loop button should be empty when not logged in");
|
||||
|
||||
info("Login");
|
||||
statusChangedPromise = promiseObserverNotified("loop-status-changed", "login");
|
||||
let tokenData = yield MozLoopService.logInToFxA();
|
||||
yield promiseObserverNotified("loop-status-changed", "login");
|
||||
yield statusChangedPromise;
|
||||
ise(tokenData.access_token, "code1_access_token", "Check access_token");
|
||||
ise(tokenData.scope, "profile", "Check scope");
|
||||
ise(tokenData.token_type, "bearer", "Check token_type");
|
||||
|
@ -74,7 +74,6 @@ add_task(function* guest_401() {
|
||||
Assert.strictEqual(err.code, 401);
|
||||
Assert.strictEqual(err.friendlyMessage, getLoopString("session_expired_error_description"));
|
||||
Assert.equal(err.friendlyDetails, null);
|
||||
Assert.equal(err.friendlyDetailsButtonLabel, null);
|
||||
});
|
||||
});
|
||||
|
||||
@ -115,7 +114,6 @@ add_task(function* error_404() {
|
||||
Assert.strictEqual(err.code, 404);
|
||||
Assert.strictEqual(err.friendlyMessage, getLoopString("generic_failure_title"));
|
||||
Assert.equal(err.friendlyDetails, null);
|
||||
Assert.equal(err.friendlyDetailsButtonLabel, null);
|
||||
});
|
||||
});
|
||||
|
||||
@ -149,7 +147,6 @@ add_task(function* profile_500() {
|
||||
Assert.strictEqual(err.code, 500);
|
||||
Assert.strictEqual(err.friendlyMessage, getLoopString("problem_accessing_account"));
|
||||
Assert.equal(err.friendlyDetails, null);
|
||||
Assert.equal(err.friendlyDetailsButtonLabel, null);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -77,6 +77,9 @@ add_task(function test_initialize_with_invalid_fxa_token() {
|
||||
"FXA profile pref should be cleared if token was invalid");
|
||||
Assert.ok(MozLoopServiceInternal.errors.has("login"),
|
||||
"Initialization error should have been reported to UI");
|
||||
Assert.ok(MozLoopServiceInternal.errors.has("login"));
|
||||
Assert.ok(MozLoopServiceInternal.errors.get("login").friendlyDetailsButtonCallback,
|
||||
"Check that there is a retry callback");
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1038,7 +1038,7 @@ PlacesToolbar.prototype = {
|
||||
else {
|
||||
button = document.createElement("toolbarbutton");
|
||||
button.className = "bookmark-item";
|
||||
button.setAttribute("label", aChild.title);
|
||||
button.setAttribute("label", aChild.title || "");
|
||||
let icon = aChild.icon;
|
||||
if (icon)
|
||||
button.setAttribute("image",
|
||||
@ -1866,7 +1866,7 @@ PlacesPanelMenuView.prototype = {
|
||||
button.className = "bookmark-item";
|
||||
if (typeof this.options.extraClasses.entry == "string")
|
||||
button.classList.add(this.options.extraClasses.entry);
|
||||
button.setAttribute("label", aChild.title);
|
||||
button.setAttribute("label", aChild.title || "");
|
||||
let icon = aChild.icon;
|
||||
if (icon)
|
||||
button.setAttribute("image",
|
||||
|
@ -4,7 +4,8 @@
|
||||
|
||||
EXTRA_JS_MODULES.devtools += [
|
||||
'resize-commands.js',
|
||||
'responsivedesign.jsm',
|
||||
'responsivedesign-child.js',
|
||||
'responsivedesign.jsm'
|
||||
]
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
|
||||
|
129
browser/devtools/responsivedesign/responsivedesign-child.js
Normal file
129
browser/devtools/responsivedesign/responsivedesign-child.js
Normal file
@ -0,0 +1,129 @@
|
||||
/* 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/. */
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const gDeviceSizeWasPageSize = docShell.deviceSizeIsPageSize;
|
||||
const gFloatingScrollbarsStylesheet = Services.io.newURI("chrome://browser/skin/devtools/floating-scrollbars.css", null, null);
|
||||
let gRequiresFloatingScrollbars;
|
||||
|
||||
let active = false;
|
||||
|
||||
addMessageListener("ResponsiveMode:Start", startResponsiveMode);
|
||||
addMessageListener("ResponsiveMode:Stop", stopResponsiveMode);
|
||||
|
||||
function startResponsiveMode({data:data}) {
|
||||
if (active) {
|
||||
return;
|
||||
}
|
||||
addMessageListener("ResponsiveMode:RequestScreenshot", screenshot);
|
||||
addMessageListener("ResponsiveMode:NotifyOnResize", notifiyOnResize);
|
||||
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress);
|
||||
webProgress.addProgressListener(WebProgressListener, Ci.nsIWebProgress.NOTIFY_ALL);
|
||||
docShell.deviceSizeIsPageSize = true;
|
||||
gRequiresFloatingScrollbars = data.requiresFloatingScrollbars;
|
||||
|
||||
// At this point, a content viewer might not be loaded for this
|
||||
// docshell. makeScrollbarsFloating will be triggered by onLocationChange.
|
||||
if (docShell.contentViewer) {
|
||||
makeScrollbarsFloating();
|
||||
}
|
||||
active = true;
|
||||
sendAsyncMessage("ResponsiveMode:Start:Done");
|
||||
}
|
||||
|
||||
function notifiyOnResize() {
|
||||
content.addEventListener("resize", () => {
|
||||
sendAsyncMessage("ResponsiveMode:OnContentResize");
|
||||
}, false);
|
||||
sendAsyncMessage("ResponsiveMode:NotifyOnResize:Done");
|
||||
}
|
||||
|
||||
function stopResponsiveMode() {
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
active = false;
|
||||
removeMessageListener("ResponsiveMode:RequestScreenshot", screenshot);
|
||||
removeMessageListener("ResponsiveMode:NotifyOnResize", notifiyOnResize);
|
||||
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress);
|
||||
webProgress.removeProgressListener(WebProgressListener);
|
||||
docShell.deviceSizeIsPageSize = gDeviceSizeWasPageSize;
|
||||
restoreScrollbars();
|
||||
sendAsyncMessage("ResponsiveMode:Stop:Done");
|
||||
}
|
||||
|
||||
function makeScrollbarsFloating() {
|
||||
if (!gRequiresFloatingScrollbars) {
|
||||
return;
|
||||
}
|
||||
|
||||
let allDocShells = [docShell];
|
||||
|
||||
for (let i = 0; i < docShell.childCount; i++) {
|
||||
let child = docShell.getChildAt(i).QueryInterface(Ci.nsIDocShell);
|
||||
allDocShells.push(child);
|
||||
}
|
||||
|
||||
for (let d of allDocShells) {
|
||||
let win = d.contentViewer.DOMDocument.defaultView;
|
||||
let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
try {
|
||||
winUtils.loadSheet(gFloatingScrollbarsStylesheet, win.AGENT_SHEET);
|
||||
} catch(e) { }
|
||||
}
|
||||
|
||||
flushStyle();
|
||||
}
|
||||
|
||||
function restoreScrollbars() {
|
||||
let allDocShells = [docShell];
|
||||
for (let i = 0; i < docShell.childCount; i++) {
|
||||
allDocShells.push(docShell.getChildAt(i).QueryInterface(Ci.nsIDocShell));
|
||||
}
|
||||
for (let d of allDocShells) {
|
||||
let win = d.contentViewer.DOMDocument.defaultView;
|
||||
let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
try {
|
||||
winUtils.removeSheet(gFloatingScrollbarsStylesheet, win.AGENT_SHEET);
|
||||
} catch(e) { }
|
||||
}
|
||||
flushStyle();
|
||||
}
|
||||
|
||||
function flushStyle() {
|
||||
// Force presContext destruction
|
||||
let isSticky = docShell.contentViewer.sticky;
|
||||
docShell.contentViewer.sticky = false;
|
||||
docShell.contentViewer.hide();
|
||||
docShell.contentViewer.show();
|
||||
docShell.contentViewer.sticky = isSticky;
|
||||
}
|
||||
|
||||
function screenshot() {
|
||||
let canvas = content.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
||||
let width = content.innerWidth;
|
||||
let height = content.innerHeight;
|
||||
canvas.mozOpaque = true;
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
let ctx = canvas.getContext("2d");
|
||||
ctx.drawWindow(content, content.scrollX, content.scrollY, width, height, "#fff");
|
||||
sendAsyncMessage("ResponsiveMode:RequestScreenshot:Done", canvas.toDataURL());
|
||||
}
|
||||
|
||||
let WebProgressListener = {
|
||||
onLocationChange: function onLocationChange(aWebProgress) {
|
||||
makeScrollbarsFloating();
|
||||
},
|
||||
QueryInterface: function QueryInterface(aIID) {
|
||||
if (aIID.equals(Ci.nsIWebProgressListener) ||
|
||||
aIID.equals(Ci.nsISupportsWeakReference) ||
|
||||
aIID.equals(Ci.nsISupports)) {
|
||||
return this;
|
||||
}
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
};
|
||||
|
||||
sendAsyncMessage("ResponsiveMode:ChildScriptReady");
|
@ -10,8 +10,8 @@ const Cu = Components.utils;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource:///modules/devtools/gDevTools.jsm");
|
||||
Cu.import("resource:///modules/devtools/FloatingScrollbars.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/event-emitter.js");
|
||||
let { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
|
||||
"resource://gre/modules/SystemAppProxy.jsm");
|
||||
|
||||
@ -33,6 +33,8 @@ const ROUND_RATIO = 10;
|
||||
|
||||
const INPUT_PARSER = /(\d+)[^\d]+(\d+)/;
|
||||
|
||||
let ActiveTabs = new Map();
|
||||
|
||||
this.ResponsiveUIManager = {
|
||||
/**
|
||||
* Check if the a tab is in a responsive mode.
|
||||
@ -43,8 +45,8 @@ this.ResponsiveUIManager = {
|
||||
* @param aTab the tab targeted.
|
||||
*/
|
||||
toggle: function(aWindow, aTab) {
|
||||
if (aTab.__responsiveUI) {
|
||||
aTab.__responsiveUI.close();
|
||||
if (this.isActiveForTab(aTab)) {
|
||||
ActiveTabs.get(aTab).close();
|
||||
} else {
|
||||
new ResponsiveUI(aWindow, aTab);
|
||||
}
|
||||
@ -56,7 +58,14 @@ this.ResponsiveUIManager = {
|
||||
* @param aTab the tab targeted.
|
||||
*/
|
||||
isActiveForTab: function(aTab) {
|
||||
return !!aTab.__responsiveUI;
|
||||
return ActiveTabs.has(aTab);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the responsive UI controller for a tab.
|
||||
*/
|
||||
getResponsiveUIForTab: function(aTab) {
|
||||
return ActiveTabs.get(aTab);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -70,19 +79,19 @@ this.ResponsiveUIManager = {
|
||||
handleGcliCommand: function(aWindow, aTab, aCommand, aArgs) {
|
||||
switch (aCommand) {
|
||||
case "resize to":
|
||||
if (!aTab.__responsiveUI) {
|
||||
if (!this.isActiveForTab(aTab)) {
|
||||
new ResponsiveUI(aWindow, aTab);
|
||||
}
|
||||
aTab.__responsiveUI.setSize(aArgs.width, aArgs.height);
|
||||
ActiveTabs.get(aTab).setSize(aArgs.width, aArgs.height);
|
||||
break;
|
||||
case "resize on":
|
||||
if (!aTab.__responsiveUI) {
|
||||
if (!this.isActiveForTab(aTab)) {
|
||||
new ResponsiveUI(aWindow, aTab);
|
||||
}
|
||||
break;
|
||||
case "resize off":
|
||||
if (aTab.__responsiveUI) {
|
||||
aTab.__responsiveUI.close();
|
||||
if (this.isActiveForTab(aTab)) {
|
||||
ActiveTabs.get(aTab).close();
|
||||
}
|
||||
break;
|
||||
case "resize toggle":
|
||||
@ -115,13 +124,28 @@ function ResponsiveUI(aWindow, aTab)
|
||||
{
|
||||
this.mainWindow = aWindow;
|
||||
this.tab = aTab;
|
||||
this.mm = this.tab.linkedBrowser.messageManager;
|
||||
this.tabContainer = aWindow.gBrowser.tabContainer;
|
||||
this.browser = aTab.linkedBrowser;
|
||||
this.chromeDoc = aWindow.document;
|
||||
this.container = aWindow.gBrowser.getBrowserContainer(this.browser);
|
||||
this.stack = this.container.querySelector(".browserStack");
|
||||
this._telemetry = new Telemetry();
|
||||
this._floatingScrollbars = !this.mainWindow.matchMedia("(-moz-overlay-scrollbars)").matches;
|
||||
this.e10s = !this.browser.contentWindow;
|
||||
|
||||
let childOn = () => {
|
||||
this.mm.removeMessageListener("ResponsiveMode:Start:Done", childOn);
|
||||
ResponsiveUIManager.emit("on", { tab: this.tab });
|
||||
}
|
||||
this.mm.addMessageListener("ResponsiveMode:Start:Done", childOn);
|
||||
|
||||
let requiresFloatingScrollbars = !this.mainWindow.matchMedia("(-moz-overlay-scrollbars)").matches;
|
||||
this.mm.loadFrameScript("resource:///modules/devtools/responsivedesign-child.js", true);
|
||||
this.mm.addMessageListener("ResponsiveMode:ChildScriptReady", () => {
|
||||
this.mm.sendAsyncMessage("ResponsiveMode:Start", {
|
||||
requiresFloatingScrollbars: requiresFloatingScrollbars
|
||||
});
|
||||
});
|
||||
|
||||
// Try to load presets from prefs
|
||||
if (Services.prefs.prefHasUserValue("devtools.responsiveUI.presets")) {
|
||||
@ -163,8 +187,6 @@ function ResponsiveUI(aWindow, aTab)
|
||||
this.stack.setAttribute("responsivemode", "true");
|
||||
|
||||
// Let's bind some callbacks.
|
||||
this.bound_onPageLoad = this.onPageLoad.bind(this);
|
||||
this.bound_onPageUnload = this.onPageUnload.bind(this);
|
||||
this.bound_presetSelected = this.presetSelected.bind(this);
|
||||
this.bound_handleManualInput = this.handleManualInput.bind(this);
|
||||
this.bound_addPreset = this.addPreset.bind(this);
|
||||
@ -184,41 +206,22 @@ function ResponsiveUI(aWindow, aTab)
|
||||
this.buildUI();
|
||||
this.checkMenus();
|
||||
|
||||
this.docShell = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell);
|
||||
|
||||
this._deviceSizeWasPageSize = this.docShell.deviceSizeIsPageSize;
|
||||
this.docShell.deviceSizeIsPageSize = true;
|
||||
|
||||
try {
|
||||
if (Services.prefs.getBoolPref("devtools.responsiveUI.rotate")) {
|
||||
this.rotate();
|
||||
}
|
||||
} catch(e) {}
|
||||
|
||||
if (this._floatingScrollbars)
|
||||
switchToFloatingScrollbars(this.tab);
|
||||
|
||||
this.tab.__responsiveUI = this;
|
||||
ActiveTabs.set(aTab, this);
|
||||
|
||||
this._telemetry.toolOpened("responsive");
|
||||
|
||||
if (!this.e10s) {
|
||||
// Touch events support
|
||||
this.touchEnableBefore = false;
|
||||
this.touchEventHandler = new TouchEventHandler(this.browser);
|
||||
|
||||
this.browser.addEventListener("load", this.bound_onPageLoad, true);
|
||||
this.browser.addEventListener("unload", this.bound_onPageUnload, true);
|
||||
|
||||
if (this.browser.contentWindow.document &&
|
||||
this.browser.contentWindow.document.readyState == "complete") {
|
||||
this.onPageLoad();
|
||||
}
|
||||
|
||||
// E10S: We should be using target here. See bug 1028234
|
||||
ResponsiveUIManager.emit("on", { tab: this.tab });
|
||||
|
||||
// Hook to display promotional Developer Edition doorhanger. Only displayed once.
|
||||
showDoorhanger({
|
||||
window: this.mainWindow,
|
||||
@ -239,45 +242,14 @@ ResponsiveUI.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Window onload / onunload
|
||||
*/
|
||||
onPageLoad: function() {
|
||||
this.touchEventHandler = new TouchEventHandler(this.browser);
|
||||
if (this.touchEnableBefore) {
|
||||
this.enableTouch();
|
||||
}
|
||||
},
|
||||
|
||||
onPageUnload: function(evt) {
|
||||
// Ignore sub frames unload events
|
||||
if (evt.target != this.browser.contentDocument)
|
||||
return;
|
||||
if (this.closing)
|
||||
return;
|
||||
if (this.touchEventHandler) {
|
||||
this.touchEnableBefore = this.touchEventHandler.enabled;
|
||||
this.disableTouch();
|
||||
delete this.touchEventHandler;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy the nodes. Remove listeners. Reset the style.
|
||||
*/
|
||||
close: function RUI_unload() {
|
||||
close: function RUI_close() {
|
||||
if (this.closing)
|
||||
return;
|
||||
this.closing = true;
|
||||
|
||||
this.docShell.deviceSizeIsPageSize = this._deviceSizeWasPageSize;
|
||||
|
||||
this.browser.removeEventListener("load", this.bound_onPageLoad, true);
|
||||
this.browser.removeEventListener("unload", this.bound_onPageUnload, true);
|
||||
|
||||
if (this._floatingScrollbars)
|
||||
switchToNativeScrollbars(this.tab);
|
||||
|
||||
this.unCheckMenus();
|
||||
// Reset style of the stack.
|
||||
let style = "max-width: none;" +
|
||||
@ -296,10 +268,12 @@ ResponsiveUI.prototype = {
|
||||
this.tabContainer.removeEventListener("TabSelect", this);
|
||||
this.rotatebutton.removeEventListener("command", this.bound_rotate, true);
|
||||
this.screenshotbutton.removeEventListener("command", this.bound_screenshot, true);
|
||||
this.touchbutton.removeEventListener("command", this.bound_touch, true);
|
||||
this.closebutton.removeEventListener("command", this.bound_close, true);
|
||||
this.addbutton.removeEventListener("command", this.bound_addPreset, true);
|
||||
this.removebutton.removeEventListener("command", this.bound_removePreset, true);
|
||||
if (!this.e10s) {
|
||||
this.touchbutton.removeEventListener("command", this.bound_touch, true);
|
||||
}
|
||||
|
||||
// Removed elements.
|
||||
this.container.removeChild(this.toolbar);
|
||||
@ -317,13 +291,40 @@ ResponsiveUI.prototype = {
|
||||
this.container.removeAttribute("responsivemode");
|
||||
this.stack.removeAttribute("responsivemode");
|
||||
|
||||
delete this.docShell;
|
||||
delete this.tab.__responsiveUI;
|
||||
if (this.touchEventHandler)
|
||||
ActiveTabs.delete(this.tab);
|
||||
if (!this.e10s && this.touchEventHandler) {
|
||||
this.touchEventHandler.stop();
|
||||
}
|
||||
this._telemetry.toolClosed("responsive");
|
||||
// E10S: We should be using target here. See bug 1028234
|
||||
let childOff = () => {
|
||||
this.mm.removeMessageListener("ResponsiveMode:Stop:Done", childOff);
|
||||
ResponsiveUIManager.emit("off", { tab: this.tab });
|
||||
}
|
||||
this.mm.addMessageListener("ResponsiveMode:Stop:Done", childOff);
|
||||
this.tab.linkedBrowser.messageManager.sendAsyncMessage("ResponsiveMode:Stop");
|
||||
},
|
||||
|
||||
/**
|
||||
* Notify when the content has been resized. Only used in tests.
|
||||
*/
|
||||
_test_notifyOnResize: function() {
|
||||
let deferred = promise.defer();
|
||||
let mm = this.mm;
|
||||
|
||||
this.bound_onContentResize = this.onContentResize.bind(this);
|
||||
|
||||
mm.addMessageListener("ResponsiveMode:OnContentResize", this.bound_onContentResize);
|
||||
|
||||
mm.sendAsyncMessage("ResponsiveMode:NotifyOnResize");
|
||||
mm.addMessageListener("ResponsiveMode:NotifyOnResize:Done", function onListeningResize() {
|
||||
mm.removeMessageListener("ResponsiveMode:NotifyOnResize:Done", onListeningResize);
|
||||
deferred.resolve();
|
||||
});
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
onContentResize: function() {
|
||||
ResponsiveUIManager.emit("contentResize", { tab: this.tab });
|
||||
},
|
||||
|
||||
/**
|
||||
@ -427,12 +428,6 @@ ResponsiveUI.prototype = {
|
||||
this.screenshotbutton.className = "devtools-responsiveui-toolbarbutton devtools-responsiveui-screenshot";
|
||||
this.screenshotbutton.addEventListener("command", this.bound_screenshot, true);
|
||||
|
||||
this.touchbutton = this.chromeDoc.createElement("toolbarbutton");
|
||||
this.touchbutton.setAttribute("tabindex", "0");
|
||||
this.touchbutton.setAttribute("tooltiptext", this.strings.GetStringFromName("responsiveUI.touch"));
|
||||
this.touchbutton.className = "devtools-responsiveui-toolbarbutton devtools-responsiveui-touch";
|
||||
this.touchbutton.addEventListener("command", this.bound_touch, true);
|
||||
|
||||
this.closebutton = this.chromeDoc.createElement("toolbarbutton");
|
||||
this.closebutton.setAttribute("tabindex", "0");
|
||||
this.closebutton.className = "devtools-responsiveui-toolbarbutton devtools-responsiveui-close";
|
||||
@ -442,7 +437,16 @@ ResponsiveUI.prototype = {
|
||||
this.toolbar.appendChild(this.closebutton);
|
||||
this.toolbar.appendChild(this.menulist);
|
||||
this.toolbar.appendChild(this.rotatebutton);
|
||||
|
||||
if (!this.e10s) {
|
||||
this.touchbutton = this.chromeDoc.createElement("toolbarbutton");
|
||||
this.touchbutton.setAttribute("tabindex", "0");
|
||||
this.touchbutton.setAttribute("tooltiptext", this.strings.GetStringFromName("responsiveUI.touch"));
|
||||
this.touchbutton.className = "devtools-responsiveui-toolbarbutton devtools-responsiveui-touch";
|
||||
this.touchbutton.addEventListener("command", this.bound_touch, true);
|
||||
this.toolbar.appendChild(this.touchbutton);
|
||||
}
|
||||
|
||||
this.toolbar.appendChild(this.screenshotbutton);
|
||||
|
||||
// Resizers
|
||||
@ -583,8 +587,9 @@ ResponsiveUI.prototype = {
|
||||
this.selectedItem = menuitem;
|
||||
}
|
||||
|
||||
if (preset.custom)
|
||||
if (preset.custom) {
|
||||
this.customMenuitem = menuitem;
|
||||
}
|
||||
|
||||
this.setMenuLabel(menuitem, preset);
|
||||
fragment.appendChild(menuitem);
|
||||
@ -662,9 +667,7 @@ ResponsiveUI.prototype = {
|
||||
|
||||
if (!promptOk) {
|
||||
// Prompt has been cancelled
|
||||
let menuitem = this.customMenuitem;
|
||||
this.menulist.selectedItem = menuitem;
|
||||
this.currentPresetKey = this.customPreset.key;
|
||||
this.menulist.selectedItem = this.selectedItem;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -762,21 +765,7 @@ ResponsiveUI.prototype = {
|
||||
* @param aFileName name of the screenshot file (used for tests).
|
||||
*/
|
||||
screenshot: function RUI_screenshot(aFileName) {
|
||||
let window = this.browser.contentWindow;
|
||||
let document = window.document;
|
||||
let canvas = this.chromeDoc.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
||||
|
||||
let width = window.innerWidth;
|
||||
let height = window.innerHeight;
|
||||
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
||||
let ctx = canvas.getContext("2d");
|
||||
ctx.drawWindow(window, window.scrollX, window.scrollY, width, height, "#fff");
|
||||
|
||||
let filename = aFileName;
|
||||
|
||||
if (!filename) {
|
||||
let date = new Date();
|
||||
let month = ("0" + (date.getMonth() + 1)).substr(-2, 2);
|
||||
@ -785,12 +774,15 @@ ResponsiveUI.prototype = {
|
||||
let timeString = date.toTimeString().replace(/:/g, ".").split(" ")[0];
|
||||
filename = this.strings.formatStringFromName("responsiveUI.screenshotGeneratedFilename", [dateString, timeString], 2);
|
||||
}
|
||||
|
||||
canvas.toBlob(blob => {
|
||||
let mm = this.tab.linkedBrowser.messageManager;
|
||||
let chromeWindow = this.chromeDoc.defaultView;
|
||||
let url = chromeWindow.URL.createObjectURL(blob);
|
||||
chromeWindow.saveURL(url, filename + ".png", null, true, true, document.documentURIObject, document);
|
||||
});
|
||||
let doc = chromeWindow.document;
|
||||
function onScreenshot(aMessage) {
|
||||
mm.removeMessageListener("ResponsiveMode:RequestScreenshot:Done", onScreenshot);
|
||||
chromeWindow.saveURL(aMessage.data, filename + ".png", null, true, true, doc.documentURIObject, doc);
|
||||
}
|
||||
mm.addMessageListener("ResponsiveMode:RequestScreenshot:Done", onScreenshot);
|
||||
mm.sendAsyncMessage("ResponsiveMode:RequestScreenshot");
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,4 @@
|
||||
[DEFAULT]
|
||||
skip-if = e10s # Bug ?????? - devtools tests disabled with e10s
|
||||
subsuite = devtools
|
||||
support-files =
|
||||
head.js
|
||||
@ -7,8 +6,11 @@ support-files =
|
||||
|
||||
[browser_responsive_cmd.js]
|
||||
[browser_responsivecomputedview.js]
|
||||
skip-if = e10s # Bug ??????
|
||||
[browser_responsiveruleview.js]
|
||||
skip-if = e10s # Bug ??????
|
||||
[browser_responsiveui.js]
|
||||
[browser_responsiveui_touch.js]
|
||||
skip-if = e10s # Bug ?????? - [e10s] re-introduce touch feature in responsive mode
|
||||
[browser_responsiveuiaddcustompreset.js]
|
||||
[browser_responsive_devicewidth.js]
|
||||
|
@ -10,10 +10,11 @@ thisTestLeaksUncaughtRejectionsAndShouldBeFixed("destroy");
|
||||
|
||||
function test() {
|
||||
function isOpen() {
|
||||
return !!gBrowser.selectedTab.__responsiveUI;
|
||||
return gBrowser.getBrowserContainer(gBrowser.selectedTab.linkedBrowser)
|
||||
.hasAttribute("responsivemode");
|
||||
}
|
||||
|
||||
helpers.addTabWithToolbar("about:blank", function(options) {
|
||||
helpers.addTabWithToolbar("data:text/html;charset=utf-8,hi", function(options) {
|
||||
return helpers.audit(options, [
|
||||
{
|
||||
setup: "resize toggle",
|
||||
|
@ -7,21 +7,19 @@ function test() {
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:logo");
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(startTest, content);
|
||||
startTest();
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,mop";
|
||||
|
||||
function startTest() {
|
||||
mgr.once("on", function() {executeSoon(onUIOpen)});
|
||||
document.getElementById("Tools:ResponsiveUI").doCommand();
|
||||
}
|
||||
|
||||
function onUIOpen() {
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
instance.stack.setAttribute("notransition", "true");
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
|
@ -8,11 +8,12 @@ function test() {
|
||||
let inspector;
|
||||
|
||||
waitForExplicitFinish();
|
||||
let mgr = ResponsiveUI.ResponsiveUIManager;
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(startTest, content);
|
||||
startTest();
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf-8,<html><style>" +
|
||||
@ -43,7 +44,7 @@ function test() {
|
||||
}
|
||||
|
||||
function onUIOpen() {
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
instance.stack.setAttribute("notransition", "true");
|
||||
|
@ -11,10 +11,7 @@ function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(startTest, content);
|
||||
}, true);
|
||||
gBrowser.selectedBrowser.addEventListener("load", startTest, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf-8,<html><style>" +
|
||||
"div {" +
|
||||
@ -34,12 +31,13 @@ function test() {
|
||||
}
|
||||
|
||||
function startTest() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", startTest, true);
|
||||
document.getElementById("Tools:ResponsiveUI").doCommand();
|
||||
executeSoon(onUIOpen);
|
||||
}
|
||||
|
||||
function onUIOpen() {
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
instance.stack.setAttribute("notransition", "true");
|
||||
|
@ -1,77 +1,12 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Protocol error (unknownError): Error: Got an invalid root window in DocumentWalker");
|
||||
|
||||
function test() {
|
||||
let instance, widthBeforeClose, heightBeforeClose;
|
||||
let mgr = ResponsiveUI.ResponsiveUIManager;
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(startTest, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,mop";
|
||||
|
||||
function startTest() {
|
||||
document.getElementById("Tools:ResponsiveUI").removeAttribute("disabled");
|
||||
mgr.once("on", function() {executeSoon(onUIOpen)});
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
}
|
||||
|
||||
function onUIOpen() {
|
||||
// Is it open?
|
||||
let container = gBrowser.getBrowserContainer();
|
||||
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
|
||||
|
||||
// Menus are correctly updated?
|
||||
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "true", "menus checked");
|
||||
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
if (instance._floatingScrollbars) {
|
||||
ensureScrollbarsAreFloating();
|
||||
}
|
||||
|
||||
instance.transitionsEnabled = false;
|
||||
|
||||
testPresets();
|
||||
}
|
||||
|
||||
function ensureScrollbarsAreFloating() {
|
||||
let body = gBrowser.contentDocument.body;
|
||||
let html = gBrowser.contentDocument.documentElement;
|
||||
|
||||
let originalWidth = body.getBoundingClientRect().width;
|
||||
|
||||
html.style.overflowY = "scroll"; // Force scrollbars
|
||||
// Flush. Should not be needed as getBoundingClientRect() should flush,
|
||||
// but just in case.
|
||||
gBrowser.contentWindow.getComputedStyle(html).overflowY;
|
||||
let newWidth = body.getBoundingClientRect().width;
|
||||
is(originalWidth, newWidth, "Floating scrollbars are presents");
|
||||
}
|
||||
|
||||
function testPresets() {
|
||||
function testOnePreset(c) {
|
||||
if (c == 0) {
|
||||
executeSoon(testCustom);
|
||||
return;
|
||||
}
|
||||
instance.menulist.selectedIndex = c;
|
||||
let item = instance.menulist.firstChild.childNodes[c];
|
||||
let [width, height] = extractSizeFromString(item.getAttribute("label"));
|
||||
is(content.innerWidth, width, "preset " + c + ": dimension valid (width)");
|
||||
is(content.innerHeight, height, "preset " + c + ": dimension valid (height)");
|
||||
|
||||
testOnePreset(c - 1);
|
||||
}
|
||||
// Starting from length - 4 because last 3 items are not presets : separator, addbutton and removebutton
|
||||
testOnePreset(instance.menulist.firstChild.childNodes.length - 4);
|
||||
}
|
||||
SimpleTest.requestCompleteLog();
|
||||
Task.spawn(function() {
|
||||
|
||||
function extractSizeFromString(str) {
|
||||
let numbers = str.match(/(\d+)[^\d]*(\d+)/);
|
||||
@ -82,22 +17,79 @@ function test() {
|
||||
}
|
||||
}
|
||||
|
||||
function testCustom() {
|
||||
function processStringAsKey(str) {
|
||||
for (let i = 0, l = str.length; i < l; i++) {
|
||||
EventUtils.synthesizeKey(str.charAt(i), {});
|
||||
}
|
||||
}
|
||||
|
||||
yield addTab("data:text/html,mop");
|
||||
|
||||
let mgr = ResponsiveUI.ResponsiveUIManager;
|
||||
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
|
||||
yield once(mgr, "on");
|
||||
|
||||
// Is it open?
|
||||
let container = gBrowser.getBrowserContainer();
|
||||
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
|
||||
|
||||
// Menus are correctly updated?
|
||||
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "true", "menus checked");
|
||||
|
||||
let instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
let originalWidth = content.innerWidth;
|
||||
content.location = "data:text/html;charset=utf-8,mop<div style%3D'height%3A5000px'><%2Fdiv>";
|
||||
let newWidth = content.innerWidth;
|
||||
is(originalWidth, newWidth, "Floating scrollbars are presents");
|
||||
|
||||
yield instance._test_notifyOnResize();
|
||||
|
||||
yield nextTick();
|
||||
|
||||
instance.transitionsEnabled = false;
|
||||
|
||||
// Starting from length - 4 because last 3 items are not presets : separator, addbutton and removebutton
|
||||
for (let c = instance.menulist.firstChild.childNodes.length - 4; c >= 0; c--) {
|
||||
let item = instance.menulist.firstChild.childNodes[c];
|
||||
let [width, height] = extractSizeFromString(item.getAttribute("label"));
|
||||
let onContentResize = once(mgr, "contentResize");
|
||||
instance.menulist.selectedIndex = c;
|
||||
yield onContentResize;
|
||||
is(content.innerWidth, width, "preset " + c + ": dimension valid (width)");
|
||||
is(content.innerHeight, height, "preset " + c + ": dimension valid (height)");
|
||||
}
|
||||
|
||||
// test custom
|
||||
|
||||
instance.setSize(100, 100);
|
||||
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
let initialWidth = content.innerWidth;
|
||||
let initialHeight = content.innerHeight;
|
||||
|
||||
is(initialWidth, 100, "Width reset to 100");
|
||||
is(initialHeight, 100, "Height reset to 100");
|
||||
|
||||
let x = 2, y = 2;
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousedown"}, window);
|
||||
x += 20; y += 10;
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousemove"}, window);
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mouseup"}, window);
|
||||
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
let expectedWidth = initialWidth + 20;
|
||||
let expectedHeight = initialHeight + 10;
|
||||
info("initial width: " + initialWidth);
|
||||
info("initial height: " + initialHeight);
|
||||
is(content.innerWidth, expectedWidth, "Size correcty updated (width).");
|
||||
is(content.innerHeight, expectedHeight, "Size correcty updated (height).");
|
||||
is(content.innerWidth, expectedWidth, "Size correctly updated (width).");
|
||||
is(content.innerHeight, expectedHeight, "Size correctly updated (height).");
|
||||
|
||||
is(instance.menulist.selectedIndex, -1, "Custom menuitem cannot be selected");
|
||||
let label = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
let value = instance.menulist.value;
|
||||
@ -108,71 +100,80 @@ function test() {
|
||||
[width, height] = extractSizeFromString(value);
|
||||
is(width, expectedWidth, "Value updated (width).");
|
||||
is(height, expectedHeight, "Value updated (height).");
|
||||
testCustom2();
|
||||
}
|
||||
|
||||
function testCustom2() {
|
||||
let initialWidth = content.innerWidth;
|
||||
let initialHeight = content.innerHeight;
|
||||
// With "shift" key pressed
|
||||
|
||||
let x = 2, y = 2;
|
||||
instance.setSize(100, 100);
|
||||
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
initialWidth = content.innerWidth;
|
||||
initialHeight = content.innerHeight;
|
||||
|
||||
x = 2; y = 2;
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousedown"}, window);
|
||||
x += 23; y += 13;
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousemove", shiftKey: true}, window);
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mouseup"}, window);
|
||||
|
||||
let expectedWidth = initialWidth + 20;
|
||||
let expectedHeight = initialHeight + 10;
|
||||
is(content.innerWidth, expectedWidth, "with shift: Size correcty updated (width).");
|
||||
is(content.innerHeight, expectedHeight, "with shift: Size correcty updated (height).");
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
expectedWidth = initialWidth + 20;
|
||||
expectedHeight = initialHeight + 10;
|
||||
is(content.innerWidth, expectedWidth, "with shift: Size correctly updated (width).");
|
||||
is(content.innerHeight, expectedHeight, "with shift: Size correctly updated (height).");
|
||||
is(instance.menulist.selectedIndex, -1, "with shift: Custom menuitem cannot be selected");
|
||||
let label = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
let value = instance.menulist.value;
|
||||
isnot(label, value, "Label from the menulist item is different than the value of the menulist")
|
||||
let [width, height] = extractSizeFromString(label);
|
||||
label = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
value = instance.menulist.value;
|
||||
isnot(label, value, "Label from the menulist item is different than the value of the menulist");
|
||||
[width, height] = extractSizeFromString(label);
|
||||
is(width, expectedWidth, "Label updated (width).");
|
||||
is(height, expectedHeight, "Label updated (height).");
|
||||
[width, height] = extractSizeFromString(value);
|
||||
is(width, expectedWidth, "Value updated (width).");
|
||||
is(height, expectedHeight, "Value updated (height).");
|
||||
testCustom3();
|
||||
}
|
||||
|
||||
function testCustom3() {
|
||||
let initialWidth = content.innerWidth;
|
||||
let initialHeight = content.innerHeight;
|
||||
|
||||
let x = 2, y = 2;
|
||||
// With "ctrl" key pressed
|
||||
|
||||
instance.setSize(100, 100);
|
||||
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
initialWidth = content.innerWidth;
|
||||
initialHeight = content.innerHeight;
|
||||
|
||||
x = 2; y = 2;
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousedown"}, window);
|
||||
x += 60; y += 30;
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousemove", ctrlKey: true}, window);
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mouseup"}, window);
|
||||
|
||||
let expectedWidth = initialWidth + 10;
|
||||
let expectedHeight = initialHeight + 5;
|
||||
is(content.innerWidth, expectedWidth, "with ctrl: Size correcty updated (width).");
|
||||
is(content.innerHeight, expectedHeight, "with ctrl: Size correcty updated (height).");
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
expectedWidth = initialWidth + 10;
|
||||
expectedHeight = initialHeight + 5;
|
||||
is(content.innerWidth, expectedWidth, "with ctrl: Size correctly updated (width).");
|
||||
is(content.innerHeight, expectedHeight, "with ctrl: Size correctly updated (height).");
|
||||
is(instance.menulist.selectedIndex, -1, "with ctrl: Custom menuitem cannot be selected");
|
||||
let label = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
let value = instance.menulist.value;
|
||||
isnot(label, value, "Label from the menulist item is different than the value of the menulist")
|
||||
let [width, height] = extractSizeFromString(label);
|
||||
label = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
value = instance.menulist.value;
|
||||
isnot(label, value, "Label from the menulist item is different than the value of the menulist");
|
||||
[width, height] = extractSizeFromString(label);
|
||||
is(width, expectedWidth, "Label updated (width).");
|
||||
is(height, expectedHeight, "Label updated (height).");
|
||||
[width, height] = extractSizeFromString(value);
|
||||
is(width, expectedWidth, "Value updated (width).");
|
||||
is(height, expectedHeight, "Value updated (height).");
|
||||
|
||||
testCustomInput();
|
||||
}
|
||||
|
||||
function testCustomInput() {
|
||||
let initialWidth = content.innerWidth;
|
||||
let initialHeight = content.innerHeight;
|
||||
let expectedWidth = initialWidth - 20;
|
||||
let expectedHeight = initialHeight - 10;
|
||||
// Test custom input
|
||||
|
||||
initialWidth = content.innerWidth;
|
||||
initialHeight = content.innerHeight;
|
||||
expectedWidth = initialWidth - 20;
|
||||
expectedHeight = initialHeight - 10;
|
||||
let index = instance.menulist.selectedIndex;
|
||||
let label, value, width, height;
|
||||
|
||||
let userInput = expectedWidth + " x " + expectedHeight;
|
||||
|
||||
@ -187,6 +188,8 @@ function test() {
|
||||
// Only the `change` event must change the size
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
is(content.innerWidth, expectedWidth, "Size correctly updated (width).");
|
||||
is(content.innerHeight, expectedHeight, "Size correctly updated (height).");
|
||||
is(instance.menulist.selectedIndex, -1, "Custom menuitem cannot be selected");
|
||||
@ -200,17 +203,17 @@ function test() {
|
||||
is(width, expectedWidth, "Value updated (width).");
|
||||
is(height, expectedHeight, "Value updated (height).");
|
||||
|
||||
testCustomInput2();
|
||||
}
|
||||
|
||||
function testCustomInput2() {
|
||||
let initialWidth = content.innerWidth;
|
||||
let initialHeight = content.innerHeight;
|
||||
let index = instance.menulist.selectedIndex;
|
||||
// Invalid input
|
||||
|
||||
|
||||
initialWidth = content.innerWidth;
|
||||
initialHeight = content.innerHeight;
|
||||
index = instance.menulist.selectedIndex;
|
||||
let expectedValue = initialWidth + "x" + initialHeight;
|
||||
let expectedLabel = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
|
||||
let userInput = "I'm wrong";
|
||||
userInput = "I'm wrong";
|
||||
|
||||
instance.menulist.inputField.value = "";
|
||||
instance.menulist.focus();
|
||||
@ -221,93 +224,75 @@ function test() {
|
||||
is(content.innerHeight, initialHeight, "Size hasn't changed (height).");
|
||||
is(instance.menulist.selectedIndex, index, "Selected item hasn't changed.");
|
||||
is(instance.menulist.value, expectedValue, "Value has been reset")
|
||||
let label = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
label = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
is(label, expectedLabel, "Custom menuitem's label hasn't changed");
|
||||
|
||||
rotate();
|
||||
}
|
||||
|
||||
function rotate() {
|
||||
let initialWidth = content.innerWidth;
|
||||
let initialHeight = content.innerHeight;
|
||||
// Rotate
|
||||
|
||||
initialWidth = content.innerWidth;
|
||||
initialHeight = content.innerHeight;
|
||||
|
||||
info("rotate");
|
||||
instance.rotate();
|
||||
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
is(content.innerWidth, initialHeight, "The width is now the height.");
|
||||
is(content.innerHeight, initialWidth, "The height is now the width.");
|
||||
let [width, height] = extractSizeFromString(instance.menulist.firstChild.firstChild.getAttribute("label"));
|
||||
[width, height] = extractSizeFromString(instance.menulist.firstChild.firstChild.getAttribute("label"));
|
||||
is(width, initialHeight, "Label updated (width).");
|
||||
is(height, initialWidth, "Label updated (height).");
|
||||
|
||||
widthBeforeClose = content.innerWidth;
|
||||
heightBeforeClose = content.innerHeight;
|
||||
let widthBeforeClose = content.innerWidth;
|
||||
let heightBeforeClose = content.innerHeight;
|
||||
|
||||
info("XXX BUG 851296: instance.closing: " + !!instance.closing);
|
||||
// Restart
|
||||
|
||||
mgr.once("off", function() {
|
||||
info("XXX BUG 851296: 'off' received.");
|
||||
executeSoon(restart);
|
||||
});
|
||||
mgr.toggle(window, gBrowser.selectedTab);
|
||||
}
|
||||
|
||||
function restart() {
|
||||
info("XXX BUG 851296: restarting.");
|
||||
info("XXX BUG 851296: __responsiveUI: " + gBrowser.selectedTab.__responsiveUI);
|
||||
mgr.once("on", function() {
|
||||
info("XXX BUG 851296: 'on' received.");
|
||||
executeSoon(onUIOpen2);
|
||||
});
|
||||
//XXX BUG 851296: synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
yield once(mgr, "off");
|
||||
|
||||
mgr.toggle(window, gBrowser.selectedTab);
|
||||
info("XXX BUG 851296: restart() finished.");
|
||||
}
|
||||
|
||||
function onUIOpen2() {
|
||||
info("XXX BUG 851296: onUIOpen2.");
|
||||
let container = gBrowser.getBrowserContainer();
|
||||
yield once(mgr, "on");
|
||||
|
||||
container = gBrowser.getBrowserContainer();
|
||||
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
|
||||
|
||||
// Menus are correctly updated?
|
||||
|
||||
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "true", "menus checked");
|
||||
|
||||
is(content.innerWidth, widthBeforeClose, "width restored.");
|
||||
is(content.innerHeight, heightBeforeClose, "height restored.");
|
||||
|
||||
mgr.once("off", function() {executeSoon(testScreenshot)});
|
||||
mgr.toggle(window, gBrowser.selectedTab);
|
||||
}
|
||||
// Screenshot
|
||||
|
||||
|
||||
function testScreenshot() {
|
||||
let isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
|
||||
if (isWinXP) {
|
||||
// We have issues testing this on Windows XP.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=848760#c17
|
||||
return finishUp();
|
||||
}
|
||||
|
||||
if (!isWinXP) {
|
||||
info("screenshot");
|
||||
instance.screenshot("responsiveui");
|
||||
let FileUtils = (Cu.import("resource://gre/modules/FileUtils.jsm", {})).FileUtils;
|
||||
|
||||
// while(1) until we find the file.
|
||||
while(true) {
|
||||
// while(true) until we find the file.
|
||||
// no need for a timeout, the test will get killed anyway.
|
||||
info("checking if file exists in 200ms");
|
||||
function checkIfFileExist() {
|
||||
let file = FileUtils.getFile("DfltDwnld", [ "responsiveui.png" ]);
|
||||
if (file.exists()) {
|
||||
ok(true, "Screenshot file exists");
|
||||
file.remove(false);
|
||||
finishUp();
|
||||
} else {
|
||||
setTimeout(checkIfFileExist, 200);
|
||||
break;
|
||||
}
|
||||
info("checking if file exists in 200ms");
|
||||
yield wait(200);
|
||||
}
|
||||
checkIfFileExist();
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
mgr.toggle(window, gBrowser.selectedTab);
|
||||
|
||||
yield once(mgr, "off");
|
||||
|
||||
// Menus are correctly updated?
|
||||
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "false", "menu unchecked");
|
||||
@ -315,39 +300,6 @@ function test() {
|
||||
delete instance;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function synthesizeKeyFromKeyTag(aKeyId) {
|
||||
let key = document.getElementById(aKeyId);
|
||||
isnot(key, null, "Successfully retrieved the <key> node");
|
||||
|
||||
let modifiersAttr = key.getAttribute("modifiers");
|
||||
|
||||
let name = null;
|
||||
|
||||
if (key.getAttribute("keycode"))
|
||||
name = key.getAttribute("keycode");
|
||||
else if (key.getAttribute("key"))
|
||||
name = key.getAttribute("key");
|
||||
|
||||
isnot(name, null, "Successfully retrieved keycode/key");
|
||||
|
||||
let modifiers = {
|
||||
shiftKey: modifiersAttr.match("shift"),
|
||||
ctrlKey: modifiersAttr.match("ctrl"),
|
||||
altKey: modifiersAttr.match("alt"),
|
||||
metaKey: modifiersAttr.match("meta"),
|
||||
accelKey: modifiersAttr.match("accel")
|
||||
}
|
||||
|
||||
info("XXX BUG 851296: key name: " + name);
|
||||
info("XXX BUG 851296: key modifiers: " + JSON.stringify(modifiers));
|
||||
EventUtils.synthesizeKey(name, modifiers);
|
||||
}
|
||||
|
||||
function processStringAsKey(str) {
|
||||
for (let i = 0, l = str.length; i < l; i++) {
|
||||
EventUtils.synthesizeKey(str.charAt(i), {});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ function test() {
|
||||
}
|
||||
|
||||
function testWithTouch() {
|
||||
gBrowser.selectedTab.__responsiveUI.enableTouch();
|
||||
mgr.getResponsiveUIForTab(gBrowser.selectedTab).enableTouch();
|
||||
let div = content.document.querySelector("div");
|
||||
let x = 2, y = 2;
|
||||
EventUtils.synthesizeMouse(div, x, y, {type: "mousedown", isSynthesized: false}, content);
|
||||
@ -47,7 +47,7 @@ function test() {
|
||||
}
|
||||
|
||||
function testWithTouchAgain() {
|
||||
gBrowser.selectedTab.__responsiveUI.disableTouch();
|
||||
mgr.getResponsiveUIForTab(gBrowser.selectedTab).disableTouch();
|
||||
let div = content.document.querySelector("div");
|
||||
let x = 2, y = 2;
|
||||
EventUtils.synthesizeMouse(div, x, y, {type: "mousedown", isSynthesized: false}, content);
|
||||
|
@ -2,170 +2,10 @@
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
let instance, deletedPresetA, deletedPresetB, oldPrompt;
|
||||
let mgr = ResponsiveUI.ResponsiveUIManager;
|
||||
|
||||
waitForExplicitFinish();
|
||||
SimpleTest.requestCompleteLog();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(startTest, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf8,test custom presets in responsive mode";
|
||||
|
||||
// This test uses executeSoon() when responsive mode is initialized and when
|
||||
// it is destroyed such that we get out of the init/destroy loops. If we try
|
||||
// to init/destroy immediately, without waiting for the next loop, we get
|
||||
// intermittent test failures.
|
||||
|
||||
function startTest() {
|
||||
// Mocking prompt
|
||||
oldPrompt = Services.prompt;
|
||||
Services.prompt = {
|
||||
value: "",
|
||||
returnBool: true,
|
||||
prompt: function(aParent, aDialogTitle, aText, aValue, aCheckMsg, aCheckState) {
|
||||
aValue.value = this.value;
|
||||
return this.returnBool;
|
||||
}
|
||||
};
|
||||
|
||||
registerCleanupFunction(() => Services.prompt = oldPrompt);
|
||||
|
||||
info("test started, waiting for responsive mode to activate");
|
||||
|
||||
document.getElementById("Tools:ResponsiveUI").removeAttribute("disabled");
|
||||
mgr.once("on", onUIOpen);
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
}
|
||||
|
||||
function onUIOpen() {
|
||||
// Is it open?
|
||||
let container = gBrowser.getBrowserContainer();
|
||||
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
|
||||
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
instance.transitionsEnabled = false;
|
||||
|
||||
testAddCustomPreset();
|
||||
}
|
||||
|
||||
function testAddCustomPreset() {
|
||||
// Tries to add a custom preset and cancel the prompt
|
||||
let idx = instance.menulist.selectedIndex;
|
||||
let presetCount = instance.presets.length;
|
||||
|
||||
Services.prompt.value = "";
|
||||
Services.prompt.returnBool = false;
|
||||
instance.addbutton.doCommand();
|
||||
|
||||
is(idx, instance.menulist.selectedIndex, "selected item didn't change after add preset and cancel");
|
||||
is(presetCount, instance.presets.length, "number of presets didn't change after add preset and cancel");
|
||||
|
||||
let customHeight = 123, customWidth = 456;
|
||||
instance.setSize(customWidth, customHeight);
|
||||
|
||||
// Adds the custom preset with "Testing preset"
|
||||
Services.prompt.value = "Testing preset";
|
||||
Services.prompt.returnBool = true;
|
||||
instance.addbutton.doCommand();
|
||||
|
||||
instance.menulist.selectedIndex = 1;
|
||||
|
||||
info("waiting for responsive mode to turn off");
|
||||
mgr.once("off", restart);
|
||||
|
||||
// Force document reflow to avoid intermittent failures.
|
||||
info("document height " + document.height);
|
||||
|
||||
// We're still in the loop of initializing the responsive mode.
|
||||
// Let's wait next loop to stop it.
|
||||
executeSoon(function() {
|
||||
instance.close();
|
||||
});
|
||||
}
|
||||
|
||||
function restart() {
|
||||
info("Restarting Responsive Mode");
|
||||
mgr.once("on", function() {
|
||||
let container = gBrowser.getBrowserContainer();
|
||||
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
|
||||
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
|
||||
testCustomPresetInList();
|
||||
});
|
||||
|
||||
// We're still in the loop of destroying the responsive mode.
|
||||
// Let's wait next loop to start it.
|
||||
executeSoon(function() {
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
});
|
||||
}
|
||||
|
||||
function testCustomPresetInList() {
|
||||
let customPresetIndex = getPresetIndex("456x123 (Testing preset)");
|
||||
ok(customPresetIndex >= 0, "is the previously added preset (idx = " + customPresetIndex + ") in the list of items");
|
||||
|
||||
instance.menulist.selectedIndex = customPresetIndex;
|
||||
|
||||
is(content.innerWidth, 456, "add preset, and selected in the list, dimension valid (width)");
|
||||
is(content.innerHeight, 123, "add preset, and selected in the list, dimension valid (height)");
|
||||
|
||||
testDeleteCustomPresets();
|
||||
}
|
||||
|
||||
function testDeleteCustomPresets() {
|
||||
instance.removebutton.doCommand();
|
||||
|
||||
instance.menulist.selectedIndex = 2;
|
||||
deletedPresetA = instance.menulist.selectedItem.getAttribute("label");
|
||||
instance.removebutton.doCommand();
|
||||
|
||||
instance.menulist.selectedIndex = 2;
|
||||
deletedPresetB = instance.menulist.selectedItem.getAttribute("label");
|
||||
instance.removebutton.doCommand();
|
||||
|
||||
info("waiting for responsive mode to turn off");
|
||||
mgr.once("off", restartAgain);
|
||||
|
||||
// We're still in the loop of initializing the responsive mode.
|
||||
// Let's wait next loop to stop it.
|
||||
executeSoon(() => instance.close());
|
||||
}
|
||||
|
||||
function restartAgain() {
|
||||
info("waiting for responsive mode to turn on");
|
||||
mgr.once("on", () => {
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
testCustomPresetsNotInListAnymore();
|
||||
});
|
||||
|
||||
// We're still in the loop of destroying the responsive mode.
|
||||
// Let's wait next loop to start it.
|
||||
executeSoon(() => synthesizeKeyFromKeyTag("key_responsiveUI"));
|
||||
}
|
||||
|
||||
function testCustomPresetsNotInListAnymore() {
|
||||
let customPresetIndex = getPresetIndex(deletedPresetA);
|
||||
is(customPresetIndex, -1, "deleted preset " + deletedPresetA + " is not in the list anymore");
|
||||
|
||||
customPresetIndex = getPresetIndex(deletedPresetB);
|
||||
is(customPresetIndex, -1, "deleted preset " + deletedPresetB + " is not in the list anymore");
|
||||
|
||||
executeSoon(finishUp);
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
delete instance;
|
||||
gBrowser.removeCurrentTab();
|
||||
|
||||
finish();
|
||||
}
|
||||
let instance, deletedPresetA, deletedPresetB, oldPrompt;
|
||||
|
||||
function getPresetIndex(presetLabel) {
|
||||
function testOnePreset(c) {
|
||||
@ -199,4 +39,121 @@ function test() {
|
||||
|
||||
key.doCommand();
|
||||
}
|
||||
|
||||
Task.spawn(function() {
|
||||
|
||||
yield addTab("data:text/html;charset=utf8,test custom presets in responsive mode");
|
||||
|
||||
let mgr = ResponsiveUI.ResponsiveUIManager;
|
||||
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
|
||||
yield once(mgr, "on");
|
||||
|
||||
oldPrompt = Services.prompt;
|
||||
Services.prompt = {
|
||||
value: "",
|
||||
returnBool: true,
|
||||
prompt: function(aParent, aDialogTitle, aText, aValue, aCheckMsg, aCheckState) {
|
||||
aValue.value = this.value;
|
||||
return this.returnBool;
|
||||
}
|
||||
};
|
||||
|
||||
registerCleanupFunction(() => Services.prompt = oldPrompt);
|
||||
|
||||
// Is it open?
|
||||
let container = gBrowser.getBrowserContainer();
|
||||
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
|
||||
|
||||
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
instance.transitionsEnabled = false;
|
||||
|
||||
yield instance._test_notifyOnResize();
|
||||
|
||||
// Tries to add a custom preset and cancel the prompt
|
||||
let idx = instance.menulist.selectedIndex;
|
||||
let presetCount = instance.presets.length;
|
||||
|
||||
Services.prompt.value = "";
|
||||
Services.prompt.returnBool = false;
|
||||
instance.addbutton.doCommand();
|
||||
|
||||
is(idx, instance.menulist.selectedIndex, "selected item didn't change after add preset and cancel");
|
||||
is(presetCount, instance.presets.length, "number of presets didn't change after add preset and cancel");
|
||||
|
||||
// Adds the custom preset with "Testing preset"
|
||||
Services.prompt.value = "Testing preset";
|
||||
Services.prompt.returnBool = true;
|
||||
|
||||
let customHeight = 123, customWidth = 456;
|
||||
instance.startResizing({});
|
||||
instance.setSize(customWidth, customHeight);
|
||||
instance.stopResizing({});
|
||||
|
||||
instance.addbutton.doCommand();
|
||||
|
||||
// Force document reflow to avoid intermittent failures.
|
||||
info("document height " + document.height);
|
||||
|
||||
instance.close();
|
||||
|
||||
info("waiting for responsive mode to turn off");
|
||||
yield once(mgr, "off");
|
||||
|
||||
// We're still in the loop of initializing the responsive mode.
|
||||
// Let's wait next loop to stop it.
|
||||
yield nextTick();
|
||||
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
|
||||
yield once(mgr, "on");
|
||||
|
||||
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
|
||||
|
||||
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
|
||||
let customPresetIndex = getPresetIndex("456x123 (Testing preset)");
|
||||
info(customPresetIndex);
|
||||
ok(customPresetIndex >= 0, "is the previously added preset (idx = " + customPresetIndex + ") in the list of items");
|
||||
|
||||
instance.menulist.selectedIndex = customPresetIndex;
|
||||
|
||||
is(content.innerWidth, 456, "add preset, and selected in the list, dimension valid (width)");
|
||||
is(content.innerHeight, 123, "add preset, and selected in the list, dimension valid (height)");
|
||||
|
||||
instance.removebutton.doCommand();
|
||||
|
||||
instance.menulist.selectedIndex = 2;
|
||||
deletedPresetA = instance.menulist.selectedItem.getAttribute("label");
|
||||
instance.removebutton.doCommand();
|
||||
|
||||
instance.menulist.selectedIndex = 2;
|
||||
deletedPresetB = instance.menulist.selectedItem.getAttribute("label");
|
||||
instance.removebutton.doCommand();
|
||||
|
||||
yield nextTick();
|
||||
instance.close();
|
||||
yield once(mgr, "off");
|
||||
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
|
||||
info("waiting for responsive mode to turn on");
|
||||
yield once(mgr, "on");
|
||||
|
||||
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
|
||||
customPresetIndex = getPresetIndex(deletedPresetA);
|
||||
is(customPresetIndex, -1, "deleted preset " + deletedPresetA + " is not in the list anymore");
|
||||
|
||||
customPresetIndex = getPresetIndex(deletedPresetB);
|
||||
is(customPresetIndex, -1, "deleted preset " + deletedPresetB + " is not in the list anymore");
|
||||
|
||||
yield nextTick();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
@ -123,3 +123,92 @@ function openComputedView() {
|
||||
function openRuleView() {
|
||||
return openInspectorSideBar("ruleview");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a new test tab in the browser and load the given url.
|
||||
* @param {String} url The url to be loaded in the new tab
|
||||
* @return a promise that resolves to the tab object when the url is loaded
|
||||
*/
|
||||
let addTab = Task.async(function* (url) {
|
||||
info("Adding a new tab with URL: '" + url + "'");
|
||||
|
||||
window.focus();
|
||||
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab(url);
|
||||
let browser = tab.linkedBrowser;
|
||||
|
||||
yield once(browser, "load", true);
|
||||
info("URL '" + url + "' loading complete");
|
||||
|
||||
return tab;
|
||||
});
|
||||
|
||||
/**
|
||||
* Wait for eventName on target.
|
||||
* @param {Object} target An observable object that either supports on/off or
|
||||
* addEventListener/removeEventListener
|
||||
* @param {String} eventName
|
||||
* @param {Boolean} useCapture Optional, for addEventListener/removeEventListener
|
||||
* @return A promise that resolves when the event has been handled
|
||||
*/
|
||||
function once(target, eventName, useCapture=false) {
|
||||
info("Waiting for event: '" + eventName + "' on " + target + ".");
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
for (let [add, remove] of [
|
||||
["addEventListener", "removeEventListener"],
|
||||
["addListener", "removeListener"],
|
||||
["on", "off"]
|
||||
]) {
|
||||
if ((add in target) && (remove in target)) {
|
||||
target[add](eventName, function onEvent(...aArgs) {
|
||||
info("Got event: '" + eventName + "' on " + target + ".");
|
||||
target[remove](eventName, onEvent, useCapture);
|
||||
deferred.resolve.apply(deferred, aArgs);
|
||||
}, useCapture);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function wait(ms) {
|
||||
let def = promise.defer();
|
||||
setTimeout(def.resolve, ms);
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
function synthesizeKeyFromKeyTag(aKeyId) {
|
||||
let key = document.getElementById(aKeyId);
|
||||
isnot(key, null, "Successfully retrieved the <key> node");
|
||||
|
||||
let modifiersAttr = key.getAttribute("modifiers");
|
||||
|
||||
let name = null;
|
||||
|
||||
if (key.getAttribute("keycode"))
|
||||
name = key.getAttribute("keycode");
|
||||
else if (key.getAttribute("key"))
|
||||
name = key.getAttribute("key");
|
||||
|
||||
isnot(name, null, "Successfully retrieved keycode/key");
|
||||
|
||||
let modifiers = {
|
||||
shiftKey: modifiersAttr.match("shift"),
|
||||
ctrlKey: modifiersAttr.match("ctrl"),
|
||||
altKey: modifiersAttr.match("alt"),
|
||||
metaKey: modifiersAttr.match("meta"),
|
||||
accelKey: modifiersAttr.match("accel")
|
||||
}
|
||||
|
||||
EventUtils.synthesizeKey(name, modifiers);
|
||||
}
|
||||
|
||||
function nextTick() {
|
||||
let def = promise.defer();
|
||||
executeSoon(() => def.resolve())
|
||||
return def.promise;
|
||||
}
|
||||
|
@ -1,126 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ "switchToFloatingScrollbars", "switchToNativeScrollbars" ];
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
let URL = Services.io.newURI("chrome://browser/skin/devtools/floating-scrollbars.css", null, null);
|
||||
|
||||
let trackedTabs = new WeakMap();
|
||||
|
||||
/**
|
||||
* Switch to floating scrollbars, à la mobile.
|
||||
*
|
||||
* @param aTab the targeted tab.
|
||||
*
|
||||
*/
|
||||
this.switchToFloatingScrollbars = function switchToFloatingScrollbars(aTab) {
|
||||
let mgr = trackedTabs.get(aTab);
|
||||
if (!mgr) {
|
||||
mgr = new ScrollbarManager(aTab);
|
||||
}
|
||||
mgr.switchToFloating();
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch to original native scrollbars.
|
||||
*
|
||||
* @param aTab the targeted tab.
|
||||
*
|
||||
*/
|
||||
this.switchToNativeScrollbars = function switchToNativeScrollbars(aTab) {
|
||||
let mgr = trackedTabs.get(aTab);
|
||||
if (mgr) {
|
||||
mgr.reset();
|
||||
}
|
||||
}
|
||||
|
||||
function ScrollbarManager(aTab) {
|
||||
trackedTabs.set(aTab, this);
|
||||
|
||||
this.attachedTab = aTab;
|
||||
this.attachedBrowser = aTab.linkedBrowser;
|
||||
|
||||
this.reset = this.reset.bind(this);
|
||||
this.switchToFloating = this.switchToFloating.bind(this);
|
||||
|
||||
this.attachedTab.addEventListener("TabClose", this.reset, true);
|
||||
this.attachedBrowser.addEventListener("DOMContentLoaded", this.switchToFloating, true);
|
||||
}
|
||||
|
||||
ScrollbarManager.prototype = {
|
||||
get win() {
|
||||
return this.attachedBrowser.contentWindow;
|
||||
},
|
||||
|
||||
/*
|
||||
* Change the look of the scrollbars.
|
||||
*/
|
||||
switchToFloating: function() {
|
||||
let windows = this.getInnerWindows(this.win);
|
||||
windows.forEach(this.injectStyleSheet);
|
||||
this.forceStyle();
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* Reset the look of the scrollbars.
|
||||
*/
|
||||
reset: function() {
|
||||
let windows = this.getInnerWindows(this.win);
|
||||
windows.forEach(this.removeStyleSheet);
|
||||
this.forceStyle(this.attachedBrowser);
|
||||
this.attachedBrowser.removeEventListener("DOMContentLoaded", this.switchToFloating, true);
|
||||
this.attachedTab.removeEventListener("TabClose", this.reset, true);
|
||||
trackedTabs.delete(this.attachedTab);
|
||||
},
|
||||
|
||||
/*
|
||||
* Toggle the display property of the window to force the style to be applied.
|
||||
*/
|
||||
forceStyle: function() {
|
||||
let parentWindow = this.attachedBrowser.ownerDocument.defaultView;
|
||||
let display = parentWindow.getComputedStyle(this.attachedBrowser).display; // Save display value
|
||||
this.attachedBrowser.style.display = "none";
|
||||
parentWindow.getComputedStyle(this.attachedBrowser).display; // Flush
|
||||
this.attachedBrowser.style.display = display; // Restore
|
||||
},
|
||||
|
||||
/*
|
||||
* return all the window objects present in the hiearchy of a window.
|
||||
*/
|
||||
getInnerWindows: function(win) {
|
||||
let iframes = win.document.querySelectorAll("iframe");
|
||||
let innerWindows = [];
|
||||
for (let iframe of iframes) {
|
||||
innerWindows = innerWindows.concat(this.getInnerWindows(iframe.contentWindow));
|
||||
}
|
||||
return [win].concat(innerWindows);
|
||||
},
|
||||
|
||||
/*
|
||||
* Append the new scrollbar style.
|
||||
*/
|
||||
injectStyleSheet: function(win) {
|
||||
let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
try {
|
||||
winUtils.loadSheet(URL, win.AGENT_SHEET);
|
||||
}catch(e) {}
|
||||
},
|
||||
|
||||
/*
|
||||
* Remove the injected stylesheet.
|
||||
*/
|
||||
removeStyleSheet: function(win) {
|
||||
let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
try {
|
||||
winUtils.removeSheet(URL, win.AGENT_SHEET);
|
||||
}catch(e) {}
|
||||
},
|
||||
}
|
@ -12,7 +12,6 @@ EXTRA_JS_MODULES.devtools += [
|
||||
'Curl.jsm',
|
||||
'DeveloperToolbar.jsm',
|
||||
'DOMHelpers.jsm',
|
||||
'FloatingScrollbars.jsm',
|
||||
'Jsbeautify.jsm',
|
||||
'Parser.jsm',
|
||||
'SplitView.jsm',
|
||||
|
@ -41,7 +41,7 @@ let WebAudioEditorController = {
|
||||
/**
|
||||
* Listen for events emitted by the current tab target.
|
||||
*/
|
||||
initialize: function() {
|
||||
initialize: Task.async(function* () {
|
||||
telemetry.toolOpened("webaudioeditor");
|
||||
this._onTabNavigated = this._onTabNavigated.bind(this);
|
||||
this._onThemeChange = this._onThemeChange.bind(this);
|
||||
@ -60,7 +60,10 @@ let WebAudioEditorController = {
|
||||
// the graph's marker styling, since we can't do this
|
||||
// with CSS
|
||||
gDevTools.on("pref-changed", this._onThemeChange);
|
||||
},
|
||||
|
||||
// Store the AudioNode definitions from the WebAudioFront
|
||||
AUDIO_NODE_DEFINITION = yield gFront.getDefinition();
|
||||
}),
|
||||
|
||||
/**
|
||||
* Remove events emitted by the current tab target.
|
||||
|
@ -15,6 +15,7 @@ const { require } = devtools;
|
||||
|
||||
let { console } = Cu.import("resource://gre/modules/devtools/Console.jsm", {});
|
||||
let { EventTarget } = require("sdk/event/target");
|
||||
|
||||
const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
|
||||
const { Class } = require("sdk/core/heritage");
|
||||
const EventEmitter = require("devtools/toolkit/event-emitter");
|
||||
@ -25,6 +26,10 @@ const telemetry = new Telemetry();
|
||||
devtools.lazyImporter(this, "LineGraphWidget",
|
||||
"resource:///modules/devtools/Graphs.jsm");
|
||||
|
||||
// `AUDIO_NODE_DEFINITION` defined in the controller's initialization,
|
||||
// which describes all the properties of an AudioNode
|
||||
let AUDIO_NODE_DEFINITION;
|
||||
|
||||
// Override DOM promises with Promise.jsm helpers
|
||||
const { defer, all } = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
|
||||
|
||||
|
@ -35,6 +35,12 @@ const AudioNodeModel = Class({
|
||||
*/
|
||||
setup: Task.async(function* () {
|
||||
yield this.getType();
|
||||
|
||||
// Query bypass status on start up
|
||||
this._bypassed = yield this.isBypassed();
|
||||
|
||||
// Store whether or not this node is bypassable in the first place
|
||||
this.bypassable = !AUDIO_NODE_DEFINITION[this.type].unbypassable;
|
||||
}),
|
||||
|
||||
/**
|
||||
@ -75,6 +81,26 @@ const AudioNodeModel = Class({
|
||||
coreEmit(this, "disconnect", this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the bypass status of the audio node.
|
||||
*
|
||||
* @return Promise->Boolean
|
||||
*/
|
||||
isBypassed: function () {
|
||||
return this.actor.isBypassed();
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the bypass value of an AudioNode.
|
||||
*
|
||||
* @param Boolean enable
|
||||
* @return Promise
|
||||
*/
|
||||
bypass: function (enable) {
|
||||
this._bypassed = enable;
|
||||
return this.actor.bypass(enable).then(() => coreEmit(this, "bypass", this, enable));
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a promise that resolves to an array of objects containing
|
||||
* both a `param` name property and a `value` property.
|
||||
@ -106,7 +132,8 @@ const AudioNodeModel = Class({
|
||||
graph.addNode(this.id, {
|
||||
type: this.type,
|
||||
label: this.type.replace(/Node$/, ""),
|
||||
id: this.id
|
||||
id: this.id,
|
||||
bypassed: this._bypassed
|
||||
});
|
||||
},
|
||||
|
||||
@ -279,7 +306,7 @@ const AudioNodesCollection = Class({
|
||||
this.remove(node);
|
||||
} else {
|
||||
// Pipe the event to the collection
|
||||
coreEmit(this, eventName, [node].concat(args));
|
||||
coreEmit(this, eventName, node, ...args);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -52,6 +52,7 @@ support-files =
|
||||
|
||||
[browser_wa_inspector.js]
|
||||
[browser_wa_inspector-toggle.js]
|
||||
[browser_wa_inspector-bypass-01.js]
|
||||
|
||||
[browser_wa_properties-view.js]
|
||||
[browser_wa_properties-view-edit-01.js]
|
||||
|
@ -15,14 +15,22 @@ add_task(function*() {
|
||||
is((yield gainNode.isBypassed()), false, "Nodes start off unbypassed.");
|
||||
|
||||
info("Calling node#bypass(true)");
|
||||
yield gainNode.bypass(true);
|
||||
let isBypassed = yield gainNode.bypass(true);
|
||||
|
||||
is(isBypassed, true, "node.bypass(true) resolves to true");
|
||||
is((yield gainNode.isBypassed()), true, "Node is now bypassed.");
|
||||
|
||||
info("Calling node#bypass(false)");
|
||||
yield gainNode.bypass(false);
|
||||
isBypassed = yield gainNode.bypass(false);
|
||||
|
||||
is(isBypassed, false, "node.bypass(false) resolves to false");
|
||||
is((yield gainNode.isBypassed()), false, "Node back to being unbypassed.");
|
||||
|
||||
info("Calling node#bypass(true) on unbypassable node");
|
||||
isBypassed = yield destNode.bypass(true);
|
||||
|
||||
is(isBypassed, false, "node.bypass(true) resolves to false for unbypassable node");
|
||||
is((yield gainNode.isBypassed()), false, "Unbypassable node is unaffect");
|
||||
|
||||
yield removeTab(target.tab);
|
||||
});
|
||||
|
@ -20,11 +20,12 @@ add_task(function*() {
|
||||
waitForGraphRendered(panelWin, 3, 2)
|
||||
]);
|
||||
let nodeIds = actors.map(actor => actor.actorID);
|
||||
let $tabbox = $("#web-audio-editor-tabs");
|
||||
|
||||
// Oscillator node
|
||||
click(panelWin, findGraphNode(panelWin, nodeIds[1]));
|
||||
yield waitForInspectorRender(panelWin, EVENTS);
|
||||
click(panelWin, $("#automation-tab"));
|
||||
$tabbox.selectedIndex = 1;
|
||||
|
||||
ok(isVisible($("#automation-graph-container")), "graph container should be visible");
|
||||
ok(isVisible($("#automation-content")), "automation content should be visible");
|
||||
@ -34,17 +35,17 @@ add_task(function*() {
|
||||
// Gain node
|
||||
click(panelWin, findGraphNode(panelWin, nodeIds[2]));
|
||||
yield waitForInspectorRender(panelWin, EVENTS);
|
||||
click(panelWin, $("#automation-tab"));
|
||||
$tabbox.selectedIndex = 1;
|
||||
|
||||
ok(!isVisible($("#automation-graph-container")), "graph container should be visible");
|
||||
ok(isVisible($("#automation-content")), "automation content should not be visible");
|
||||
ok(!isVisible($("#automation-graph-container")), "graph container should not be visible");
|
||||
ok(isVisible($("#automation-content")), "automation content should be visible");
|
||||
ok(isVisible($("#automation-no-events")), "no-events panel should be visible");
|
||||
ok(!isVisible($("#automation-empty")), "empty panel should not be visible");
|
||||
|
||||
// destination node
|
||||
click(panelWin, findGraphNode(panelWin, nodeIds[0]));
|
||||
yield waitForInspectorRender(panelWin, EVENTS);
|
||||
click(panelWin, $("#automation-tab"));
|
||||
$tabbox.selectedIndex = 1;
|
||||
|
||||
ok(!isVisible($("#automation-graph-container")), "graph container should not be visible");
|
||||
ok(!isVisible($("#automation-content")), "automation content should not be visible");
|
||||
|
@ -0,0 +1,67 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that nodes are correctly bypassed when bypassing.
|
||||
*/
|
||||
|
||||
add_task(function*() {
|
||||
let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL);
|
||||
let { panelWin } = panel;
|
||||
let { gFront, $, $$, EVENTS, gAudioNodes } = panelWin;
|
||||
|
||||
reload(target);
|
||||
|
||||
let [actors] = yield Promise.all([
|
||||
get3(gFront, "create-node"),
|
||||
waitForGraphRendered(panelWin, 3, 2)
|
||||
]);
|
||||
let nodeIds = actors.map(actor => actor.actorID);
|
||||
|
||||
click(panelWin, findGraphNode(panelWin, nodeIds[1]));
|
||||
// Wait for the node to be set as well as the inspector to come fully into the view
|
||||
yield Promise.all([
|
||||
waitForInspectorRender(panelWin, EVENTS),
|
||||
once(panelWin, EVENTS.UI_INSPECTOR_TOGGLED)
|
||||
]);
|
||||
|
||||
let $bypass = $("toolbarbutton.bypass");
|
||||
|
||||
is((yield actors[1].isBypassed()), false, "AudioNodeActor is not bypassed by default.")
|
||||
is($bypass.checked, true, "Button is 'on' for normal nodes");
|
||||
is($bypass.disabled, false, "Bypass button is not disabled for normal nodes");
|
||||
|
||||
command($bypass);
|
||||
yield gAudioNodes.once("bypass");
|
||||
|
||||
is((yield actors[1].isBypassed()), true, "AudioNodeActor is bypassed.")
|
||||
is($bypass.checked, false, "Button is 'off' when clicked");
|
||||
is($bypass.disabled, false, "Bypass button is not disabled after click");
|
||||
ok(findGraphNode(panelWin, nodeIds[1]).classList.contains("bypassed"),
|
||||
"AudioNode has 'bypassed' class.");
|
||||
|
||||
command($bypass);
|
||||
yield gAudioNodes.once("bypass");
|
||||
|
||||
is((yield actors[1].isBypassed()), false, "AudioNodeActor is no longer bypassed.")
|
||||
is($bypass.checked, true, "Button is back on when clicked");
|
||||
is($bypass.disabled, false, "Bypass button is not disabled after click");
|
||||
ok(!findGraphNode(panelWin, nodeIds[1]).classList.contains("bypassed"),
|
||||
"AudioNode no longer has 'bypassed' class.");
|
||||
|
||||
click(panelWin, findGraphNode(panelWin, nodeIds[0]));
|
||||
|
||||
yield once(panelWin, EVENTS.UI_INSPECTOR_NODE_SET);
|
||||
|
||||
is((yield actors[0].isBypassed()), false, "Unbypassable AudioNodeActor is not bypassed.");
|
||||
is($bypass.checked, false, "Button is 'off' for unbypassable nodes");
|
||||
is($bypass.disabled, true, "Bypass button is disabled for unbypassable nodes");
|
||||
|
||||
command($bypass);
|
||||
is((yield actors[0].isBypassed()), false,
|
||||
"Clicking button on unbypassable node does not change bypass state on actor.");
|
||||
is($bypass.checked, false, "Button is still 'off' for unbypassable nodes");
|
||||
is($bypass.disabled, true, "Bypass button is still disabled for unbypassable nodes");
|
||||
|
||||
yield teardown(target);
|
||||
});
|
@ -34,8 +34,6 @@ add_task(function*() {
|
||||
"InspectorView empty message should still be visible.");
|
||||
ok(!isVisible($("#web-audio-editor-tabs")),
|
||||
"InspectorView tabs view should still be hidden.");
|
||||
is($("#web-audio-inspector-title").value, "AudioNode Inspector",
|
||||
"Inspector should still have default title.");
|
||||
|
||||
// Close inspector pane
|
||||
$("#inspector-pane-toggle").click();
|
||||
@ -59,8 +57,6 @@ add_task(function*() {
|
||||
"Empty message hides even when loading node while open.");
|
||||
ok(isVisible($("#web-audio-editor-tabs")),
|
||||
"Switches to tab view when loading node while open.");
|
||||
is($("#web-audio-inspector-title").value, "Oscillator",
|
||||
"Inspector title updates when loading node while open.");
|
||||
|
||||
yield teardown(target);
|
||||
});
|
||||
|
@ -27,8 +27,6 @@ add_task(function*() {
|
||||
"InspectorView empty message should show when no node's selected.");
|
||||
ok(!isVisible($("#web-audio-editor-tabs")),
|
||||
"InspectorView tabs view should be hidden when no node's selected.");
|
||||
is($("#web-audio-inspector-title").value, "AudioNode Inspector",
|
||||
"Inspector should have default title when empty.");
|
||||
|
||||
// Wait for the node to be set as well as the inspector to come fully into the view
|
||||
let nodeSet = Promise.all([
|
||||
@ -44,9 +42,6 @@ add_task(function*() {
|
||||
ok(isVisible($("#web-audio-editor-tabs")),
|
||||
"InspectorView tabs view visible when node selected.");
|
||||
|
||||
is($("#web-audio-inspector-title").value, "Oscillator",
|
||||
"Inspector should have the node title when a node is selected.");
|
||||
|
||||
is($("#web-audio-editor-tabs").selectedIndex, 0,
|
||||
"default tab selected should be the parameters tab.");
|
||||
|
||||
@ -54,8 +49,5 @@ add_task(function*() {
|
||||
click(panelWin, findGraphNode(panelWin, nodeIds[2]));
|
||||
yield nodeSet;
|
||||
|
||||
is($("#web-audio-inspector-title").value, "Gain",
|
||||
"Inspector title updates when a new node is selected.");
|
||||
|
||||
yield teardown(target);
|
||||
});
|
||||
|
@ -318,6 +318,12 @@ function mouseOver (win, element) {
|
||||
EventUtils.sendMouseEvent({ type: "mouseover" }, element, win);
|
||||
}
|
||||
|
||||
function command (button) {
|
||||
let ev = button.ownerDocument.createEvent("XULCommandEvent");
|
||||
ev.initCommandEvent("command", true, true, button.ownerDocument.defaultView, 0, false, false, false, false, null);
|
||||
button.dispatchEvent(ev);
|
||||
}
|
||||
|
||||
function isVisible (element) {
|
||||
return !element.getAttribute("hidden");
|
||||
}
|
||||
|
@ -36,13 +36,13 @@ let ContextView = {
|
||||
* Initialization function, called when the tool is started.
|
||||
*/
|
||||
initialize: function() {
|
||||
this._onGraphNodeClick = this._onGraphNodeClick.bind(this);
|
||||
this._onGraphClick = this._onGraphClick.bind(this);
|
||||
this._onThemeChange = this._onThemeChange.bind(this);
|
||||
this._onStartContext = this._onStartContext.bind(this);
|
||||
this._onEvent = this._onEvent.bind(this);
|
||||
|
||||
this.draw = debounce(this.draw.bind(this), GRAPH_DEBOUNCE_TIMER);
|
||||
$('#graph-target').addEventListener('click', this._onGraphNodeClick, false);
|
||||
$("#graph-target").addEventListener("click", this._onGraphClick, false);
|
||||
|
||||
window.on(EVENTS.THEME_CHANGE, this._onThemeChange);
|
||||
window.on(EVENTS.START_CONTEXT, this._onStartContext);
|
||||
@ -58,7 +58,8 @@ let ContextView = {
|
||||
if (this._zoomBinding) {
|
||||
this._zoomBinding.on("zoom", null);
|
||||
}
|
||||
$('#graph-target').removeEventListener('click', this._onGraphNodeClick, false);
|
||||
$("#graph-target").removeEventListener("click", this._onGraphClick, false);
|
||||
|
||||
window.off(EVENTS.THEME_CHANGE, this._onThemeChange);
|
||||
window.off(EVENTS.START_CONTEXT, this._onStartContext);
|
||||
gAudioNodes.off("*", this._onEvent);
|
||||
@ -126,6 +127,15 @@ let ContextView = {
|
||||
return $(".nodes > g[data-id='" + actorID + "']");
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the appropriate class on an SVG node when its bypass
|
||||
* status is toggled.
|
||||
*/
|
||||
_bypassNode: function (node, enabled) {
|
||||
let el = this._getNodeByID(node.id);
|
||||
el.classList[enabled ? "add" : "remove"]("bypassed");
|
||||
},
|
||||
|
||||
/**
|
||||
* This method renders the nodes currently available in `gAudioNodes` and is
|
||||
* throttled to be called at most every `GRAPH_DEBOUNCE_TIMER` milliseconds.
|
||||
@ -143,42 +153,33 @@ let ContextView = {
|
||||
let oldDrawNodes = renderer.drawNodes();
|
||||
renderer.drawNodes(function(graph, root) {
|
||||
let svgNodes = oldDrawNodes(graph, root);
|
||||
svgNodes.attr("class", (n) => {
|
||||
svgNodes.each(function (n) {
|
||||
let node = graph.node(n);
|
||||
return "audionode type-" + node.type;
|
||||
});
|
||||
svgNodes.attr("data-id", (n) => {
|
||||
let node = graph.node(n);
|
||||
return node.id;
|
||||
let classString = "audionode type-" + node.type + (node.bypassed ? " bypassed" : "");
|
||||
this.setAttribute("class", classString);
|
||||
this.setAttribute("data-id", node.id);
|
||||
this.setAttribute("data-type", node.type);
|
||||
});
|
||||
return svgNodes;
|
||||
});
|
||||
|
||||
// Post-render manipulation of edges
|
||||
// TODO do all of this more efficiently, rather than
|
||||
// using the direct D3 helper utilities to loop over each
|
||||
// edge several times
|
||||
let oldDrawEdgePaths = renderer.drawEdgePaths();
|
||||
let defaultClasses = "edgePath enter";
|
||||
|
||||
renderer.drawEdgePaths(function(graph, root) {
|
||||
let svgEdges = oldDrawEdgePaths(graph, root);
|
||||
svgEdges.attr("data-source", (n) => {
|
||||
let edge = graph.edge(n);
|
||||
return edge.source;
|
||||
});
|
||||
svgEdges.attr("data-target", (n) => {
|
||||
let edge = graph.edge(n);
|
||||
return edge.target;
|
||||
});
|
||||
svgEdges.attr("data-param", (n) => {
|
||||
let edge = graph.edge(n);
|
||||
return edge.param ? edge.param : null;
|
||||
});
|
||||
svgEdges.each(function (e) {
|
||||
let edge = graph.edge(e);
|
||||
|
||||
// We have to manually specify the default classes on the edges
|
||||
// as to not overwrite them
|
||||
let defaultClasses = "edgePath enter";
|
||||
svgEdges.attr("class", (n) => {
|
||||
let edge = graph.edge(n);
|
||||
return defaultClasses + (edge.param ? (" param-connection " + edge.param) : "");
|
||||
let edgeClass = defaultClasses + (edge.param ? (" param-connection " + edge.param) : "");
|
||||
|
||||
this.setAttribute("data-source", edge.source);
|
||||
this.setAttribute("data-target", edge.target);
|
||||
this.setAttribute("data-param", edge.param ? edge.param : null);
|
||||
this.setAttribute("class", edgeClass);
|
||||
});
|
||||
|
||||
return svgEdges;
|
||||
@ -263,6 +264,11 @@ let ContextView = {
|
||||
* in GRAPH_REDRAW_EVENTS) qualify as a redraw event.
|
||||
*/
|
||||
_onEvent: function (eventName, ...args) {
|
||||
// If bypassing, just toggle the class on the SVG node
|
||||
// rather than rerendering everything
|
||||
if (eventName === "bypass") {
|
||||
this._bypassNode.apply(this, args);
|
||||
}
|
||||
if (~GRAPH_REDRAW_EVENTS.indexOf(eventName)) {
|
||||
this.draw();
|
||||
}
|
||||
@ -280,12 +286,12 @@ let ContextView = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Fired when a node in the svg graph is clicked. Used to handle triggering the AudioNodePane.
|
||||
* Fired when a click occurs in the graph.
|
||||
*
|
||||
* @param Event e
|
||||
* Click event.
|
||||
*/
|
||||
_onGraphNodeClick: function (e) {
|
||||
_onGraphClick: function (e) {
|
||||
let node = findGraphNodeParent(e.target);
|
||||
// If node not found (clicking outside of an audio node in the graph),
|
||||
// then ignore this event
|
||||
|
@ -43,8 +43,12 @@ let InspectorView = {
|
||||
this._onNodeSelect = this._onNodeSelect.bind(this);
|
||||
this._onDestroyNode = this._onDestroyNode.bind(this);
|
||||
this._onResize = this._onResize.bind(this);
|
||||
this._onCommandClick = this._onCommandClick.bind(this);
|
||||
|
||||
this.splitter.addEventListener("mouseup", this._onResize);
|
||||
for (let $el of $$("#audio-node-toolbar toolbarbutton")) {
|
||||
$el.addEventListener("command", this._onCommandClick);
|
||||
}
|
||||
window.on(EVENTS.UI_SELECT_NODE, this._onNodeSelect);
|
||||
gAudioNodes.on("remove", this._onDestroyNode);
|
||||
},
|
||||
@ -55,6 +59,11 @@ let InspectorView = {
|
||||
destroy: function () {
|
||||
this.unbindToggle();
|
||||
this.splitter.removeEventListener("mouseup", this._onResize);
|
||||
|
||||
$("#audio-node-toolbar toolbarbutton").removeEventListener("command", this._onCommandClick);
|
||||
for (let $el of $$("#audio-node-toolbar toolbarbutton")) {
|
||||
$el.removeEventListener("command", this._onCommandClick);
|
||||
}
|
||||
window.off(EVENTS.UI_SELECT_NODE, this._onNodeSelect);
|
||||
gAudioNodes.off("remove", this._onDestroyNode);
|
||||
|
||||
@ -67,7 +76,7 @@ let InspectorView = {
|
||||
* Takes a AudioNodeView `node` and sets it as the current
|
||||
* node and scaffolds the inspector view based off of the new node.
|
||||
*/
|
||||
setCurrentAudioNode: function (node) {
|
||||
setCurrentAudioNode: Task.async(function* (node) {
|
||||
this._currentNode = node || null;
|
||||
|
||||
// If no node selected, set the inspector back to "no AudioNode selected"
|
||||
@ -81,10 +90,10 @@ let InspectorView = {
|
||||
else {
|
||||
$("#web-audio-editor-details-pane-empty").setAttribute("hidden", "true");
|
||||
$("#web-audio-editor-tabs").removeAttribute("hidden");
|
||||
this._setTitle();
|
||||
yield this._buildToolbar();
|
||||
window.emit(EVENTS.UI_INSPECTOR_NODE_SET, this._currentNode.id);
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Returns the current AudioNodeView.
|
||||
@ -104,14 +113,25 @@ let InspectorView = {
|
||||
this.hideImmediately();
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the title of the Inspector view
|
||||
*/
|
||||
_setTitle: function () {
|
||||
let node = this._currentNode;
|
||||
let title = node.type.replace(/Node$/, "");
|
||||
$("#web-audio-inspector-title").setAttribute("value", title);
|
||||
},
|
||||
_buildToolbar: Task.async(function* () {
|
||||
let node = this.getCurrentAudioNode();
|
||||
|
||||
let bypassable = node.bypassable;
|
||||
let bypassed = yield node.isBypassed();
|
||||
let button = $("#audio-node-toolbar .bypass");
|
||||
|
||||
if (!bypassable) {
|
||||
button.setAttribute("disabled", true);
|
||||
} else {
|
||||
button.removeAttribute("disabled");
|
||||
}
|
||||
|
||||
if (!bypassable || bypassed) {
|
||||
button.removeAttribute("checked");
|
||||
} else {
|
||||
button.setAttribute("checked", true);
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Event handlers
|
||||
@ -140,5 +160,26 @@ let InspectorView = {
|
||||
if (this._currentNode && this._currentNode.id === node.id) {
|
||||
this.setCurrentAudioNode(null);
|
||||
}
|
||||
},
|
||||
|
||||
_onCommandClick: function (e) {
|
||||
let node = this.getCurrentAudioNode();
|
||||
let button = e.target;
|
||||
let command = button.getAttribute("data-command");
|
||||
let checked = button.getAttribute("checked");
|
||||
|
||||
if (button.getAttribute("disabled")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (command === "bypass") {
|
||||
if (checked) {
|
||||
button.removeAttribute("checked");
|
||||
node.bypass(true);
|
||||
} else {
|
||||
button.setAttribute("checked", true);
|
||||
node.bypass(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -3,10 +3,10 @@
|
||||
- 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/. -->
|
||||
<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/content/devtools/widgets.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/devtools/common.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/devtools/widgets.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/devtools/webaudioeditor.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/content/devtools/widgets.css" type="text/css"?>
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % debuggerDTD SYSTEM "chrome://browser/locale/devtools/webaudioeditor.dtd">
|
||||
%debuggerDTD;
|
||||
@ -79,9 +79,6 @@
|
||||
</hbox>
|
||||
<splitter id="inspector-splitter" class="devtools-side-splitter"/>
|
||||
<vbox id="web-audio-inspector" hidden="true">
|
||||
<hbox class="devtools-toolbar">
|
||||
<label id="web-audio-inspector-title" value="&webAudioEditorUI.inspectorTitle;"></label>
|
||||
</hbox>
|
||||
<deck id="web-audio-editor-details-pane" flex="1">
|
||||
<vbox id="web-audio-editor-details-pane-empty" flex="1">
|
||||
<label value="&webAudioEditorUI.inspectorEmpty;"></label>
|
||||
@ -89,6 +86,13 @@
|
||||
<tabbox id="web-audio-editor-tabs"
|
||||
class="devtools-sidebar-tabs"
|
||||
handleCtrlTab="false">
|
||||
<toolbar id="audio-node-toolbar" class="devtools-toolbar">
|
||||
<hbox class="devtools-toolbarbutton-group">
|
||||
<toolbarbutton class="bypass devtools-toolbarbutton"
|
||||
data-command="bypass"
|
||||
tabindex="0"/>
|
||||
</hbox>
|
||||
</toolbar>
|
||||
<tabs>
|
||||
<tab id="properties-tab"
|
||||
label="&webAudioEditorUI.tab.properties;"/>
|
||||
|
@ -33,3 +33,7 @@ collapseInspector=Collapse inspector
|
||||
# that expands the inspector in the web audio tool UI.
|
||||
expandInspector=Expand inspector
|
||||
|
||||
# LOCALIZATION NOTE (webAudioEditorTooltipBypass): This is the tooltip for the
|
||||
# button that bypasses an AudioNode
|
||||
webAudioEditorTooltipBypass=Bypass AudioNode
|
||||
|
||||
|
@ -229,6 +229,7 @@ browser.jar:
|
||||
skin/classic/browser/devtools/newtab-inverted.png (../shared/devtools/images/newtab-inverted.png)
|
||||
skin/classic/browser/devtools/newtab-inverted@2x.png (../shared/devtools/images/newtab-inverted@2x.png)
|
||||
* skin/classic/browser/devtools/widgets.css (devtools/widgets.css)
|
||||
skin/classic/browser/devtools/power.svg (../shared/devtools/images/power.svg)
|
||||
skin/classic/browser/devtools/filetype-dir-close.svg (../shared/devtools/images/filetypes/dir-close.svg)
|
||||
skin/classic/browser/devtools/filetype-dir-open.svg (../shared/devtools/images/filetypes/dir-open.svg)
|
||||
skin/classic/browser/devtools/filetype-globe.svg (../shared/devtools/images/filetypes/globe.svg)
|
||||
|
@ -360,6 +360,7 @@ browser.jar:
|
||||
skin/classic/browser/devtools/newtab-inverted.png (../shared/devtools/images/newtab-inverted.png)
|
||||
skin/classic/browser/devtools/newtab-inverted@2x.png (../shared/devtools/images/newtab-inverted@2x.png)
|
||||
* skin/classic/browser/devtools/widgets.css (devtools/widgets.css)
|
||||
skin/classic/browser/devtools/power.svg (../shared/devtools/images/power.svg)
|
||||
skin/classic/browser/devtools/filetype-dir-close.svg (../shared/devtools/images/filetypes/dir-close.svg)
|
||||
skin/classic/browser/devtools/filetype-dir-open.svg (../shared/devtools/images/filetypes/dir-open.svg)
|
||||
skin/classic/browser/devtools/filetype-globe.svg (../shared/devtools/images/filetypes/globe.svg)
|
||||
|
@ -13,4 +13,15 @@
|
||||
<feFuncB type="table" tableValues=".6 0"/>
|
||||
</feComponentTransfer>
|
||||
</filter>
|
||||
|
||||
<!-- Web Audio Gradients -->
|
||||
<linearGradient id="bypass-light" x1="6%" y1="8%" x2="12%" y2="12%" spreadMethod="repeat">
|
||||
<stop offset="0%" stop-color="#f0f1f2"/> <!-- theme-toolbar-background -->
|
||||
<stop offset="50%" stop-color="#fff"/>
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="bypass-dark" x1="6%" y1="8%" x2="12%" y2="12%" spreadMethod="repeat">
|
||||
<stop offset="0%" stop-color="#343c45"/> <!-- theme-toolbar-background -->
|
||||
<stop offset="50%" stop-color="transparent"/>
|
||||
</linearGradient>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 592 B After Width: | Height: | Size: 1.1 KiB |
14
browser/themes/shared/devtools/images/power.svg
Normal file
14
browser/themes/shared/devtools/images/power.svg
Normal file
@ -0,0 +1,14 @@
|
||||
<!--
|
||||
Logo from raphaeljs.com, MIT License
|
||||
|
||||
Copyright © 2008 Dmitry Baranovskiy
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
The software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.
|
||||
-->
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke="#edf0f1" d="m10.89891,2.50043c-0.49827,-0.24134 -1.09841,-0.03411 -1.34129,0.46514c-0.24185,0.49928 -0.03311,1.09942 0.46517,1.34128c1.56306,0.76071 2.64193,2.36094 2.64092,4.21555c-0.00501,2.58626 -2.09749,4.6787 -4.68322,4.68321c-2.58623,-0.005 -4.67869,-2.09746 -4.68371,-4.68321c-0.001,-1.85561 1.07834,-3.45731 2.64294,-4.21654c0.49928,-0.24185 0.7065,-0.84201 0.46514,-1.34129c-0.24185,-0.49825 -0.84098,-0.70697 -1.34029,-0.46513c-2.23396,1.08135 -3.77446,3.37351 -3.77545,6.02296c0.00099,3.69518 2.99518,6.68989 6.69138,6.69088c3.6957,-0.00099 6.69037,-2.9957 6.69089,-6.69088c-0.00102,-2.64846 -1.53948,-4.9391 -3.77247,-6.02197zm-2.91842,4.9346c0.55398,0 1.00309,-0.44861 1.00309,-1.00357l0,-4.68373c0,-0.55446 -0.44911,-1.00309 -1.00309,-1.00309c-0.555,0 -1.00358,0.44911 -1.00358,1.00309l0,4.68321c0,0.55499 0.44858,1.00409 1.00358,1.00409z" stroke-width="0" fill="#edf0f1"/>
|
||||
</svg>
|
@ -81,13 +81,47 @@ g.edgePath.param-connection {
|
||||
|
||||
.nodes rect {
|
||||
stroke: var(--theme-tab-toolbar-background);
|
||||
}
|
||||
.theme-light rect {
|
||||
fill: var(--theme-tab-toolbar-background);
|
||||
}
|
||||
.theme-dark rect {
|
||||
fill: var(--theme-toolbar-background);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bypassed Nodes
|
||||
*/
|
||||
|
||||
.theme-light .nodes g.bypassed rect {
|
||||
fill: url(chrome://browser/skin/devtools/filters.svg#bypass-light);
|
||||
}
|
||||
.theme-dark .nodes g.bypassed rect {
|
||||
fill: url(chrome://browser/skin/devtools/filters.svg#bypass-dark);
|
||||
}
|
||||
.nodes g.bypassed.selected rect {
|
||||
stroke: var(--theme-selection-background);
|
||||
}
|
||||
|
||||
/*
|
||||
.nodes g.bypassed text {
|
||||
opacity: 0.8;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Selected Nodes
|
||||
*/
|
||||
.nodes g.selected rect {
|
||||
fill: var(--theme-selection-background);
|
||||
}
|
||||
|
||||
/* Don't style bypassed nodes text different because it'd be illegible in light-theme */
|
||||
.theme-light g.selected:not(.bypassed) text {
|
||||
fill: var(--theme-toolbar-background);
|
||||
}
|
||||
|
||||
|
||||
/* Text in nodes and edges */
|
||||
text {
|
||||
cursor: default; /* override the "text" cursor */
|
||||
@ -100,9 +134,6 @@ text {
|
||||
fill: var(--theme-body-color-alt);
|
||||
}
|
||||
|
||||
.theme-light g.selected text {
|
||||
fill: var(--theme-toolbar-background);
|
||||
}
|
||||
|
||||
.nodes text {
|
||||
cursor: pointer;
|
||||
@ -178,6 +209,32 @@ text {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspector toolbar
|
||||
*/
|
||||
|
||||
#audio-node-toolbar .bypass {
|
||||
list-style-image: url(power.svg);
|
||||
}
|
||||
|
||||
#audio-node-toolbar toolbarbutton[disabled] {
|
||||
opacity: 0.5;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.theme-dark #audio-node-toolbar toolbarbutton[checked] {
|
||||
background-color: #1d4f73; /* Select Highlight Blue */
|
||||
}
|
||||
.theme-light #audio-node-toolbar toolbarbutton[checked] {
|
||||
background-color: #4c9ed9; /* Select Highlight Blue */
|
||||
}
|
||||
|
||||
/* don't invert checked buttons so we can have white icons on light theme */
|
||||
#audio-node-toolbar toolbarbutton[checked] > .toolbarbutton-icon {
|
||||
filter: none;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Responsive Styles
|
||||
* `.devtools-responsive-container` takes care of most of
|
||||
|
@ -266,6 +266,7 @@ browser.jar:
|
||||
skin/classic/browser/devtools/newtab-inverted.png (../shared/devtools/images/newtab-inverted.png)
|
||||
skin/classic/browser/devtools/newtab-inverted@2x.png (../shared/devtools/images/newtab-inverted@2x.png)
|
||||
* skin/classic/browser/devtools/widgets.css (devtools/widgets.css)
|
||||
skin/classic/browser/devtools/power.svg (../shared/devtools/images/power.svg)
|
||||
skin/classic/browser/devtools/filetype-dir-close.svg (../shared/devtools/images/filetypes/dir-close.svg)
|
||||
skin/classic/browser/devtools/filetype-dir-open.svg (../shared/devtools/images/filetypes/dir-open.svg)
|
||||
skin/classic/browser/devtools/filetype-globe.svg (../shared/devtools/images/filetypes/globe.svg)
|
||||
@ -729,6 +730,7 @@ browser.jar:
|
||||
skin/classic/aero/browser/devtools/newtab-inverted.png (../shared/devtools/images/newtab-inverted.png)
|
||||
skin/classic/aero/browser/devtools/newtab-inverted@2x.png (../shared/devtools/images/newtab-inverted@2x.png)
|
||||
* skin/classic/aero/browser/devtools/widgets.css (devtools/widgets.css)
|
||||
skin/classic/aero/browser/devtools/power.svg (../shared/devtools/images/power.svg)
|
||||
skin/classic/aero/browser/devtools/filetype-dir-close.svg (../shared/devtools/images/filetypes/dir-close.svg)
|
||||
skin/classic/aero/browser/devtools/filetype-dir-open.svg (../shared/devtools/images/filetypes/dir-open.svg)
|
||||
skin/classic/aero/browser/devtools/filetype-globe.svg (../shared/devtools/images/filetypes/globe.svg)
|
||||
|
@ -39,7 +39,7 @@ if test $android_version -lt MIN_ANDROID_VERSION ; then
|
||||
fi
|
||||
|
||||
case "$target" in
|
||||
arm-linux*-android*|*-linuxandroid*)
|
||||
arm-*linux*-android*|*-linuxandroid*)
|
||||
android_tool_prefix="arm-linux-androideabi"
|
||||
;;
|
||||
i?86-*android*)
|
||||
|
@ -32,7 +32,7 @@ using dom::ConstrainLongRange;
|
||||
NS_IMPL_ISUPPORTS(MediaEngineTabVideoSource, nsIDOMEventListener, nsITimerCallback)
|
||||
|
||||
MediaEngineTabVideoSource::MediaEngineTabVideoSource()
|
||||
: mMonitor("MediaEngineTabVideoSource"), mTabSource(nullptr)
|
||||
: mData(NULL), mDataSize(0), mMonitor("MediaEngineTabVideoSource"), mTabSource(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@ -79,7 +79,6 @@ MediaEngineTabVideoSource::Notify(nsITimer*) {
|
||||
nsresult
|
||||
MediaEngineTabVideoSource::InitRunnable::Run()
|
||||
{
|
||||
mVideoSource->mData = (unsigned char*)malloc(mVideoSource->mBufW * mVideoSource->mBufH * 4);
|
||||
if (mVideoSource->mWindowId != -1) {
|
||||
nsCOMPtr<nsPIDOMWindow> window = nsGlobalWindow::GetOuterWindowWithId(mVideoSource->mWindowId);
|
||||
if (window) {
|
||||
@ -150,20 +149,10 @@ MediaEngineTabVideoSource::Allocate(const VideoTrackConstraintsN& aConstraints,
|
||||
}
|
||||
}
|
||||
|
||||
mBufW = aPrefs.GetWidth(false);
|
||||
mBufH = aPrefs.GetHeight(false);
|
||||
ConstrainLongRange defaultRange;
|
||||
|
||||
if (cWidth.mMin > mBufW) {
|
||||
mBufW = cWidth.mMin;
|
||||
} else if (cWidth.mMax < mBufW) {
|
||||
mBufW = cWidth.mMax;
|
||||
}
|
||||
|
||||
if (cHeight.mMin > mBufH) {
|
||||
mBufH = cHeight.mMin;
|
||||
} else if (cHeight.mMax < mBufH) {
|
||||
mBufH = cHeight.mMax;
|
||||
}
|
||||
mBufWidthMax = defaultRange.mMax > cWidth.mMax ? cWidth.mMax : aPrefs.GetWidth(false);
|
||||
mBufHeightMax = defaultRange.mMax > cHeight.mMax ? cHeight.mMax : aPrefs.GetHeight(false);
|
||||
|
||||
mTimePerFrame = aPrefs.mFPS ? 1000 / aPrefs.mFPS : aPrefs.mFPS;
|
||||
return NS_OK;
|
||||
@ -213,35 +202,38 @@ MediaEngineTabVideoSource::NotifyPull(MediaStreamGraph*,
|
||||
|
||||
void
|
||||
MediaEngineTabVideoSource::Draw() {
|
||||
|
||||
IntSize size(mBufW, mBufH);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mWindow);
|
||||
|
||||
if (!win) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t width, height;
|
||||
win->GetInnerWidth(&width);
|
||||
win->GetInnerHeight(&height);
|
||||
int32_t innerWidth, innerHeight;
|
||||
win->GetInnerWidth(&innerWidth);
|
||||
win->GetInnerHeight(&innerHeight);
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
if (innerWidth == 0 || innerHeight == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t srcW;
|
||||
int32_t srcH;
|
||||
|
||||
float aspectRatio = ((float) size.width) / size.height;
|
||||
if (width / aspectRatio < height) {
|
||||
srcW = width;
|
||||
srcH = width / aspectRatio;
|
||||
IntSize size;
|
||||
// maintain source aspect ratio
|
||||
if (mBufWidthMax/innerWidth < mBufHeightMax/innerHeight) {
|
||||
size = IntSize(mBufWidthMax, (mBufWidthMax * ((float) innerHeight/innerWidth)));
|
||||
} else {
|
||||
srcW = height * aspectRatio;
|
||||
srcH = height;
|
||||
size = IntSize((mBufHeightMax * ((float) innerWidth/innerHeight)), mBufHeightMax);
|
||||
}
|
||||
|
||||
gfxImageFormat format = gfxImageFormat::RGB24;
|
||||
uint32_t stride = gfxASurface::FormatStrideForWidth(format, size.width);
|
||||
|
||||
if (mDataSize < static_cast<size_t>(stride * size.height)) {
|
||||
mDataSize = stride * size.height;
|
||||
mData = static_cast<unsigned char*>(malloc(mDataSize));
|
||||
}
|
||||
|
||||
if (!mData) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<nsPresContext> presContext;
|
||||
@ -259,11 +251,8 @@ MediaEngineTabVideoSource::Draw() {
|
||||
if (!mScrollWithPage) {
|
||||
renderDocFlags |= nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
|
||||
}
|
||||
nsRect r(0, 0, nsPresContext::CSSPixelsToAppUnits((float)srcW),
|
||||
nsPresContext::CSSPixelsToAppUnits((float)srcH));
|
||||
|
||||
gfxImageFormat format = gfxImageFormat::RGB24;
|
||||
uint32_t stride = gfxASurface::FormatStrideForWidth(format, size.width);
|
||||
nsRect r(0, 0, nsPresContext::CSSPixelsToAppUnits((float)innerWidth),
|
||||
nsPresContext::CSSPixelsToAppUnits((float)innerHeight));
|
||||
|
||||
nsRefPtr<layers::ImageContainer> container = layers::LayerManager::CreateImageContainer();
|
||||
RefPtr<DrawTarget> dt =
|
||||
@ -276,12 +265,10 @@ MediaEngineTabVideoSource::Draw() {
|
||||
return;
|
||||
}
|
||||
nsRefPtr<gfxContext> context = new gfxContext(dt);
|
||||
context->SetMatrix(context->CurrentMatrix().Scale((float)size.width/srcW,
|
||||
(float)size.height/srcH));
|
||||
context->SetMatrix(context->CurrentMatrix().Scale((((float) size.width)/innerWidth),
|
||||
(((float) size.height)/innerHeight)));
|
||||
|
||||
rv = presShell->RenderDocument(r, renderDocFlags, bgColor, context);
|
||||
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
NS_ENSURE_SUCCESS_VOID(presShell->RenderDocument(r, renderDocFlags, bgColor, context));
|
||||
|
||||
RefPtr<SourceSurface> surface = dt->Snapshot();
|
||||
if (!surface) {
|
||||
|
@ -70,12 +70,13 @@ protected:
|
||||
~MediaEngineTabVideoSource() {}
|
||||
|
||||
private:
|
||||
int mBufW;
|
||||
int mBufH;
|
||||
int mBufWidthMax;
|
||||
int mBufHeightMax;
|
||||
int64_t mWindowId;
|
||||
bool mScrollWithPage;
|
||||
int mTimePerFrame;
|
||||
ScopedFreePtr<unsigned char> mData;
|
||||
size_t mDataSize;
|
||||
nsCOMPtr<nsIDOMWindow> mWindow;
|
||||
nsRefPtr<layers::CairoImage> mImage;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
|
@ -2923,6 +2923,7 @@ RilObject.prototype = {
|
||||
* @param command
|
||||
* @param deviceIdentities
|
||||
* @param resultCode
|
||||
* @param [optional] additionalInformation
|
||||
* @param [optional] itemIdentifier
|
||||
* @param [optional] input
|
||||
* @param [optional] isYesNo
|
||||
@ -2978,8 +2979,25 @@ RilObject.prototype = {
|
||||
// Result
|
||||
GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_RESULT |
|
||||
COMPREHENSIONTLV_FLAG_CR);
|
||||
if ("additionalInformation" in response) {
|
||||
// In |12.12 Result| TS 11.14, the length of additional information is
|
||||
// varied and all possible values are addressed in 12.12.1-11 of TS 11.14
|
||||
// and 8.12.1-13 in TS 31.111.
|
||||
// However,
|
||||
// 1. Only SEND SS requires info with more than 1 octet.
|
||||
// 2. In rild design, SEND SS is expected to be handled by modem and
|
||||
// UNSOLICITED_STK_EVENT_NOTIFY will be sent to application layer to
|
||||
// indicate appropriate messages to users. TR is not required in this
|
||||
// case.
|
||||
// Hence, we simplify the structure of |additionalInformation| to a
|
||||
// numeric value instead of a octet array.
|
||||
GsmPDUHelper.writeHexOctet(2);
|
||||
GsmPDUHelper.writeHexOctet(response.resultCode);
|
||||
GsmPDUHelper.writeHexOctet(response.additionalInformation);
|
||||
} else {
|
||||
GsmPDUHelper.writeHexOctet(1);
|
||||
GsmPDUHelper.writeHexOctet(response.resultCode);
|
||||
}
|
||||
|
||||
// Item Identifier
|
||||
if (response.itemIdentifier != null) {
|
||||
@ -3004,7 +3022,7 @@ RilObject.prototype = {
|
||||
text = response.input;
|
||||
}
|
||||
|
||||
if (text) {
|
||||
if (text !== undefined) {
|
||||
GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_TEXT_STRING |
|
||||
COMPREHENSIONTLV_FLAG_CR);
|
||||
|
||||
|
@ -156,6 +156,77 @@ add_test(function test_stk_terminal_response() {
|
||||
context.RIL.sendStkTerminalResponse(response);
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify STK terminal response : GET INPUT with empty string.
|
||||
*
|
||||
* @See |TERMINAL RESPONSE: GET INPUT 1.9.1A| of 27.22.4.3.1 GET INPUT (normal)
|
||||
* in TS 102 384.
|
||||
*/
|
||||
add_test(function test_stk_terminal_response_get_input_empty_string() {
|
||||
let worker = newUint8SupportOutgoingIndexWorker();
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let buf = context.Buf;
|
||||
let pduHelper = context.GsmPDUHelper;
|
||||
|
||||
buf.sendParcel = function() {
|
||||
// Type
|
||||
do_check_eq(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE);
|
||||
|
||||
// Token : we don't care
|
||||
this.readInt32();
|
||||
|
||||
// Data Size, 30 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) +
|
||||
// TLV_DEVICE_ID_SIZE(4) +
|
||||
// TLV_RESULT_SIZE(3) +
|
||||
// TEXT LENGTH(3))
|
||||
do_check_eq(this.readInt32(), 30);
|
||||
|
||||
// Command Details, Type-Length-Value
|
||||
do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS |
|
||||
COMPREHENSIONTLV_FLAG_CR);
|
||||
do_check_eq(pduHelper.readHexOctet(), 3);
|
||||
do_check_eq(pduHelper.readHexOctet(), 0x01);
|
||||
do_check_eq(pduHelper.readHexOctet(), STK_CMD_GET_INPUT);
|
||||
do_check_eq(pduHelper.readHexOctet(), 0x00);
|
||||
|
||||
// Device Identifies, Type-Length-Value(Source ID-Destination ID)
|
||||
do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID);
|
||||
do_check_eq(pduHelper.readHexOctet(), 2);
|
||||
do_check_eq(pduHelper.readHexOctet(), STK_DEVICE_ID_ME);
|
||||
do_check_eq(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
|
||||
|
||||
// Result
|
||||
do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_RESULT |
|
||||
COMPREHENSIONTLV_FLAG_CR);
|
||||
do_check_eq(pduHelper.readHexOctet(), 1);
|
||||
do_check_eq(pduHelper.readHexOctet(), STK_RESULT_OK);
|
||||
|
||||
// Text
|
||||
do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_TEXT_STRING |
|
||||
COMPREHENSIONTLV_FLAG_CR);
|
||||
do_check_eq(pduHelper.readHexOctet(), 1);
|
||||
do_check_eq(pduHelper.readHexOctet(), STK_TEXT_CODING_GSM_8BIT);
|
||||
|
||||
run_next_test();
|
||||
};
|
||||
|
||||
let response = {
|
||||
command: {
|
||||
commandNumber: 0x01,
|
||||
typeOfCommand: STK_CMD_GET_INPUT,
|
||||
commandQualifier: 0x00,
|
||||
options: {
|
||||
minLength: 0,
|
||||
maxLength: 1,
|
||||
defaultText: "<SEND>"
|
||||
}
|
||||
},
|
||||
input: "",
|
||||
resultCode: STK_RESULT_OK
|
||||
};
|
||||
context.RIL.sendStkTerminalResponse(response);
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify STK terminal response : GET_INKEY - YES/NO request
|
||||
*/
|
||||
@ -205,8 +276,6 @@ add_test(function test_stk_terminal_response_get_inkey() {
|
||||
do_check_eq(pduHelper.readHexOctet(), 2);
|
||||
do_check_eq(pduHelper.readHexOctet(), STK_TEXT_CODING_GSM_8BIT);
|
||||
do_check_eq(pduHelper.readHexOctet(), isYesNo ? 0x01 : 0x00);
|
||||
|
||||
run_next_test();
|
||||
};
|
||||
|
||||
let response = {
|
||||
@ -229,6 +298,73 @@ add_test(function test_stk_terminal_response_get_inkey() {
|
||||
do_test(true);
|
||||
// Test "No" response
|
||||
do_test(false);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify STK terminal response with additional information.
|
||||
*/
|
||||
add_test(function test_stk_terminal_response_with_additional_info() {
|
||||
function do_test(aInfo) {
|
||||
let worker = newUint8SupportOutgoingIndexWorker();
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let buf = context.Buf;
|
||||
let pduHelper = context.GsmPDUHelper;
|
||||
|
||||
buf.sendParcel = function() {
|
||||
// Type
|
||||
do_check_eq(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE);
|
||||
|
||||
// Token : we don't care
|
||||
this.readInt32();
|
||||
|
||||
// Data Length 26 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) +
|
||||
// TLV_DEVICE_ID_SIZE(4) +
|
||||
// TLV_RESULT_SIZE(4))
|
||||
do_check_eq(this.readInt32(), 26);
|
||||
|
||||
// Command Details, Type-Length-Value(commandNumber, typeOfCommand, commandQualifier)
|
||||
do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS |
|
||||
COMPREHENSIONTLV_FLAG_CR);
|
||||
do_check_eq(pduHelper.readHexOctet(), 3);
|
||||
do_check_eq(pduHelper.readHexOctet(), 0x01);
|
||||
do_check_eq(pduHelper.readHexOctet(), STK_CMD_DISPLAY_TEXT);
|
||||
do_check_eq(pduHelper.readHexOctet(), 0x01);
|
||||
|
||||
// Device Identifies, Type-Length-Value(Source ID-Destination ID)
|
||||
do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID);
|
||||
do_check_eq(pduHelper.readHexOctet(), 2);
|
||||
do_check_eq(pduHelper.readHexOctet(), STK_DEVICE_ID_ME);
|
||||
do_check_eq(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
|
||||
|
||||
// Result, Type-Length-Value(General result, Additional information on result)
|
||||
do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_RESULT |
|
||||
COMPREHENSIONTLV_FLAG_CR);
|
||||
do_check_eq(pduHelper.readHexOctet(), 2);
|
||||
do_check_eq(pduHelper.readHexOctet(), STK_RESULT_TERMINAL_CRNTLY_UNABLE_TO_PROCESS);
|
||||
do_check_eq(pduHelper.readHexOctet(), aInfo);
|
||||
};
|
||||
|
||||
let response = {
|
||||
command: {
|
||||
commandNumber: 0x01,
|
||||
typeOfCommand: STK_CMD_DISPLAY_TEXT,
|
||||
commandQualifier: 0x01,
|
||||
options: {
|
||||
isHighPriority: true
|
||||
}
|
||||
},
|
||||
resultCode: STK_RESULT_TERMINAL_CRNTLY_UNABLE_TO_PROCESS,
|
||||
additionalInformation: aInfo
|
||||
};
|
||||
|
||||
context.RIL.sendStkTerminalResponse(response);
|
||||
};
|
||||
|
||||
do_test(0x01); // 'Screen is busy'
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
// Test ComprehensionTlvHelper
|
||||
|
@ -149,6 +149,20 @@ interface MozIccManager : EventTarget
|
||||
/** Bearer independent protocol error */
|
||||
const unsigned short STK_RESULT_BIP_ERROR = 0x3a;
|
||||
|
||||
/**
|
||||
* Additional information on result:
|
||||
*
|
||||
* TS 11.14, 12.12.1-11 and TS 31.111,8.12.1-13 defines additional infomation
|
||||
* for different categories such as SEND SS, ME problem, network problem, etc.
|
||||
*
|
||||
* Note: We define these information here by category when needed.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 12.12.2 Additional information for ME problem:
|
||||
*/
|
||||
const unsigned short STK_ADDITIONAL_INFO_ME_PROBLEM_SCREEN_IS_BUSY = 0x01;
|
||||
|
||||
/**
|
||||
* STK event list.
|
||||
*/
|
||||
|
@ -90,7 +90,7 @@ dictionary MozStkTextMessage : MozStkIconContainer
|
||||
* or a low battery warning. In that situation, the resolution is left to
|
||||
* the terminal. If the command is rejected in spite of the high priority,
|
||||
* the terminal shall inform the ICC with resultCode is
|
||||
* TERMINAL_CRNTLY_UNABLE_TO_PROCESS in MozStkResponse.
|
||||
* MozIccManager.STK_RESULT_TERMINAL_CRNTLY_UNABLE_TO_PROCESS in MozStkResponse.
|
||||
*
|
||||
* true: high priority
|
||||
* false: normal priority
|
||||
@ -104,7 +104,7 @@ dictionary MozStkTextMessage : MozStkIconContainer
|
||||
*
|
||||
* If this attribute is true, but user doesn't give any input within a period
|
||||
* of time(said 30 secs), the terminal shall inform the ICC with resultCode
|
||||
* is NO_RESPONSE_FROM_USER in MozStkResponse.
|
||||
* is MozIccManager.STK_RESULT_NO_RESPONSE_FROM_USER in MozStkResponse.
|
||||
*
|
||||
* true: Wait for user to clear message.
|
||||
* false: clear message after a delay.
|
||||
@ -151,7 +151,7 @@ dictionary MozStkMenu : MozStkIconContainer
|
||||
sequence<MozStkItem> items;
|
||||
|
||||
/**
|
||||
* Presentation type, one of TYPE_*.
|
||||
* Presentation type, one of MozIccManager.STK_MENU_TYPE_*.
|
||||
*/
|
||||
unsigned short presentationType;
|
||||
|
||||
@ -177,10 +177,10 @@ dictionary MozStkMenu : MozStkIconContainer
|
||||
|
||||
/**
|
||||
* List of Next Action Indicators.
|
||||
* Each element should be one of nsIDOMMozIccManager.STK_CMD_*
|
||||
* or nsIDOMMozIccManager.STK_NEXT_ACTION_*
|
||||
* If it's STK_NEXT_ACTION_NULL, the terminal should ignore this action
|
||||
* in corresponding item.
|
||||
* Each element should be one of MozIccManager.STK_CMD_*
|
||||
* or MozIccManager.STK_NEXT_ACTION_*
|
||||
* If it's MozIccManager.STK_NEXT_ACTION_NULL, the terminal should ignore this
|
||||
* action in corresponding item.
|
||||
*
|
||||
* @see TS 11.14, clause 12.24, Items Next Action Indicator.
|
||||
*/
|
||||
@ -293,9 +293,7 @@ dictionary MozStkBrowserSetting
|
||||
DOMString url;
|
||||
|
||||
/**
|
||||
* One of STK_BROWSER_MODE_*.
|
||||
*
|
||||
* @see nsIDOMMozIccManager.STK_BROWSER_MODE_*
|
||||
* One of MozIccManager.STK_BROWSER_MODE_*.
|
||||
*/
|
||||
unsigned short mode;
|
||||
};
|
||||
@ -332,7 +330,7 @@ dictionary MozStkSetUpEventList
|
||||
* When this valus is null, means an indication to remove the existing list
|
||||
* of events in ME.
|
||||
*
|
||||
* @see nsIDOMMozIccManager.STK_EVENT_TYPE_*
|
||||
* @see MozIccManager.STK_EVENT_TYPE_*
|
||||
*/
|
||||
sequence<unsigned short> eventList;
|
||||
};
|
||||
@ -363,7 +361,7 @@ dictionary MozStkLocationInfo
|
||||
dictionary MozStkDuration
|
||||
{
|
||||
/**
|
||||
* Time unit used, should be one of STK_TIME_UNIT_*.
|
||||
* Time unit used, should be one of MozIccManager.STK_TIME_UNIT_*.
|
||||
*/
|
||||
unsigned short timeUnit;
|
||||
|
||||
@ -381,7 +379,7 @@ dictionary MozStkPlayTone : MozStkIconContainer
|
||||
DOMString text;
|
||||
|
||||
/**
|
||||
* One of STK_TONE_TYPE_*.
|
||||
* One of MozIccManager.STK_TONE_TYPE_*.
|
||||
*/
|
||||
unsigned short tone;
|
||||
|
||||
@ -403,10 +401,10 @@ dictionary MozStkProvideLocalInfo
|
||||
/**
|
||||
* Indicate which local information is required.
|
||||
* It shall be one of following:
|
||||
* - nsIDOMMozIccManager.STK_LOCAL_INFO_LOCATION_INFO
|
||||
* - nsIDOMMozIccManager.STK_LOCAL_INFO_IMEI
|
||||
* - nsIDOMMozIccManager.STK_LOCAL_INFO_DATE_TIME_ZONE
|
||||
* - nsIDOMMozIccManager.STK_LOCAL_INFO_LANGUAGE
|
||||
* - MozIccManager.STK_LOCAL_INFO_LOCATION_INFO
|
||||
* - MozIccManager.STK_LOCAL_INFO_IMEI
|
||||
* - MozIccManager.STK_LOCAL_INFO_DATE_TIME_ZONE
|
||||
* - MozIccManager.STK_LOCAL_INFO_LANGUAGE
|
||||
*/
|
||||
unsigned short localInfoType;
|
||||
};
|
||||
@ -415,23 +413,23 @@ dictionary MozStkLocationEvent
|
||||
{
|
||||
/**
|
||||
* The type of this event.
|
||||
* It shall be nsIDOMMozIccManager.STK_EVENT_TYPE_LOCATION_STATUS;
|
||||
* It shall be MozIccManager.STK_EVENT_TYPE_LOCATION_STATUS;
|
||||
*/
|
||||
unsigned short eventType;
|
||||
|
||||
/**
|
||||
* Indicate current service state of the MS with one of the values listed
|
||||
* below:
|
||||
* - nsIDOMMozIccManager.STK_SERVICE_STATE_NORMAL
|
||||
* - nsIDOMMozIccManager.STK_SERVICE_STATE_LIMITED
|
||||
* - nsIDOMMozIccManager.STK_SERVICE_STATE_UNAVAILABLE
|
||||
* - MozIccManager.STK_SERVICE_STATE_NORMAL
|
||||
* - MozIccManager.STK_SERVICE_STATE_LIMITED
|
||||
* - MozIccManager.STK_SERVICE_STATE_UNAVAILABLE
|
||||
*/
|
||||
unsigned short locationStatus;
|
||||
|
||||
/**
|
||||
* See MozStkLocationInfo.
|
||||
* This value shall only be provided if the locationStatus indicates
|
||||
* 'STK_SERVICE_STATE_NORMAL'.
|
||||
* MozIccManager.STK_SERVICE_STATE_NORMAL.
|
||||
*/
|
||||
MozStkLocationInfo locationInfo;
|
||||
};
|
||||
@ -452,9 +450,9 @@ dictionary MozStkTimer
|
||||
/**
|
||||
* The action requested from UICC.
|
||||
* It shall be one of below:
|
||||
* - nsIDOMMozIccManager.STK_TIMER_START
|
||||
* - nsIDOMMozIccManager.STK_TIMER_DEACTIVATE
|
||||
* - nsIDOMMozIccManager.STK_TIMER_GET_CURRENT_VALUE
|
||||
* - MozIccManager.STK_TIMER_START
|
||||
* - MozIccManager.STK_TIMER_DEACTIVATE
|
||||
* - MozIccManager.STK_TIMER_GET_CURRENT_VALUE
|
||||
*/
|
||||
unsigned short timerAction;
|
||||
};
|
||||
@ -478,7 +476,7 @@ dictionary MozStkCommand
|
||||
unsigned short commandNumber;
|
||||
|
||||
/**
|
||||
* One of STK_CMD_*
|
||||
* One of MozIccManager.STK_CMD_*
|
||||
*/
|
||||
unsigned short typeOfCommand;
|
||||
|
||||
@ -491,62 +489,62 @@ dictionary MozStkCommand
|
||||
* options varies accrording to the typeOfCommand in MozStkCommand.
|
||||
*
|
||||
* When typeOfCommand is
|
||||
* - STK_CMD_DISPLAY_TEXT
|
||||
* - STK_CMD_SET_UP_IDLE_MODE_TEXT
|
||||
* - STK_CMD_SEND_{SS|USSD|SMS|DTMF},
|
||||
* - MozIccManager.STK_CMD_DISPLAY_TEXT
|
||||
* - MozIccManager.STK_CMD_SET_UP_IDLE_MODE_TEXT
|
||||
* - MozIccManager.STK_CMD_SEND_{SS|USSD|SMS|DTMF},
|
||||
* options is MozStkTextMessage.
|
||||
*
|
||||
* When typeOfCommand is
|
||||
* - STK_CMD_SELECT_ITEM
|
||||
* - STK_CMD_SET_UP_MENU
|
||||
* - MozIccManager.STK_CMD_SELECT_ITEM
|
||||
* - MozIccManager.STK_CMD_SET_UP_MENU
|
||||
* options is MozStkMenu.
|
||||
*
|
||||
* When typeOfCommand is
|
||||
* - STK_CMD_GET_INKEY
|
||||
* - STK_CMD_GET_INPUT,
|
||||
* - MozIccManager.STK_CMD_GET_INKEY
|
||||
* - MozIccManager.STK_CMD_GET_INPUT,
|
||||
* options is MozStkInput.
|
||||
*
|
||||
* When typeOfCommand is
|
||||
* - STK_CMD_LAUNCH_BROWSER
|
||||
* - MozIccManager.STK_CMD_LAUNCH_BROWSER
|
||||
* options is MozStkBrowserSetting.
|
||||
*
|
||||
* When typeOfCommand is
|
||||
* - STK_CMD_SET_UP_CALL
|
||||
* - MozIccManager.STK_CMD_SET_UP_CALL
|
||||
* options is MozStkSetUpCall.
|
||||
*
|
||||
* When typeOfCommand is
|
||||
* - STK_CMD_SET_UP_EVENT_LIST
|
||||
* - MozIccManager.STK_CMD_SET_UP_EVENT_LIST
|
||||
* options is MozStkSetUpEventList.
|
||||
*
|
||||
* When typeOfCommand is
|
||||
* - STK_CMD_PLAY_TONE
|
||||
* - MozIccManager.STK_CMD_PLAY_TONE
|
||||
* options is MozStkPlayTone.
|
||||
*
|
||||
* When typeOfCommand is
|
||||
* - STK_CMD_POLL_INTERVAL
|
||||
* - MozIccManager.STK_CMD_POLL_INTERVAL
|
||||
* options is MozStkDuration.
|
||||
*
|
||||
* When typeOfCommand is
|
||||
* - STK_CMD_PROVIDE_LOCAL_INFO
|
||||
* - MozIccManager.STK_CMD_PROVIDE_LOCAL_INFO
|
||||
* options is MozStkProvideLocalInfo.
|
||||
*
|
||||
* When typeOfCommand is
|
||||
* - STK_CMD_TIMER_MANAGEMENT
|
||||
* - MozIccManager.STK_CMD_TIMER_MANAGEMENT
|
||||
* option is MozStkTimer
|
||||
*
|
||||
* When typeOfCommand is
|
||||
* - STK_CMD_OPEN_CHANNEL
|
||||
* - STK_CMD_CLOSE_CHANNEL
|
||||
* - STK_CMD_SEND_DATA
|
||||
* - STK_CMD_RECEIVE_DATA
|
||||
* - MozIccManager.STK_CMD_OPEN_CHANNEL
|
||||
* - MozIccManager.STK_CMD_CLOSE_CHANNEL
|
||||
* - MozIccManager.STK_CMD_SEND_DATA
|
||||
* - MozIccManager.STK_CMD_RECEIVE_DATA
|
||||
* options is MozStkBipMessage
|
||||
*
|
||||
* When typeOfCommand is
|
||||
* - STK_CMD_POLL_OFF
|
||||
* - MozIccManager.STK_CMD_POLL_OFF
|
||||
* options is null.
|
||||
*
|
||||
* When typeOfCommand is
|
||||
* - STK_CMD_REFRESH
|
||||
* - MozIccManager.STK_CMD_REFRESH
|
||||
* options is null.
|
||||
*/
|
||||
any options;
|
||||
@ -555,10 +553,15 @@ dictionary MozStkCommand
|
||||
dictionary MozStkResponse
|
||||
{
|
||||
/**
|
||||
* One of RESULT_*
|
||||
* One of MozIccManager.STK_RESULT_*
|
||||
*/
|
||||
unsigned short resultCode;
|
||||
|
||||
/**
|
||||
* One of MozIccManager.STK_ADDITIONAL_INFO_*
|
||||
*/
|
||||
unsigned short additionalInformation;
|
||||
|
||||
/**
|
||||
* The identifier of the item selected by user.
|
||||
*
|
||||
@ -579,7 +582,8 @@ dictionary MozStkResponse
|
||||
boolean isYesNo;
|
||||
|
||||
/**
|
||||
* User has confirmed or rejected the call during STK_CMD_CALL_SET_UP.
|
||||
* User has confirmed or rejected the call during
|
||||
* MozIccManager.STK_CMD_CALL_SET_UP.
|
||||
*
|
||||
* @see RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM
|
||||
*
|
||||
@ -589,15 +593,16 @@ dictionary MozStkResponse
|
||||
boolean hasConfirmed;
|
||||
|
||||
/**
|
||||
* The response for STK_CMD_PROVIDE_LOCAL_INFO
|
||||
* The response for MozIccManager.STK_CMD_PROVIDE_LOCAL_INFO
|
||||
*/
|
||||
MozStkLocalInfo localInfo;
|
||||
|
||||
/**
|
||||
* The response for STK_CMD_TIMER_MANAGEMENT.
|
||||
* The 'timerValue' is needed if the action of STK_CMD_TIMER_MANAGEMENT is
|
||||
* 'STK_TIMER_DEACTIVATE' or 'STK_TIMER_GET_CURRENT_VALUE'. It shall state
|
||||
* the current value of a timer. And the resolution is 1 second.
|
||||
* The response for MozIccManager.STK_CMD_TIMER_MANAGEMENT.
|
||||
* The 'timerValue' is needed if the action of
|
||||
* MozIccManager.STK_CMD_TIMER_MANAGEMENT is MozIccManager.STK_TIMER_DEACTIVATE
|
||||
* or MozIccManager.STK_TIMER_GET_CURRENT_VALUE.
|
||||
* It shall state the current value of a timer. And the resolution is 1 second.
|
||||
*/
|
||||
MozStkTimer timer;
|
||||
};
|
||||
@ -607,9 +612,9 @@ dictionary MozStkCallEvent
|
||||
/**
|
||||
* The type of this event.
|
||||
* It shall be one of following:
|
||||
* - nsIDOMMozIccManager.STK_EVENT_TYPE_MT_CALL,
|
||||
* - nsIDOMMozIccManager.STK_EVENT_TYPE_CALL_CONNECTED,
|
||||
* - nsIDOMMozIccManager.STK_EVENT_TYPE_CALL_DISCONNECTED.
|
||||
* - MozIccManager.STK_EVENT_TYPE_MT_CALL,
|
||||
* - MozIccManager.STK_EVENT_TYPE_CALL_CONNECTED,
|
||||
* - MozIccManager.STK_EVENT_TYPE_CALL_DISCONNECTED.
|
||||
*/
|
||||
unsigned short eventType;
|
||||
|
||||
@ -619,19 +624,20 @@ dictionary MozStkCallEvent
|
||||
DOMString number;
|
||||
|
||||
/**
|
||||
* This field is available in 'STK_EVENT_TYPE_CALL_CONNECTED' and
|
||||
* 'STK_EVENT_TYPE_CALL_DISCONNECTED' events.
|
||||
* For the STK_EVENT_TYPE_CALL_CONNECTED event, setting this to true means the
|
||||
* connection is answered by remote end, that is, this is an outgoing call.
|
||||
* For the STK_EVENT_TYPE_CALL_DISCONNECTED event, setting this to true
|
||||
* indicates the connection is hung up by remote.
|
||||
* This field is available in MozIccManager.STK_EVENT_TYPE_CALL_CONNECTED and
|
||||
* MozIccManager.STK_EVENT_TYPE_CALL_DISCONNECTED events.
|
||||
* For the MozIccManager.STK_EVENT_TYPE_CALL_CONNECTED event, setting this to
|
||||
* true means the connection is answered by remote end, that is, this is an
|
||||
* outgoing call.
|
||||
* For the MozIccManager.STK_EVENT_TYPE_CALL_DISCONNECTED event, setting this
|
||||
* to true indicates the connection is hung up by remote.
|
||||
*/
|
||||
boolean isIssuedByRemote;
|
||||
|
||||
/**
|
||||
* This field is available in Call Disconnected event to indicate the cause
|
||||
* of disconnection. The cause string is passed to gaia through the error
|
||||
* listener of nsIDOMCallEvent. Null if there's no error.
|
||||
* listener of CallEvent. Null if there's no error.
|
||||
*/
|
||||
DOMString error;
|
||||
};
|
||||
@ -665,7 +671,7 @@ dictionary MozStkLanguageSelectionEvent
|
||||
{
|
||||
/**
|
||||
* The type of this event.
|
||||
* It shall be nsIDOMMozIccManager.STK_EVENT_TYPE_LANGUAGE_SELECTION.
|
||||
* It shall be MozIccManager.STK_EVENT_TYPE_LANGUAGE_SELECTION.
|
||||
*/
|
||||
unsigned short eventType;
|
||||
|
||||
@ -682,15 +688,15 @@ dictionary MozStkBrowserTerminationEvent
|
||||
{
|
||||
/**
|
||||
* The type of this event.
|
||||
* It shall be nsIDOMMozIccManager.STK_EVENT_TYPE_BROWSER_TERMINATION
|
||||
* It shall be MozIccManager.STK_EVENT_TYPE_BROWSER_TERMINATION
|
||||
*/
|
||||
unsigned short eventType;
|
||||
|
||||
/**
|
||||
* This object shall contain the browser termination cause.
|
||||
* See TZ 102 223 8.51. It shall be one of following:
|
||||
* - nsIDOMMozIccManager.STK_BROWSER_TERMINATION_CAUSE_USER
|
||||
* - nsIDOMMozIccManager.STK_BROWSER_TERMINATION_CAUSE_ERROR
|
||||
* - MozIccManager.STK_BROWSER_TERMINATION_CAUSE_USER
|
||||
* - MozIccManager.STK_BROWSER_TERMINATION_CAUSE_ERROR
|
||||
*/
|
||||
unsigned short terminationCause;
|
||||
};
|
||||
@ -700,8 +706,8 @@ dictionary MozStkGeneralEvent
|
||||
/**
|
||||
* The type of this event, MozStkGeneralEvent can be used for all Stk Event
|
||||
* requires no more parameter than event type, including
|
||||
* nsIDOMMozIccManager.STK_EVENT_TYPE_USER_ACTIVITY.
|
||||
* nsIDOMMozIccManager.STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE.
|
||||
* MozIccManager.STK_EVENT_TYPE_USER_ACTIVITY.
|
||||
* MozIccManager.STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE.
|
||||
* HCI Connectivity Event(Not defined in interface yet).
|
||||
*/
|
||||
unsigned short eventType;
|
||||
|
@ -11179,248 +11179,250 @@
|
||||
46753a52402,52403
|
||||
> terahertz/M
|
||||
> terapixel/MS
|
||||
46806,46807c52456
|
||||
46756a52407
|
||||
> teriyaki
|
||||
46806,46807c52457
|
||||
< test's/AFK
|
||||
< test/AKFCDGS
|
||||
---
|
||||
> test/AKFCDGSM
|
||||
46817a52467
|
||||
46817a52468
|
||||
> testcase/MS
|
||||
46831a52482
|
||||
46831a52483
|
||||
> testsuite/MS
|
||||
46845a52497
|
||||
46845a52498
|
||||
> textbox/SM
|
||||
46925a52578
|
||||
46925a52579
|
||||
> theremin/MS
|
||||
46999c52652
|
||||
46999c52653
|
||||
< thinking's
|
||||
---
|
||||
> thinking/M
|
||||
47095,47096c52748
|
||||
47095,47096c52749
|
||||
< throne's
|
||||
< throne/CDS
|
||||
---
|
||||
> throne/CDSM
|
||||
47188,47189c52840
|
||||
47188,47189c52841
|
||||
< tie's
|
||||
< tie/AUSD
|
||||
---
|
||||
> tie/AUSDM
|
||||
47213,47214c52864
|
||||
47213,47214c52865
|
||||
< till's
|
||||
< till/EDRZGS
|
||||
---
|
||||
> till/EDRZGSM
|
||||
47303,47304c52953
|
||||
47303,47304c52954
|
||||
< tire's
|
||||
< tire/AGDS
|
||||
---
|
||||
> tire/AGDSM
|
||||
47433,47434c53082
|
||||
47433,47434c53083
|
||||
< tone's
|
||||
< tone/IZGDRS
|
||||
---
|
||||
> tone/IZGDRSM
|
||||
47453,47455c53101,53102
|
||||
47453,47455c53102,53103
|
||||
< tool's
|
||||
< tool/ADGS
|
||||
< toolbar
|
||||
---
|
||||
> tool/ADGSM
|
||||
> toolbar/MS
|
||||
47540,47541c53187
|
||||
47540,47541c53188
|
||||
< tort's
|
||||
< tort/FEAS
|
||||
---
|
||||
> tort/FEASM
|
||||
47644a53291
|
||||
47644a53292
|
||||
> traceur/SM
|
||||
47657,47658c53304
|
||||
47657,47658c53305
|
||||
< tract's
|
||||
< tract/CEKFAS
|
||||
---
|
||||
> tract/CEKFASM
|
||||
47755a53402
|
||||
47755a53403
|
||||
> transfect/DSMG
|
||||
47774a53422,53423
|
||||
47774a53423,53424
|
||||
> transgenderism
|
||||
> transgene/MS
|
||||
47807,47808c53456
|
||||
47807,47808c53457
|
||||
< transmission's
|
||||
< transmission/AS
|
||||
---
|
||||
> transmission/ASM
|
||||
47928,47929c53576
|
||||
47928,47929c53577
|
||||
< trench's
|
||||
< trench/AIGSD
|
||||
---
|
||||
> trench/AIGSDM
|
||||
47951c53598
|
||||
47951c53599
|
||||
< triage/M
|
||||
---
|
||||
> triage/MGS
|
||||
47976,47977c53623
|
||||
47976,47977c53624
|
||||
< tribute's
|
||||
< tribute/FS
|
||||
---
|
||||
> tribute/FSM
|
||||
47997a53644
|
||||
47997a53645
|
||||
> trifecta/S
|
||||
48165,48166c53812
|
||||
48165,48166c53813
|
||||
< trust's/E
|
||||
< trust/IESGD
|
||||
---
|
||||
> trust/IESGDM
|
||||
48180,48181c53826
|
||||
48180,48181c53827
|
||||
< try's
|
||||
< try/AGDS
|
||||
---
|
||||
> try/AGDSM
|
||||
48271a53917
|
||||
48271a53918
|
||||
> turducken
|
||||
48334a53981
|
||||
48334a53982
|
||||
> tweep/S
|
||||
48371,48372c54018
|
||||
48371,48372c54019
|
||||
< twist's
|
||||
< twist/USDG
|
||||
---
|
||||
> twist/USDGM
|
||||
48396,48397c54042
|
||||
48396,48397c54043
|
||||
< type's
|
||||
< type/AGDS
|
||||
---
|
||||
> type/AGDSM
|
||||
48869a54515
|
||||
48869a54516
|
||||
> unlikeable
|
||||
49163,49164c54809
|
||||
49163,49164c54810
|
||||
< usual's
|
||||
< usual/UY
|
||||
---
|
||||
> usual/UYM
|
||||
49211c54856
|
||||
49211c54857
|
||||
< vagina/M
|
||||
---
|
||||
> vagina/MS
|
||||
49249,49250c54894
|
||||
49249,49250c54895
|
||||
< value's
|
||||
< value/CAGSD
|
||||
---
|
||||
> value/CAGSDM
|
||||
49292,49293c54936
|
||||
49292,49293c54937
|
||||
< variant's
|
||||
< variant/IS
|
||||
---
|
||||
> variant/ISM
|
||||
49356,49357c54999
|
||||
49356,49357c55000
|
||||
< veil's
|
||||
< veil/UDGS
|
||||
---
|
||||
> veil/UDGSM
|
||||
49368,49369c55010
|
||||
49368,49369c55011
|
||||
< velour's
|
||||
< velours's
|
||||
---
|
||||
> velour/MS
|
||||
49398,49399c55039
|
||||
49398,49399c55040
|
||||
< vent's
|
||||
< vent/DGS
|
||||
---
|
||||
> vent/DGSM
|
||||
49435,49436c55075
|
||||
49435,49436c55076
|
||||
< verge's
|
||||
< verge/FDSG
|
||||
---
|
||||
> verge/FDSGM
|
||||
49478a55118
|
||||
49478a55119
|
||||
> vertices
|
||||
49488,49489c55128
|
||||
49488,49489c55129
|
||||
< vest's
|
||||
< vest/ILDGS
|
||||
---
|
||||
> vest/ILDGSM
|
||||
49681,49682c55320
|
||||
49681,49682c55321
|
||||
< visit's
|
||||
< visit/ASGD
|
||||
---
|
||||
> visit/ASGDM
|
||||
49772a55411,55413
|
||||
49772a55412,55414
|
||||
> volcanological
|
||||
> volcanologist/MS
|
||||
> volcanology/M
|
||||
49807,49808c55448
|
||||
49807,49808c55449
|
||||
< vote's
|
||||
< vote/CGVDS
|
||||
---
|
||||
> vote/CGVDSM
|
||||
50148a55789
|
||||
50148a55790
|
||||
> weaponize/DSG
|
||||
50215,50216c55856
|
||||
50215,50216c55857
|
||||
< weigh's
|
||||
< weigh/AGD
|
||||
---
|
||||
> weigh/AGDM
|
||||
50260,50261d55899
|
||||
50260,50261d55900
|
||||
< werwolf/M
|
||||
< werwolves
|
||||
50555,50556c56193
|
||||
50555,50556c56194
|
||||
< wind's
|
||||
< wind/UASG
|
||||
---
|
||||
> wind/UASGM
|
||||
50626,50627c56263
|
||||
50626,50627c56264
|
||||
< wire's
|
||||
< wire/AGDS
|
||||
---
|
||||
> wire/AGDSM
|
||||
50728c56364
|
||||
50728c56365
|
||||
< women
|
||||
---
|
||||
> women/M
|
||||
50794,50796c56430,56431
|
||||
50794,50796c56431,56432
|
||||
< wop/S!
|
||||
< word's
|
||||
< word/AJDSG
|
||||
---
|
||||
> wop/MS!
|
||||
> word/AJDSGM
|
||||
50801c56436
|
||||
50801c56437
|
||||
< wording's
|
||||
---
|
||||
> wording/M
|
||||
50808,50809c56443
|
||||
50808,50809c56444
|
||||
< work's
|
||||
< work/ADJSG
|
||||
---
|
||||
> work/ADJSGM
|
||||
50824c56458
|
||||
50824c56459
|
||||
< working's
|
||||
---
|
||||
> working/M
|
||||
50884,50885c56518
|
||||
50884,50885c56519
|
||||
< worthy's
|
||||
< worthy/UPRT
|
||||
---
|
||||
> worthy/UPRTM
|
||||
50903,50904c56536
|
||||
50903,50904c56537
|
||||
< wrap's
|
||||
< wrap/US
|
||||
---
|
||||
> wrap/USM
|
||||
50945c56577
|
||||
50945c56578
|
||||
< writing's
|
||||
---
|
||||
> writing/M
|
||||
51118,51119c56750
|
||||
51118,51119c56751
|
||||
< yoke's
|
||||
< yoke/UGDS
|
||||
---
|
||||
> yoke/UGDSM
|
||||
51212,51213c56843
|
||||
51212,51213c56844
|
||||
< zip's
|
||||
< zip/US
|
||||
---
|
||||
> zip/USM
|
||||
51228,51229c56858
|
||||
51228,51229c56859
|
||||
< zone's
|
||||
< zone/AGDS
|
||||
---
|
||||
|
@ -1,4 +1,4 @@
|
||||
57245
|
||||
57246
|
||||
0/nm
|
||||
0th/pt
|
||||
1/n1
|
||||
@ -52757,6 +52757,7 @@ terapixel/MS
|
||||
terbium/M
|
||||
tercentenary/SM
|
||||
tercentennial/MS
|
||||
teriyaki
|
||||
term/MDYGS
|
||||
termagant/MS
|
||||
terminable/IC
|
||||
|
@ -250,7 +250,7 @@ class FilePickerResultHandler implements ActivityResultHandler {
|
||||
// will eventually does the cleanup for us.
|
||||
@Override
|
||||
public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) {
|
||||
if (tab.getId() != tabId) {
|
||||
if ((tab == null) || (tab.getId() != tabId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
#filter substitution
|
||||
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
|
||||
/* 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
|
||||
|
@ -1,4 +1,3 @@
|
||||
#filter substitution
|
||||
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
|
||||
/* 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
|
||||
@ -10,6 +9,7 @@ let Ci = Components.interfaces;
|
||||
let Cu = Components.utils;
|
||||
let Cr = Components.results;
|
||||
|
||||
Cu.import("resource://gre/modules/AppConstants.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/AddonManager.jsm");
|
||||
@ -17,9 +17,9 @@ Cu.import('resource://gre/modules/Payment.jsm');
|
||||
Cu.import("resource://gre/modules/NotificationDB.jsm");
|
||||
Cu.import("resource://gre/modules/SpatialNavigation.jsm");
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
if (AppConstants.ACCESSIBILITY) {
|
||||
Cu.import("resource://gre/modules/accessibility/AccessFu.jsm");
|
||||
#endif
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DownloadNotifications",
|
||||
"resource://gre/modules/DownloadNotifications.jsm");
|
||||
@ -57,10 +57,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerParent",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
|
||||
|
||||
#ifdef MOZ_SAFE_BROWSING
|
||||
if (AppConstants.MOZ_SAFE_BROWSING) {
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing",
|
||||
"resource://gre/modules/SafeBrowsing.jsm");
|
||||
#endif
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
|
||||
"resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
@ -87,10 +87,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SimpleServiceDiscovery",
|
||||
"resource://gre/modules/SimpleServiceDiscovery.jsm");
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
if (AppConstants.NIGHTLY_BUILD) {
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ShumwayUtils",
|
||||
"resource://shumway/ShumwayUtils.jsm");
|
||||
#endif
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "WebappManager",
|
||||
"resource://gre/modules/WebappManager.jsm");
|
||||
@ -113,8 +113,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "Notifications",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "GMPInstallManager",
|
||||
"resource://gre/modules/GMPInstallManager.jsm");
|
||||
|
||||
// Lazily-loaded browser scripts:
|
||||
[
|
||||
let lazilyLoadedBrowserScripts = [
|
||||
["SelectHelper", "chrome://browser/content/SelectHelper.js"],
|
||||
["InputWidgetHelper", "chrome://browser/content/InputWidgetHelper.js"],
|
||||
["MasterPassword", "chrome://browser/content/MasterPassword.js"],
|
||||
@ -123,10 +122,13 @@ XPCOMUtils.defineLazyModuleGetter(this, "GMPInstallManager",
|
||||
["Linkifier", "chrome://browser/content/Linkify.js"],
|
||||
["ZoomHelper", "chrome://browser/content/ZoomHelper.js"],
|
||||
["CastingApps", "chrome://browser/content/CastingApps.js"],
|
||||
#ifdef NIGHTLY_BUILD
|
||||
["WebcompatReporter", "chrome://browser/content/WebcompatReporter.js"],
|
||||
#endif
|
||||
].forEach(function (aScript) {
|
||||
];
|
||||
if (AppConstants.NIGHTLY_BUILD) {
|
||||
lazilyLoadedBrowserScripts.push(
|
||||
["WebcompatReporter", "chrome://browser/content/WebcompatReporter.js"]);
|
||||
}
|
||||
|
||||
lazilyLoadedBrowserScripts.forEach(function (aScript) {
|
||||
let [name, script] = aScript;
|
||||
XPCOMUtils.defineLazyGetter(window, name, function() {
|
||||
let sandbox = {};
|
||||
@ -135,10 +137,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "GMPInstallManager",
|
||||
});
|
||||
});
|
||||
|
||||
[
|
||||
#ifdef MOZ_WEBRTC
|
||||
["WebrtcUI", ["getUserMedia:request", "recording-device-events"], "chrome://browser/content/WebrtcUI.js"],
|
||||
#endif
|
||||
let lazilyLoadedObserverScripts = [
|
||||
["MemoryObserver", ["memory-pressure", "Memory:Dump"], "chrome://browser/content/MemoryObserver.js"],
|
||||
["ConsoleAPI", ["console-api-log-event"], "chrome://browser/content/ConsoleAPI.js"],
|
||||
["FindHelper", ["FindInPage:Opened", "FindInPage:Closed", "Tab:Selected"], "chrome://browser/content/FindHelper.js"],
|
||||
@ -148,7 +147,13 @@ XPCOMUtils.defineLazyModuleGetter(this, "GMPInstallManager",
|
||||
["SelectionHandler", ["TextSelection:Get"], "chrome://browser/content/SelectionHandler.js"],
|
||||
["EmbedRT", ["GeckoView:ImportScript"], "chrome://browser/content/EmbedRT.js"],
|
||||
["Reader", ["Reader:Added", "Reader:Removed", "Gesture:DoubleTap"], "chrome://browser/content/Reader.js"],
|
||||
].forEach(function (aScript) {
|
||||
];
|
||||
if (AppConstants.MOZ_WEBRTC) {
|
||||
lazilyLoadedObserverScripts.push(
|
||||
["WebrtcUI", ["getUserMedia:request", "recording-device-events"], "chrome://browser/content/WebrtcUI.js"])
|
||||
}
|
||||
|
||||
lazilyLoadedObserverScripts.forEach(function (aScript) {
|
||||
let [name, notifications, script] = aScript;
|
||||
XPCOMUtils.defineLazyGetter(window, name, function() {
|
||||
let sandbox = {};
|
||||
@ -227,10 +232,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "DOMUtils",
|
||||
XPCOMUtils.defineLazyServiceGetter(window, "URIFixup",
|
||||
"@mozilla.org/docshell/urifixup;1", "nsIURIFixup");
|
||||
|
||||
#ifdef MOZ_WEBRTC
|
||||
if (AppConstants.MOZ_WEBRTC) {
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "MediaManagerService",
|
||||
"@mozilla.org/mediaManagerService;1", "nsIMediaManagerService");
|
||||
#endif
|
||||
}
|
||||
|
||||
const kStateActive = 0x00000001; // :active pseudoclass for elements
|
||||
|
||||
@ -287,12 +292,6 @@ function convertFromTwipsToPx(aSize) {
|
||||
return aSize/240 * 16.0;
|
||||
}
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter",
|
||||
"@mozilla.org/xre/app-info;1", "nsICrashReporter");
|
||||
#endif
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "ContentAreaUtils", function() {
|
||||
let ContentAreaUtils = {};
|
||||
Services.scriptloader.loadSubScript("chrome://global/content/contentAreaUtils.js", ContentAreaUtils);
|
||||
@ -382,17 +381,18 @@ var BrowserApp = {
|
||||
}, 1000 * 60);
|
||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
|
||||
#ifdef MOZ_SAFE_BROWSING
|
||||
if (AppConstants.MOZ_SAFE_BROWSING) {
|
||||
Services.tm.mainThread.dispatch(function() {
|
||||
// Bug 778855 - Perf regression if we do this here. To be addressed in bug 779008.
|
||||
SafeBrowsing.init();
|
||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
#endif
|
||||
#ifdef NIGHTLY_BUILD
|
||||
}
|
||||
|
||||
if (AppConstants.NIGHTLY_BUILD) {
|
||||
WebcompatReporter.init();
|
||||
Telemetry.addData("TRACKING_PROTECTION_ENABLED",
|
||||
Services.prefs.getBoolPref("privacy.trackingprotection.enabled"));
|
||||
#endif
|
||||
}
|
||||
} catch(ex) { console.log(ex); }
|
||||
}, false);
|
||||
|
||||
@ -483,12 +483,12 @@ var BrowserApp = {
|
||||
Distribution.init();
|
||||
Tabs.init();
|
||||
SearchEngines.init();
|
||||
#ifdef ACCESSIBILITY
|
||||
if (AppConstants.ACCESSIBILITY) {
|
||||
AccessFu.attach(window);
|
||||
#endif
|
||||
#ifdef NIGHTLY_BUILD
|
||||
}
|
||||
if (AppConstants.NIGHTLY_BUILD) {
|
||||
ShumwayUtils.init();
|
||||
#endif
|
||||
}
|
||||
|
||||
let url = null;
|
||||
if ("arguments" in window) {
|
||||
@ -548,7 +548,7 @@ var BrowserApp = {
|
||||
savedMilestone = Services.prefs.getCharPref("browser.startup.homepage_override.mstone");
|
||||
} catch (e) {
|
||||
}
|
||||
#expand let ourMilestone = "__MOZ_APP_VERSION__";
|
||||
let ourMilestone = AppConstants.MOZ_APP_VERSION;
|
||||
this._startupStatus = "";
|
||||
if (ourMilestone != savedMilestone) {
|
||||
Services.prefs.setCharPref("browser.startup.homepage_override.mstone", ourMilestone);
|
||||
@ -1335,14 +1335,15 @@ var BrowserApp = {
|
||||
pref.value = MasterPassword.enabled;
|
||||
prefs.push(pref);
|
||||
continue;
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
// Crash reporter submit pref must be fetched from nsICrashReporter service.
|
||||
case "datareporting.crashreporter.submitEnabled":
|
||||
let crashReporterBuilt = "nsICrashReporter" in Ci && Services.appinfo instanceof Ci.nsICrashReporter;
|
||||
if (crashReporterBuilt) {
|
||||
pref.type = "bool";
|
||||
pref.value = CrashReporter.submitReports;
|
||||
pref.value = Services.appinfo.submitReports;
|
||||
prefs.push(pref);
|
||||
}
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
|
||||
try {
|
||||
@ -1421,12 +1422,14 @@ var BrowserApp = {
|
||||
Services.prefs.setBoolPref(SearchEngines.PREF_SUGGEST_PROMPTED, true);
|
||||
break;
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
// Crash reporter preference is in a service; set and return.
|
||||
case "datareporting.crashreporter.submitEnabled":
|
||||
CrashReporter.submitReports = json.value;
|
||||
let crashReporterBuilt = "nsICrashReporter" in Ci && Services.appinfo instanceof Ci.nsICrashReporter;
|
||||
if (crashReporterBuilt) {
|
||||
Services.appinfo.submitReports = json.value;
|
||||
}
|
||||
return;
|
||||
#endif
|
||||
|
||||
// When sending to Java, we normalized special preferences that use
|
||||
// integers and strings to represent booleans. Here, we convert them back
|
||||
// to their actual types so we can store them.
|
||||
@ -3066,8 +3069,7 @@ var DesktopUserAgent = {
|
||||
},
|
||||
|
||||
onRequest: function(channel, defaultUA) {
|
||||
#ifdef NIGHTLY_BUILD
|
||||
if (this.TCO_DOMAIN == channel.URI.host) {
|
||||
if (AppConstants.NIGHTLY_BUILD && this.TCO_DOMAIN == channel.URI.host) {
|
||||
// Force the referrer
|
||||
channel.referrer = channel.URI;
|
||||
|
||||
@ -3075,7 +3077,6 @@ var DesktopUserAgent = {
|
||||
// "Gecko/x.y Firefox/x.y" part
|
||||
return defaultUA.replace(this.TCO_REPLACE, "");
|
||||
}
|
||||
#endif
|
||||
|
||||
let channelWindow = this._getWindowForRequest(channel);
|
||||
let tab = BrowserApp.getTabForWindow(channelWindow);
|
||||
@ -5868,12 +5869,9 @@ let HealthReportStatusListener = {
|
||||
PREF_ACCEPT_LANG: "intl.accept_languages",
|
||||
PREF_BLOCKLIST_ENABLED: "extensions.blocklist.enabled",
|
||||
|
||||
PREF_TELEMETRY_ENABLED:
|
||||
#ifdef MOZ_TELEMETRY_REPORTING
|
||||
"toolkit.telemetry.enabled",
|
||||
#else
|
||||
PREF_TELEMETRY_ENABLED: AppConstants.MOZ_TELEMETRY_REPORTING ?
|
||||
"toolkit.telemetry.enabled" :
|
||||
null,
|
||||
#endif
|
||||
|
||||
init: function () {
|
||||
try {
|
||||
|
@ -24,18 +24,18 @@ chrome.jar:
|
||||
content/Reader.js (content/Reader.js)
|
||||
content/aboutHome.xhtml (content/aboutHome.xhtml)
|
||||
content/aboutRights.xhtml (content/aboutRights.xhtml)
|
||||
* content/aboutApps.xhtml (content/aboutApps.xhtml)
|
||||
* content/aboutApps.js (content/aboutApps.js)
|
||||
content/aboutApps.xhtml (content/aboutApps.xhtml)
|
||||
content/aboutApps.js (content/aboutApps.js)
|
||||
content/blockedSite.xhtml (content/blockedSite.xhtml)
|
||||
content/languages.properties (content/languages.properties)
|
||||
content/browser.xul (content/browser.xul)
|
||||
* content/browser.js (content/browser.js)
|
||||
content/browser.js (content/browser.js)
|
||||
content/bindings/checkbox.xml (content/bindings/checkbox.xml)
|
||||
content/bindings/settings.xml (content/bindings/settings.xml)
|
||||
content/netError.xhtml (content/netError.xhtml)
|
||||
content/SelectHelper.js (content/SelectHelper.js)
|
||||
content/SelectionHandler.js (content/SelectionHandler.js)
|
||||
* content/WebappRT.js (content/WebappRT.js)
|
||||
content/WebappRT.js (content/WebappRT.js)
|
||||
content/EmbedRT.js (content/EmbedRT.js)
|
||||
content/InputWidgetHelper.js (content/InputWidgetHelper.js)
|
||||
content/WebrtcUI.js (content/WebrtcUI.js)
|
||||
@ -53,7 +53,7 @@ chrome.jar:
|
||||
content/CastingApps.js (content/CastingApps.js)
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
content/aboutHealthReport.xhtml (content/aboutHealthReport.xhtml)
|
||||
* content/aboutHealthReport.js (content/aboutHealthReport.js)
|
||||
content/aboutHealthReport.js (content/aboutHealthReport.js)
|
||||
#endif
|
||||
#ifdef MOZ_DEVICES
|
||||
content/aboutDevices.xhtml (content/aboutDevices.xhtml)
|
||||
|
@ -3,8 +3,10 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/AppConstants.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
let modules = {
|
||||
// about:
|
||||
@ -30,11 +32,9 @@ let modules = {
|
||||
},
|
||||
|
||||
rights: {
|
||||
#ifdef MOZ_OFFICIAL_BRANDING
|
||||
uri: "chrome://browser/content/aboutRights.xhtml",
|
||||
#else
|
||||
uri: "chrome://global/content/aboutRights-unbranded.xhtml",
|
||||
#endif
|
||||
uri: AppConstants.MOZ_OFFICIAL_BRANDING ?
|
||||
"chrome://browser/content/aboutRights.xhtml" :
|
||||
"chrome://global/content/aboutRights-unbranded.xhtml",
|
||||
privileged: false
|
||||
},
|
||||
blocked: {
|
||||
@ -72,24 +72,25 @@ let modules = {
|
||||
uri: "chrome://browser/content/aboutPrivateBrowsing.xhtml",
|
||||
privileged: true
|
||||
},
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
healthreport: {
|
||||
}
|
||||
|
||||
if (AppConstants.MOZ_SERVICES_HEALTHREPORT) {
|
||||
modules['healthreport'] = {
|
||||
uri: "chrome://browser/content/aboutHealthReport.xhtml",
|
||||
privileged: true
|
||||
},
|
||||
#endif
|
||||
#ifdef MOZ_DEVICES
|
||||
devices: {
|
||||
};
|
||||
}
|
||||
if (AppConstants.MOZ_DEVICES) {
|
||||
modules['devices'] = {
|
||||
uri: "chrome://browser/content/aboutDevices.xhtml",
|
||||
privileged: true
|
||||
},
|
||||
#endif
|
||||
#ifdef NIGHTLY_BUILD
|
||||
passwords: {
|
||||
};
|
||||
}
|
||||
if (AppConstants.NIGHTLY_BUILD) {
|
||||
modules['passwords'] = {
|
||||
uri: "chrome://browser/content/aboutPasswords.xhtml",
|
||||
privileged: true
|
||||
}
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
function AboutRedirector() {}
|
||||
|
@ -2,12 +2,11 @@
|
||||
* 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/. */
|
||||
|
||||
#filter substitution
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/AppConstants.jsm");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
@ -27,7 +26,7 @@ const ENVVAR_UPDATE_DIR = "UPDATES_DIRECTORY";
|
||||
const WEBAPPS_DIR = "webappsDir";
|
||||
const DOWNLOAD_DIR = "DfltDwnld";
|
||||
|
||||
const SYSTEM_DIST_PATH = "/system/@ANDROID_PACKAGE_NAME@/distribution";
|
||||
const SYSTEM_DIST_PATH = `/system/${AppConstants.ANDROID_PACKAGE_NAME}/distribution`;
|
||||
|
||||
function DirectoryProvider() {}
|
||||
|
||||
@ -172,4 +171,3 @@ DirectoryProvider.prototype = {
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DirectoryProvider]);
|
||||
|
||||
|
@ -10,11 +10,6 @@ const Cr = Components.results;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter",
|
||||
"@mozilla.org/xre/app-info;1", "nsICrashReporter");
|
||||
#endif
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Messaging", "resource://gre/modules/Messaging.jsm");
|
||||
@ -565,7 +560,10 @@ SessionStore.prototype = {
|
||||
},
|
||||
|
||||
_updateCrashReportURL: function ss_updateCrashReportURL(aWindow) {
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
let crashReporterBuilt = "nsICrashReporter" in Ci && Services.appinfo instanceof Ci.nsICrashReporter;
|
||||
if (!crashReporterBuilt)
|
||||
return;
|
||||
|
||||
if (!aWindow.BrowserApp.selectedBrowser)
|
||||
return;
|
||||
|
||||
@ -577,14 +575,13 @@ SessionStore.prototype = {
|
||||
}
|
||||
catch (ex) { } // ignore failures on about: URIs
|
||||
|
||||
CrashReporter.annotateCrashReport("URL", currentURI.spec);
|
||||
Services.appinfo.annotateCrashReport("URL", currentURI.spec);
|
||||
}
|
||||
catch (ex) {
|
||||
// don't make noise when crashreporter is built but not enabled
|
||||
if (ex.result != Components.results.NS_ERROR_NOT_INITIALIZED)
|
||||
Components.utils.reportError("SessionStore:" + ex);
|
||||
if (ex.result != Cr.NS_ERROR_NOT_INITIALIZED)
|
||||
Cu.reportError("SessionStore:" + ex);
|
||||
}
|
||||
#endif
|
||||
},
|
||||
|
||||
_serializeHistoryEntry: function _serializeHistoryEntry(aEntry) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 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/.
|
||||
/* 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/. */
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
|
@ -11,16 +11,22 @@ XPIDL_SOURCES += [
|
||||
XPIDL_MODULE = 'MobileComponents'
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'AboutRedirector.js',
|
||||
'ActivitiesGlue.js',
|
||||
'AddonUpdateService.js',
|
||||
'BlocklistPrompt.js',
|
||||
'BrowserCLH.js',
|
||||
'ColorPicker.js',
|
||||
'ContentDispatchChooser.js',
|
||||
'ContentPermissionPrompt.js',
|
||||
'DirectoryProvider.js',
|
||||
'FilePicker.js',
|
||||
'HelperAppDialog.js',
|
||||
'LoginManagerPrompter.js',
|
||||
'NSSDialogService.js',
|
||||
'PromptService.js',
|
||||
'SessionStore.js',
|
||||
'Sidebar.js',
|
||||
'SiteSpecificUserAgent.js',
|
||||
'Snippets.js',
|
||||
'TabSource.js',
|
||||
@ -34,16 +40,10 @@ if CONFIG['MOZ_PAY']:
|
||||
'PaymentsUI.js'
|
||||
]
|
||||
|
||||
# Keep it this way if at all possible. If you need preprocessing,
|
||||
# consider adding fields to AppConstants.jsm.
|
||||
EXTRA_PP_COMPONENTS += [
|
||||
'AboutRedirector.js',
|
||||
'BrowserCLH.js',
|
||||
'DirectoryProvider.js',
|
||||
'HelperAppDialog.js',
|
||||
'MobileComponents.manifest',
|
||||
'SessionStore.js',
|
||||
'Sidebar.js',
|
||||
]
|
||||
|
||||
DEFINES['ANDROID_PACKAGE_NAME'] = CONFIG['ANDROID_PACKAGE_NAME']
|
||||
|
||||
DIRS += ['build']
|
||||
|
97
mobile/android/modules/AppConstants.jsm
Normal file
97
mobile/android/modules/AppConstants.jsm
Normal file
@ -0,0 +1,97 @@
|
||||
#filter substitution;
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["AppConstants"];
|
||||
|
||||
// Immutable for export.
|
||||
let AppConstants = Object.freeze({
|
||||
// See this wiki page for more details about channel specific build
|
||||
// defines: https://wiki.mozilla.org/Platform/Channel-specific_build_defines
|
||||
NIGHTLY_BUILD:
|
||||
#ifdef NIGHTLY_BUILD
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
RELEASE_BUILD:
|
||||
#ifdef RELEASE_BUILD
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
ACCESSIBILITY:
|
||||
#ifdef MOZ_ACCESSIBILITY
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
// Official corresponds, roughly, to whether this build is performed
|
||||
// on Mozilla's continuous integration infrastructure. You should
|
||||
// disable developer-only functionality when this flag is set.
|
||||
MOZILLA_OFFICIAL:
|
||||
#ifdef MOZILLA_OFFICIAL
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
MOZ_OFFICIAL_BRANDING:
|
||||
#ifdef MOZ_OFFICIAL_BRANDING
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
MOZ_SERVICES_HEALTHREPORT:
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
MOZ_DEVICES:
|
||||
#ifdef MOZ_DEVICES
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
MOZ_DEVICES:
|
||||
#ifdef MOZ_DEVICES
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
MOZ_SAFE_BROWSING:
|
||||
#ifdef MOZ_SAFE_BROWSING
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
MOZ_TELEMETRY_REPORTING:
|
||||
#ifdef MOZ_TELEMETRY_REPORTING
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
MOZ_WEBRTC:
|
||||
#ifdef MOZ_WEBRTC
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
MOZ_APP_VERSION: "@MOZ_APP_VERSION@",
|
||||
|
||||
ANDROID_PACKAGE_NAME: "@ANDROID_PACKAGE_NAME@",
|
||||
});
|
@ -41,30 +41,16 @@ TabMirror.prototype = {
|
||||
this._pc.onicecandidate = this._onIceCandidate.bind(this);
|
||||
|
||||
let windowId = this._window.BrowserApp.selectedBrowser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
|
||||
let viewport = this._window.BrowserApp.selectedTab.getViewport();
|
||||
let maxWidth = Math.max(viewport.cssWidth, viewport.width);
|
||||
let maxHeight = Math.max(viewport.cssHeight, viewport.height);
|
||||
|
||||
let videoWidth = 0;
|
||||
let videoHeight = 0;
|
||||
if (this._screenSize.width/this._screenSize.height < maxWidth / maxHeight) {
|
||||
videoWidth = this._screenSize.width;
|
||||
videoHeight = Math.ceil(videoWidth * maxHeight / maxWidth);
|
||||
} else {
|
||||
videoHeight = this._screenSize.height;
|
||||
videoWidth = Math.ceil(videoHeight * maxWidth / maxHeight);
|
||||
}
|
||||
|
||||
let constraints = {
|
||||
video: {
|
||||
mediaSource: "browser",
|
||||
browserWindow: windowId,
|
||||
scrollWithPage: true,
|
||||
advanced: [
|
||||
{ width: { min: videoWidth, max: videoWidth },
|
||||
height: { min: videoHeight, max: videoHeight }
|
||||
{ width: { min: 0, max: this._screenSize.width },
|
||||
height: { min: 0, max: this._screenSize.height }
|
||||
},
|
||||
{ aspectRatio: maxWidth / maxHeight }
|
||||
{ aspectRatio: this._screenSize.width / this._screenSize.height }
|
||||
]
|
||||
}
|
||||
};
|
||||
|
@ -27,9 +27,21 @@ EXTRA_JS_MODULES += [
|
||||
'SharedPreferences.jsm',
|
||||
'SSLExceptions.jsm',
|
||||
'TabMirror.jsm',
|
||||
'WebappManager.jsm',
|
||||
'WebappManagerWorker.js',
|
||||
]
|
||||
|
||||
for var in ('ANDROID_PACKAGE_NAME', 'MOZ_APP_VERSION'):
|
||||
DEFINES[var] = CONFIG[var]
|
||||
|
||||
for var in ('NIGHTLY_BUILD', 'RELEASE_BUILD', 'MOZ_ACCESSIBILITY',
|
||||
'MOZILLA_OFFICIAL', 'MOZ_OFFICIAL_BRANDING', 'MOZ_SERVICES_HEALTHREPORT',
|
||||
'MOZ_DEVICES', 'MOZ_DEVICES', 'MOZ_SAFE_BROWSING',
|
||||
'MOZ_TELEMETRY_REPORTING', 'MOZ_WEBRTC'):
|
||||
if CONFIG[var]:
|
||||
DEFINES[var] = 1
|
||||
|
||||
# Keep it this way if at all possible.
|
||||
EXTRA_PP_JS_MODULES += [
|
||||
'WebappManager.jsm',
|
||||
'AppConstants.jsm',
|
||||
]
|
||||
|
@ -20,7 +20,7 @@ chrome.jar:
|
||||
skin/aboutHealthReport.css (aboutHealthReport.css)
|
||||
#endif
|
||||
skin/aboutMemory.css (aboutMemory.css)
|
||||
* skin/aboutPrivateBrowsing.css (aboutPrivateBrowsing.css)
|
||||
skin/aboutPrivateBrowsing.css (aboutPrivateBrowsing.css)
|
||||
skin/aboutReader.css (aboutReader.css)
|
||||
skin/aboutSupport.css (aboutSupport.css)
|
||||
skin/browser.css (browser.css)
|
||||
|
@ -1558,6 +1558,23 @@ nsHttpChannel::ProcessResponse()
|
||||
Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_VERSION,
|
||||
mResponseHead->Version());
|
||||
|
||||
#if defined(ANDROID) || defined(MOZ_B2G)
|
||||
if (gHttpHandler->IsTelemetryEnabled()) {
|
||||
// Gather telemetry on being sent a WAP content-type
|
||||
// This check will catch (at least) the following content types:
|
||||
// application/wml+xml, application/vnd.wap.xhtml+xml,
|
||||
// text/vnd.wap.wml, application/vnd.wap.wmlc
|
||||
bool isWap = false;
|
||||
if (!mResponseHead->ContentType().IsEmpty() && (
|
||||
mResponseHead->ContentType().Find(".wap") != -1 ||
|
||||
mResponseHead->ContentType().Find("/wml") != -1)) {
|
||||
isWap = true;
|
||||
}
|
||||
|
||||
Telemetry::Accumulate(Telemetry::HTTP_WAP_CONTENT_TYPE_RECEIVED, isWap);
|
||||
}
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -262,6 +262,7 @@ user_pref("browser.newtabpage.directory.source", 'data:application/json,{"testin
|
||||
user_pref("browser.newtabpage.directory.ping", "");
|
||||
|
||||
// Enable Loop
|
||||
user_pref("loop.debug.loglevel", "All");
|
||||
user_pref("loop.enabled", true);
|
||||
user_pref("loop.throttled", false);
|
||||
user_pref("loop.oauth.google.URL", "http://%(server)s/browser/browser/components/loop/test/mochitest/google_service.sjs?action=");
|
||||
|
@ -52,7 +52,8 @@ add_task(function* test_searchEngine_autoFill() {
|
||||
}
|
||||
yield promiseAddVisits(visits);
|
||||
addBookmark({ uri: uri, title: "Example bookmark" });
|
||||
ok(frecencyForUrl(uri) > 10000, "Adeded URI should have expected high frecency");
|
||||
yield promiseAsyncUpdates();
|
||||
ok(frecencyForUrl(uri) > 10000, "Added URI should have expected high frecency");
|
||||
|
||||
do_log_info("Check search domain is autoFilled even if there's an higher frecency match");
|
||||
yield check_autocomplete({
|
||||
|
@ -1210,6 +1210,11 @@
|
||||
"kind": "boolean",
|
||||
"description": "Whether a HTTP transaction routed via Alt-Svc was scheme=http"
|
||||
},
|
||||
"HTTP_WAP_CONTENT_TYPE_RECEIVED": {
|
||||
"expires_in_version": "40",
|
||||
"kind": "boolean",
|
||||
"description": "Whether a WAP content type response is served to the browser."
|
||||
},
|
||||
"SSL_HANDSHAKE_VERSION": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
|
@ -44,6 +44,7 @@ const NODE_ROUTING_METHODS = [
|
||||
|
||||
const NODE_PROPERTIES = {
|
||||
"OscillatorNode": {
|
||||
"properties": {
|
||||
"type": {},
|
||||
"frequency": {
|
||||
"param": true
|
||||
@ -51,34 +52,34 @@ const NODE_PROPERTIES = {
|
||||
"detune": {
|
||||
"param": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"GainNode": {
|
||||
"gain": {
|
||||
"param": true
|
||||
}
|
||||
"properties": { "gain": { "param": true }}
|
||||
},
|
||||
"DelayNode": {
|
||||
"delayTime": {
|
||||
"param": true
|
||||
}
|
||||
"properties": { "delayTime": { "param": true }}
|
||||
},
|
||||
// TODO deal with figuring out adding `detune` AudioParam
|
||||
// for AudioBufferSourceNode, which is in the spec
|
||||
// but not yet added in implementation
|
||||
// bug 1116852
|
||||
"AudioBufferSourceNode": {
|
||||
"properties": {
|
||||
"buffer": { "Buffer": true },
|
||||
"playbackRate": {
|
||||
"param": true,
|
||||
"param": true
|
||||
},
|
||||
"loop": {},
|
||||
"loopStart": {},
|
||||
"loopEnd": {}
|
||||
}
|
||||
},
|
||||
"ScriptProcessorNode": {
|
||||
"bufferSize": { "readonly": true }
|
||||
"properties": { "bufferSize": { "readonly": true }}
|
||||
},
|
||||
"PannerNode": {
|
||||
"properties": {
|
||||
"panningModel": {},
|
||||
"distanceModel": {},
|
||||
"refDistance": {},
|
||||
@ -87,66 +88,70 @@ const NODE_PROPERTIES = {
|
||||
"coneInnerAngle": {},
|
||||
"coneOuterAngle": {},
|
||||
"coneOuterGain": {}
|
||||
}
|
||||
},
|
||||
"ConvolverNode": {
|
||||
"properties": {
|
||||
"buffer": { "Buffer": true },
|
||||
"normalize": {},
|
||||
}
|
||||
},
|
||||
"DynamicsCompressorNode": {
|
||||
"threshold": {
|
||||
"param": true
|
||||
},
|
||||
"knee": {
|
||||
"param": true
|
||||
},
|
||||
"ratio": {
|
||||
"param": true
|
||||
},
|
||||
"properties": {
|
||||
"threshold": { "param": true },
|
||||
"knee": { "param": true },
|
||||
"ratio": { "param": true },
|
||||
"reduction": {},
|
||||
"attack": {
|
||||
"param": true
|
||||
},
|
||||
"release": {
|
||||
"param": true
|
||||
"attack": { "param": true },
|
||||
"release": { "param": true }
|
||||
}
|
||||
},
|
||||
"BiquadFilterNode": {
|
||||
"properties": {
|
||||
"type": {},
|
||||
"frequency": {
|
||||
"param": true
|
||||
},
|
||||
"Q": {
|
||||
"param": true
|
||||
},
|
||||
"detune": {
|
||||
"param": true
|
||||
},
|
||||
"gain": {
|
||||
"param": true
|
||||
"frequency": { "param": true },
|
||||
"Q": { "param": true },
|
||||
"detune": { "param": true },
|
||||
"gain": { "param": true }
|
||||
}
|
||||
},
|
||||
"WaveShaperNode": {
|
||||
"properties": {
|
||||
"curve": { "Float32Array": true },
|
||||
"oversample": {}
|
||||
}
|
||||
},
|
||||
"AnalyserNode": {
|
||||
"properties": {
|
||||
"fftSize": {},
|
||||
"minDecibels": {},
|
||||
"maxDecibels": {},
|
||||
"smoothingTimeConstant": {},
|
||||
"frequencyBinCount": { "readonly": true },
|
||||
}
|
||||
},
|
||||
"AudioDestinationNode": {
|
||||
"unbypassable": true
|
||||
},
|
||||
"ChannelSplitterNode": {
|
||||
"unbypassable": true
|
||||
},
|
||||
"ChannelMergerNode": {
|
||||
"unbypassable": true
|
||||
},
|
||||
"AudioDestinationNode": {},
|
||||
"ChannelSplitterNode": {},
|
||||
"ChannelMergerNode": {},
|
||||
"MediaElementAudioSourceNode": {},
|
||||
"MediaStreamAudioSourceNode": {},
|
||||
"MediaStreamAudioDestinationNode": {
|
||||
"unbypassable": true,
|
||||
"properties": {
|
||||
"stream": { "MediaStream": true }
|
||||
}
|
||||
},
|
||||
"StereoPannerNode": {
|
||||
"properties": {
|
||||
"pan": {}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -184,7 +189,7 @@ let AudioNodeActor = exports.AudioNodeActor = protocol.ActorClass({
|
||||
}
|
||||
|
||||
// Create automation timelines for all AudioParams
|
||||
Object.keys(NODE_PROPERTIES[this.type])
|
||||
Object.keys(NODE_PROPERTIES[this.type].properties || {})
|
||||
.filter(isAudioParam.bind(null, node))
|
||||
.forEach(paramName => {
|
||||
this.automation[paramName] = new AutomationTimeline(node[paramName].defaultValue);
|
||||
@ -223,7 +228,9 @@ let AudioNodeActor = exports.AudioNodeActor = protocol.ActorClass({
|
||||
return false;
|
||||
}
|
||||
|
||||
return node.passThrough;
|
||||
// Cast to boolean incase `passThrough` is undefined,
|
||||
// like for AudioDestinationNode
|
||||
return !!node.passThrough;
|
||||
}, {
|
||||
response: { bypassed: RetVal("boolean") }
|
||||
}),
|
||||
@ -231,10 +238,12 @@ let AudioNodeActor = exports.AudioNodeActor = protocol.ActorClass({
|
||||
/**
|
||||
* Takes a boolean, either enabling or disabling the "passThrough" option
|
||||
* on an AudioNode. If a node is bypassed, an effects processing node (like gain, biquad),
|
||||
* will allow the audio stream to pass through the node, unaffected.
|
||||
* will allow the audio stream to pass through the node, unaffected. Returns
|
||||
* the bypass state of the node.
|
||||
*
|
||||
* @param Boolean enable
|
||||
* Whether the bypass value should be set on or off.
|
||||
* @return Boolean
|
||||
*/
|
||||
bypass: method(function (enable) {
|
||||
let node = this.node.get();
|
||||
@ -243,10 +252,15 @@ let AudioNodeActor = exports.AudioNodeActor = protocol.ActorClass({
|
||||
return;
|
||||
}
|
||||
|
||||
let bypassable = !NODE_PROPERTIES[this.type].unbypassable;
|
||||
if (bypassable) {
|
||||
node.passThrough = enable;
|
||||
}
|
||||
|
||||
return this.isBypassed();
|
||||
}, {
|
||||
request: { enable: Arg(0, "boolean") },
|
||||
oneway: true
|
||||
response: { bypassed: RetVal("boolean") }
|
||||
}),
|
||||
|
||||
/**
|
||||
@ -331,7 +345,7 @@ let AudioNodeActor = exports.AudioNodeActor = protocol.ActorClass({
|
||||
* Name of the AudioParam whose flags are desired.
|
||||
*/
|
||||
getParamFlags: method(function (param) {
|
||||
return (NODE_PROPERTIES[this.type] || {})[param];
|
||||
return ((NODE_PROPERTIES[this.type] || {}).properties || {})[param];
|
||||
}, {
|
||||
request: { param: Arg(0, "string") },
|
||||
response: { flags: RetVal("nullable:primitive") }
|
||||
@ -341,8 +355,8 @@ let AudioNodeActor = exports.AudioNodeActor = protocol.ActorClass({
|
||||
* Get an array of objects each containing a `param` and `value` property,
|
||||
* corresponding to a property name and current value of the audio node.
|
||||
*/
|
||||
getParams: method(function () {
|
||||
let props = Object.keys(NODE_PROPERTIES[this.type]);
|
||||
getParams: method(function (param) {
|
||||
let props = Object.keys(NODE_PROPERTIES[this.type].properties || {});
|
||||
return props.map(prop =>
|
||||
({ param: prop, value: this.getParam(prop), flags: this.getParamFlags(prop) }));
|
||||
}, {
|
||||
@ -600,6 +614,16 @@ let WebAudioActor = exports.WebAudioActor = protocol.ActorClass({
|
||||
this.finalize();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns definition of all AudioNodes, such as AudioParams, and
|
||||
* flags.
|
||||
*/
|
||||
getDefinition: method(function () {
|
||||
return NODE_PROPERTIES;
|
||||
}, {
|
||||
response: { definition: RetVal("json") }
|
||||
}),
|
||||
|
||||
/**
|
||||
* Starts waiting for the current tab actor's document global to be
|
||||
* created, in order to instrument the Canvas context and become
|
||||
@ -810,7 +834,7 @@ let WebAudioActor = exports.WebAudioActor = protocol.ActorClass({
|
||||
*/
|
||||
_instrumentParams: function (node) {
|
||||
let type = getConstructorName(node);
|
||||
Object.keys(NODE_PROPERTIES[type])
|
||||
Object.keys(NODE_PROPERTIES[type].properties || {})
|
||||
.filter(isAudioParam.bind(null, node))
|
||||
.forEach(paramName => {
|
||||
let param = node[paramName];
|
||||
|
@ -489,9 +489,9 @@ let NetworkHelper = {
|
||||
* @param object securityInfo
|
||||
* The securityInfo object of a request. If null channel is assumed
|
||||
* to be insecure.
|
||||
* @param nsIRequest request
|
||||
* The nsIRequest object for the request used to dig more information
|
||||
* about this request.
|
||||
* @param object httpActivity
|
||||
* The httpActivity object for the request with at least members
|
||||
* { private, hostname }.
|
||||
*
|
||||
* @return object
|
||||
* Returns an object containing following members:
|
||||
@ -510,7 +510,7 @@ let NetworkHelper = {
|
||||
* - hsts: true if host uses Strict Transport Security, false otherwise
|
||||
* - hpkp: true if host uses Public Key Pinning, false otherwise
|
||||
*/
|
||||
parseSecurityInfo: function NH_parseSecurityInfo(securityInfo, request) {
|
||||
parseSecurityInfo: function NH_parseSecurityInfo(securityInfo, httpActivity) {
|
||||
const info = {
|
||||
state: "insecure",
|
||||
};
|
||||
@ -574,25 +574,24 @@ let NetworkHelper = {
|
||||
info.cert = this.parseCertificateInfo(SSLStatus.serverCert);
|
||||
|
||||
// HSTS and HPKP if available.
|
||||
if (request.URI) {
|
||||
if (httpActivity.hostname) {
|
||||
const sss = Cc["@mozilla.org/ssservice;1"]
|
||||
.getService(Ci.nsISiteSecurityService);
|
||||
|
||||
request.QueryInterface(Ci.nsIPrivateBrowsingChannel);
|
||||
|
||||
// SiteSecurityService uses different storage if the channel is
|
||||
// private. Thus we must give isSecureHost correct flags or we
|
||||
// might get incorrect results.
|
||||
let flags = (request.isChannelPrivate) ?
|
||||
let flags = (httpActivity.private) ?
|
||||
Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0;
|
||||
|
||||
let host = request.URI.host;
|
||||
let host = httpActivity.hostname;
|
||||
|
||||
info.hsts = sss.isSecureHost(sss.HEADER_HSTS, host, flags);
|
||||
info.hpkp = sss.isSecureHost(sss.HEADER_HPKP, host, flags);
|
||||
} else {
|
||||
DevToolsUtils.reportException("NetworkHelper.parseSecurityInfo",
|
||||
"Could not get HSTS/HPKP status as request.URI not available.");
|
||||
"Could not get HSTS/HPKP status as hostname is not available.");
|
||||
info.hsts = false;
|
||||
info.hpkp = false;
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ loader.lazyGetter(this, "NetworkHelper", () => require("devtools/toolkit/webcons
|
||||
loader.lazyImporter(this, "Services", "resource://gre/modules/Services.jsm");
|
||||
loader.lazyImporter(this, "DevToolsUtils", "resource://gre/modules/devtools/DevToolsUtils.jsm");
|
||||
loader.lazyImporter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm");
|
||||
loader.lazyImporter(this, "PrivateBrowsingUtils", "resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
loader.lazyServiceGetter(this, "gActivityDistributor",
|
||||
"@mozilla.org/network/http-activity-distributor;1",
|
||||
"nsIHttpActivityDistributor");
|
||||
@ -175,7 +174,7 @@ NetworkResponseListener.prototype = {
|
||||
// was a redirect from http to https, the request object seems to contain
|
||||
// security info for the https request after redirect.
|
||||
let secinfo = this.httpActivity.channel.securityInfo;
|
||||
let info = NetworkHelper.parseSecurityInfo(secinfo, this.request);
|
||||
let info = NetworkHelper.parseSecurityInfo(secinfo, this.httpActivity);
|
||||
|
||||
this.httpActivity.owner.addSecurityInfo(info);
|
||||
}),
|
||||
@ -665,7 +664,9 @@ NetworkMonitor.prototype = {
|
||||
|
||||
// see NM__onRequestBodySent()
|
||||
httpActivity.charset = win ? win.document.characterSet : null;
|
||||
httpActivity.private = win ? PrivateBrowsingUtils.isWindowPrivate(win) : false;
|
||||
|
||||
aChannel.QueryInterface(Ci.nsIPrivateBrowsingChannel);
|
||||
httpActivity.private = aChannel.isChannelPrivate;
|
||||
|
||||
httpActivity.timings.REQUEST_HEADER = {
|
||||
first: aTimestamp,
|
||||
@ -751,6 +752,7 @@ NetworkMonitor.prototype = {
|
||||
channel: aChannel,
|
||||
charset: null, // see NM__onRequestHeader()
|
||||
url: aChannel.URI.spec,
|
||||
hostname: aChannel.URI.host, // needed for host specific security info
|
||||
discardRequestBody: !this.saveRequestAndResponseBodies,
|
||||
discardResponseBody: !this.saveRequestAndResponseBodies,
|
||||
timings: {}, // internal timing information, see NM_observeActivity()
|
||||
|
@ -34,14 +34,12 @@ const MockSecurityInfo = {
|
||||
}
|
||||
};
|
||||
|
||||
const MockRequest = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPrivateBrowsingChannel]),
|
||||
URI: {
|
||||
host: "include-subdomains.pinning.example.com"
|
||||
}
|
||||
const MockHttpInfo = {
|
||||
hostname: "include-subdomains.pinning.example.com",
|
||||
private: false,
|
||||
};
|
||||
|
||||
function run_test() {
|
||||
let result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, MockRequest);
|
||||
let result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, MockHttpInfo);
|
||||
equal(result.hpkp, true, "Static HPKP detected.");
|
||||
}
|
||||
|
@ -288,24 +288,9 @@ function RemoteMirror(url, win, viewport, mirrorStartedCallback, contentWindow)
|
||||
// This code insures the generated tab mirror is not wider than 1280 nor taller than 720
|
||||
// Better dimensions should be chosen after the Roku Channel is working.
|
||||
let windowId = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
|
||||
let cWidth = Math.max(viewport.cssWidth, viewport.width);
|
||||
let cHeight = Math.max(viewport.cssHeight, viewport.height);
|
||||
|
||||
const MAX_WIDTH = 1280;
|
||||
const MAX_HEIGHT = 720;
|
||||
|
||||
let tWidth = 0;
|
||||
let tHeight = 0;
|
||||
|
||||
// division and multiplication by 4 to ensure dimensions are multiples of 4
|
||||
if ((cWidth / MAX_WIDTH) > (cHeight / MAX_HEIGHT)) {
|
||||
tHeight = Math.ceil((MAX_WIDTH / (4* cWidth)) * cHeight) * 4;
|
||||
tWidth = MAX_WIDTH;
|
||||
} else {
|
||||
tWidth = Math.ceil((MAX_HEIGHT / (4 * cHeight)) * cWidth) * 4;
|
||||
tHeight = MAX_HEIGHT;
|
||||
}
|
||||
|
||||
let constraints = {
|
||||
video: {
|
||||
mediaSource: "browser",
|
||||
@ -313,10 +298,10 @@ function RemoteMirror(url, win, viewport, mirrorStartedCallback, contentWindow)
|
||||
scrollWithPage: true,
|
||||
advanced: [
|
||||
{
|
||||
width: { min: tWidth, max: tWidth },
|
||||
height: { min: tHeight, max: tHeight }
|
||||
width: { min: 0, max: MAX_WIDTH },
|
||||
height: { min: 0, max: MAX_HEIGHT }
|
||||
},
|
||||
{ aspectRatio: cWidth / cHeight }
|
||||
{ aspectRatio: MAX_WIDTH/MAX_HEIGHT }
|
||||
]
|
||||
}
|
||||
};
|
||||
|
@ -26,6 +26,10 @@ xul|button {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
xul|caption {
|
||||
-moz-padding-start: 0;
|
||||
}
|
||||
|
||||
xul|groupbox > xul|*.groupbox-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user