hterm 1.31: a new zoom warning

* Re-implement zoom detection in terms of the currentScale property of svg
  elements.  This requires the svg element to be in the topmost document,
  or at least not in the "about:blank" document that the scrollport creates
  so it may not be perfect, but it's better than nothing.

Change-Id: I57fb9fea24e0c9743b5abac695213333e356f022
Reviewed-on: https://chromium-review.googlesource.com/188911
Reviewed-by: Marvelous Marius <mschilder@chromium.org>
Reviewed-by: Robert Ginda <rginda@chromium.org>
Tested-by: Robert Ginda <rginda@chromium.org>
diff --git a/hterm/doc/changelog.txt b/hterm/doc/changelog.txt
index 561cb26..911f7b7 100644
--- a/hterm/doc/changelog.txt
+++ b/hterm/doc/changelog.txt
@@ -1,3 +1,10 @@
+1.31, 2014-03-04, Add svg based zoom detection.
+
+* Re-implement zoom detection in terms of the currentScale property of svg
+  elements.  This requires the svg element to be in the topmost document,
+  or at least not in the "about:blank" document that the scrollport creates
+  so it may not be perfect, but it's better than nothing.
+
 1.30, 2014-03-04, Even better recursive "copy" fix.
 
 * BUG=chromium:340699: Auto copy doesn't work.
diff --git a/hterm/js/hterm_scrollport.js b/hterm/js/hterm_scrollport.js
index 66ba767..f5b7dc2 100644
--- a/hterm/js/hterm_scrollport.js
+++ b/hterm/js/hterm_scrollport.js
@@ -366,6 +366,20 @@
   this.scrollArea_.style.cssText = 'visibility: hidden';
   this.screen_.appendChild(this.scrollArea_);
 
+  // This svg element is used to detect when the browser is zoomed.  It must be
+  // placed in the outermost document for currentScale to be correct.
+  // TODO(rginda): This means that hterm nested in an iframe will not correctly
+  // detect browser zoom level.  We should come up with a better solution.
+  this.svg_ = this.div_.ownerDocument.createElementNS(
+      'http://www.w3.org/2000/svg', 'svg');
+  this.svg_.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+  this.svg_.setAttribute('version', '1.1');
+  this.svg_.style.cssText = (
+      'position: absolute;' +
+      'top: 0;' +
+      'left: 0;' +
+      'visibility: hidden');
+
   this.setSelectionEnabled(true);
   this.resize();
 };
@@ -616,16 +630,9 @@
 
   this.rowNodes_.removeChild(this.ruler_);
 
-  if ('width' in this.document_) {
-    size.zoomFactor = this.document_.width / this.document_.body.clientWidth;
-  } else {
-    // Current versions of Chrome have removed document.width/height.  We can
-    // no longer depend on it to determine the zoom factor.
-    // TODO(rginda): Remove this code once document.width/height are a distant
-    // memory.
-    size.zoomFactor = 1;
-  }
-
+  this.div_.ownerDocument.body.appendChild(this.svg_);
+  size.zoomFactor = this.svg_.currentScale;
+  this.div_.ownerDocument.body.removeChild(this.svg_);
 
   return size;
 };