Index: android_webview/java/src/org/chromium/android_webview/AwLayoutSizer.java |
diff --git a/android_webview/java/src/org/chromium/android_webview/AwLayoutSizer.java b/android_webview/java/src/org/chromium/android_webview/AwLayoutSizer.java |
index 3789dc7ba5fcd60eabbe9691f9cbdefa7f10671c..6957a97ced78bce1053c0d58badbe975c7107b5b 100644 |
--- a/android_webview/java/src/org/chromium/android_webview/AwLayoutSizer.java |
+++ b/android_webview/java/src/org/chromium/android_webview/AwLayoutSizer.java |
@@ -11,8 +11,6 @@ import android.view.View.MeasureSpec; |
* Helper methods used to manage the layout of the View that contains AwContents. |
*/ |
public class AwLayoutSizer { |
- public static final int FIXED_LAYOUT_HEIGHT = 0; |
- |
// These are used to prevent a re-layout if the content size changes within a dimension that is |
// fixed by the view system. |
private boolean mWidthMeasurementIsFixed; |
@@ -25,8 +23,6 @@ public class AwLayoutSizer { |
// Page scale factor. This is set to zero initially so that we don't attempt to do a layout if |
// we get the content size change notification first and a page scale change second. |
private float mPageScaleFactor = 0.0f; |
- // The page scale factor that was used in the most recent onMeasure call. |
- private float mLastMeasuredPageScaleFactor = 0.0f; |
// Whether to postpone layout requests. |
private boolean mFreezeLayoutRequests; |
@@ -40,22 +36,17 @@ public class AwLayoutSizer { |
// If mHeightMeasurementLimited is true then this contains the height limit. |
private int mHeightMeasurementLimit; |
- // The most recent width and height seen in onSizeChanged. |
- private int mLastWidth; |
- private int mLastHeight; |
- |
- // Used to prevent sending multiple setFixedLayoutSize notifications with the same values. |
- private int mLastSentFixedLayoutSizeWidth = -1; |
- private int mLastSentFixedLayoutSizeHeight = -1; |
- |
// Callback object for interacting with the View. |
private Delegate mDelegate; |
+ /** |
+ * Delegate interface through which the AwLayoutSizer communicates with the view it's sizing. |
+ */ |
public interface Delegate { |
void requestLayout(); |
void setMeasuredDimension(int measuredWidth, int measuredHeight); |
- void setFixedLayoutSize(int widthDip, int heightDip); |
boolean isLayoutParamsHeightWrapContent(); |
+ void setForceZeroLayoutHeight(boolean forceZeroHeight); |
} |
/** |
@@ -136,10 +127,6 @@ public class AwLayoutSizer { |
} else { |
mDelegate.requestLayout(); |
} |
- } else if (pageScaleChanged && mLastWidth != 0) { |
- // Because the fixed layout size is directly impacted by the pageScaleFactor we must |
- // update it even if the physical size of the view doesn't change. |
- updateFixedLayoutSize(mLastWidth, mLastHeight, mPageScaleFactor); |
} |
} |
@@ -159,8 +146,6 @@ public class AwLayoutSizer { |
int measuredHeight = contentHeightPix; |
int measuredWidth = contentWidthPix; |
- mLastMeasuredPageScaleFactor = mPageScaleFactor; |
- |
// Always use the given size unless unspecified. This matches WebViewClassic behavior. |
mWidthMeasurementIsFixed = (widthMode != MeasureSpec.UNSPECIFIED); |
mHeightMeasurementIsFixed = (heightMode == MeasureSpec.EXACTLY); |
@@ -193,9 +178,7 @@ public class AwLayoutSizer { |
* changed. |
*/ |
public void onSizeChanged(int w, int h, int ow, int oh) { |
- mLastWidth = w; |
- mLastHeight = h; |
- updateFixedLayoutSize(mLastWidth, mLastHeight, mLastMeasuredPageScaleFactor); |
+ updateLayoutSettings(); |
} |
/** |
@@ -204,72 +187,12 @@ public class AwLayoutSizer { |
* This should be called after onSizeChanged regardless of whether the size has changed or not. |
*/ |
public void onLayoutChange() { |
- updateFixedLayoutSize(mLastWidth, mLastHeight, mLastMeasuredPageScaleFactor); |
+ updateLayoutSettings(); |
} |
- private void setFixedLayoutSize(int widthDip, int heightDip) { |
- if (widthDip == mLastSentFixedLayoutSizeWidth && |
- heightDip == mLastSentFixedLayoutSizeHeight) |
- return; |
- mLastSentFixedLayoutSizeWidth = widthDip; |
- mLastSentFixedLayoutSizeHeight = heightDip; |
- |
- mDelegate.setFixedLayoutSize(widthDip, heightDip); |
- } |
- |
- // This needs to be called every time either the physical size of the view is changed or the |
- // pageScale is changed. Since we need to ensure that this is called immediately after |
- // onSizeChanged we can't just wait for onLayoutChange. At the same time we can't only make this |
- // call from onSizeChanged, since onSizeChanged won't fire if the view's physical size doesn't |
- // change. |
- private void updateFixedLayoutSize(int w, int h, float pageScaleFactor) { |
- boolean wrapContentForHeight = mDelegate.isLayoutParamsHeightWrapContent(); |
- // If the WebView's size in the Android view system depends on the size of its contents then |
- // the viewport size cannot be directly calculated from the WebView's physical size as that |
- // can result in the layout being unstable (for example loading the following contents |
- // <div style="height:150%">a</a> |
- // would cause the WebView to indefinitely attempt to increase its height by 50%). |
- // If both the width and height are fixed (specified by the parent View) then content size |
- // changes will not cause subsequent layout passes and so we don't need to do anything |
- // special. |
- // We assume the width is 'fixed' if the parent View specified an EXACT or an AT_MOST |
- // measureSpec for the width (in which case the AT_MOST upper bound is the width). |
- // That means that the WebView will ignore LayoutParams.width set to WRAP_CONTENT and will |
- // instead try to take up as much width as possible. This is necessary because it's not |
- // practical to do web layout without a set width. |
- // For height the behavior is different because for a given width it is possible to |
- // calculate the minimum height required to display all of the content. As such the WebView |
- // can size itself vertically to match the content height. Because certain container views |
- // (LinearLayout with a WRAP_CONTENT height, for example) can result in onMeasure calls with |
- // both EXACTLY and AT_MOST height measureSpecs it is not possible to infer the sizing |
- // policy for the whole subtree based on the parameters passed to the onMeasure call. |
- // For that reason the LayoutParams.height property of the WebView is used. This behaves |
- // more predictably and means that toggling the fixedLayoutSize mode (which can have |
- // significant impact on how the web contents is laid out) is a direct consequence of the |
- // developer's choice. The downside is that it could result in the Android layout being |
- // unstable if a parent of the WebView has a wrap_content height while the WebView itself |
- // has height set to match_parent. Unfortunately addressing this edge case is costly so it |
- // will have to stay as is (this is compatible with Classic behavior). |
- if ((mWidthMeasurementIsFixed && !wrapContentForHeight) || pageScaleFactor == 0) { |
- setFixedLayoutSize(0, 0); |
- return; |
- } |
- |
- final double dipAndPageScale = pageScaleFactor * mDIPScale; |
- final int contentWidthPix = (int) (mContentWidthCss * dipAndPageScale); |
- |
- int widthDip = (int) Math.ceil(w / dipAndPageScale); |
- |
- // Make sure that we don't introduce rounding errors if the viewport is to be exactly as |
- // wide as the contents. |
- if (w == contentWidthPix) { |
- widthDip = mContentWidthCss; |
- } |
- |
- // This is workaround due to the fact that in wrap content mode we need to use a fixed |
- // layout size independent of view height, otherwise things like <div style="height:120%"> |
- // cause the webview to grow indefinitely. We need to use a height independent of the |
- // webview's height. 0 is the value used in WebViewClassic. |
- setFixedLayoutSize(widthDip, FIXED_LAYOUT_HEIGHT); |
+ // This needs to be called every time either the physical size of the view is changed or layout |
+ // params are updated. |
+ private void updateLayoutSettings() { |
+ mDelegate.setForceZeroLayoutHeight(mDelegate.isLayoutParamsHeightWrapContent()); |
} |
} |