Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge mozilla-b2g18 to mozilla-b2g18_v1_0_1

  • Loading branch information...
commit 31d444671f52b999b6c9d2ff8809f7a558c429b4 2 parents ffaf605 + 70dd74b
@rail rail authored
Showing with 2,212 additions and 2,083 deletions.
  1. +8 −6 b2g/app/b2g.js
  2. +0 −2  b2g/chrome/content/UAO_child.js
  3. +2 −1  b2g/chrome/content/forms.js
  4. +10 −5 b2g/chrome/content/settings.js
  5. +17 −14 b2g/chrome/content/shell.js
  6. +0 −2  b2g/chrome/jar.mn
  7. +0 −6 b2g/components/Keyboard.jsm
  8. +0 −12 b2g/components/ProcessGlobal.js
  9. +2 −1  b2g/components/RecoveryService.js
  10. +2 −1  b2g/config/panda-gaia-central/config.json
  11. +2 −1  b2g/config/panda/config.json
  12. +0 −10 b2g/installer/package-manifest.in
  13. +0 −10 browser/installer/package-manifest.in
  14. +0 −1  browser/installer/removed-files.in
  15. +0 −6 configure.in
  16. +6 −6 content/base/crashtests/crashtests.list
  17. +3 −2 content/base/public/nsIFrameLoader.idl
  18. +16 −36 content/base/src/nsFrameLoader.cpp
  19. +3 −3 content/base/src/nsFrameLoader.h
  20. +1 −1  content/canvas/crashtests/crashtests.list
  21. +1 −1  content/html/content/crashtests/crashtests.list
  22. +2 −2 content/media/test/crashtests/crashtests.list
  23. +1 −1  content/svg/content/src/crashtests/crashtests.list
  24. +7 −7 content/xbl/crashtests/crashtests.list
  25. +1 −1  content/xml/content/crashtest/crashtests.list
  26. +1 −1  content/xml/document/crashtests/crashtests.list
  27. +28 −21 dom/apps/src/AppsUtils.jsm
  28. +54 −21 dom/apps/src/Webapps.jsm
  29. +1 −1  dom/base/nsContentPermissionHelper.cpp
  30. +1 −0  dom/base/nsDOMClassInfo.cpp
  31. +11 −4 dom/base/nsJSEnvironment.cpp
  32. +18 −20 dom/bluetooth/linux/BluetoothDBusService.cpp
  33. +16 −825 dom/browser-element/BrowserElementChild.js
  34. +826 −0 dom/browser-element/BrowserElementChildPreload.js
  35. +10 −3 dom/browser-element/{BrowserElementScrolling.js → BrowserElementPanning.js}
  36. +8 −12 dom/browser-element/BrowserElementParent.jsm
  37. +1 −4 dom/camera/GonkCameraHwMgr.cpp
  38. +100 −11 dom/camera/GonkNativeWindow.cpp
  39. +13 −0 dom/camera/GonkNativeWindow.h
  40. +15 −2 dom/identity/nsDOMIdentity.js
  41. +0 −2  dom/imptests/failures/editing/conformancetest/test_runtest.html.json
  42. +11 −4 dom/ipc/ProcessPriorityManager.cpp
  43. +18 −1 dom/ipc/TabChild.cpp
  44. +3 −1 dom/ipc/jar.mn
  45. +25 −7 dom/ipc/preload.js
  46. +15 −53 dom/workers/ChromeWorkerScope.cpp
  47. +33 −1 dom/workers/RuntimeService.cpp
  48. +322 −255 dom/workers/WorkerPrivate.cpp
  49. +99 −11 dom/workers/WorkerPrivate.h
  50. +19 −2 gfx/layers/ipc/AsyncPanZoomController.cpp
  51. +21 −0 hal/Hal.cpp
  52. +8 −0 hal/HalTypes.h
  53. +112 −41 hal/gonk/GonkHal.cpp
  54. +20 −1 ipc/dbus/DBusUtils.cpp
  55. +12 −0 js/src/ctypes/CTypes.cpp
  56. +6 −4 js/src/frontend/BytecodeCompiler.cpp
  57. +2 −1  js/src/frontend/BytecodeCompiler.h
  58. +25 −0 js/src/jsapi-tests/testSourcePolicy.cpp
  59. +5 −2 js/src/jsapi.cpp
  60. +2 −0  js/src/jscntxt.h
  61. +18 −0 js/src/jsfriendapi.cpp
  62. +41 −0 js/src/jsfriendapi.h
  63. +11 −11 js/src/jsscript.cpp
  64. +2 −7 js/src/jsscript.h
  65. +4 −1 js/src/jsutil.cpp
  66. +23 −23 layout/base/crashtests/crashtests.list
  67. +17 −4 layout/base/nsIPresShell.h
  68. +22 −5 layout/base/nsPresShell.cpp
  69. +1 −0  layout/base/nsPresShell.h
  70. +1 −1  layout/forms/crashtests/crashtests.list
  71. +34 −0 layout/generic/nsSubDocumentFrame.cpp
  72. +1 −0  layout/generic/nsSubDocumentFrame.h
  73. +2 −2 layout/style/crashtests/crashtests.list
  74. +1 −0  layout/style/html.css
  75. +2 −2 layout/svg/crashtests/crashtests.list
  76. +1 −1  layout/tables/crashtests/crashtests.list
  77. +0 −8 mobile/android/installer/package-manifest.in
  78. +4 −0 modules/libpref/src/init/all.js
  79. +0 −4 services/Makefile.in
  80. +0 −2  services/captivedetect/CaptivePortalDetectComponents.manifest
  81. +0 −27 services/captivedetect/Makefile.in
  82. +0 −426 services/captivedetect/captivedetect.js
  83. +0 −53 services/captivedetect/nsICaptivePortalDetector.idl
  84. +0 −9 services/captivedetect/services-captivedetect.js
  85. +0 −1  services/makefiles.sh
  86. +33 −27 testing/marionette/marionette-actors.js
  87. +20 −19 testing/marionette/marionette-listener.js
  88. +1 −1  toolkit/content/devicestorage.properties
  89. +28 −0 widget/xpwidgets/PuppetWidget.cpp
View
14 b2g/app/b2g.js
@@ -180,8 +180,6 @@ pref("content.sink.perf_parse_time", 50000000);
// Maximum scripts runtime before showing an alert
pref("dom.max_chrome_script_run_time", 0); // disable slow script dialog for chrome
-// Bug 817230 - disable the dialog until we implement its checkbox properly
-pref("dom.max_script_run_time", 0);
// plugins
pref("plugin.disable", true);
@@ -561,7 +559,7 @@ pref("hal.processPriorityManager.gonk.masterKillUnderMB", 1);
pref("hal.processPriorityManager.gonk.foregroundOomScoreAdjust", 67);
pref("hal.processPriorityManager.gonk.foregroundKillUnderMB", 4);
pref("hal.processPriorityManager.gonk.backgroundPerceivableOomScoreAdjust", 134);
-pref("hal.processPriorityManager.gonk.backgroundPerceivebleKillUnderMB", 5);
+pref("hal.processPriorityManager.gonk.backgroundPerceivableKillUnderMB", 5);
pref("hal.processPriorityManager.gonk.backgroundHomescreenOomScoreAdjust", 200);
pref("hal.processPriorityManager.gonk.backgroundHomescreenKillUnderMB", 5);
pref("hal.processPriorityManager.gonk.backgroundOomScoreAdjust", 400);
@@ -569,9 +567,11 @@ pref("hal.processPriorityManager.gonk.backgroundKillUnderMB", 8);
pref("hal.processPriorityManager.gonk.notifyLowMemUnderMB", 10);
// Niceness values (i.e., CPU priorities) for B2G processes.
-pref("hal.processPriorityManager.gonk.masterNice", -1);
-pref("hal.processPriorityManager.gonk.foregroundNice", 0);
-pref("hal.processPriorityManager.gonk.backgroundNice", 10);
+pref("hal.processPriorityManager.gonk.masterNice", 0);
+pref("hal.processPriorityManager.gonk.foregroundNice", 1);
+pref("hal.processPriorityManager.gonk.backgroundPerceivableNice", 10);
+pref("hal.processPriorityManager.gonk.backgroundHomescreenNice", 20);
+pref("hal.processPriorityManager.gonk.backgroundNice", 20);
#ifndef DEBUG
// Enable pre-launching content processes for improved startup time
@@ -645,3 +645,5 @@ pref("memory_info_dumper.watch_fifo.directory", "/data/local");
// <input type='file'> implementation is not complete. We have to disable the
// type to web content to help them do feature detection.
pref("dom.disable_input_file", true);
+
+pref("general.useragent.enable_overrides", true);
View
2  b2g/chrome/content/UAO_child.js
@@ -1,2 +0,0 @@
-Components.utils.import('resource://gre/modules/UserAgentOverrides.jsm');
-UserAgentOverrides.init();
View
3  b2g/chrome/content/forms.js
@@ -448,7 +448,7 @@ function getJSON(element) {
value = element.textContent;
}
- // Until the input type=date/datetime/time have been implemented
+ // Until the input type=date/datetime/range have been implemented
// let's return their real type even if the platform returns 'text'
// Related to Bug 769352 - Implement <input type=date>
// Related to Bug 777279 - Implement <input type=time>
@@ -461,6 +461,7 @@ function getJSON(element) {
case "time":
case "datetime":
case "datetime-local":
+ case "range":
type = typeLowerCase;
break;
}
View
15 b2g/chrome/content/settings.js
@@ -207,12 +207,17 @@ SettingsListener.observe('devtools.debugger.remote-enabled', false, function(val
#ifdef MOZ_WIDGET_GONK
let enableAdb = value;
- if (Services.prefs.getBoolPref('marionette.defaultPrefs.enabled')) {
- // Marionette is enabled. Force adb on, since marionette requires remote
- // debugging to be disabled (we don't want adb to track the remote debugger
- // setting).
+ try {
+ if (Services.prefs.getBoolPref('marionette.defaultPrefs.enabled')) {
+ // Marionette is enabled. Force adb on, since marionette requires remote
+ // debugging to be disabled (we don't want adb to track the remote debugger
+ // setting).
- enableAdb = true;
+ enableAdb = true;
+ }
+ } catch (e) {
+ // This means that the pref doesn't exist. Which is fine. We just leave
+ // enableAdb alone.
}
// Configure adb.
View
31 b2g/chrome/content/shell.js
@@ -673,7 +673,7 @@ var AlertsHelper = {
return;
let topic = detail.type == "desktop-notification-click" ? "alertclickcallback"
- : "alertfinished";
+ /* desktop-notification-close */ : "alertfinished";
if (uid.startsWith("app-notif")) {
try {
listener.mm.sendAsyncMessage("app-notification-return", {
@@ -682,13 +682,17 @@ var AlertsHelper = {
target: listener.target
});
} catch(e) {
+ // we get an exception if the app is not launched yet
+
gSystemMessenger.sendMessage("notification", {
- title: listener.title,
- body: listener.text,
- imageURL: listener.imageURL
- },
- Services.io.newURI(listener.target, null, null),
- Services.io.newURI(listener.manifestURL, null, null));
+ clicked: (detail.type === "desktop-notification-click"),
+ title: listener.title,
+ body: listener.text,
+ imageURL: listener.imageURL
+ },
+ Services.io.newURI(listener.target, null, null),
+ Services.io.newURI(listener.manifestURL, null, null)
+ );
}
} else if (uid.startsWith("alert")) {
try {
@@ -1039,21 +1043,20 @@ window.addEventListener('ContentStart', function update_onContentStart() {
});
(function geolocationStatusTracker() {
- let gGeolocationActiveCount = 0;
+ let gGeolocationActive = false;
Services.obs.addObserver(function(aSubject, aTopic, aData) {
- let oldCount = gGeolocationActiveCount;
+ let oldState = gGeolocationActive;
if (aData == "starting") {
- gGeolocationActiveCount += 1;
+ gGeolocationActive = true;
} else if (aData == "shutdown") {
- gGeolocationActiveCount -= 1;
+ gGeolocationActive = false;
}
- // We need to track changes from 1 <-> 0
- if (gGeolocationActiveCount + oldCount == 1) {
+ if (gGeolocationActive != oldState) {
shell.sendChromeEvent({
type: 'geolocation-status',
- active: (gGeolocationActiveCount == 1)
+ active: gGeolocationActive
});
}
}, "geolocation-device-events", false);
View
2  b2g/chrome/jar.mn
@@ -25,8 +25,6 @@ chrome.jar:
content/payment.js (content/payment.js)
content/identity.js (content/identity.js)
- content/UAO_child.js (content/UAO_child.js)
-
% override chrome://global/content/netError.xhtml chrome://browser/content/netError.xhtml
% override chrome://global/skin/netError.css chrome://browser/content/netError.css
% override chrome://global/skin/media/videocontrols.css chrome://browser/content/touchcontrols.css
View
6 b2g/components/Keyboard.jsm
@@ -46,12 +46,6 @@ let Keyboard = {
let frameLoader = subject.QueryInterface(Ci.nsIFrameLoader);
let mm = frameLoader.messageManager;
mm.addMessageListener('Forms:Input', this);
-
- try {
- mm.loadFrameScript(kFormsFrameScript, true);
- } catch (e) {
- dump('Error loading ' + kFormsFrameScript + ' as frame script: ' + e + '\n');
- }
},
receiveMessage: function keyboardReceiveMessage(msg) {
View
12 b2g/components/ProcessGlobal.js
@@ -43,7 +43,6 @@ ProcessGlobal.prototype = {
switch (topic) {
case 'app-startup': {
Services.obs.addObserver(this, 'console-api-log-event', false);
- Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
break;
}
case 'console-api-log-event': {
@@ -57,17 +56,6 @@ ProcessGlobal.prototype = {
' '));
break;
}
- case 'remote-browser-frame-shown': {
- let frameLoader = subject.QueryInterface(Ci.nsIFrameLoader);
- let mm = frameLoader.messageManager;
-
- const kFrameScript = "chrome://browser/content/UAO_child.js";
- try {
- mm.loadFrameScript(kFrameScript, true);
- } catch (e) {
- dump('Error loading ' + kFrameScript + ' as frame script: ' + e + '\n');
- }
- }
}
},
};
View
3  b2g/components/RecoveryService.js
@@ -19,8 +19,9 @@ function log(msg) {
#ifdef MOZ_WIDGET_GONK
let librecovery = (function() {
+ let library;
try {
- let library = ctypes.open("librecovery.so");
+ library = ctypes.open("librecovery.so");
} catch (e) {
log("Unable to open librecovery.so");
throw Cr.NS_ERROR_FAILURE;
View
3  b2g/config/panda-gaia-central/config.json
@@ -4,9 +4,10 @@
"mock_target": "mozilla-centos6-i386",
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel"],
"mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
- "build_targets": ["boottarball", "systemtarball", "userdatatarball"],
+ "build_targets": ["boottarball", "systemtarball", "userdatatarball", "package-tests"],
"upload_files": [
"{workdir}/out/target/product/panda/*.tar.bz2",
+ "{workdir}/out/target/product/panda/tests/*.zip",
"{objdir}/dist/b2g-update/*.mar",
"{objdir}/dist/b2g-*.tar.gz",
"{objdir}/dist/b2g-*.crashreporter-symbols.zip",
View
3  b2g/config/panda/config.json
@@ -4,9 +4,10 @@
"mock_target": "mozilla-centos6-i386",
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel"],
"mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
- "build_targets": ["boottarball", "systemtarball", "userdatatarball"],
+ "build_targets": ["boottarball", "systemtarball", "userdatatarball", "package-tests"],
"upload_files": [
"{workdir}/out/target/product/panda/*.tar.bz2",
+ "{workdir}/out/target/product/panda/tests/*.zip",
"{objdir}/dist/b2g-update/*.mar",
"{objdir}/dist/b2g-*.tar.gz",
"{objdir}/dist/b2g-*.crashreporter-symbols.zip",
View
10 b2g/installer/package-manifest.in
@@ -285,9 +285,6 @@
@BINPATH@/components/services-crypto.xpt
#endif
@BINPATH@/components/services-crypto-component.xpt
-#ifdef MOZ_SERVICES_CAPTIVEDETECT
-@BINPATH@/components/services-captivedetect.xpt
-#endif
@BINPATH@/components/shellservice.xpt
@BINPATH@/components/shistory.xpt
@BINPATH@/components/spellchecker.xpt
@@ -492,10 +489,6 @@
@BINPATH@/components/HealthReportComponents.manifest
@BINPATH@/components/HealthReportService.js
#endif
-#ifdef MOZ_SERVICES_CAPTIVEDETECT
-@BINPATH@/components/CaptivePortalDetectComponents.manifest
-@BINPATH@/components/captivedetect.js
-#endif
@BINPATH@/components/TelemetryPing.js
@BINPATH@/components/TelemetryPing.manifest
@BINPATH@/components/Webapps.js
@@ -590,9 +583,6 @@
#ifdef MOZ_SERVICES_HEALTHREPORT
@BINPATH@/@PREF_DIR@/healthreport-prefs.js
#endif
-#ifdef MOZ_SERVICES_CAPTIVEDETECT
-@BINPATH@/@PREF_DIR@/services-captivedetect.js
-#endif
@BINPATH@/greprefs.js
@BINPATH@/defaults/autoconfig/platform.js
@BINPATH@/defaults/autoconfig/prefcalls.js
View
10 browser/installer/package-manifest.in
@@ -282,9 +282,6 @@
@BINPATH@/components/saxparser.xpt
@BINPATH@/components/sessionstore.xpt
@BINPATH@/components/services-crypto-component.xpt
-#ifdef MOZ_SERVICES_CAPTIVEDETECT
-@BINPATH@/components/services-captivedetect.xpt
-#endif
@BINPATH@/components/shellservice.xpt
@BINPATH@/components/shistory.xpt
@BINPATH@/components/spellchecker.xpt
@@ -478,10 +475,6 @@
@BINPATH@/components/SyncComponents.manifest
@BINPATH@/components/Weave.js
#endif
-#ifdef MOZ_SERVICES_CAPTIVEDETECT
-@BINPATH@/components/CaptivePortalDetectComponents.manifest
-@BINPATH@/components/captivedetect.js
-#endif
@BINPATH@/components/TelemetryPing.js
@BINPATH@/components/TelemetryPing.manifest
@BINPATH@/components/messageWakeupService.js
@@ -585,9 +578,6 @@
#ifdef MOZ_SERVICES_HEALTHREPORT
@BINPATH@/@PREF_DIR@/healthreport-prefs.js
#endif
-#ifdef MOZ_SERVICES_CAPTIVEDETECT
-@BINPATH@/@PREF_DIR@/services-captivedetect.js
-#endif
@BINPATH@/greprefs.js
@BINPATH@/defaults/autoconfig/platform.js
@BINPATH@/defaults/autoconfig/prefcalls.js
View
1  browser/installer/removed-files.in
@@ -966,7 +966,6 @@ xpicleanup@BIN_SUFFIX@
defaults/pref/firefox.js
defaults/pref/firefox-l10n.js
defaults/pref/services-sync.js
- defaults/pref/services-captivedetect.js
defaults/profile/bookmarks.html
defaults/profile/chrome/userChrome-example.css
defaults/profile/chrome/userContent-example.css
View
6 configure.in
@@ -8435,12 +8435,6 @@ if test -n "$MOZ_SERVICES_SYNC"; then
AC_DEFINE(MOZ_SERVICES_SYNC)
fi
-dnl Build Captive Portal Detector if required
-AC_SUBST(MOZ_SERVICES_CAPTIVEDETECT)
-if test -n "$MOZ_SERVICES_CAPTIVEDETECT"; then
- AC_DEFINE(MOZ_SERVICES_CAPTIVEDETECT)
-fi
-
dnl ========================================================
if test "$MOZ_DEBUG" -o "$NS_TRACE_MALLOC" -o "$MOZ_DMD"; then
MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS=
View
12 content/base/crashtests/crashtests.list
@@ -4,12 +4,12 @@ load 149320-1.html
load 205225-1.html
load 231475-1.html
load 293388-1.html
-load 308120-1.xul
+skip-if(B2G) load 308120-1.xul # bug 834382
load 324871-1.html
load 325730-1.html
load 326618-1.html
load 326646-1.html
-load 326778-1.xul
+skip-if(B2G) load 326778-1.xul # bug 834382
load 326865-1.html
load 327694.html
load 330925-1.xhtml
@@ -20,12 +20,12 @@ load 340733-1.html
load 343730-1.xhtml
load 343850-1.xhtml
load 343889-1.html
-load 344434-1.xhtml
+skip-if(B2G) load 344434-1.xhtml # bug 834382
load 348049-1.xhtml
load 344882-1.html
load 345837-1.xhtml
load 349355-1.html
-load 354645-1.xul
+skip-if(B2G) load 354645-1.xul # bug 834382
load 360599-1.html
load 366200-1.xhtml
load 369216-1.html
@@ -38,9 +38,9 @@ load 387460-1.html
load 395469-1.xhtml
load 395469-2.xhtml
skip load 399712-1.html # sporadically times out (bug 473680)
-load 398088-1.xul
+skip-if(B2G) load 398088-1.xul # bug 834382
load 400763-1.html
-load 401993-1.html
+skip-if(B2G) load 401993-1.html # bug 834382
load 407818.html
load 410860-1.xml
load 411882-1.xhtml
View
5 content/base/public/nsIFrameLoader.idl
@@ -8,6 +8,7 @@
interface nsIDocShell;
interface nsIURI;
interface nsIFrame;
+interface nsSubDocumentFrame;
interface nsIMessageSender;
interface nsIVariant;
interface nsIDOMElement;
@@ -108,7 +109,7 @@ interface nsIContentViewManager : nsISupports
readonly attribute nsIContentView rootContentView;
};
-[scriptable, uuid(f234c232-bb17-4450-b324-bf1ef5ccfd34)]
+[scriptable, uuid(a4db652e-e3b0-4345-8107-cf6a30486759)]
interface nsIFrameLoader : nsISupports
{
/**
@@ -146,7 +147,7 @@ interface nsIFrameLoader : nsISupports
*
* @param aIFrame The nsIFrame for the content node that owns this frameloader
*/
- [noscript] void updatePositionAndSize(in nsIFrame aIFrame);
+ [noscript] void updatePositionAndSize(in nsSubDocumentFrame aIFrame);
/**
* Activate remote frame.
View
52 content/base/src/nsFrameLoader.cpp
@@ -816,26 +816,17 @@ nsFrameLoader::Show(int32_t marginWidth, int32_t marginHeight,
}
}
+ nsIntSize size = frame->GetSubdocumentSize();
+ if (mRemoteFrame) {
+ return ShowRemoteFrame(size, frame);
+ }
+
nsIView* view = frame->EnsureInnerView();
if (!view)
return false;
- if (mRemoteFrame) {
- return ShowRemoteFrame(GetSubDocumentSize(frame));
- }
-
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mDocShell);
NS_ASSERTION(baseWindow, "Found a nsIDocShell that isn't a nsIBaseWindow.");
- nsIntSize size;
- if (!(frame->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
- // We have a useful size already; use it, since we might get no
- // more size updates.
- size = GetSubDocumentSize(frame);
- } else {
- // Pick some default size for now. Using 10x10 because that's what the
- // code here used to do.
- size.SizeTo(10, 10);
- }
baseWindow->InitWindow(nullptr, view->GetWidget(), 0, 0,
size.width, size.height);
// This is kinda whacky, this "Create()" call doesn't really
@@ -921,7 +912,8 @@ nsFrameLoader::MarginsChanged(uint32_t aMarginWidth,
}
bool
-nsFrameLoader::ShowRemoteFrame(const nsIntSize& size)
+nsFrameLoader::ShowRemoteFrame(const nsIntSize& size,
+ nsSubDocumentFrame *aFrame)
{
NS_ASSERTION(mRemoteFrame, "ShowRemote only makes sense on remote frames.");
@@ -964,7 +956,11 @@ nsFrameLoader::ShowRemoteFrame(const nsIntSize& size)
} else {
nsRect dimensions;
NS_ENSURE_SUCCESS(GetWindowDimensions(dimensions), false);
- mRemoteBrowser->UpdateDimensions(dimensions, size);
+
+ // Don't show remote iframe if we are waiting for the completion of reflow.
+ if (!aFrame || !(aFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
+ mRemoteBrowser->UpdateDimensions(dimensions, size);
+ }
}
return true;
@@ -1831,11 +1827,11 @@ nsFrameLoader::GetWindowDimensions(nsRect& aRect)
}
NS_IMETHODIMP
-nsFrameLoader::UpdatePositionAndSize(nsIFrame *aIFrame)
+nsFrameLoader::UpdatePositionAndSize(nsSubDocumentFrame *aIFrame)
{
if (mRemoteFrame) {
if (mRemoteBrowser) {
- nsIntSize size = GetSubDocumentSize(aIFrame);
+ nsIntSize size = aIFrame->GetSubdocumentSize();
nsRect dimensions;
NS_ENSURE_SUCCESS(GetWindowDimensions(dimensions), NS_ERROR_FAILURE);
mRemoteBrowser->UpdateDimensions(dimensions, size);
@@ -1846,7 +1842,7 @@ nsFrameLoader::UpdatePositionAndSize(nsIFrame *aIFrame)
}
nsresult
-nsFrameLoader::UpdateBaseWindowPositionAndSize(nsIFrame *aIFrame)
+nsFrameLoader::UpdateBaseWindowPositionAndSize(nsSubDocumentFrame *aIFrame)
{
nsCOMPtr<nsIDocShell> docShell;
GetDocShell(getter_AddRefs(docShell));
@@ -1866,7 +1862,7 @@ nsFrameLoader::UpdateBaseWindowPositionAndSize(nsIFrame *aIFrame)
return NS_OK;
}
- nsIntSize size = GetSubDocumentSize(aIFrame);
+ nsIntSize size = aIFrame->GetSubdocumentSize();
baseWindow->SetPositionAndSize(x, y, size.width, size.height, false);
}
@@ -1970,22 +1966,6 @@ nsFrameLoader::SetClampScrollPosition(bool aClamp)
return NS_OK;
}
-nsIntSize
-nsFrameLoader::GetSubDocumentSize(const nsIFrame *aIFrame)
-{
- nsSize docSizeAppUnits;
- nsPresContext* presContext = aIFrame->PresContext();
- nsCOMPtr<nsIDOMHTMLFrameElement> frameElem =
- do_QueryInterface(aIFrame->GetContent());
- if (frameElem) {
- docSizeAppUnits = aIFrame->GetSize();
- } else {
- docSizeAppUnits = aIFrame->GetContentRect().Size();
- }
- return nsIntSize(presContext->AppUnitsToDevPixels(docSizeAppUnits.width),
- presContext->AppUnitsToDevPixels(docSizeAppUnits.height));
-}
-
bool
nsFrameLoader::TryRemoteBrowser()
{
View
6 content/base/src/nsFrameLoader.h
@@ -357,12 +357,11 @@ class nsFrameLoader MOZ_FINAL : public nsIFrameLoader,
NS_HIDDEN_(void) GetURL(nsString& aURL);
// Properly retrieves documentSize of any subdocument type.
- NS_HIDDEN_(nsIntSize) GetSubDocumentSize(const nsIFrame *aIFrame);
nsresult GetWindowDimensions(nsRect& aRect);
// Updates the subdocument position and size. This gets called only
// when we have our own in-process DocShell.
- NS_HIDDEN_(nsresult) UpdateBaseWindowPositionAndSize(nsIFrame *aIFrame);
+ NS_HIDDEN_(nsresult) UpdateBaseWindowPositionAndSize(nsSubDocumentFrame *aIFrame);
nsresult CheckURILoad(nsIURI* aURI);
void FireErrorEvent();
nsresult ReallyStartLoadingInternal();
@@ -371,7 +370,8 @@ class nsFrameLoader MOZ_FINAL : public nsIFrameLoader,
bool TryRemoteBrowser();
// Tell the remote browser that it's now "virtually visible"
- bool ShowRemoteFrame(const nsIntSize& size);
+ bool ShowRemoteFrame(const nsIntSize& size,
+ nsSubDocumentFrame *aFrame = nullptr);
bool AddTreeItemToTreeOwner(nsIDocShellTreeItem* aItem,
nsIDocShellTreeOwner* aOwner,
View
2  content/canvas/crashtests/crashtests.list
@@ -13,6 +13,6 @@ load 746813-1.html
#load 745818-large-source.html
load 743499-negative-size.html
load 767337-1.html
-load 780392-1.html
+skip-if(B2G) load 780392-1.html # bug 833371
load 794463-1.html
load 802926-1.html
View
2  content/html/content/crashtests/crashtests.list
@@ -30,7 +30,7 @@ load 614988-1.html
load 616401.html
load 620078-1.html
load 620078-2.html
-load 680922-1.xul
+skip-if(B2G) load 680922-1.xul # bug 834382
load 682058.xhtml
load 682460.html
load 673853.html
View
4 content/media/test/crashtests/crashtests.list
@@ -10,5 +10,5 @@ load 492286-1.xhtml
load 576612-1.html
skip-if(Android) load 691096-1.html # Android sound API can't handle playing large number of sounds at once.
load 752784-1.html
-HTTP load 795892-1.html
-load 789075-1.html
+skip-if(B2G) HTTP load 795892-1.html # bug 833371
+skip-if(B2G) load 789075-1.html # bug 833371
View
2  content/svg/content/src/crashtests/crashtests.list
@@ -18,7 +18,7 @@ load 381777-1.svg
load 383685-1.svg
load 385096.html
load 385554-1.html
-load 385554-2.xul
+skip-if(B2G) load 385554-2.xul # bug 834382
load 388712-1.svg
load 395616-1.html
load 396618-1.html
View
14 content/xbl/crashtests/crashtests.list
@@ -1,7 +1,7 @@
load 205735-1.xhtml
-load 223799-1.xul
+skip-if(B2G) load 223799-1.xul # bug 834382
load 226744-1.xhtml
-load 232095-1.xul
+skip-if(B2G) load 232095-1.xul # bug 834382
load 277523-1.xhtml
load 277950-1.xhtml
skip-if(Android||browserIsRemote) load 336744-1.html # no remote support for xul popups, bug 617653
@@ -15,12 +15,12 @@ load 382376-1.xhtml
load 382376-2.xhtml
load 397596-1.xhtml
load 404125-1.xhtml
-load 406900-1.xul
+skip-if(B2G) load 406900-1.xul # bug 834382
load 406904-1.xhtml
load 406904-2.xhtml
-load 415301-1.xul
+skip-if(B2G) load 415301-1.xul # bug 834382
load 418133-1.xhtml
-load 415192-1.xul
+skip-if(B2G) load 415192-1.xul # bug 834382
load 420233-1.xhtml
load 421997-1.xhtml
load 432813-1.xhtml
@@ -28,9 +28,9 @@ load 454820-1.html
load 460665-1.xhtml
load 463511-1.xhtml
load 464863-1.xhtml
-load 472260-1.xhtml
+skip-if(B2G) load 472260-1.xhtml # bug 834382
load 477878-1.html
-load 492978-1.xul
+skip-if(B2G) load 492978-1.xul # bug 834382
asserts-if(Android,2) load 493123-1.xhtml
load 495354-1.xhtml
load 507628-1.xhtml
View
2  content/xml/content/crashtest/crashtests.list
@@ -1,2 +1,2 @@
-load 420429.xul
+skip-if(B2G) load 420429.xul # bug 834382
load 453278.html
View
2  content/xml/document/crashtests/crashtests.list
@@ -3,5 +3,5 @@ load 185285-1.xml
load 382636-1.xml
load 382636-2.svg
load 382636-3.xhtml
-load 382636-4.xul # Throws (bug 455856)
+skip-if(B2G) load 382636-4.xul # Throws (bug 455856), bug 834382
load 431703-1.xhtml
View
49 dom/apps/src/AppsUtils.jsm
@@ -32,6 +32,33 @@ function isAbsoluteURI(aURI) {
Services.io.newURI(aURI, null, bar).prePath != bar.prePath;
}
+function mozIApplication() {
+}
+
+mozIApplication.prototype = {
+ hasPermission: function(aPermission) {
+ let uri = Services.io.newURI(this.origin, null, null);
+ let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
+ .getService(Ci.nsIScriptSecurityManager);
+ // This helper checks an URI inside |aApp|'s origin and part of |aApp| has a
+ // specific permission. It is not checking if browsers inside |aApp| have such
+ // permission.
+ let principal = secMan.getAppCodebasePrincipal(uri, this.localId,
+ /*mozbrowser*/false);
+ let perm = Services.perms.testExactPermissionFromPrincipal(principal,
+ aPermission);
+ return (perm === Ci.nsIPermissionManager.ALLOW_ACTION);
+ },
+
+ QueryInterface: function(aIID) {
+ if (aIID.equals(Ci.mozIDOMApplication) ||
+ aIID.equals(Ci.mozIApplication) ||
+ aIID.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ }
+}
+
this.AppsUtils = {
// Clones a app, without the manifest.
cloneAppObject: function cloneAppObject(aApp) {
@@ -68,27 +95,7 @@ this.AppsUtils = {
cloneAsMozIApplication: function cloneAsMozIApplication(aApp) {
let res = this.cloneAppObject(aApp);
- res.hasPermission = function(aPermission) {
- let uri = Services.io.newURI(this.origin, null, null);
- let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
- .getService(Ci.nsIScriptSecurityManager);
- // This helper checks an URI inside |aApp|'s origin and part of |aApp| has a
- // specific permission. It is not checking if browsers inside |aApp| have such
- // permission.
- let principal = secMan.getAppCodebasePrincipal(uri, aApp.localId,
- /*mozbrowser*/false);
- let perm = Services.perms.testExactPermissionFromPrincipal(principal,
- aPermission);
- return (perm === Ci.nsIPermissionManager.ALLOW_ACTION);
- };
- res.QueryInterface = function(aIID) {
- if (aIID.equals(Ci.mozIDOMApplication) ||
- aIID.equals(Ci.mozIApplication) ||
- aIID.equals(Ci.nsISupports))
- return this;
- throw Cr.NS_ERROR_NO_INTERFACE;
- }
-
+ res.__proto__ = mozIApplication.prototype;
return res;
},
View
75 dom/apps/src/Webapps.jsm
@@ -511,29 +511,38 @@ this.DOMApplicationRegistry = {
let manifest = new ManifestHelper(aManifest, aApp.origin);
for (let activity in root.activities) {
let description = root.activities[activity];
- if (!description.href) {
- description.href = manifest.launch_path;
+ let href = description.href;
+ if (!href) {
+ href = manifest.launch_path;
}
try {
- description.href = manifest.resolveFromOrigin(description.href);
+ href = manifest.resolveFromOrigin(href);
} catch (e) {
- debug("Activity href (" + description.href + ") is invalid, skipping. " +
+ debug("Activity href (" + href + ") is invalid, skipping. " +
"Error is: " + e);
continue;
}
+ // Make a copy of the description object since we don't want to modify
+ // the manifest itself, but need to register with a resolved URI.
+ let newDesc = {};
+ for (let prop in description) {
+ newDesc[prop] = description[prop];
+ }
+ newDesc.href = href;
+
debug('_createActivitiesToRegister: ' + aApp.manifestURL + ', activity ' +
- activity + ', description.href is ' + description.href);
+ activity + ', description.href is ' + newDesc.href);
if (aRunUpdate) {
activitiesToRegister.push({ "manifest": aApp.manifestURL,
"name": activity,
"icon": manifest.iconURLForSize(128),
- "description": description });
+ "description": newDesc });
}
- let launchPath = Services.io.newURI(description.href, null, null);
+ let launchPath = Services.io.newURI(href, null, null);
let manifestURL = Services.io.newURI(aApp.manifestURL, null, null);
if (SystemMessagePermissionsChecker
@@ -1171,6 +1180,9 @@ this.DOMApplicationRegistry = {
? updateSvc.scheduleCustomProfileUpdate(appcacheURI, docURI, aProfileDir)
: updateSvc.scheduleAppUpdate(appcacheURI, docURI, aApp.localId, false);
+ // initialize the progress to 0 right now
+ aApp.progress = 0;
+
// We save the download details for potential further usage like cancelling
// it.
let download = {
@@ -2017,10 +2029,6 @@ this.DOMApplicationRegistry = {
let download = AppDownloadManager.get(aApp.manifestURL);
app.downloading = false;
- // To prevent repeated prompts, wait for the next checkForUpdates to
- // try a new download.
- app.downloadAvailable = false;
-
// If there were not enough storage to download the package we
// won't have a record of the download details, so we just set the
// installState to 'pending' at first download and to 'installed' when
@@ -2042,6 +2050,13 @@ this.DOMApplicationRegistry = {
AppDownloadManager.remove(aApp.manifestURL);
}
+ function sendProgressEvent() {
+ self.broadcastMessage("Webapps:PackageEvent",
+ { type: "progress",
+ manifestURL: aApp.manifestURL,
+ app: app });
+ }
+
function download() {
debug("About to download " + aManifest.fullPackagePath());
@@ -2062,6 +2077,7 @@ this.DOMApplicationRegistry = {
);
let lastProgressTime = 0;
+
requestChannel.notificationCallbacks = {
QueryInterface: function notifQI(aIID) {
if (aIID.equals(Ci.nsISupports) ||
@@ -2080,10 +2096,7 @@ this.DOMApplicationRegistry = {
let now = Date.now();
if (now - lastProgressTime > MIN_PROGRESS_EVENT_DELAY) {
debug("onProgress: " + aProgress + "/" + aProgressMax);
- self.broadcastMessage("Webapps:PackageEvent",
- { type: "progress",
- manifestURL: aApp.manifestURL,
- app: app });
+ sendProgressEvent();
lastProgressTime = now;
self._saveApps();
}
@@ -2109,6 +2122,9 @@ this.DOMApplicationRegistry = {
// installed apps should morph to 'updating'.
app.installState = aIsUpdate ? "updating" : "pending";
+ // initialize the progress to 0 right now
+ app.progress = 0;
+
// Staging the zip in TmpD until all the checks are done.
let zipFile = FileUtils.getFile("TmpD",
["webapps", id, "application.zip"], true);
@@ -2144,6 +2160,8 @@ this.DOMApplicationRegistry = {
// network error.
let responseStatus = requestChannel.responseStatus;
if (responseStatus >= 400 && responseStatus <= 599) {
+ // unrecoverable error, don't bug the user
+ app.downloadAvailable = false;
cleanup("NETWORK_ERROR");
return;
}
@@ -2179,6 +2197,8 @@ this.DOMApplicationRegistry = {
certdb = Cc["@mozilla.org/security/x509certdb;1"]
.getService(Ci.nsIX509CertDB);
} catch (e) {
+ // unrecoverable error, don't bug the user
+ app.downloadAvailable = false;
cleanup("CERTDB_ERROR");
return;
}
@@ -2296,6 +2316,8 @@ this.DOMApplicationRegistry = {
}
} catch (e) {
// Something bad happened when reading the package.
+ // unrecoverable error, don't bug the user
+ app.downloadAvailable = false;
if (typeof e == 'object') {
Cu.reportError("Error while reading package:" + e);
cleanup("INVALID_PACKAGE");
@@ -2313,6 +2335,9 @@ this.DOMApplicationRegistry = {
});
requestChannel.asyncOpen(listener, null);
+
+ // send a first progress event to correctly set the DOM object's properties
+ sendProgressEvent();
};
let deviceStorage = Services.wm.getMostRecentWindow("navigator:browser")
@@ -2797,18 +2822,30 @@ let AppcacheObserver = function(aApp) {
this.app = aApp;
this.startStatus = aApp.installState;
this.lastProgressTime = 0;
+ // send a first progress event to correctly set the DOM object's properties
+ this._sendProgressEvent();
};
AppcacheObserver.prototype = {
// nsIOfflineCacheUpdateObserver implementation
+ _sendProgressEvent: function() {
+ let app = this.app;
+ DOMApplicationRegistry.broadcastMessage("Webapps:OfflineCache",
+ { manifest: app.manifestURL,
+ installState: app.installState,
+ progress: app.progress });
+ },
+
updateStateChanged: function appObs_Update(aUpdate, aState) {
let mustSave = false;
let app = this.app;
debug("Offline cache state change for " + app.origin + " : " + aState);
+ var self = this;
let setStatus = function appObs_setStatus(aStatus, aProgress) {
- debug("Offlinecache setStatus to " + aStatus + " for " + app.origin);
+ debug("Offlinecache setStatus to " + aStatus + " with progress " +
+ aProgress + " for " + app.origin);
mustSave = (app.installState != aStatus);
app.installState = aStatus;
app.progress = aProgress;
@@ -2816,10 +2853,7 @@ AppcacheObserver.prototype = {
app.downloading = false;
app.downloadAvailable = false;
}
- DOMApplicationRegistry.broadcastMessage("Webapps:OfflineCache",
- { manifest: app.manifestURL,
- installState: app.installState,
- progress: app.progress });
+ self._sendProgressEvent();
}
let setError = function appObs_setError(aError) {
@@ -2835,7 +2869,6 @@ AppcacheObserver.prototype = {
}
app.downloading = false;
- app.downloadAvailable = false;
mustSave = true;
}
View
2  dom/base/nsContentPermissionHelper.cpp
@@ -92,7 +92,7 @@ nsContentPermissionRequestProxy::GetElement(nsIDOMElement * *aRequestingElement)
return NS_ERROR_FAILURE;
}
- NS_ADDREF(*aRequestingElement = mParent->mElement);
+ NS_IF_ADDREF(*aRequestingElement = mParent->mElement);
return NS_OK;
}
View
1  dom/base/nsDOMClassInfo.cpp
@@ -7398,6 +7398,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *windowObj = win->GetGlobalJSObject();
+ JSAutoCompartment ac(cx, windowObj);
JSAutoRequest ar(cx);
JSFunction *fun = ::JS_NewFunction(cx, ContentWindowGetter, 0, 0,
View
15 dom/base/nsJSEnvironment.cpp
@@ -132,6 +132,9 @@ static PRLogModuleInfo* gJSDiagnostics;
#define JAVASCRIPT nsIProgrammingLanguage::JAVASCRIPT
+// Large value used to specify that a script should run essentially forever
+#define NS_UNLIMITED_SCRIPT_RUNTIME LL_INIT(0x40000000, 0)
+
// if you add statics here, add them to the list in nsJSRuntime::Startup
static nsITimer *sGCTimer;
@@ -888,8 +891,13 @@ nsJSContext::DOMOperationCallback(JSContext *cx)
// Allow the script to continue running
if (neverShowDlgChk) {
- Preferences::SetInt(isTrackingChromeCodeTime ?
- "dom.max_chrome_script_run_time" : "dom.max_script_run_time", 0);
+ if (isTrackingChromeCodeTime) {
+ Preferences::SetInt("dom.max_chrome_script_run_time", 0);
+ sMaxChromeScriptRunTime = NS_UNLIMITED_SCRIPT_RUNTIME;
+ } else {
+ Preferences::SetInt("dom.max_script_run_time", 0);
+ sMaxScriptRunTime = NS_UNLIMITED_SCRIPT_RUNTIME;
+ }
}
ctx->mOperationCallbackTime = PR_Now();
@@ -3779,8 +3787,7 @@ MaxScriptRunTimePrefChangedCallback(const char *aPrefName, void *aClosure)
PRTime t;
if (time <= 0) {
- // Let scripts run for a really, really long time.
- t = LL_INIT(0x40000000, 0);
+ t = NS_UNLIMITED_SCRIPT_RUNTIME;
} else {
t = time * PR_USEC_PER_SEC;
}
View
38 dom/bluetooth/linux/BluetoothDBusService.cpp
@@ -29,6 +29,7 @@
#include <cstdio>
#include <dbus/dbus.h>
+#include "pratom.h"
#include "nsAutoPtr.h"
#include "nsThreadUtils.h"
#include "nsDebug.h"
@@ -151,7 +152,7 @@ static const char* sBluetoothDBusSignals[] =
static nsAutoPtr<RawDBusConnection> gThreadConnection;
static nsDataHashtable<nsStringHashKey, DBusMessage* > sPairingReqTable;
static nsDataHashtable<nsStringHashKey, DBusMessage* > sAuthorizeReqTable;
-static bool sIsPairing = false;
+static PRInt32 sIsPairing = 0;
typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&);
class RemoveDeviceTask : public nsRunnable {
@@ -907,8 +908,7 @@ GetObjectPathCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
if (sIsPairing) {
RunDBusCallback(aMsg, aBluetoothReplyRunnable,
UnpackObjectPathMessage);
-
- sIsPairing = false;
+ PR_AtomicDecrement(&sIsPairing);
}
}
@@ -1655,7 +1655,7 @@ BluetoothDBusService::StopInternal()
sAuthorizeReqTable.EnumerateRead(UnrefDBusMessages, nullptr);
sAuthorizeReqTable.Clear();
- sIsPairing = false;
+ PR_AtomicSet(&sIsPairing, 0);
StopDBus();
return NS_OK;
@@ -2154,6 +2154,20 @@ BluetoothDBusService::CreatePairedDeviceInternal(const nsAString& aAdapterPath,
nsCString tempDeviceAddress = NS_ConvertUTF16toUTF8(aDeviceAddress);
const char *deviceAddress = tempDeviceAddress.get();
+ /**
+ * FIXME: Bug 820274
+ *
+ * If the user turns off Bluetooth in the middle of pairing process, the
+ * callback function GetObjectPathCallback (see the third argument of the
+ * function call above) may still be called while enabling next time by
+ * dbus daemon. To prevent this from happening, added a flag to distinguish
+ * if Bluetooth has been turned off. Nevertheless, we need a check if there
+ * is a better solution.
+ *
+ * Please see Bug 818696 for more information.
+ */
+ PR_AtomicIncrement(&sIsPairing);
+
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
// Then send CreatePairedDevice, it will register a temp device agent then
// unregister it after pairing process is over
@@ -2168,27 +2182,11 @@ BluetoothDBusService::CreatePairedDeviceInternal(const nsAString& aAdapterPath,
DBUS_TYPE_OBJECT_PATH, &deviceAgentPath,
DBUS_TYPE_STRING, &capabilities,
DBUS_TYPE_INVALID);
-
if (!ret) {
NS_WARNING("Could not start async function!");
return NS_ERROR_FAILURE;
}
-
- /**
- * FIXME: Bug 820274
- *
- * If the user turns off Bluetooth in the middle of pairing process, the
- * callback function GetObjectPathCallback (see the third argument of the
- * function call above) may still be called while enabling next time by
- * dbus daemon. To prevent this from happening, added a flag to distinguish
- * if Bluetooth has been turned off. Nevertheless, we need a check if there
- * is a better solution.
- *
- * Please see Bug 818696 for more information.
- */
- sIsPairing = true;
-
runnable.forget();
return NS_OK;
}
View
841 dom/browser-element/BrowserElementChild.js
@@ -8,838 +8,29 @@ let { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Geometry.jsm");
-Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
-
-// Event whitelisted for bubbling.
-let whitelistedEvents = [
- Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE, // Back button.
- Ci.nsIDOMKeyEvent.DOM_VK_SLEEP, // Power button.
- Ci.nsIDOMKeyEvent.DOM_VK_CONTEXT_MENU,
- Ci.nsIDOMKeyEvent.DOM_VK_F5, // Search button.
- Ci.nsIDOMKeyEvent.DOM_VK_PAGE_UP, // Volume up.
- Ci.nsIDOMKeyEvent.DOM_VK_PAGE_DOWN // Volume down.
-];
function debug(msg) {
//dump("BrowserElementChild - " + msg + "\n");
}
-function sendAsyncMsg(msg, data) {
- if (!data) {
- data = { };
- }
-
- data.msg_name = msg;
- sendAsyncMessage('browser-element-api:call', data);
-}
-
-function sendSyncMsg(msg, data) {
- if (!data) {
- data = { };
- }
-
- data.msg_name = msg;
- return sendSyncMessage('browser-element-api:call', data);
-}
-
-/**
- * The BrowserElementChild implements one half of <iframe mozbrowser>.
- * (The other half is, unsurprisingly, BrowserElementParent.)
- *
- * This script is injected into an <iframe mozbrowser> via
- * nsIMessageManager::LoadFrameScript().
- *
- * Our job here is to listen for events within this frame and bubble them up to
- * the parent process.
- */
-
-var global = this;
-
-function BrowserElementChild() {
- // Maps outer window id --> weak ref to window. Used by modal dialog code.
- this._windowIDDict = {};
-
- // _forcedVisible corresponds to the visibility state our owner has set on us
- // (via iframe.setVisible). ownerVisible corresponds to whether the docShell
- // whose window owns this element is visible.
- //
- // Our docShell is visible iff _forcedVisible and _ownerVisible are both
- // true.
- this._forcedVisible = true;
- this._ownerVisible = true;
-
- this._nextPaintHandler = null;
-
- this._init();
-};
-
-BrowserElementChild.prototype = {
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
- Ci.nsISupportsWeakReference]),
-
- _init: function() {
- debug("Starting up.");
-
- // NB: this must happen before we process any messages from
- // mozbrowser API clients.
- docShell.isActive = true;
-
- sendAsyncMsg("hello");
-
- // Set the docshell's name according to our <iframe>'s name attribute.
- docShell.QueryInterface(Ci.nsIDocShellTreeItem).name =
- sendSyncMsg('get-name')[0];
-
- docShell.setFullscreenAllowed(sendSyncMsg('get-fullscreen-allowed')[0]);
-
- BrowserElementPromptService.mapWindowToBrowserElementChild(content, this);
-
- docShell.QueryInterface(Ci.nsIWebProgress)
- .addProgressListener(this._progressListener,
- Ci.nsIWebProgress.NOTIFY_LOCATION |
- Ci.nsIWebProgress.NOTIFY_SECURITY |
- Ci.nsIWebProgress.NOTIFY_STATE_WINDOW);
-
- docShell.QueryInterface(Ci.nsIWebNavigation)
- .sessionHistory = Cc["@mozilla.org/browser/shistory;1"]
- .createInstance(Ci.nsISHistory);
-
- // This is necessary to get security web progress notifications.
- var securityUI = Cc['@mozilla.org/secure_browser_ui;1']
- .createInstance(Ci.nsISecureBrowserUI);
- securityUI.init(content);
-
- // A cache of the menuitem dom objects keyed by the id we generate
- // and pass to the embedder
- this._ctxHandlers = {};
- // Counter of contextmenu events fired
- this._ctxCounter = 0;
-
- addEventListener('DOMTitleChanged',
- this._titleChangedHandler.bind(this),
- /* useCapture = */ true,
- /* wantsUntrusted = */ false);
-
- addEventListener('DOMLinkAdded',
- this._iconChangedHandler.bind(this),
- /* useCapture = */ true,
- /* wantsUntrusted = */ false);
-
- // Registers a MozAfterPaint handler for the very first paint.
- this._addMozAfterPaintHandler(function () {
- sendAsyncMsg('firstpaint');
- });
-
- let self = this;
-
- let mmCalls = {
- "purge-history": this._recvPurgeHistory,
- "get-screenshot": this._recvGetScreenshot,
- "set-visible": this._recvSetVisible,
- "get-visible": this._recvVisible,
- "send-mouse-event": this._recvSendMouseEvent,
- "send-touch-event": this._recvSendTouchEvent,
- "get-can-go-back": this._recvCanGoBack,
- "get-can-go-forward": this._recvCanGoForward,
- "go-back": this._recvGoBack,
- "go-forward": this._recvGoForward,
- "reload": this._recvReload,
- "stop": this._recvStop,
- "unblock-modal-prompt": this._recvStopWaiting,
- "fire-ctx-callback": this._recvFireCtxCallback,
- "owner-visibility-change": this._recvOwnerVisibilityChange,
- "exit-fullscreen": this._recvExitFullscreen.bind(this),
- "activate-next-paint-listener": this._activateNextPaintListener.bind(this),
- "deactivate-next-paint-listener": this._deactivateNextPaintListener.bind(this)
- }
-
- addMessageListener("browser-element-api:call", function(aMessage) {
- if (aMessage.data.msg_name in mmCalls) {
- return mmCalls[aMessage.data.msg_name].apply(self, arguments);
- }
- });
-
- let els = Cc["@mozilla.org/eventlistenerservice;1"]
- .getService(Ci.nsIEventListenerService);
-
- // We are using the system group for those events so if something in the
- // content called .stopPropagation() this will still be called.
- els.addSystemEventListener(global, 'keydown',
- this._keyEventHandler.bind(this),
- /* useCapture = */ true);
- els.addSystemEventListener(global, 'keypress',
- this._keyEventHandler.bind(this),
- /* useCapture = */ true);
- els.addSystemEventListener(global, 'keyup',
- this._keyEventHandler.bind(this),
- /* useCapture = */ true);
- els.addSystemEventListener(global, 'DOMWindowClose',
- this._closeHandler.bind(this),
- /* useCapture = */ false);
- els.addSystemEventListener(global, 'contextmenu',
- this._contextmenuHandler.bind(this),
- /* useCapture = */ false);
- els.addSystemEventListener(global, 'scroll',
- this._scrollEventHandler.bind(this),
- /* useCapture = */ false);
-
- Services.obs.addObserver(this,
- "fullscreen-origin-change",
- /* ownsWeak = */ true);
-
- Services.obs.addObserver(this,
- 'ask-parent-to-exit-fullscreen',
- /* ownsWeak = */ true);
-
- Services.obs.addObserver(this,
- 'ask-parent-to-rollback-fullscreen',
- /* ownsWeak = */ true);
- },
-
- observe: function(subject, topic, data) {
- // Ignore notifications not about our document.
- if (subject != content.document)
- return;
- switch (topic) {
- case 'fullscreen-origin-change':
- sendAsyncMsg('fullscreen-origin-change', { _payload_: data });
- break;
- case 'ask-parent-to-exit-fullscreen':
- sendAsyncMsg('exit-fullscreen');
- break;
- case 'ask-parent-to-rollback-fullscreen':
- sendAsyncMsg('rollback-fullscreen');
- break;
- }
- },
-
- _tryGetInnerWindowID: function(win) {
- let utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- try {
- return utils.currentInnerWindowID;
- }
- catch(e) {
- return null;
- }
- },
-
- /**
- * Show a modal prompt. Called by BrowserElementPromptService.
- */
- showModalPrompt: function(win, args) {
- let utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
-
- args.windowID = { outer: utils.outerWindowID,
- inner: this._tryGetInnerWindowID(win) };
- sendAsyncMsg('showmodalprompt', args);
-
- let returnValue = this._waitForResult(win);
-
- if (args.promptType == 'prompt' ||
- args.promptType == 'confirm' ||
- args.promptType == 'custom-prompt') {
- return returnValue;
- }
- },
-
- /**
- * Spin in a nested event loop until we receive a unblock-modal-prompt message for
- * this window.
- */
- _waitForResult: function(win) {
- debug("_waitForResult(" + win + ")");
- let utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
-
- let outerWindowID = utils.outerWindowID;
- let innerWindowID = this._tryGetInnerWindowID(win);
- if (innerWindowID === null) {
- // I have no idea what waiting for a result means when there's no inner
- // window, so let's just bail.
- debug("_waitForResult: No inner window. Bailing.");
- return;
- }
-
- this._windowIDDict[outerWindowID] = Cu.getWeakReference(win);
-
- debug("Entering modal state (outerWindowID=" + outerWindowID + ", " +
- "innerWindowID=" + innerWindowID + ")");
-
- // In theory, we're supposed to pass |modalStateWin| back to
- // leaveModalStateWithWindow. But in practice, the window is always null,
- // because it's the window associated with this script context, which
- // doesn't have a window. But we'll play along anyway in case this
- // changes.
- var modalStateWin = utils.enterModalStateWithWindow();
-
- // We'll decrement win.modalDepth when we receive a unblock-modal-prompt message
- // for the window.
- if (!win.modalDepth) {
- win.modalDepth = 0;
- }
- win.modalDepth++;
- let origModalDepth = win.modalDepth;
-
- let thread = Services.tm.currentThread;
- debug("Nested event loop - begin");
- while (win.modalDepth == origModalDepth) {
- // Bail out of the loop if the inner window changed; that means the
- // window navigated.
- if (this._tryGetInnerWindowID(win) !== innerWindowID) {
- debug("_waitForResult: Inner window ID changed " +
- "while in nested event loop.");
- break;
- }
-
- thread.processNextEvent(/* mayWait = */ true);
- }
- debug("Nested event loop - finish");
-
- // If we exited the loop because the inner window changed, then bail on the
- // modal prompt.
- if (innerWindowID !== this._tryGetInnerWindowID(win)) {
- throw Components.Exception("Modal state aborted by navigation",
- Cr.NS_ERROR_NOT_AVAILABLE);
- }
-
- let returnValue = win.modalReturnValue;
- delete win.modalReturnValue;
-
- utils.leaveModalStateWithWindow(modalStateWin);
-
- debug("Leaving modal state (outerID=" + outerWindowID + ", " +
- "innerID=" + innerWindowID + ")");
- return returnValue;
- },
-
- _recvStopWaiting: function(msg) {
- let outerID = msg.json.windowID.outer;
- let innerID = msg.json.windowID.inner;
- let returnValue = msg.json.returnValue;
- debug("recvStopWaiting(outer=" + outerID + ", inner=" + innerID +
- ", returnValue=" + returnValue + ")");
-
- if (!this._windowIDDict[outerID]) {
- debug("recvStopWaiting: No record of outer window ID " + outerID);
- return;
- }
-
- let win = this._windowIDDict[outerID].get();
- delete this._windowIDDict[outerID];
-
- if (!win) {
- debug("recvStopWaiting, but window is gone\n");
- return;
- }
-
- if (innerID !== this._tryGetInnerWindowID(win)) {
- debug("recvStopWaiting, but inner ID has changed\n");
- return;
- }
-
- debug("recvStopWaiting " + win);
- win.modalReturnValue = returnValue;
- win.modalDepth--;
- },
-
- _recvExitFullscreen: function() {
- var utils = content.document.defaultView
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- utils.exitFullscreen();
- },
-
- _titleChangedHandler: function(e) {
- debug("Got titlechanged: (" + e.target.title + ")");
- var win = e.target.defaultView;
-
- // Ignore titlechanges which don't come from the top-level
- // <iframe mozbrowser> window.
- if (win == content) {
- sendAsyncMsg('titlechange', { _payload_: e.target.title });
- }
- else {
- debug("Not top level!");
- }
- },
-
- _iconChangedHandler: function(e) {
- debug("Got iconchanged: (" + e.target.href + ")");
- var hasIcon = e.target.rel.split(' ').some(function(x) {
- return x.toLowerCase() === 'icon';
- });
-
- if (hasIcon) {
- var win = e.target.ownerDocument.defaultView;
- // Ignore iconchanges which don't come from the top-level
- // <iframe mozbrowser> window.
- if (win == content) {
- sendAsyncMsg('iconchange', { _payload_: e.target.href });
- }
- else {
- debug("Not top level!");
- }
- }
- },
-
- _addMozAfterPaintHandler: function(callback) {
- function onMozAfterPaint() {
- let uri = docShell.QueryInterface(Ci.nsIWebNavigation).currentURI;
- debug("Got afterpaint event: " + uri.spec);
- if (uri.spec != "about:blank") {
- removeEventListener('MozAfterPaint', onMozAfterPaint,
- /* useCapture = */ true);
- callback();
- }
- }
+// NB: this must happen before we process any messages from
+// mozbrowser API clients.
+docShell.isActive = true;
- addEventListener('MozAfterPaint', onMozAfterPaint, /* useCapture = */ true);
- return onMozAfterPaint;
- },
+let infos = sendSyncMessage('browser-element-api:call',
+ { 'msg_name': 'hello' })[0];
+docShell.QueryInterface(Ci.nsIDocShellTreeItem).name = infos.name;
+docShell.setFullscreenAllowed(infos.fullscreenAllowed);
- _removeMozAfterPaintHandler: function(listener) {
- removeEventListener('MozAfterPaint', listener,
- /* useCapture = */ true);
- },
- _activateNextPaintListener: function(e) {
- if (!this._nextPaintHandler) {
- this._nextPaintHandler = this._addMozAfterPaintHandler(function () {
- this._nextPaintHandler = null;
- sendAsyncMsg('nextpaint');
- }.bind(this));
- }
- },
-
- _deactivateNextPaintListener: function(e) {
- if (this._nextPaintHandler) {
- this._removeMozAfterPaintHandler(this._nextPaintHandler);
- this._nextPaintHandler = null;
- }
- },
-
- _closeHandler: function(e) {
- let win = e.target;
- if (win != content || e.defaultPrevented) {
- return;
- }
-
- debug("Closing window " + win);
- sendAsyncMsg('close');
-
- // Inform the window implementation that we handled this close ourselves.
- e.preventDefault();
- },
-
- _contextmenuHandler: function(e) {
- debug("Got contextmenu");
-
- if (e.defaultPrevented) {
- return;
- }
-
- e.preventDefault();
-
- this._ctxCounter++;
- this._ctxHandlers = {};
-
- var elem = e.target;
- var menuData = {systemTargets: [], contextmenu: null};
- var ctxMenuId = null;
-
- while (elem && elem.parentNode) {
- var ctxData = this._getSystemCtxMenuData(elem);
- if (ctxData) {
- menuData.systemTargets.push({
- nodeName: elem.nodeName,
- data: ctxData
- });
- }
-
- if (!ctxMenuId && 'hasAttribute' in elem && elem.hasAttribute('contextmenu')) {
- ctxMenuId = elem.getAttribute('contextmenu');
- }
- elem = elem.parentNode;
- }
-
- if (ctxMenuId) {
- var menu = e.target.ownerDocument.getElementById(ctxMenuId);
- if (menu) {
- menuData.contextmenu = this._buildMenuObj(menu, '');
- }
- }
- sendAsyncMsg('contextmenu', menuData);
- },
-
- _getSystemCtxMenuData: function(elem) {
- if ((elem instanceof Ci.nsIDOMHTMLAnchorElement && elem.href) ||
- (elem instanceof Ci.nsIDOMHTMLAreaElement && elem.href)) {
- return elem.href;
- }
- if (elem instanceof Ci.nsIImageLoadingContent && elem.currentURI) {
- return elem.currentURI.spec;
- }
- if ((elem instanceof Ci.nsIDOMHTMLMediaElement) ||
- (elem instanceof Ci.nsIDOMHTMLImageElement)) {
- return elem.currentSrc || elem.src;
- }
- return false;
- },
-
- _scrollEventHandler: function(e) {
- let win = e.target.defaultView;
- if (win != content) {
- return;
- }
-
- debug("scroll event " + win);
- sendAsyncMsg("scroll", { top: win.scrollY, left: win.scrollX });
- },
-
- _recvPurgeHistory: function(data) {
- debug("Received purgeHistory message: (" + data.json.id + ")");
-
- let history = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
-
- try {
- if (history && history.count) {
- history.PurgeHistory(history.count);
- }
- } catch(e) {}
-
- sendAsyncMsg('got-purge-history', { id: data.json.id, successRv: true });
- },
-
- _recvGetScreenshot: function(data) {
- debug("Received getScreenshot message: (" + data.json.id + ")");
-
- let self = this;
- let maxWidth = data.json.args.width;
- let maxHeight = data.json.args.height;
- let domRequestID = data.json.id;
-
- let takeScreenshotClosure = function() {
- self._takeScreenshot(maxWidth, maxHeight, domRequestID);
- };
-
- let maxDelayMS = 2000;
- try {
- maxDelayMS = Services.prefs.getIntPref('dom.browserElement.maxScreenshotDelayMS');
- }
- catch(e) {}
-
- // Try to wait for the event loop to go idle before we take the screenshot,
- // but once we've waited maxDelayMS milliseconds, go ahead and take it
- // anyway.
- Cc['@mozilla.org/message-loop;1'].getService(Ci.nsIMessageLoop).postIdleTask(
- takeScreenshotClosure, maxDelayMS);
- },
-
- /**
- * Actually take a screenshot and foward the result up to our parent, given
- * the desired maxWidth and maxHeight, and given the DOMRequest ID associated
- * with the request from the parent.
- */
- _takeScreenshot: function(maxWidth, maxHeight, domRequestID) {
- // You can think of the screenshotting algorithm as carrying out the
- // following steps:
- //
- // - Let scaleWidth be the factor by which we'd need to downscale the
- // viewport so it would fit within maxWidth. (If the viewport's width
- // is less than maxWidth, let scaleWidth be 1.) Compute scaleHeight
- // the same way.
- //
- // - Scale the viewport by max(scaleWidth, scaleHeight). Now either the
- // viewport's width is no larger than maxWidth, the viewport's height is
- // no larger than maxHeight, or both.
- //
- // - Crop the viewport so its width is no larger than maxWidth and its
- // height is no larger than maxHeight.
- //
- // - Return a screenshot of the page's viewport scaled and cropped per
- // above.
- debug("Taking a screenshot: maxWidth=" + maxWidth +
- ", maxHeight=" + maxHeight +
- ", domRequestID=" + domRequestID + ".");
-
- let scaleWidth = Math.min(1, maxWidth / content.innerWidth);
- let scaleHeight = Math.min(1, maxHeight / content.innerHeight);
-
- let scale = Math.max(scaleWidth, scaleHeight);
-
- let canvasWidth = Math.min(maxWidth, Math.round(content.innerWidth * scale));
- let canvasHeight = Math.min(maxHeight, Math.round(content.innerHeight * scale));
-
- var canvas = content.document
- .createElementNS("http://www.w3.org/1999/xhtml", "canvas");
- canvas.mozOpaque = true;
- canvas.width = canvasWidth;
- canvas.height = canvasHeight;
-
- var ctx = canvas.getContext("2d");
- ctx.scale(scale, scale);
- ctx.drawWindow(content, 0, 0, content.innerWidth, content.innerHeight,
- "rgb(255,255,255)");
-
- // Take a JPEG screenshot to hack around the fact that we can't specify
- // opaque PNG. This requires us to unpremultiply the alpha channel, which
- // is expensive on ARM processors because they lack a hardware integer
- // division instruction.
- canvas.toBlob(function(blob) {
- sendAsyncMsg('got-screenshot', {
- id: domRequestID,
- successRv: blob
- });
- }, 'image/jpeg');
- },
-
- _recvFireCtxCallback: function(data) {
- debug("Received fireCtxCallback message: (" + data.json.menuitem + ")");
- // We silently ignore if the embedder uses an incorrect id in the callback
- if (data.json.menuitem in this._ctxHandlers) {
- this._ctxHandlers[data.json.menuitem].click();
- this._ctxHandlers = {};
- } else {
- debug("Ignored invalid contextmenu invocation");
- }
- },
-
- _buildMenuObj: function(menu, idPrefix) {
- function maybeCopyAttribute(src, target, attribute) {
- if (src.getAttribute(attribute)) {
- target[attribute] = src.getAttribute(attribute);
- }
- }
-
- var menuObj = {type: 'menu', items: []};
- maybeCopyAttribute(menu, menuObj, 'label');
-
- for (var i = 0, child; child = menu.children[i++];) {
- if (child.nodeName === 'MENU') {
- menuObj.items.push(this._buildMenuObj(child, idPrefix + i + '_'));
- } else if (child.nodeName === 'MENUITEM') {
- var id = this._ctxCounter + '_' + idPrefix + i;
- var menuitem = {id: id, type: 'menuitem'};
- maybeCopyAttribute(child, menuitem, 'label');
- maybeCopyAttribute(child, menuitem, 'icon');
- this._ctxHandlers[id] = child;
- menuObj.items.push(menuitem);
- }
- }
- return menuObj;
- },
-
- _recvSetVisible: function(data) {
- debug("Received setVisible message: (" + data.json.visible + ")");
- this._forcedVisible = data.json.visible;
- this._updateDocShellVisibility();
- },
-
- _recvVisible: function(data) {
- sendAsyncMsg('got-visible', {
- id: data.json.id,
- successRv: docShell.isActive
- });
- },
-
- /**
- * Called when the window which contains this iframe becomes hidden or
- * visible.
- */
- _recvOwnerVisibilityChange: function(data) {
- debug("Received ownerVisibilityChange: (" + data.json.visible + ")");
- this._ownerVisible = data.json.visible;
- this._updateDocShellVisibility();
- },
-
- _updateDocShellVisibility: function() {
- var visible = this._forcedVisible && this._ownerVisible;
- if (docShell.isActive !== visible) {
- docShell.isActive = visible;
- }
- },
-
- _recvSendMouseEvent: function(data) {
- let json = data.json;
- let utils = content.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- utils.sendMouseEvent(json.type, json.x, json.y, json.button,
- json.clickCount, json.modifiers);
- },
-
- _recvSendTouchEvent: function(data) {
- let json = data.json;
- let utils = content.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- utils.sendTouchEvent(json.type, json.identifiers, json.touchesX,
- json.touchesY, json.radiisX, json.radiisY,
- json.rotationAngles, json.forces, json.count,
- json.modifiers);
- },
-
- _recvCanGoBack: function(data) {
- var webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
- sendAsyncMsg('got-can-go-back', {
- id: data.json.id,
- successRv: webNav.canGoBack
- });
- },
-
- _recvCanGoForward: function(data) {
- var webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
- sendAsyncMsg('got-can-go-forward', {
- id: data.json.id,
- successRv: webNav.canGoForward
- });
- },
-
- _recvGoBack: function(data) {
- try {
- docShell.QueryInterface(Ci.nsIWebNavigation).goBack();
- } catch(e) {
- // Silently swallow errors; these happen when we can't go back.
- }
- },
-
- _recvGoForward: function(data) {
- try {
- docShell.QueryInterface(Ci.nsIWebNavigation).goForward();
- } catch(e) {
- // Silently swallow errors; these happen when we can't go forward.
- }
- },
-
- _recvReload: function(data) {
- let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
- let reloadFlags = data.json.hardReload ?
- webNav.LOAD_FLAGS_BYPASS_PROXY | webNav.LOAD_FLAGS_BYPASS_CACHE :
- webNav.LOAD_FLAGS_NONE;
- try {
- webNav.reload(reloadFlags);
- } catch(e) {
- // Silently swallow errors; these can happen if a used cancels reload
- }
- },
-
- _recvStop: function(data) {
- let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
- webNav.stop(webNav.STOP_NETWORK);
- },
-
- _keyEventHandler: function(e) {
- if (whitelistedEvents.indexOf(e.keyCode) != -1 && !e.defaultPrevented) {
- sendAsyncMsg('keyevent', {
- type: e.type,
- keyCode: e.keyCode,
- charCode: e.charCode,
- });
- }
- },
-
- // The docShell keeps a weak reference to the progress listener, so we need
- // to keep a strong ref to it ourselves.
- _progressListener: {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
- Ci.nsISupportsWeakReference]),
- _seenLoadStart: false,
-
- onLocationChange: function(webProgress, request, location, flags) {
- // We get progress events from subshells here, which is kind of weird.
- if (webProgress != docShell) {
- return;
- }
-
- // Ignore locationchange events which occur before the first loadstart.
- // These are usually about:blank loads we don't care about.
- if (!this._seenLoadStart) {
- return;
- }
-
- // Remove password and wyciwyg from uri.
- location = Cc["@mozilla.org/docshell/urifixup;1"]
- .getService(Ci.nsIURIFixup).createExposableURI(location);
-
- sendAsyncMsg('locationchange', { _payload_: location.spec });
- },
-
- onStateChange: function(webProgress, request, stateFlags, status) {
- if (webProgress != docShell) {
- return;
- }
-
- if (stateFlags & Ci.nsIWebProgressListener.STATE_START) {
- this._seenLoadStart = true;
- sendAsyncMsg('loadstart');
- }
-
- if (stateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
- sendAsyncMsg('loadend');
-
- // Ignoring NS_BINDING_ABORTED, which is set when loading page is
- // stopped.
- if (status == Cr.NS_OK ||
- status == Cr.NS_BINDING_ABORTED) {
- return;
- }
-
- // TODO See nsDocShell::DisplayLoadError for a list of all the error
- // codes (the status param) we should eventually handle here.
- sendAsyncMsg('error', { type: 'other' });
- }
- },
-
- onSecurityChange: function(webProgress, request, state) {
- if (webProgress != docShell) {
- return;
- }
-
- var stateDesc;
- if (state & Ci.nsIWebProgressListener.STATE_IS_SECURE) {
- stateDesc = 'secure';
- }
- else if (state & Ci.nsIWebProgressListener.STATE_IS_BROKEN) {
- stateDesc = 'broken';
- }
- else if (state & Ci.nsIWebProgressListener.STATE_IS_INSECURE) {
- stateDesc = 'insecure';
- }
- else {
- debug("Unexpected securitychange state!");
- stateDesc = '???';
- }
-
- // XXX Until bug 764496 is fixed, this will always return false.
- var isEV = !!(state & Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL);
-
- sendAsyncMsg('securitychange', { state: stateDesc, extendedValidation: isEV });
- },
-
- onStatusChange: function(webProgress, request, status, message) {},
- onProgressChange: function(webProgress, request, curSelfProgress,
- maxSelfProgress, curTotalProgress, maxTotalProgress) {},
- },
-
- // Expose the message manager for WebApps and others.
- _messageManagerPublic: {
- sendAsyncMessage: global.sendAsyncMessage.bind(global),
- sendSyncMessage: global.sendSyncMessage.bind(global),
- addMessageListener: global.addMessageListener.bind(global),
- removeMessageListener: global.removeMessageListener.bind(global)
- },
-
- get messageManager() {
- return this._messageManagerPublic;
+if (!('BrowserElementIsPreloaded' in this)) {
+ // This is a produc-specific file that's sometimes unavailable.
+ try {
+ Services.scriptloader.loadSubScript("chrome://browser/content/forms.js");
+ } catch (e) {
}
-};
-
-var api = new BrowserElementChild();
+ Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementPanning.js");
+ Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementChildPreload.js");
+}
-// FIXME/bug 775438: use a JSM?
-//
-// The code in this included file depends on the |addEventListener|,
-// |addMessageListener|, |content|, |Geometry| and |Services| symbols
-// being "exported" from here.
-#include BrowserElementScrolling.js
+var BrowserElementIsReady = true;
View
826 dom/browser-element/BrowserElementChildPreload.js
@@ -0,0 +1,826 @@
+/* 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";
+
+dump("######################## BrowserElementChildPreload.js loaded\n");
+
+var BrowserElementIsReady = false;
+
+let { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
+
+// Event whitelisted for bubbling.
+let whitelistedEvents = [
+ Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE, // Back button.
+ Ci.nsIDOMKeyEvent.DOM_VK_SLEEP, // Power button.
+ Ci.nsIDOMKeyEvent.DOM_VK_CONTEXT_MENU,
+ Ci.nsIDOMKeyEvent.DOM_VK_F5, // Search button.
+ Ci.nsIDOMKeyEvent.DOM_VK_PAGE_UP, // Volume up.
+ Ci.nsIDOMKeyEvent.DOM_VK_PAGE_DOWN // Volume down.
+];
+
+function debug(msg) {
+ //dump("BrowserElementChildPreload - " + msg + "\n");
+}
+
+function sendAsyncMsg(msg, data) {
+ // Ensure that we don't send any messages before BrowserElementChild.js
+ // finishes loading.
+ if (!BrowserElementIsReady)
+ return;
+
+ if (!data) {
+ data = { };
+ }
+
+ data.msg_name = msg;
+ sendAsyncMessage('browser-element-api:call', data);
+}
+
+/**
+ * The BrowserElementChild implements one half of <iframe mozbrowser>.
+ * (The other half is, unsurprisingly, BrowserElementParent.)
+ *
+ * This script is injected into an <iframe mozbrowser> via
+ * nsIMessageManager::LoadFrameScript().
+ *
+ * Our job here is to listen for events within this frame and bubble them up to
+ * the parent process.
+ */
+
+var global = this;
+
+function BrowserElementChild() {
+ // Maps outer window id --> weak ref to window. Used by modal dialog code.
+ this._windowIDDict = {};
+
+ // _forcedVisible corresponds to the visibility state our owner has set on us
+ // (via iframe.setVisible). ownerVisible corresponds to whether the docShell
+ // whose window owns this element is visible.
+ //
+ // Our docShell is visible iff _forcedVisible and _ownerVisible are both
+ // true.
+ this._forcedVisible = true;
+ this._ownerVisible = true;
+
+ this._nextPaintHandler = null;
+
+ this._init();
+};
+
+BrowserElementChild.prototype = {
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
+ Ci.nsISupportsWeakReference]),
+
+ _init: function() {
+ debug("Starting up.");
+
+ BrowserElementPromptService.mapWindowToBrowserElementChild(content, this);
+
+ docShell.QueryInterface(Ci.nsIWebProgress)
+ .addProgressListener(this._progressListener,
+ Ci.nsIWebProgress.NOTIFY_LOCATION |
+ Ci.nsIWebProgress.NOTIFY_SECURITY |
+ Ci.nsIWebProgress.NOTIFY_STATE_WINDOW);
+
+ docShell.QueryInterface(Ci.nsIWebNavigation)
+ .sessionHistory = Cc["@mozilla.org/browser/shistory;1"]
+ .createInstance(Ci.nsISHistory);
+
+ // This is necessary to get security web progress notifications.
+ var securityUI = Cc['@mozilla.org/secure_browser_ui;1']
+ .createInstance(Ci.nsISecureBrowserUI);
+ securityUI.init(content);
+
+ // A cache of the menuitem dom objects keyed by the id we generate
+ // and pass to the embedder
+ this._ctxHandlers = {};
+ // Counter of contextmenu events fired
+ this._ctxCounter = 0;
+
+ addEventListener('DOMTitleChanged',
+ this._titleChangedHandler.bind(this),
+ /* useCapture = */ true,
+ /* wantsUntrusted = */ false);
+
+ addEventListener('DOMLinkAdded',