diff options
author | Andy Huang <ath@google.com> | 2012-10-13 13:30:19 -0700 |
---|---|---|
committer | Andy Huang <ath@google.com> | 2012-10-13 22:24:40 -0700 |
commit | adbf3e8cadb66666f307352b72537fbac57b916f (patch) | |
tree | 383c766111ca2bc87675a971fd6043ef4af9dd04 | |
parent | 90528f425e09a72b1505c3a1066051ab5a3a67b4 (diff) | |
download | android_packages_apps_UnifiedEmail-adbf3e8cadb66666f307352b72537fbac57b916f.tar.gz android_packages_apps_UnifiedEmail-adbf3e8cadb66666f307352b72537fbac57b916f.tar.bz2 android_packages_apps_UnifiedEmail-adbf3e8cadb66666f307352b72537fbac57b916f.zip |
toggle normalization & zoom on/off
and wire it all up to a pref that re-renders upon change.
separately, make a few improvements to whitespace management
when zoomed in with normalized mode:
* place attachment overlays at the top of their regions
* place overlays above the first expanded message at the top of
the conversation, instead of the usual position just above the
message.
* impose a max zoom factor to limit excessive spacer whitespace
Bug: 7312540
Change-Id: Iae3afff0ee81e4ba9367568e884a041780b24ebf
-rw-r--r-- | assets/script.js | 35 | ||||
-rw-r--r-- | res/raw/template_conversation_lower.html | 1 | ||||
-rw-r--r-- | res/raw/template_conversation_upper.html | 4 | ||||
-rw-r--r-- | res/raw/template_message.html | 2 | ||||
-rw-r--r-- | res/raw/template_super_collapsed.html | 2 | ||||
-rw-r--r-- | src/com/android/mail/browse/ConversationContainer.java | 120 | ||||
-rw-r--r-- | src/com/android/mail/browse/ConversationOverlayItem.java | 5 | ||||
-rw-r--r-- | src/com/android/mail/browse/ConversationViewAdapter.java | 8 | ||||
-rw-r--r-- | src/com/android/mail/browse/SecureConversationViewFragment.java | 3 | ||||
-rw-r--r-- | src/com/android/mail/ui/AbstractConversationViewFragment.java | 5 | ||||
-rw-r--r-- | src/com/android/mail/ui/ConversationViewFragment.java | 66 | ||||
-rw-r--r-- | src/com/android/mail/ui/HtmlConversationTemplates.java | 4 |
12 files changed, 190 insertions, 65 deletions
diff --git a/assets/script.js b/assets/script.js index 27da9be3e..2aaf314e5 100644 --- a/assets/script.js +++ b/assets/script.js @@ -111,9 +111,15 @@ function normalizeAllMessageWidths() { function normalizeElementWidths(elements) { var i; var el; - var documentWidth = document.body.offsetWidth; + var documentWidth; var newZoom, oldZoom; + if (!NORMALIZE_MESSAGE_WIDTHS) { + return; + } + + documentWidth = document.body.offsetWidth; + for (i = 0; i < elements.length; i++) { el = elements[i]; oldZoom = el.style.zoom; @@ -256,23 +262,32 @@ function setupContentReady() { // BEGIN Java->JavaScript handlers function measurePositions() { - var overlayBottoms; - var h; + var overlayTops, overlayBottoms; var i; var len; - var expandedSpacerDivs = document.querySelectorAll(".expanded > .spacer"); + var expandedBody, headerSpacer; + var prevBodyBottom = 0; + var expandedBodyDivs = document.querySelectorAll(".expanded > .mail-message-content"); + + // N.B. offsetTop and offsetHeight of an element with the "zoom:" style applied cannot be + // trusted. - overlayBottoms = new Array(expandedSpacerDivs.length + 1); - for (i = 0, len = expandedSpacerDivs.length; i < len; i++) { - h = expandedSpacerDivs[i].offsetHeight; + overlayTops = new Array(expandedBodyDivs.length + 1); + overlayBottoms = new Array(expandedBodyDivs.length + 1); + for (i = 0, len = expandedBodyDivs.length; i < len; i++) { + expandedBody = expandedBodyDivs[i]; + headerSpacer = expandedBody.previousElementSibling; // addJavascriptInterface handler only supports string arrays - overlayBottoms[i] = "" + (getTotalOffset(expandedSpacerDivs[i]).top + h); + overlayTops[i] = "" + prevBodyBottom; + overlayBottoms[i] = "" + (getTotalOffset(headerSpacer).top + headerSpacer.offsetHeight); + prevBodyBottom = getTotalOffset(expandedBody.nextElementSibling).top; } - // add an extra one to mark the bottom of the last message + // add an extra one to mark the top/bottom of the last message footer spacer + overlayTops[i] = "" + prevBodyBottom; overlayBottoms[i] = "" + document.body.offsetHeight; - window.mail.onWebContentGeometryChange(overlayBottoms); + window.mail.onWebContentGeometryChange(overlayTops, overlayBottoms); } function unblockImages(messageDomId) { diff --git a/res/raw/template_conversation_lower.html b/res/raw/template_conversation_lower.html index f51207bbf..773e9e20e 100644 --- a/res/raw/template_conversation_lower.html +++ b/res/raw/template_conversation_lower.html @@ -8,6 +8,7 @@ var VIEW_WIDTH = %s; var WIDE_VIEWPORT_WIDTH = %s; var ENABLE_CONTENT_READY = %s; + var NORMALIZE_MESSAGE_WIDTHS = %s; </script> <script type="text/javascript" src="file:///android_asset/script.js"></script> </html> diff --git a/res/raw/template_conversation_upper.html b/res/raw/template_conversation_upper.html index 905370a87..adfdfbf06 100644 --- a/res/raw/template_conversation_upper.html +++ b/res/raw/template_conversation_upper.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <html> <head> - <meta id="meta-viewport" name="viewport" content="width=device-width"/> + <meta id="meta-viewport" name="viewport" content="width=device-width, maximum-scale=2"/> <style> .elided-text, .quoted-text { @@ -43,4 +43,4 @@ </style> </head> <body style="margin: 0 %spx;"> -<div id="conversation-header" style="height: %spx;"></div> +<div id="conversation-header" class="spacer" style="height: %spx;"></div> diff --git a/res/raw/template_message.html b/res/raw/template_message.html index f0002154f..9de1c6486 100644 --- a/res/raw/template_message.html +++ b/res/raw/template_message.html @@ -1,5 +1,5 @@ <div id="%s" class="mail-message %s"> <div class="mail-message-header spacer" style="height: %spx;"></div> <div class="mail-message-content collapsible zoom-normal %s" style="display: %s; padding: 16px 0;">%s</div> - <div class="mail-message-footer collapsible" style="display: %s; height: %spx;"></div> + <div class="mail-message-footer spacer collapsible" style="display: %s; height: %spx;"></div> </div> diff --git a/res/raw/template_super_collapsed.html b/res/raw/template_super_collapsed.html index e46ead2c9..386bbae33 100644 --- a/res/raw/template_super_collapsed.html +++ b/res/raw/template_super_collapsed.html @@ -1 +1 @@ -<div class="mail-super-collapsed-block" index="%s" style="height: %spx;"></div> +<div class="mail-super-collapsed-block spacer" index="%s" style="height: %spx;"></div> diff --git a/src/com/android/mail/browse/ConversationContainer.java b/src/com/android/mail/browse/ConversationContainer.java index 08b4092da..57234d7c5 100644 --- a/src/com/android/mail/browse/ConversationContainer.java +++ b/src/com/android/mail/browse/ConversationContainer.java @@ -22,6 +22,7 @@ import android.database.DataSetObserver; import android.graphics.Canvas; import android.util.AttributeSet; import android.util.SparseArray; +import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; @@ -82,7 +83,7 @@ public class ConversationContainer extends ViewGroup implements ScrollListener { private static final float SNAP_HEADER_MAX_SCROLL_SPEED = 600f; private ConversationViewAdapter mOverlayAdapter; - private int[] mOverlayBottoms; + private OverlayPosition[] mOverlayPositions; private ConversationWebView mWebView; private MessageHeaderView mSnapHeader; private View mTopMostOverlay; @@ -192,6 +193,16 @@ public class ConversationContainer extends ViewGroup implements ScrollListener { void onDetachedFromParent(); } + public static class OverlayPosition { + public final int top; + public final int bottom; + + public OverlayPosition(int top, int bottom) { + this.top = top; + this.bottom = bottom; + } + } + private static class OverlayView { public View view; int itemType; @@ -378,7 +389,7 @@ public class ConversationContainer extends ViewGroup implements ScrollListener { traceLayout("in positionOverlays, raw scale=%f, effective scale=%f", mWebView.getScale(), mScale); - if (mOverlayBottoms == null || mOverlayAdapter == null) { + if (mOverlayPositions == null || mOverlayAdapter == null) { return; } @@ -390,41 +401,64 @@ public class ConversationContainer extends ViewGroup implements ScrollListener { // in a single stack until you encounter a non-contiguous expanded message header, // then decrement to the next spacer. - traceLayout("IN positionOverlays, spacerCount=%d overlayCount=%d", mOverlayBottoms.length, + traceLayout("IN positionOverlays, spacerCount=%d overlayCount=%d", mOverlayPositions.length, mOverlayAdapter.getCount()); mSnapIndex = -1; - int adapterIndex = mOverlayAdapter.getCount() - 1; - int spacerIndex = mOverlayBottoms.length - 1; - while (spacerIndex >= 0 && adapterIndex >= 0) { + int adapterLoopIndex = mOverlayAdapter.getCount() - 1; + int spacerIndex = mOverlayPositions.length - 1; + while (spacerIndex >= 0 && adapterLoopIndex >= 0) { + + final int spacerTop = getOverlayTop(spacerIndex); + final int spacerBottom = getOverlayBottom(spacerIndex); + + final boolean flip; + final int flipOffset; + final int forceGravity; + // flip direction from bottom->top to top->bottom traversal on the very first spacer + // to facilitate top-aligned headers at spacer index = 0 + if (spacerIndex == 0) { + flip = true; + flipOffset = adapterLoopIndex; + forceGravity = Gravity.TOP; + } else { + flip = false; + flipOffset = 0; + forceGravity = Gravity.NO_GRAVITY; + } - final int spacerBottomY = getOverlayBottom(spacerIndex); + int adapterIndex = flip ? flipOffset - adapterLoopIndex : adapterLoopIndex; // always place at least one overlay per spacer ConversationOverlayItem adapterItem = mOverlayAdapter.getItem(adapterIndex); - int overlayBottomY = spacerBottomY; - int overlayTopY = overlayBottomY - adapterItem.getHeight(); + OverlayPosition itemPos = calculatePosition(adapterItem, spacerTop, spacerBottom, + forceGravity); traceLayout("in loop, spacer=%d overlay=%d t/b=%d/%d (%s)", spacerIndex, adapterIndex, - overlayTopY, overlayBottomY, adapterItem); - positionOverlay(adapterIndex, overlayTopY, overlayBottomY); + itemPos.top, itemPos.bottom, adapterItem); + positionOverlay(adapterIndex, itemPos.top, itemPos.bottom); - // and keep stacking overlays as long as they are contiguous - while (--adapterIndex >= 0) { + // and keep stacking overlays unconditionally if we are on the first spacer, or as long + // as overlays are contiguous + while (--adapterLoopIndex >= 0) { + adapterIndex = flip ? flipOffset - adapterLoopIndex : adapterLoopIndex; adapterItem = mOverlayAdapter.getItem(adapterIndex); - if (!adapterItem.isContiguous()) { + if (spacerIndex > 0 && !adapterItem.isContiguous()) { // advance to the next spacer, but stay on this adapter item break; } - overlayBottomY = overlayTopY; // stack on top of previous overlay - overlayTopY = overlayBottomY - adapterItem.getHeight(); + // place this overlay in the region of the spacer above or below the last item, + // depending on direction of iteration + final int regionTop = flip ? itemPos.bottom : spacerTop; + final int regionBottom = flip ? spacerBottom : itemPos.top; + itemPos = calculatePosition(adapterItem, regionTop, regionBottom, forceGravity); traceLayout("in contig loop, spacer=%d overlay=%d t/b=%d/%d (%s)", spacerIndex, - adapterIndex, overlayTopY, overlayBottomY, adapterItem); - positionOverlay(adapterIndex, overlayTopY, overlayBottomY); + adapterIndex, itemPos.top, itemPos.bottom, adapterItem); + positionOverlay(adapterIndex, itemPos.top, itemPos.bottom); } spacerIndex--; @@ -433,6 +467,27 @@ public class ConversationContainer extends ViewGroup implements ScrollListener { positionSnapHeader(mSnapIndex); } + private OverlayPosition calculatePosition(ConversationOverlayItem adapterItem, int withinTop, + int withinBottom, int forceGravity) { + if (adapterItem.getHeight() == 0) { + // "place" invisible items at the bottom of their region to stay consistent with the + // stacking algorithm in positionOverlays(), unless gravity is forced to the top + final int y = (forceGravity == Gravity.TOP) ? withinTop : withinBottom; + return new OverlayPosition(y, y); + } + + final int v = ((forceGravity != Gravity.NO_GRAVITY) ? + forceGravity : adapterItem.getGravity()) & Gravity.VERTICAL_GRAVITY_MASK; + switch (v) { + case Gravity.BOTTOM: + return new OverlayPosition(withinBottom - adapterItem.getHeight(), withinBottom); + case Gravity.TOP: + return new OverlayPosition(withinTop, withinTop + adapterItem.getHeight()); + default: + throw new UnsupportedOperationException("unsupported gravity: " + v); + } + } + /** * Executes a measure pass over the specified child overlay view and returns the measured * height. The measurement uses whatever the current container's width measure spec is. @@ -596,9 +651,18 @@ public class ConversationContainer extends ViewGroup implements ScrollListener { return p instanceof MarginLayoutParams; } + private int getOverlayTop(int spacerIndex) { + return webPxToScreenPx(mOverlayPositions[spacerIndex].top); + } + private int getOverlayBottom(int spacerIndex) { + return webPxToScreenPx(mOverlayPositions[spacerIndex].bottom); + } + + private int webPxToScreenPx(int webPx) { // TODO: round or truncate? - return (int) (mOverlayBottoms[spacerIndex] * mScale); + // TODO: refactor and unify with ConversationWebView.webPxToScreenPx() + return (int) (webPx * mScale); } private void positionOverlay(int adapterIndex, int overlayTopY, int overlayBottomY) { @@ -733,24 +797,26 @@ public class ConversationContainer extends ViewGroup implements ScrollListener { } /** - * Prevents any layouts from happening until the next time {@link #onGeometryChange(int[])} is + * Prevents any layouts from happening until the next time + * {@link #onGeometryChange(OverlayPosition[])} is * called. Useful when you know the HTML spacer coordinates are inconsistent with adapter items. * <p> - * If you call this, you must ensure that a followup call to {@link #onGeometryChange(int[])} + * If you call this, you must ensure that a followup call to + * {@link #onGeometryChange(OverlayPosition[])} * is made later, when the HTML spacer coordinates are updated. * */ public void invalidateSpacerGeometry() { - mOverlayBottoms = null; + mOverlayPositions = null; } - public void onGeometryChange(int[] overlayBottoms) { - traceLayout("*** got overlay spacer bottoms:"); - for (int offsetY : overlayBottoms) { - traceLayout("%d", offsetY); + public void onGeometryChange(OverlayPosition[] overlayPositions) { + traceLayout("*** got overlay spacer positions:"); + for (OverlayPosition pos : overlayPositions) { + traceLayout("top=%d bottom=%d", pos.top, pos.bottom); } - mOverlayBottoms = overlayBottoms; + mOverlayPositions = overlayPositions; positionOverlays(0, mOffsetY); } diff --git a/src/com/android/mail/browse/ConversationOverlayItem.java b/src/com/android/mail/browse/ConversationOverlayItem.java index 5d5fd88bb..10ef34293 100644 --- a/src/com/android/mail/browse/ConversationOverlayItem.java +++ b/src/com/android/mail/browse/ConversationOverlayItem.java @@ -18,6 +18,7 @@ package com.android.mail.browse; import android.content.Context; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -60,6 +61,10 @@ public abstract class ConversationOverlayItem { */ public abstract boolean isContiguous(); + public int getGravity() { + return Gravity.BOTTOM; + } + /** * This method's behavior is critical and requires some 'splainin. * <p> diff --git a/src/com/android/mail/browse/ConversationViewAdapter.java b/src/com/android/mail/browse/ConversationViewAdapter.java index 4c201e069..c2cfcc91b 100644 --- a/src/com/android/mail/browse/ConversationViewAdapter.java +++ b/src/com/android/mail/browse/ConversationViewAdapter.java @@ -20,6 +20,7 @@ package com.android.mail.browse; import android.app.FragmentManager; import android.app.LoaderManager; import android.content.Context; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -238,6 +239,13 @@ public class ConversationViewAdapter extends BaseAdapter { } @Override + public int getGravity() { + // attachments are top-aligned within their spacer area + // Attachments should stay near the body they belong to, even when zoomed far in. + return Gravity.TOP; + } + + @Override public int getHeight() { // a footer may change height while its view does not exist because it is offscreen // (but the header is onscreen and thus collapsible) diff --git a/src/com/android/mail/browse/SecureConversationViewFragment.java b/src/com/android/mail/browse/SecureConversationViewFragment.java index 627694c99..60e4b66f5 100644 --- a/src/com/android/mail/browse/SecureConversationViewFragment.java +++ b/src/com/android/mail/browse/SecureConversationViewFragment.java @@ -37,6 +37,7 @@ import com.android.mail.R; import com.android.mail.browse.ConversationViewAdapter.MessageHeaderItem; import com.android.mail.browse.MessageCursor.ConversationMessage; import com.android.mail.browse.MessageHeaderView.MessageHeaderViewCallbacks; +import com.android.mail.providers.Account; import com.android.mail.providers.Conversation; import com.android.mail.providers.ConversationInfo; import com.android.mail.providers.Message; @@ -150,7 +151,7 @@ public class SecureConversationViewFragment extends AbstractConversationViewFrag } @Override - public void onAccountChanged() { + public void onAccountChanged(Account newAccount, Account oldAccount) { // Do nothing. } diff --git a/src/com/android/mail/ui/AbstractConversationViewFragment.java b/src/com/android/mail/ui/AbstractConversationViewFragment.java index ca633c68e..4f62973c7 100644 --- a/src/com/android/mail/ui/AbstractConversationViewFragment.java +++ b/src/com/android/mail/ui/AbstractConversationViewFragment.java @@ -156,8 +156,9 @@ public abstract class AbstractConversationViewFragment extends Fragment implemen private final AccountObserver mAccountObserver = new AccountObserver() { @Override public void onChanged(Account newAccount) { + final Account oldAccount = mAccount; mAccount = newAccount; - onAccountChanged(); + onAccountChanged(newAccount, oldAccount); } }; private TextView mSendersView; @@ -208,7 +209,7 @@ public abstract class AbstractConversationViewFragment extends Fragment implemen /** * Subclasses must override this. */ - protected abstract void onAccountChanged(); + protected abstract void onAccountChanged(Account newAccount, Account oldAccount); @Override public void onCreate(Bundle savedState) { diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java index 596d93b42..23d4e5e47 100644 --- a/src/com/android/mail/ui/ConversationViewFragment.java +++ b/src/com/android/mail/ui/ConversationViewFragment.java @@ -46,9 +46,9 @@ import android.widget.TextView; import com.android.mail.FormattedDateBuilder; import com.android.mail.R; import com.android.mail.browse.ConversationContainer; +import com.android.mail.browse.ConversationContainer.OverlayPosition; import com.android.mail.browse.ConversationOverlayItem; import com.android.mail.browse.ConversationViewAdapter; -import com.android.mail.browse.ScrollIndicatorsView; import com.android.mail.browse.ConversationViewAdapter.ConversationAccountController; import com.android.mail.browse.ConversationViewAdapter.MessageFooterItem; import com.android.mail.browse.ConversationViewAdapter.MessageHeaderItem; @@ -61,6 +61,7 @@ import com.android.mail.browse.MessageCursor.ConversationController; import com.android.mail.browse.MessageCursor.ConversationMessage; import com.android.mail.browse.MessageHeaderView; import com.android.mail.browse.MessageHeaderView.MessageHeaderViewCallbacks; +import com.android.mail.browse.ScrollIndicatorsView; import com.android.mail.browse.SuperCollapsedBlock; import com.android.mail.browse.WebViewContextMenu; import com.android.mail.providers.Account; @@ -209,7 +210,21 @@ public final class ConversationViewFragment extends AbstractConversationViewFrag } @Override - public void onAccountChanged() { + public void onAccountChanged(Account newAccount, Account oldAccount) { + // if overview mode has changed, re-render completely (no need to also update headers) + if (isOverviewMode(newAccount) != isOverviewMode(oldAccount)) { + setupOverviewMode(); + final MessageCursor c = getMessageCursor(); + if (c != null) { + renderConversation(c); + } else { + // Null cursor means this fragment is either waiting to load or in the middle of + // loading. Either way, a future render will happen anyway, and the new setting + // will take effect when that happens. + } + return; + } + // settings may have been updated; refresh views that are known to // depend on settings mConversationContainer.getSnapHeader().onAccountChanged(); @@ -246,6 +261,9 @@ public final class ConversationViewFragment extends AbstractConversationViewFrag mWebView.setOnCreateContextMenuListener(new WebViewContextMenu(getActivity())); + // set this up here instead of onCreateView to ensure the latest Account is loaded + setupOverviewMode(); + // Defer the call to initLoader with a Handler. // We want to wait until we know which fragments are present and their final visibility // states before going off and doing work. This prevents extraneous loading from occurring @@ -331,10 +349,6 @@ public final class ConversationViewFragment extends AbstractConversationViewFrag settings.setJavaScriptEnabled(true); settings.setUseWideViewPort(true); - settings.setSupportZoom(true); - settings.setBuiltInZoomControls(true); - settings.setDisplayZoomControls(false); - final float fontScale = getResources().getConfiguration().fontScale; final int desiredFontSizePx = getResources() .getInteger(R.integer.conversation_desired_font_size_px); @@ -650,7 +664,7 @@ public final class ConversationViewFragment extends AbstractConversationViewFrag final String conversationBaseUri = mConversation.conversationBaseUri != null ? mConversation.conversationBaseUri.toString() : mBaseUri; return mTemplates.endConversation(mBaseUri, conversationBaseUri, 320, - mWebView.getViewportWidth(), enableContentReadySignal); + mWebView.getViewportWidth(), enableContentReadySignal, isOverviewMode(mAccount)); } private void renderSuperCollapsedBlock(int start, int end) { @@ -820,13 +834,15 @@ public final class ConversationViewFragment extends AbstractConversationViewFrag // per onLoadFinished() } - private static int[] parseInts(final String[] stringArray) { - final int len = stringArray.length; - final int[] ints = new int[len]; + private static OverlayPosition[] parsePositions(final String[] topArray, + final String[] bottomArray) { + final int len = topArray.length; + final OverlayPosition[] positions = new OverlayPosition[len]; for (int i = 0; i < len; i++) { - ints[i] = Integer.parseInt(stringArray[i]); + positions[i] = new OverlayPosition( + Integer.parseInt(topArray[i]), Integer.parseInt(bottomArray[i])); } - return ints; + return positions; } @Override @@ -848,11 +864,6 @@ public final class ConversationViewFragment extends AbstractConversationViewFrag return addr; } - @Override - public Account getAccount() { - return mAccount; - } - private void ensureContentSizeChangeListener() { if (mWebViewSizeChangeListener == null) { mWebViewSizeChangeListener = new ConversationWebView.ContentSizeChangeListener() { @@ -870,6 +881,20 @@ public final class ConversationViewFragment extends AbstractConversationViewFrag mWebView.setContentSizeChangeListener(mWebViewSizeChangeListener); } + private static boolean isOverviewMode(Account acct) { + return acct.settings.conversationViewMode == UIProvider.ConversationViewMode.OVERVIEW; + } + + private void setupOverviewMode() { + final boolean overviewMode = isOverviewMode(mAccount); + final WebSettings settings = mWebView.getSettings(); + settings.setSupportZoom(overviewMode); + if (overviewMode) { + settings.setBuiltInZoomControls(true); + settings.setDisplayZoomControls(false); + } + } + private class ConversationWebViewClient extends AbstractConversationWebViewClient { @Override public void onPageFinished(WebView view, String url) { @@ -923,11 +948,13 @@ public final class ConversationViewFragment extends AbstractConversationViewFrag * via reflection and not stripped. * */ + // TODO: switch these Runnables to FragmentRunnables? private class MailJsBridge { @SuppressWarnings("unused") @JavascriptInterface - public void onWebContentGeometryChange(final String[] overlayBottomStrs) { + public void onWebContentGeometryChange(final String[] overlayTopStrs, + final String[] overlayBottomStrs) { try { getHandler().post(new Runnable() { @@ -938,7 +965,8 @@ public final class ConversationViewFragment extends AbstractConversationViewFrag + " are gone, %s", ConversationViewFragment.this); return; } - mConversationContainer.onGeometryChange(parseInts(overlayBottomStrs)); + mConversationContainer.onGeometryChange( + parsePositions(overlayTopStrs, overlayBottomStrs)); if (mDiff != 0) { // SCROLL! int scale = (int) (mWebView.getScale() / mWebView.getInitialScale()); diff --git a/src/com/android/mail/ui/HtmlConversationTemplates.java b/src/com/android/mail/ui/HtmlConversationTemplates.java index 3f485e673..2e5a8d038 100644 --- a/src/com/android/mail/ui/HtmlConversationTemplates.java +++ b/src/com/android/mail/ui/HtmlConversationTemplates.java @@ -181,14 +181,14 @@ public class HtmlConversationTemplates { } public String endConversation(String docBaseUri, String conversationBaseUri, int viewWidth, - int viewportWidth, boolean enableContentReadySignal) { + int viewportWidth, boolean enableContentReadySignal, boolean normalizeMessageWidths) { if (!mInProgress) { throw new IllegalStateException("must call startConversation first"); } append(sConversationLower, mContext.getString(R.string.hide_elided), mContext.getString(R.string.show_elided), docBaseUri, conversationBaseUri, - viewWidth, viewportWidth, enableContentReadySignal); + viewWidth, viewportWidth, enableContentReadySignal, normalizeMessageWidths); mInProgress = false; |