You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by mh...@apache.org on 2010/12/16 00:32:55 UTC

svn commit: r1049747 - in /shindig/trunk/features/src/main/javascript/features: ./ dynamic-height.height/ dynamic-height.util/ dynamic-height/

Author: mhermanto
Date: Wed Dec 15 23:32:55 2010
New Revision: 1049747

URL: http://svn.apache.org/viewvc?rev=1049747&view=rev
Log:
Refactor getHeight() calculation, so it can be re-used independent of dynamic-height.
http://codereview.appspot.com/3651041/


Added:
    shindig/trunk/features/src/main/javascript/features/dynamic-height.height/
    shindig/trunk/features/src/main/javascript/features/dynamic-height.height/dynamic-height-height.js
    shindig/trunk/features/src/main/javascript/features/dynamic-height.height/feature.xml
Modified:
    shindig/trunk/features/src/main/javascript/features/dynamic-height.util/feature.xml
    shindig/trunk/features/src/main/javascript/features/dynamic-height/dynamic-height.js
    shindig/trunk/features/src/main/javascript/features/dynamic-height/feature.xml
    shindig/trunk/features/src/main/javascript/features/dynamic-height/taming.js
    shindig/trunk/features/src/main/javascript/features/features.txt

Added: shindig/trunk/features/src/main/javascript/features/dynamic-height.height/dynamic-height-height.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/dynamic-height.height/dynamic-height-height.js?rev=1049747&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/dynamic-height.height/dynamic-height-height.js (added)
+++ shindig/trunk/features/src/main/javascript/features/dynamic-height.height/dynamic-height-height.js Wed Dec 15 23:32:55 2010
@@ -0,0 +1,271 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+/**
+ * @fileoverview This library augments gadgets.window with functionality
+ * to change the height of a gadget dynamically.
+ */
+
+/**
+ * @static
+ * @class Provides operations for getting information about the window the
+ *        gadget is placed in.
+ * @name gadgets.window
+ */
+gadgets.window = gadgets.window || {};
+
+(function() {
+
+  /**
+   * Parse out the value (specified in px) for a CSS attribute of an element.
+   *
+   * @param {Element} elem the element with the attribute to look for.
+   * @param {string} attr the CSS attribute name of interest.
+   * @return {number} the value of the px attr of the elem.
+   * @private
+   */
+  function parseIntFromElemPxAttribute(elem, attr) {
+    var style = window.getComputedStyle(elem, '');
+    var value = style.getPropertyValue(attr);
+    value.match(/^([0-9]+)/);
+    return parseInt(RegExp.$1, 10);
+  }
+
+  /**
+   * For Webkit-based browsers, calculate the height of the gadget iframe by
+   * iterating through all elements in the gadget, starting with the body tag.
+   * It is not sufficient to only account body children elements, because
+   * CSS style position "float" may place a child element outside of the
+   * containing parent element. Not counting "float" elements may lead to
+   * undercounting.
+   *
+   * @return {number} the height of the gadget.
+   * @private
+   */
+  function getHeightForWebkit() {
+    var result = 0;
+    var queue = [document.body];
+
+    while (queue.length > 0) {
+      var elem = queue.shift();
+      var children = elem.childNodes;
+
+      /*
+       * Here, we are checking if we are a container that clips its overflow wit h
+       * a specific height, because if so, we should ignore children
+       */
+
+      // check that elem is actually an element, could be a text node otherwise
+      if (typeof elem.style !== 'undefined') {
+        // Get the overflowY value, looking in the computed style if necessary
+        var overflowY = elem.style['overflowY'];
+        if (!overflowY) {
+          var css = document.defaultView.getComputedStyle(elem, null);
+          overflowY = css ? css['overflowY'] : null;
+        }
+
+        // The only non-clipping values of overflow is 'visible'. We assume that 'inherit'
+        // is also non-clipping at the moment, but should we check this?
+        if (overflowY != 'visible' && overflowY != 'inherit') {
+          // Make sure this element explicitly specifies a height
+          var height = elem.style['height'];
+          if (!height) {
+            var css = document.defaultView.getComputedStyle(elem, null);
+            height = css ? css['height'] : '';
+          }
+          if (height.length > 0 && height != 'auto') {
+            // We can safely ignore the children of this element,
+            // so move onto the next in the queue
+            continue;
+          }
+        }
+      }
+
+      for (var i = 0; i < children.length; i++) {
+        var child = children[i];
+        if (typeof child.offsetTop !== 'undefined' &&
+            typeof child.offsetHeight !== 'undefined') {
+          // offsetHeight already accounts for border-bottom, padding-bottom.
+          var bottom = child.offsetTop + child.offsetHeight +
+              parseIntFromElemPxAttribute(child, 'margin-bottom');
+          result = Math.max(result, bottom);
+        }
+        queue.push(child);
+      }
+    }
+
+    // Add border, padding and margin of the containing body.
+    return result
+        + parseIntFromElemPxAttribute(document.body, 'border-bottom')
+        + parseIntFromElemPxAttribute(document.body, 'margin-bottom')
+        + parseIntFromElemPxAttribute(document.body, 'padding-bottom');
+  }
+
+  /**
+   * Adjusts the gadget height
+   * @param {number=} opt_height An optional preferred height in pixels. If not
+   *     specified, will attempt to fit the gadget to its content.
+   * @member gadgets.window
+   */
+  
+  /**
+   * Calculate inner content height is hard and different between
+   * browsers rendering in Strict vs. Quirks mode.  We use a combination of
+   * three properties within document.body and document.documentElement:
+   * - scrollHeight
+   * - offsetHeight
+   * - clientHeight
+   * These values differ significantly between browsers and rendering modes.
+   * But there are patterns.  It just takes a lot of time and persistence
+   * to figure out.
+   */
+  gadgets.window.getHeight = function() {
+    // Get the height of the viewport
+    var vh = gadgets.window.getViewportDimensions().height;
+    var body = document.body;
+    var docEl = document.documentElement;
+    if (document.compatMode === 'CSS1Compat' && docEl.scrollHeight) {
+      // In Strict mode:
+      // The inner content height is contained in either:
+      //    document.documentElement.scrollHeight
+      //    document.documentElement.offsetHeight
+      // Based on studying the values output by different browsers,
+      // use the value that's NOT equal to the viewport height found above.
+      return docEl.scrollHeight !== vh ?
+          docEl.scrollHeight : docEl.offsetHeight;
+    } else if (navigator.userAgent.indexOf('AppleWebKit') >= 0) {
+      // In Webkit:
+      // Property scrollHeight and offsetHeight will only increase in value.
+      // This will incorrectly calculate reduced height of a gadget
+      // (ie: made smaller).
+      return getHeightForWebkit();
+    } else if (body && docEl) {
+      // In Quirks mode:
+      // documentElement.clientHeight is equal to documentElement.offsetHeight
+      // except in IE.  In most browsers, document.documentElement can be used
+      // to calculate the inner content height.
+      // However, in other browsers (e.g. IE), document.body must be used
+      // instead.  How do we know which one to use?
+      // If document.documentElement.clientHeight does NOT equal
+      // document.documentElement.offsetHeight, then use document.body.
+      var sh = docEl.scrollHeight;
+      var oh = docEl.offsetHeight;
+      if (docEl.clientHeight !== oh) {
+        sh = body.scrollHeight;
+        oh = body.offsetHeight;
+      }
+
+      // Detect whether the inner content height is bigger or smaller
+      // than the bounding box (viewport).  If bigger, take the larger
+      // value.  If smaller, take the smaller value.
+      if (sh > vh) {
+        // Content is larger
+        return sh > oh ? sh : oh;
+      } else {
+        // Content is smaller
+        return sh < oh ? sh : oh;
+      }
+    }
+  };
+  
+  /**
+   * Parse out the value (specified in px) for a CSS attribute of an element.
+   *
+   * @param {Element} elem the element with the attribute to look for.
+   * @param {string} attr the CSS attribute name of interest.
+   * @return {number} the value of the px attr of the elem.
+   * @private
+   */
+  function parseIntFromElemPxAttribute(elem, attr) {
+    var style = window.getComputedStyle(elem, '');
+    var value = style.getPropertyValue(attr);
+    value.match(/^([0-9]+)/);
+    return parseInt(RegExp.$1, 10);
+  }
+
+  /**
+   * For Webkit-based browsers, calculate the height of the gadget iframe by
+   * iterating through all elements in the gadget, starting with the body tag.
+   * It is not sufficient to only account body children elements, because
+   * CSS style position "float" may place a child element outside of the
+   * containing parent element. Not counting "float" elements may lead to
+   * undercounting.
+   *
+   * @return {number} the height of the gadget.
+   * @private
+   */
+  function getHeightForWebkit() {
+    var result = 0;
+    var queue = [document.body];
+
+    while (queue.length > 0) {
+      var elem = queue.shift();
+      var children = elem.childNodes;
+
+      /*
+       * Here, we are checking if we are a container that clips its overflow wit h
+       * a specific height, because if so, we should ignore children
+       */
+
+      // check that elem is actually an element, could be a text node otherwise
+      if (typeof elem.style !== 'undefined') {
+        // Get the overflowY value, looking in the computed style if necessary
+        var overflowY = elem.style['overflowY'];
+        if (!overflowY) {
+          var css = document.defaultView.getComputedStyle(elem, null);
+          overflowY = css ? css['overflowY'] : null;
+        }
+
+        // The only non-clipping values of overflow is 'visible'. We assume that 'inherit'
+        // is also non-clipping at the moment, but should we check this?
+        if (overflowY != 'visible' && overflowY != 'inherit') {
+          // Make sure this element explicitly specifies a height
+          var height = elem.style['height'];
+          if (!height) {
+            var css = document.defaultView.getComputedStyle(elem, null);
+            height = css ? css['height'] : '';
+          }
+          if (height.length > 0 && height != 'auto') {
+            // We can safely ignore the children of this element,
+            // so move onto the next in the queue
+            continue;
+          }
+        }
+      }
+
+      for (var i = 0; i < children.length; i++) {
+        var child = children[i];
+        if (typeof child.offsetTop !== 'undefined' &&
+            typeof child.offsetHeight !== 'undefined') {
+          // offsetHeight already accounts for border-bottom, padding-bottom.
+          var bottom = child.offsetTop + child.offsetHeight +
+              parseIntFromElemPxAttribute(child, 'margin-bottom');
+          result = Math.max(result, bottom);
+        }
+        queue.push(child);
+      }
+    }
+
+    // Add border, padding and margin of the containing body.
+    return result
+        + parseIntFromElemPxAttribute(document.body, 'border-bottom')
+        + parseIntFromElemPxAttribute(document.body, 'margin-bottom')
+        + parseIntFromElemPxAttribute(document.body, 'padding-bottom');
+  }  
+  
+}());

Added: shindig/trunk/features/src/main/javascript/features/dynamic-height.height/feature.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/dynamic-height.height/feature.xml?rev=1049747&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/dynamic-height.height/feature.xml (added)
+++ shindig/trunk/features/src/main/javascript/features/dynamic-height.height/feature.xml Wed Dec 15 23:32:55 2010
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+-->
+<feature>
+  <name>dynamic-height.height</name>
+  <dependency>globals</dependency>
+  <dependency>dynamic-height.util</dependency>
+  <gadget>
+    <script src="dynamic-height-height.js"/>
+  </gadget>
+  <container>
+    <script src="dynamic-height-height.js"/>
+  </container>
+</feature>

Modified: shindig/trunk/features/src/main/javascript/features/dynamic-height.util/feature.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/dynamic-height.util/feature.xml?rev=1049747&r1=1049746&r2=1049747&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/dynamic-height.util/feature.xml (original)
+++ shindig/trunk/features/src/main/javascript/features/dynamic-height.util/feature.xml Wed Dec 15 23:32:55 2010
@@ -16,6 +16,8 @@ software distributed under the License i
 KIND, either express or implied. See the License for the
 specific language governing permissions and limitations under the License.
 -->
+
+<!-- TODO: rename to dynamic-height.viewport -->
 <feature>
   <name>dynamic-height.util</name>
   <dependency>globals</dependency>

Modified: shindig/trunk/features/src/main/javascript/features/dynamic-height/dynamic-height.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/dynamic-height/dynamic-height.js?rev=1049747&r1=1049746&r2=1049747&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/dynamic-height/dynamic-height.js (original)
+++ shindig/trunk/features/src/main/javascript/features/dynamic-height/dynamic-height.js Wed Dec 15 23:32:55 2010
@@ -36,91 +36,6 @@ gadgets.window = gadgets.window || {};
   var oldHeight;
 
   /**
-   * Parse out the value (specified in px) for a CSS attribute of an element.
-   *
-   * @param {Element} elem the element with the attribute to look for.
-   * @param {string} attr the CSS attribute name of interest.
-   * @return {number} the value of the px attr of the elem.
-   * @private
-   */
-  function parseIntFromElemPxAttribute(elem, attr) {
-    var style = window.getComputedStyle(elem, '');
-    var value = style.getPropertyValue(attr);
-    value.match(/^([0-9]+)/);
-    return parseInt(RegExp.$1, 10);
-  }
-
-  /**
-   * For Webkit-based browsers, calculate the height of the gadget iframe by
-   * iterating through all elements in the gadget, starting with the body tag.
-   * It is not sufficient to only account body children elements, because
-   * CSS style position "float" may place a child element outside of the
-   * containing parent element. Not counting "float" elements may lead to
-   * undercounting.
-   *
-   * @return {number} the height of the gadget.
-   * @private
-   */
-  function getHeightForWebkit() {
-    var result = 0;
-    var queue = [document.body];
-
-    while (queue.length > 0) {
-      var elem = queue.shift();
-      var children = elem.childNodes;
-
-      /*
-       * Here, we are checking if we are a container that clips its overflow wit h
-       * a specific height, because if so, we should ignore children
-       */
-
-      // check that elem is actually an element, could be a text node otherwise
-      if (typeof elem.style !== 'undefined') {
-        // Get the overflowY value, looking in the computed style if necessary
-        var overflowY = elem.style['overflowY'];
-        if (!overflowY) {
-          var css = document.defaultView.getComputedStyle(elem, null);
-          overflowY = css ? css['overflowY'] : null;
-        }
-
-        // The only non-clipping values of overflow is 'visible'. We assume that 'inherit'
-        // is also non-clipping at the moment, but should we check this?
-        if (overflowY != 'visible' && overflowY != 'inherit') {
-          // Make sure this element explicitly specifies a height
-          var height = elem.style['height'];
-          if (!height) {
-            var css = document.defaultView.getComputedStyle(elem, null);
-            height = css ? css['height'] : '';
-          }
-          if (height.length > 0 && height != 'auto') {
-            // We can safely ignore the children of this element,
-            // so move onto the next in the queue
-            continue;
-          }
-        }
-      }
-
-      for (var i = 0; i < children.length; i++) {
-        var child = children[i];
-        if (typeof child.offsetTop !== 'undefined' &&
-            typeof child.offsetHeight !== 'undefined') {
-          // offsetHeight already accounts for border-bottom, padding-bottom.
-          var bottom = child.offsetTop + child.offsetHeight +
-              parseIntFromElemPxAttribute(child, 'margin-bottom');
-          result = Math.max(result, bottom);
-        }
-        queue.push(child);
-      }
-    }
-
-    // Add border, padding and margin of the containing body.
-    return result
-        + parseIntFromElemPxAttribute(document.body, 'border-bottom')
-        + parseIntFromElemPxAttribute(document.body, 'margin-bottom')
-        + parseIntFromElemPxAttribute(document.body, 'padding-bottom');
-  }
-
-  /**
    * Adjusts the gadget height
    * @param {number=} opt_height An optional preferred height in pixels. If not
    *     specified, will attempt to fit the gadget to its content.
@@ -131,65 +46,7 @@ gadgets.window = gadgets.window || {};
     var heightAutoCalculated = false;
     if (isNaN(newHeight)) {
       heightAutoCalculated = true;
-
-      // Resize the gadget to fit its content.
-
-      // Calculating inner content height is hard and different between
-      // browsers rendering in Strict vs. Quirks mode.  We use a combination of
-      // three properties within document.body and document.documentElement:
-      // - scrollHeight
-      // - offsetHeight
-      // - clientHeight
-      // These values differ significantly between browsers and rendering modes.
-      // But there are patterns.  It just takes a lot of time and persistence
-      // to figure out.
-
-      // Get the height of the viewport
-      var vh = gadgets.window.getViewportDimensions().height;
-      var body = document.body;
-      var docEl = document.documentElement;
-      if (document.compatMode === 'CSS1Compat' && docEl.scrollHeight) {
-        // In Strict mode:
-        // The inner content height is contained in either:
-        //    document.documentElement.scrollHeight
-        //    document.documentElement.offsetHeight
-        // Based on studying the values output by different browsers,
-        // use the value that's NOT equal to the viewport height found above.
-        newHeight = docEl.scrollHeight !== vh ?
-            docEl.scrollHeight : docEl.offsetHeight;
-      } else if (navigator.userAgent.indexOf('AppleWebKit') >= 0) {
-        // In Webkit:
-        // Property scrollHeight and offsetHeight will only increase in value.
-        // This will incorrectly calculate reduced height of a gadget
-        // (ie: made smaller).
-        newHeight = getHeightForWebkit();
-      } else if (body && docEl) {
-        // In Quirks mode:
-        // documentElement.clientHeight is equal to documentElement.offsetHeight
-        // except in IE.  In most browsers, document.documentElement can be used
-        // to calculate the inner content height.
-        // However, in other browsers (e.g. IE), document.body must be used
-        // instead.  How do we know which one to use?
-        // If document.documentElement.clientHeight does NOT equal
-        // document.documentElement.offsetHeight, then use document.body.
-        var sh = docEl.scrollHeight;
-        var oh = docEl.offsetHeight;
-        if (docEl.clientHeight !== oh) {
-          sh = body.scrollHeight;
-          oh = body.offsetHeight;
-        }
-
-        // Detect whether the inner content height is bigger or smaller
-        // than the bounding box (viewport).  If bigger, take the larger
-        // value.  If smaller, take the smaller value.
-        if (sh > vh) {
-          // Content is larger
-          newHeight = sh > oh ? sh : oh;
-        } else {
-          // Content is smaller
-          newHeight = sh < oh ? sh : oh;
-        }
-      }
+      newHeight = gadgets.window.getHeight();
     }
 
     // Only make the IFPC call if height has changed
@@ -208,4 +65,3 @@ gadgets.window = gadgets.window || {};
 var _IG_AdjustIFrameHeight = gadgets.window.adjustHeight;
 
 // TODO Attach gadgets.window.adjustHeight to the onresize event
-

Modified: shindig/trunk/features/src/main/javascript/features/dynamic-height/feature.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/dynamic-height/feature.xml?rev=1049747&r1=1049746&r2=1049747&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/dynamic-height/feature.xml (original)
+++ shindig/trunk/features/src/main/javascript/features/dynamic-height/feature.xml Wed Dec 15 23:32:55 2010
@@ -19,6 +19,7 @@ specific language governing permissions 
 <feature>
   <name>dynamic-height</name>
   <dependency>globals</dependency>
+  <dependency>dynamic-height.height</dependency>
   <dependency>dynamic-height.util</dependency>
   <dependency>rpc</dependency>
   <gadget>

Modified: shindig/trunk/features/src/main/javascript/features/dynamic-height/taming.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/dynamic-height/taming.js?rev=1049747&r1=1049746&r2=1049747&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/dynamic-height/taming.js (original)
+++ shindig/trunk/features/src/main/javascript/features/dynamic-height/taming.js Wed Dec 15 23:32:55 2010
@@ -25,7 +25,7 @@ var tamings___ = tamings___ || [];
 tamings___.push(function(imports) {
   caja___.whitelistFuncs([
     [gadgets.window, 'adjustHeight'],
+    [gadgets.window, 'getHeight'],
     [gadgets.window, 'getViewportDimensions']
   ]);
 });
-

Modified: shindig/trunk/features/src/main/javascript/features/features.txt
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/features.txt?rev=1049747&r1=1049746&r2=1049747&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/features.txt (original)
+++ shindig/trunk/features/src/main/javascript/features/features.txt Wed Dec 15 23:32:55 2010
@@ -35,6 +35,7 @@ features/core.prefs/feature.xml
 features/core.util/feature.xml
 features/core.util.urlparams/feature.xml
 features/core/feature.xml
+features/dynamic-height.height/feature.xml
 features/dynamic-height.util/feature.xml
 features/dynamic-height/feature.xml
 features/flash/feature.xml