diff --git a/mobile/android/base/tests/robocop_input.html b/mobile/android/base/tests/robocop_input.html deleted file mode 100644 index d6f8d048e9fa..000000000000 --- a/mobile/android/base/tests/robocop_input.html +++ /dev/null @@ -1,11 +0,0 @@ - - - Input field VKB overlap test - - - - -
- - - diff --git a/mobile/android/base/tests/testVkbOverlap.java.in b/mobile/android/base/tests/testVkbOverlap.java.in index 315c49c78f66..0584da2ddfd1 100644 --- a/mobile/android/base/tests/testVkbOverlap.java.in +++ b/mobile/android/base/tests/testVkbOverlap.java.in @@ -2,6 +2,7 @@ package @ANDROID_PACKAGE_NAME@.tests; import @ANDROID_PACKAGE_NAME@.*; +import android.net.Uri; /** * A test to ensure that when an input field is focused, it is not obscured by the VKB. @@ -22,7 +23,13 @@ public class testVkbOverlap extends PixelTest { public void testVkbOverlap() { blockForGeckoReady(); - loadAndPaint(getAbsoluteUrl("/robocop/robocop_input.html")); + testSetup("initial-scale=1.0, user-scalable=no", false); + testSetup("initial-scale=1.0", false); + testSetup("", true); + } + + private void testSetup(String viewport, boolean shouldZoom) { + loadAndPaint(getAbsoluteUrl("/robocop/test_viewport.sjs?metadata=" + Uri.encode(viewport))); // scroll to the bottom of the page and let it settle Actions.RepeatedEventExpecter paintExpecter = mActions.expectPaint(); @@ -63,9 +70,14 @@ public class testVkbOverlap extends PixelTest { // if the vkb scrolled into view as expected, then the number of green pixels now visible should be about the // same as it was before, since the green pixels indicate the text input is in view. use a fudge factor of 0.9 to // account for borders and such of the text input which might still be out of view. - // Since we should be zooming into the input, this expects that newCount will be significantly greater than the previous count. int newCount = countGreenPixels(painted); - mAsserter.ok(newCount > greenPixelCount, "testVkbOverlap", "Found " + newCount + " green pixels after tapping; expected " + greenPixelCount); + + // if zooming is allowed, the number of green pixels visible should have increased substatially + if (shouldZoom) { + mAsserter.ok(newCount > greenPixelCount * 1.5, "testVkbOverlap", "Found " + newCount + " green pixels after tapping; expected " + greenPixelCount); + } else { + mAsserter.ok((Math.abs(greenPixelCount - newCount) / greenPixelCount < 0.1), "testVkbOverlap", "Found " + newCount + " green pixels after tapping; expected " + greenPixelCount); + } } finally { painted.close(); } diff --git a/mobile/android/base/tests/test_viewport.sjs b/mobile/android/base/tests/test_viewport.sjs new file mode 100644 index 000000000000..8a746d57e7c5 --- /dev/null +++ b/mobile/android/base/tests/test_viewport.sjs @@ -0,0 +1,33 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + function decodeQuery(query) { + let result = {}; + query.split("&").forEach(function(pair) { + let [key, val] = pair.split("="); + result[key] = decodeURIComponent(val); + }); + return result; + } + +function handleRequest(request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "text/html", false); + + let params = decodeQuery(request.queryString || ""); + + response.write('\n' + + '\n' + + 'Browser VKB Overlapping content'); + + if (params.metadata) + response.write(""); + + /* Write a spacer div into the document, above an input element*/ + response.write('\n' + + '\n' + + '
\n' + + '\n' + + '\n'); +} diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index fd36bfe68a15..6819ce6cd9e8 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -167,6 +167,12 @@ var BrowserApp = { _tabs: [], _selectedTab: null, + get isTablet() { + let sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2); + delete this.isTablet; + return this.isTablet = sysInfo.get("tablet"); + }, + deck: null, startup: function startup() { @@ -1073,9 +1079,11 @@ var BrowserApp = { scrollToFocusedInput: function(aBrowser, aAllowZoom = true) { let focused = this.getFocusedInput(aBrowser); + if (focused) { - // _zoomToElement will handle not sending any message if this input is already mostly filling the screen - BrowserEventHandler._zoomToElement(focused, -1, false, aAllowZoom); + // _zoomToElement will handle not sending any message if this input is already mostly filling the screen + BrowserEventHandler._zoomToElement(focused, -1, false, + aAllowZoom && !this.isTablet && !ViewportHandler.getViewportMetadata(aBrowser.contentWindow).hasMetaViewport); } }, @@ -4268,14 +4276,14 @@ var BrowserEventHandler = { /* Zoom to an element, optionally keeping a particular part of it * in view if it is really tall. */ - _zoomToElement: function(aElement, aClickY = -1, aCanZoomOut = true, aCanZoomIn = true) { + _zoomToElement: function(aElement, aClickY = -1, aCanZoomOut = true, aCanScrollHorizontally = true) { const margin = 15; let rect = ElementTouchHelper.getBoundingContentRect(aElement); let viewport = BrowserApp.selectedTab.getViewport(); - let bRect = new Rect(aCanZoomIn ? Math.max(viewport.cssPageLeft, rect.x - margin) : viewport.cssPageLeft, + let bRect = new Rect(aCanScrollHorizontally ? Math.max(viewport.cssPageLeft, rect.x - margin) : viewport.cssX, rect.y, - aCanZoomIn ? rect.w + 2 * margin : viewport.cssWidth, + aCanScrollHorizontally ? rect.w + 2 * margin : viewport.cssWidth, rect.h); // constrict the rect to the screen's right edge bRect.width = Math.min(bRect.width, viewport.cssPageRight - bRect.x); @@ -5467,6 +5475,7 @@ var ViewportHandler = { // Note: These values will be NaN if parseFloat or parseInt doesn't find a number. // Remember that NaN is contagious: Math.max(1, NaN) == Math.min(1, NaN) == NaN. + let hasMetaViewport = true; let scale = parseFloat(windowUtils.getDocumentMetadata("viewport-initial-scale")); let minScale = parseFloat(windowUtils.getDocumentMetadata("viewport-minimum-scale")); let maxScale = parseFloat(windowUtils.getDocumentMetadata("viewport-maximum-scale")); @@ -5494,6 +5503,7 @@ var ViewportHandler = { if (doctype && /(WAP|WML|Mobile)/.test(doctype.publicId)) return { defaultZoom: 1, autoSize: true, allowZoom: true }; + hasMetaViewport = false; let defaultZoom = Services.prefs.getIntPref("browser.viewport.defaultZoom"); if (defaultZoom >= 0) { scale = defaultZoom / 1000; @@ -5518,7 +5528,8 @@ var ViewportHandler = { width: width, height: height, autoSize: autoSize, - allowZoom: allowZoom + allowZoom: allowZoom, + hasMetaViewport: hasMetaViewport }; },