conversation view zooming

Zoom is enabled on the entire conversation using the built-in
WebView mechanism.

Wide messages are individually best-effort shrunken to
fit-width.

Start a custom ViewGroup to hold both message headers and the
single WebView. A common view parent makes input handling easy:
the WebView drives scroll position, and position is relayed
to the custom ViewGroup to cheaply shift around headers without
a full relayout. For now, all headers are inflated at once, but
soon they can be recycled depending on the virtual scroll
viewport.

Change-Id: I92555f9b79e10630457b17ca970ab9a2e9028e80
diff --git a/assets/script.js b/assets/script.js
new file mode 100644
index 0000000..acc5432
--- /dev/null
+++ b/assets/script.js
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+ * Returns the page offset of an element.
+ *
+ * @param {Element} element The element to return the page offset for.
+ * @return {left: number, top: number} A tuple including a left and top value representing
+ *     the page offset of the element.
+ */
+function getTotalOffset(el) {
+    var result = {
+        left: 0,
+        top: 0
+    };
+    var parent = el;
+
+    while (parent) {
+        result.left += parent.offsetLeft;
+        result.top += parent.offsetTop;
+        parent = parent.offsetParent;
+    }
+
+    return result;
+}
+
+function toggleQuotedText(e) {
+    var toggleElement = e.target;
+    var elidedTextElement = toggleElement.nextSibling;
+    var isHidden = getComputedStyle(elidedTextElement).display == 'none';
+    toggleElement.innerHTML = isHidden ? MSG_HIDE_ELIDED : MSG_SHOW_ELIDED;
+    elidedTextElement.style.display = isHidden ? 'block' : 'none';
+}
+
+function collapseQuotedText() {
+    var i;
+    var elements = document.getElementsByClassName("elided-text");
+    var elidedElement, toggleElement;
+    for (i = 0; i < elements.length; i++) {
+        elidedElement = elements[i];
+        toggleElement = document.createElement("div");
+        toggleElement.display = "mail-elided-text";
+        toggleElement.innerHTML = MSG_SHOW_ELIDED;
+        toggleElement.onclick = toggleQuotedText;
+        elidedElement.parentNode.insertBefore(toggleElement, elidedElement);
+    }
+}
+
+function shrinkWideMessages() {
+    var i;
+    var elements = document.getElementsByClassName("mail-message-content");
+    var messageElement;
+    var documentWidth = document.documentElement.offsetWidth;
+    var scale;
+    for (i = 0; i < elements.length; i++) {
+        messageElement = elements[i];
+        if (messageElement.scrollWidth > documentWidth) {
+            scale = documentWidth / messageElement.scrollWidth;
+
+            // TODO: 'zoom' is nice because it does a proper layout, but WebView seems to clamp the
+            // minimum 'zoom' level.
+            if (false) {
+                // TODO: this alternative works well in Chrome but doesn't work in WebView.
+                messageElement.style.webkitTransformOrigin = "left top";
+                messageElement.style.webkitTransform = "scale(" + scale + ")";
+                messageElement.style.height = (messageElement.offsetHeight * scale) + "px";
+                messageElement.style.overflowX = "visible";
+            } else {
+                messageElement.style.zoom = documentWidth / messageElement.scrollWidth;
+            }
+        }
+    }
+}
+
+function measurePositions() {
+    var messageTops;
+    var i;
+    var len;
+
+    var headers = document.querySelectorAll(".mail-message");
+
+    messageTops = new Array(headers.length);
+    for (i = 0, len = headers.length; i < len; i++) {
+        // addJavascriptInterface handler only supports string arrays
+        messageTops[i] = "" + getTotalOffset(headers[i]).top;
+    }
+
+    window.mail.onWebContentGeometryChange(messageTops);
+}
+
+collapseQuotedText();
+shrinkWideMessages();
+measurePositions();
+