All Downloads are FREE. Search and download functionalities are using the official Maven repository.

features-extras.wave.dynamic-width.js Maven / Gradle / Ivy

Go to download

Provides extra, deprecated or extended functionality. The items here have unstable APIs and could change at any time.

There is a newer version: 3.0.0-beta4
Show newest version
/*
 * 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.
 */

// TODO: Define a more convenient set of methods for iframe resizing in wave.

/**
 * @fileoverview This library augments gadgets.window with functionality
 * to change the width of a gadget dynamically. Derived from the
 * dynamic-height feature source code.
 * See:
 * http://svn.apache.org/repos/asf/shindig/trunk/features/src/main/javascript/features/dynamic-height/dynamic-height.js
 */

/**
 * @static
 * @class This namespace is used by the Gadgets API for the features it offers
 * in all containers, including Wave. Those are documented here:
 * http://code.google.com/apis/gadgets/docs/reference/
 * @name gadgets
 */

/**
 * @static
 * @class This namespace is defined by the Gadgets API, and documented here:
 * http://code.google.com/apis/gadgets/docs/reference/#gadgets.window 
* The Wave Gadgets API adds an additional method on top of the set documented * there. * @name gadgets.window */ gadgets.window = gadgets.window || {}; // we wrap these in an anonymous function to avoid storing private data // as members of gadgets.window. (function() { var oldWidth; /** * 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. * @returns {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 width 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. * * @returns {number} the width of the gadget. * @private */ function getWidthForWebkit() { var result = 0; var queue = [ document.body ]; while (queue.length > 0) { var elem = queue.shift(); var children = elem.childNodes; for (var i = 0; i < children.length; i++) { var child = children[i]; if (typeof child.offsetLeft !== 'undefined' && typeof child.scrollWidth !== 'undefined') { // scrollHeight already accounts for border-bottom, padding-bottom. var right = child.offsetLeft + child.scrollWidth + parseIntFromElemPxAttribute(child, "margin-right"); result = Math.max(result, right); } queue.push(child); } } // Add border, padding and margin of the containing body. return result + parseIntFromElemPxAttribute(document.body, "border-right") + parseIntFromElemPxAttribute(document.body, "margin-right") + parseIntFromElemPxAttribute(document.body, "padding-right"); } /** * Adjusts the gadget width * @param {number=} opt_width An optional preferred width in pixels. If not * specified, will attempt to fit the gadget to its content. * @member gadgets.window */ gadgets.window.adjustWidth = function(opt_width) { var newWidth = parseInt(opt_width, 10); var widthAutoCalculated = false; if (isNaN(newWidth)) { widthAutoCalculated = true; // Resize the gadget to fit its content. // Get the width of the viewport var vw = gadgets.window.getViewportDimensions().width; var body = document.body; var docEl = document.documentElement; if (document.compatMode === 'CSS1Compat' && docEl.scrollWidth) { // In Strict mode: // The inner content height is contained in either: // document.documentElement.scrollWidth // document.documentElement.offsetWidth // Based on studying the values output by different browsers, // use the value that's NOT equal to the viewport width found above. newWidth = docEl.scrollWidth !== vw ? docEl.scrollWidth : docEl.offsetWidth; } else if (navigator.userAgent.indexOf('AppleWebKit') >= 0) { // In Webkit: // Property scrollWidth and offsetWidth will only increase in value. // This will incorrectly calculate reduced width of a gadget // (ie: made smaller). newWidth = getWidthForWebkit(); } else if (body && docEl) { // In Quirks mode: // documentElement.clientWidth is equal to documentElement.offsetWidth // except in IE. In most browsers, document.documentElement can be used // to calculate the inner content width. // However, in other browsers (e.g. IE), document.body must be used // instead. How do we know which one to use? // If document.documentElement.clientWidth does NOT equal // document.documentElement.offsetWidth, then use document.body. var sw = docEl.scrollWidth; var ow = docEl.offsetWidth; if (docEl.clientWidth !== ow) { sw = body.scrollWidth; ow = body.offsetWidth; } // Detect whether the inner content width is bigger or smaller // than the bounding box (viewport). If bigger, take the larger // value. If smaller, take the smaller value. if (sw > vw) { // Content is larger newWidth = sw > ow ? sw : ow; } else { // Content is smaller newWidth = sw < ow ? sw : ow; } } } // Only make the RPC call if width has changed if (newWidth !== oldWidth && !isNaN(newWidth) && !(widthAutoCalculated && newWidth === 0)) { oldWidth = newWidth; gadgets.rpc.call(null, "setIframeWidth", null, newWidth); } }; }());




© 2015 - 2024 Weber Informatics LLC | Privacy Policy