Bug 830760 - Don't zoom into fields on tablets of pages with metaviewports. r=kats DONTBUILD

This commit is contained in:
Wes Johnston 2013-02-13 11:36:29 -08:00
parent 5ced0d6c69
commit 40d889999f
4 changed files with 65 additions and 20 deletions

View File

@ -1,11 +0,0 @@
<html style="margin: 0; padding: 0">
<head>
<title>Input field VKB overlap test</title>
<meta name="viewport" content="initial-scale=1.0"/>
<meta charset="utf-8">
</head>
<body style="margin: 0; padding: 0">
<div style="width: 100%; height: 100%"><!--big spacer div--></div>
<input type="text" style="background-color: green">
</body>
</html>

View File

@ -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();
}

View File

@ -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('<html>\n' +
'<head>\n' +
'<title>Browser VKB Overlapping content</title>');
if (params.metadata)
response.write("<meta name=\"viewport\" content=\"" + params.metadata + "\"/>");
/* Write a spacer div into the document, above an input element*/
response.write('</head>\n' +
'<body style="margin: 0; padding: 0">\n' +
'<div style="width: 100%; height: 100%"></div>\n' +
'<input type="text" style="background-color: green">\n' +
'</body>\n</html>');
}

View File

@ -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
};
},