Bug 757859 - Add getSize/onResize methods to browser element. r=ehsan
authorDale Harvey <dale@arandomurl.com>
Wed, 03 Sep 2014 16:20:21 +0100
changeset 203387 0f89f564efdb7b7d6922859e3433d3af0b40f835
parent 203386 ecde022a7e52bdee0c19b1f1953489600670f850
child 203388 7b20a4e9ce15652b2bbb2469cc5d63293f6716a1
push id27425
push userryanvm@gmail.com
push dateWed, 03 Sep 2014 20:38:59 +0000
treeherdermozilla-central@acbdce59da2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs757859
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 757859 - Add getSize/onResize methods to browser element. r=ehsan
dom/browser-element/BrowserElementChildPreload.js
dom/browser-element/BrowserElementParent.jsm
dom/browser-element/mochitest/browserElement_GetContentDimensions.js
dom/browser-element/mochitest/mochitest-oop.ini
dom/browser-element/mochitest/mochitest.ini
dom/browser-element/mochitest/test_browserElement_inproc_GetContentDimensions.html
dom/browser-element/mochitest/test_browserElement_oop_GetContentDimensions.html
--- a/dom/browser-element/BrowserElementChildPreload.js
+++ b/dom/browser-element/BrowserElementChildPreload.js
@@ -191,16 +191,21 @@ BrowserElementChild.prototype = {
                      /* useCapture = */ true,
                      /* wantsUntrusted = */ false);
 
     addEventListener('DOMLinkAdded',
                      this._linkAddedHandler.bind(this),
                      /* useCapture = */ true,
                      /* wantsUntrusted = */ false);
 
+    addEventListener('MozScrolledAreaChanged',
+                     this._mozScrollAreaChanged.bind(this),
+                     /* useCapture = */ true,
+                     /* wantsUntrusted = */ false);
+
     addEventListener('DOMMetaAdded',
                      this._metaChangedHandler.bind(this),
                      /* useCapture = */ true,
                      /* wantsUntrusted = */ false);
 
     addEventListener('DOMMetaChanged',
                      this._metaChangedHandler.bind(this),
                      /* useCapture = */ true,
@@ -231,16 +236,17 @@ BrowserElementChild.prototype = {
       sendAsyncMsg('firstpaint');
     });
 
     let self = this;
 
     let mmCalls = {
       "purge-history": this._recvPurgeHistory,
       "get-screenshot": this._recvGetScreenshot,
+      "get-contentdimensions": this._recvGetContentDimensions,
       "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,
@@ -869,16 +875,39 @@ BrowserElementChild.prototype = {
 
     // 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);
   },
 
+  _recvGetContentDimensions: function(data) {
+    debug("Received getContentDimensions message: (" + data.json.id + ")");
+    sendAsyncMsg('got-contentdimensions', {
+      id: data.json.id,
+      successRv: this._getContentDimensions()
+    });
+  },
+
+  _mozScrollAreaChanged: function(e) {
+    let dimensions = this._getContentDimensions();
+    sendAsyncMsg('scrollareachanged', {
+      width: dimensions.width,
+      height: dimensions.height
+    });
+  },
+
+  _getContentDimensions: function() {
+    return {
+      width: content.document.body.scrollWidth,
+      height: content.document.body.scrollHeight
+    }
+  },
+
   /**
    * Actually take a screenshot and foward the result up to our parent, given
    * the desired maxWidth and maxHeight (in CSS pixels), and given the
    * DOMRequest ID associated with the request from the parent.
    */
   _takeScreenshot: function(maxWidth, maxHeight, mimeType, domRequestID) {
     // You can think of the screenshotting algorithm as carrying out the
     // following steps:
--- a/dom/browser-element/BrowserElementParent.jsm
+++ b/dom/browser-element/BrowserElementParent.jsm
@@ -133,16 +133,17 @@ function BrowserElementParent(frameLoade
     defineNoReturnMethod('stop', this._stop);
     defineMethod('download', this._download);
     defineDOMRequestMethod('purgeHistory', 'purge-history');
     defineMethod('getScreenshot', this._getScreenshot);
     defineNoReturnMethod('zoom', this._zoom);
 
     defineDOMRequestMethod('getCanGoBack', 'get-can-go-back');
     defineDOMRequestMethod('getCanGoForward', 'get-can-go-forward');
+    defineDOMRequestMethod('getContentDimensions', 'get-contentdimensions');
   }
 
   defineMethod('addNextPaintListener', this._addNextPaintListener);
   defineMethod('removeNextPaintListener', this._removeNextPaintListener);
 
   let principal = this._frameElement.ownerDocument.nodePrincipal;
   let perm = Services.perms
              .testExactPermissionFromPrincipal(principal, "input-manage");
@@ -242,16 +243,17 @@ BrowserElementParent.prototype = {
       "close": this._fireEventFromMsg,
       "error": this._fireEventFromMsg,
       "firstpaint": this._fireProfiledEventFromMsg,
       "documentfirstpaint": this._fireProfiledEventFromMsg,
       "nextpaint": this._recvNextPaint,
       "keyevent": this._fireKeyEvent,
       "got-purge-history": this._gotDOMRequestResult,
       "got-screenshot": this._gotDOMRequestResult,
+      "got-contentdimensions": this._gotDOMRequestResult,
       "got-can-go-back": this._gotDOMRequestResult,
       "got-can-go-forward": this._gotDOMRequestResult,
       "fullscreen-origin-change": this._remoteFullscreenOriginChange,
       "rollback-fullscreen": this._remoteFrameFullscreenReverted,
       "exit-fullscreen": this._exitFullscreen,
       "got-visible": this._gotDOMRequestResult,
       "visibilitychange": this._childVisibilityChange,
       "got-set-input-method-active": this._gotDOMRequestResult,
@@ -259,16 +261,17 @@ BrowserElementParent.prototype = {
     };
 
     let mmSecuritySensitiveCalls = {
       "showmodalprompt": this._handleShowModalPrompt,
       "contextmenu": this._fireCtxMenuEvent,
       "securitychange": this._fireEventFromMsg,
       "locationchange": this._fireEventFromMsg,
       "iconchange": this._fireEventFromMsg,
+      "scrollareachanged": this._fireEventFromMsg,
       "titlechange": this._fireProfiledEventFromMsg,
       "opensearch": this._fireEventFromMsg,
       "manifestchange": this._fireEventFromMsg,
       "metachange": this._fireEventFromMsg,
       "resize": this._fireEventFromMsg,
       "activitydone": this._fireEventFromMsg,
       "scroll": this._fireEventFromMsg
     };
@@ -565,17 +568,18 @@ BrowserElementParent.prototype = {
    *
    */
   _gotDOMRequestResult: function(data) {
     let req = this._pendingDOMRequests[data.json.id];
     delete this._pendingDOMRequests[data.json.id];
 
     if ('successRv' in data.json) {
       debug("Successful gotDOMRequestResult.");
-      Services.DOMRequest.fireSuccess(req, data.json.successRv);
+      let clientObj = Cu.cloneInto(data.json.successRv, this._window);
+      Services.DOMRequest.fireSuccess(req, clientObj);
     }
     else {
       debug("Got error in gotDOMRequestResult.");
       Services.DOMRequest.fireErrorAsync(req, data.json.errorMsg);
     }
   },
 
   _setVisible: function(visible) {
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/browserElement_GetContentDimensions.js
@@ -0,0 +1,67 @@
+/* Any copyright is dedicated to the public domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Bug 757859 - Test the getContentDimensions functionality of mozbrowser
+
+"use strict";
+SimpleTest.waitForExplicitFinish();
+browserElementTestHelpers.setEnabledPref(true);
+browserElementTestHelpers.addPermission();
+
+var resizeContent = function() {
+  var innerBox = content.document.getElementById('abox');
+  innerBox.style.width = '800px';
+  innerBox.style.height = '800px';
+}
+
+function runTest() {
+
+  var iframe1 = document.createElement('iframe');
+  SpecialPowers.wrap(iframe1).mozbrowser = true;
+
+  var iframeWidth = 400;
+  var iframeHeight = 400;
+  var numIframeLoaded = 0;
+  var numResizeEvents = 0;
+  var mm;
+
+  iframe1.src = 'data:text/html,<html><body><div id=\'abox\' ' +
+    'style=\'background:blue;width:200px;height:200px\'>test</div></body></html>';
+  iframe1.style.width = iframeWidth + 'px';
+  iframe1.style.height = iframeHeight + 'px';
+  document.body.appendChild(iframe1);
+
+  function iframeScrollAreaChanged(e) {
+    numResizeEvents++;
+    if (numResizeEvents === 1) {
+      ok(true, 'Resize event when changing content size');
+      ok(e.detail.width > iframeWidth, 'Iframes content is larger than iframe');
+      ok(e.detail.height > iframeHeight, 'Iframes content is larger than iframe');
+      iframe1.src = 'data:text/html,<html><body><div id=\'abox\' ' +
+        'style=\'background:blue;width:200px;height:200px\'>test</div></body></html>';
+    } else if (numResizeEvents === 2) {
+      ok(true, 'Resize event when changing src');
+      iframe1.removeEventListener('mozbrowserresize', iframeScrollAreaChanged);
+      SimpleTest.finish();
+    }
+  }
+
+  function iframeLoadedHandler() {
+    iframe1.removeEventListener('mozbrowserloadend', iframeLoadedHandler);
+    mm = SpecialPowers.getBrowserFrameMessageManager(iframe1);
+    iframe1.getContentDimensions().onsuccess = function(e) {
+      ok(typeof e.target.result.width === 'number', 'Received width');
+      ok(typeof e.target.result.height === 'number', 'Received height');
+      ok(e.target.result.height <= iframeHeight, 'Iframes content is smaller than iframe');
+      ok(e.target.result.width <= iframeWidth, 'Iframes content is smaller than iframe');
+      iframe1.addEventListener('mozbrowserscrollareachanged', iframeScrollAreaChanged);
+      mm.loadFrameScript('data:,(' + resizeContent.toString() + ')();', false);
+    }
+  }
+
+  iframe1.addEventListener('mozbrowserloadend', iframeLoadedHandler);
+}
+
+addEventListener('load', function() {
+  SimpleTest.executeSoon(runTest);
+});
--- a/dom/browser-element/mochitest/mochitest-oop.ini
+++ b/dom/browser-element/mochitest/mochitest-oop.ini
@@ -90,8 +90,9 @@ skip-if = (toolkit == 'gonk' && !debug)
 disabled = bug 930449
 # Disabled until bug 924771 makes them stop timing out
 [test_browserElement_oop_CloseFromOpener.html]
 disabled = bug 924771
 [test_browserElement_oop_CloseApp.html]
 disabled = bug 924771
 [test_browserElement_oop_ExposableURI.html]
 disabled = bug 924771
+[test_browserElement_oop_GetContentDimensions.html]
--- a/dom/browser-element/mochitest/mochitest.ini
+++ b/dom/browser-element/mochitest/mochitest.ini
@@ -61,16 +61,18 @@ support-files =
   browserElement_TargetTop.js
   browserElement_Titlechange.js
   browserElement_TopBarrier.js
   browserElement_VisibilityChange.js
   browserElement_XFrameOptions.js
   browserElement_XFrameOptionsAllowFrom.js
   browserElement_XFrameOptionsDeny.js
   browserElement_XFrameOptionsSameOrigin.js
+  browserElement_XFrameOptionsSameOrigin.js
+  browserElement_GetContentDimensions.js
   file_browserElement_AlertInFrame.html
   file_browserElement_AlertInFrame_Inner.html
   file_browserElement_AppFramePermission.html
   file_browserElement_AppWindowNamespace.html
   file_browserElement_ThemeColor.html
   file_browserElement_BrowserWindowNamespace.html
   file_browserElement_CloseApp.html
   file_browserElement_CloseFromOpener.html
@@ -196,8 +198,9 @@ skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_inproc_XFrameOptionsSameOrigin.html]
 [test_browserElement_oop_NextPaint.html]
 # Disabled due to https://bugzilla.mozilla.org/show_bug.cgi?id=774100
 [test_browserElement_inproc_Reload.html]
 disabled = bug 774100
 # Disabled due to focus issues (no bug that I'm aware of)
 [test_browserElement_oop_KeyEvents.html]
 disabled =
+[test_browserElement_inproc_GetContentDimensions.html]
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/test_browserElement_inproc_GetContentDimensions.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test of browser element.</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script type="application/javascript;version=1.7" src="browserElement_GetContentDimensions.js">
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/test_browserElement_oop_GetContentDimensions.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test of browser element.</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script type="application/javascript;version=1.7" src="browserElement_GetContentDimensions.js">
+</script>
+</body>
+</html>