summaryrefslogtreecommitdiffstats
path: root/assets
diff options
context:
space:
mode:
authorAndy Huang <ath@google.com>2013-03-08 18:33:22 -0800
committerAndy Huang <ath@google.com>2013-03-13 17:55:12 -0700
commit0180f27c0998623b702274048b49cd4bec536cf1 (patch)
tree2daa82078fd1ec6aaf03328ee9afbd4f4e70528f /assets
parent4a16fa3ebbfb9cffe0ede9d32a969ccf42b85219 (diff)
downloadandroid_packages_apps_UnifiedEmail-0180f27c0998623b702274048b49cd4bec536cf1.tar.gz
android_packages_apps_UnifiedEmail-0180f27c0998623b702274048b49cd4bec536cf1.tar.bz2
android_packages_apps_UnifiedEmail-0180f27c0998623b702274048b49cd4bec536cf1.zip
add <img> transform for readability
Shrink any <img> elements with an effective width wider than the document. Instead of setting the width outright to the document width, use "100%" + max-width so it can be smaller if the layout allows. Genericize the actionLog to be a list of functions, contexts, and parameters. I would normally use bind() but A) it may not be available on older WebKit builds, and B) it introduces an unnecessary closure. Bug: 7400516 Change-Id: I5ab7f81674f9e238e6dc5ea04669d282c0586066
Diffstat (limited to 'assets')
-rw-r--r--assets/script.js81
1 files changed, 65 insertions, 16 deletions
diff --git a/assets/script.js b/assets/script.js
index c4f3ae6d2..b11fd6df9 100644
--- a/assets/script.js
+++ b/assets/script.js
@@ -28,7 +28,7 @@ var gScaleInfo;
* to shrink by this much. Expressed as a ratio of:
* (original width difference : width difference after transforms);
*/
-TRANSFORM_MINIMUM_EFFECTIVE_RATIO = 0.75;
+TRANSFORM_MINIMUM_EFFECTIVE_RATIO = 0.7;
/**
* Returns the page offset of an element.
@@ -182,9 +182,7 @@ function normalizeElementWidths(elements) {
el.style.zoom = 1;
}
newZoom = documentWidth / el.scrollWidth;
- if (ENABLE_MUNGE_TABLES) {
- mungeTables(el, documentWidth, el.scrollWidth);
- }
+ transformContent(el, documentWidth, el.scrollWidth);
newZoom = documentWidth / el.scrollWidth;
if (NORMALIZE_MESSAGE_WIDTHS) {
el.style.zoom = newZoom;
@@ -192,12 +190,15 @@ function normalizeElementWidths(elements) {
}
}
-function mungeTables(el, docWidth, elWidth) {
+function transformContent(el, docWidth, elWidth) {
var nodes;
var i, len;
+ var index;
var newWidth = elWidth;
var wStr;
var touched;
+ // the format of entries in this array is:
+ // entry := [ undoFunction, undoFunctionThis, undoFunctionParamArray ]
var actionLog = [];
var node;
var start;
@@ -209,14 +210,17 @@ function mungeTables(el, docWidth, elWidth) {
// Try munging all divs with inline styles where the width
// is wider than docWidth, and change it to be a max-width.
touched = false;
- nodes = el.querySelectorAll("div[style]");
+ nodes = ENABLE_MUNGE_TABLES ? el.querySelectorAll("div[style]") : [];
for (i = 0, len = nodes.length; i < len; i++) {
node = nodes[i];
wStr = node.style.width;
- if (wStr && wStr.slice(0, -2) > docWidth) {
+ index = wStr ? wStr.indexOf("px") : -1;
+ if (index >= 0 && wStr.slice(0, index) > docWidth) {
node.style.width = "";
node.style.maxWidth = wStr;
touched = true;
+ // TODO: add this to the actionLog
+ // (not a huge deal if this is missing because it's fairly non-destructive)
}
}
if (touched) {
@@ -229,8 +233,22 @@ function mungeTables(el, docWidth, elWidth) {
}
}
+ // OK, that wasn't enough. Find images with widths and override their widths.
+ nodes = ENABLE_MUNGE_IMAGES ? el.querySelectorAll("img") : [];
+ touched = transformImages(nodes, docWidth, actionLog);
+ if (touched) {
+ newWidth = el.scrollWidth;
+ console.log("ran img munger on el=" + el + " oldW=" + elWidth + " newW=" + newWidth
+ + " docW=" + docWidth);
+ if (newWidth <= docWidth) {
+ console.log("munger succeeded, elapsed time=" + (Date.now() - start));
+ return;
+ }
+ }
+
// OK, that wasn't enough. Find tables with widths and override their widths.
- touched = addClassToElements(el.querySelectorAll("table"), shouldMungeTable, "munged",
+ nodes = ENABLE_MUNGE_TABLES ? el.querySelectorAll("table") : [];
+ touched = addClassToElements(nodes, shouldMungeTable, "munged",
actionLog);
if (touched) {
newWidth = el.scrollWidth;
@@ -243,7 +261,8 @@ function mungeTables(el, docWidth, elWidth) {
}
// OK, that wasn't enough. Try munging all <td> to override any width and nowrap set.
- touched = addClassToElements(el.querySelectorAll("td"), null /* mungeAll */, "munged",
+ nodes = ENABLE_MUNGE_TABLES ? el.querySelectorAll("td") : [];
+ touched = addClassToElements(nodes, null /* mungeAll */, "munged",
actionLog);
if (touched) {
newWidth = el.scrollWidth;
@@ -256,8 +275,10 @@ function mungeTables(el, docWidth, elWidth) {
}
// OK, that wasn't enough. Try further munging all <td> to override text wrapping.
- touched = addClassToElements(el.querySelectorAll("td"), null /* mungeAll */, "munged2",
- actionLog);
+ //
+ // TODO: this is a risky transform that should not be attempted on sufficiently complex mail.
+ // (TBD how to measure that)
+ touched = addClassToElements(nodes, null /* mungeAll */, "munged2", actionLog);
if (touched) {
newWidth = el.scrollWidth;
console.log("ran td munger2 on el=" + el + " oldW=" + elWidth + " newW=" + newWidth
@@ -270,9 +291,6 @@ function mungeTables(el, docWidth, elWidth) {
// If the transformations shrank the width significantly enough, leave them in place.
// We figure that in those cases, the benefits outweight the risk of rendering artifacts.
- //
- // TODO: this is a risky transform that should not be attempted on sufficiently complex mail.
- // (TBD how to measure that)
if ((elWidth - newWidth) / (elWidth - docWidth) > TRANSFORM_MINIMUM_EFFECTIVE_RATIO) {
console.log("transform(s) deemed effective enough. elapsed time="
+ (Date.now() - start));
@@ -282,7 +300,7 @@ function mungeTables(el, docWidth, elWidth) {
// reverse all changes if the width is STILL not narrow enough
// (except the width->maxWidth change, which is not particularly destructive)
for (i = 0, len = actionLog.length; i < len; i++) {
- actionLog[i][0].classList.remove(actionLog[i][1]);
+ actionLog[i][0].apply(actionLog[i][1], actionLog[i][2]);
}
if (actionLog.length > 0) {
console.log("all mungers failed, changes reversed. elapsed time=" + (Date.now() - start));
@@ -298,12 +316,43 @@ function addClassToElements(nodes, conditionFn, classToAdd, actionLog) {
if (!conditionFn || conditionFn(node)) {
node.classList.add(classToAdd);
added = true;
- actionLog.push([node, classToAdd]);
+ actionLog.push([node.classList.remove, node.classList, [classToAdd]]);
}
}
return added;
}
+function transformImages(nodes, docWidth, actionLog) {
+ var i, len;
+ var node;
+ var w, h;
+ var touched = false;
+
+ for (i = 0, len = nodes.length; i < len; i++) {
+ node = nodes[i];
+ w = node.offsetWidth;
+ h = node.offsetHeight;
+ // shrink w/h proportionally if the img is wider than available width
+ if (w > docWidth) {
+ node.setAttribute("data-savedMaxWidth", node.style.maxWidth);
+ node.setAttribute("data-savedWidth", node.style.width);
+ node.setAttribute("data-savedHeight", node.style.height);
+ node.style.maxWidth = docWidth + "px";
+ node.style.width = "100%";
+ node.style.height = "auto";
+ actionLog.push([undoSetProperty, node, ["maxWidth", "data-savedMaxWidth"]]);
+ actionLog.push([undoSetProperty, node, ["width", "data-savedWidth"]]);
+ actionLog.push([undoSetProperty, node, ["height", "data-savedHeight"]]);
+ touched = true;
+ }
+ }
+ return touched;
+}
+
+function undoSetProperty(property, savedProperty) {
+ this.style[property] = savedProperty ? this.getAttribute(savedProperty) : "";
+}
+
function shouldMungeTable(table) {
return table.hasAttribute("width") || table.style.width;
}