Committer: dpetrov
OPSC-360: Implement JS API to navigate between different application viewsA trunk/htdocs/js/apps/ A trunk/htdocs/js/apps/shindig/ A trunk/htdocs/js/apps/shindig/core.json/ A trunk/htdocs/js/apps/shindig/core.json/feature.xml A trunk/htdocs/js/apps/shindig/core.json/json-flatten.js A trunk/htdocs/js/apps/shindig/core.json/json-jsimpl.js A trunk/htdocs/js/apps/shindig/core.json/json-native.js A trunk/htdocs/js/apps/shindig/core.json/taming.js A trunk/htdocs/js/apps/shindig/core.util/ A trunk/htdocs/js/apps/shindig/core.util/feature.xml A trunk/htdocs/js/apps/shindig/core.util/taming.js A trunk/htdocs/js/apps/shindig/core.util.base/ A trunk/htdocs/js/apps/shindig/core.util.base/base.js A trunk/htdocs/js/apps/shindig/core.util.base/feature.xml A trunk/htdocs/js/apps/shindig/core.util.dom/ A trunk/htdocs/js/apps/shindig/core.util.dom/dom.js A trunk/htdocs/js/apps/shindig/core.util.dom/feature.xml A trunk/htdocs/js/apps/shindig/core.util.event/ A trunk/htdocs/js/apps/shindig/core.util.event/event.js A trunk/htdocs/js/apps/shindig/core.util.event/feature.xml A trunk/htdocs/js/apps/shindig/core.util.onload/ A trunk/htdocs/js/apps/shindig/core.util.onload/feature.xml A trunk/htdocs/js/apps/shindig/core.util.onload/onload.js A trunk/htdocs/js/apps/shindig/core.util.onload/taming.js A trunk/htdocs/js/apps/shindig/core.util.string/ A trunk/htdocs/js/apps/shindig/core.util.string/feature.xml A trunk/htdocs/js/apps/shindig/core.util.string/string.js A trunk/htdocs/js/apps/shindig/core.util.string/taming.js A trunk/htdocs/js/apps/shindig/core.util.urlparams/ A trunk/htdocs/js/apps/shindig/core.util.urlparams/feature.xml A trunk/htdocs/js/apps/shindig/core.util.urlparams/taming.js A trunk/htdocs/js/apps/shindig/core.util.urlparams/urlparams.js A trunk/htdocs/js/apps/shindig/dynamic-height.height/ A trunk/htdocs/js/apps/shindig/dynamic-height.height/dynamic-height-height.js A trunk/htdocs/js/apps/shindig/dynamic-height.height/feature.xml A trunk/htdocs/js/apps/shindig/dynamic-height.height/taming.js A trunk/htdocs/js/apps/shindig/dynamic-height.util/ A trunk/htdocs/js/apps/shindig/dynamic-height.util/taming.js A trunk/htdocs/js/apps/shindig/globals/ A trunk/htdocs/js/apps/shindig/globals/feature.xml A trunk/htdocs/js/apps/shindig/shindig.container/ A trunk/htdocs/js/apps/shindig/shindig.container/cookiebaseduserprefstore.js A trunk/htdocs/js/apps/shindig/shindig.container/cookies.js A trunk/htdocs/js/apps/shindig/shindig.container/feature.xml A trunk/htdocs/js/apps/shindig/shindig.container/osapi.js A trunk/htdocs/js/apps/shindig/shindig.container/shindig-container.js A trunk/htdocs/js/apps/shindig/shindig.container/util.js A trunk/htdocs/js/apps/shindig/views/ A trunk/htdocs/js/apps/shindig/views/feature.xml A trunk/htdocs/js/apps/shindig/views/taming.js A trunk/htdocs/js/apps/shindig/views/views.js
Added: trunk/htdocs/js/apps/shindig/core.json/feature.xml =================================================================== --- trunk/htdocs/js/apps/shindig/core.json/feature.xml (rev 0) +++ trunk/htdocs/js/apps/shindig/core.json/feature.xml 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,44 @@ +<?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>core.json</name> + <dependency>globals</dependency> + <dependency>taming</dependency> + <gadget> + <script src="json-native.js"/> + <script src="json-jsimpl.js"/> + <script src="json-flatten.js"/> + <script src="taming.js" caja="1"/> + <api> + <exports type="js">gadgets.json.flatten</exports> + <exports type="js">gadgets.json.parse</exports> + <exports type="js">gadgets.json.stringify</exports> + </api> + </gadget> + <container> + <script src="json-native.js"/> + <script src="json-jsimpl.js"/> + <script src="json-flatten.js"/> + <api> + <exports type="js">gadgets.json.flatten</exports> + <exports type="js">gadgets.json.parse</exports> + <exports type="js">gadgets.json.stringify</exports> + </api> + </container> +</feature> Added: trunk/htdocs/js/apps/shindig/core.json/json-flatten.js =================================================================== --- trunk/htdocs/js/apps/shindig/core.json/json-flatten.js (rev 0) +++ trunk/htdocs/js/apps/shindig/core.json/json-flatten.js 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,42 @@ +/* + * 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. + */ + +/** + * Flatten an object to a stringified values. Useful for dealing with + * json->querystring transformations. Note: not in official specification yet + * + * @param {Object} obj + * @return {Object} object with only string values. + */ +gadgets.json.flatten = function(obj) { + var flat = {}; + + if (obj === null || obj === undefined) return flat; + + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + var value = obj[k]; + if (null === value || undefined === value) { + continue; + } + flat[k] = (typeof value === 'string') ? value : gadgets.json.stringify(value); + } + } + return flat; +}; Added: trunk/htdocs/js/apps/shindig/core.json/json-jsimpl.js =================================================================== --- trunk/htdocs/js/apps/shindig/core.json/json-jsimpl.js (rev 0) +++ trunk/htdocs/js/apps/shindig/core.json/json-jsimpl.js 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,184 @@ +/* + * 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 + * The global object gadgets.json contains two methods. + * + * gadgets.json.stringify(value) takes a JavaScript value and produces a JSON + * text. The value must not be cyclical. + * + * gadgets.json.parse(text) takes a JSON text and produces a JavaScript value. + * It will return false if there is an error. + */ + +/** + * @static + * @class Provides operations for translating objects to and from JSON. + * @name gadgets.json + */ + +/** + * JavaScript-based implementation when window.JSON is not present. + * Port of the public domain JSON library by Douglas Crockford. + * See: http://www.json.org/json2.js + */ +if (!(window.JSON && window.JSON.parse && window.JSON.stringify)) { + /** + * Port of the public domain JSON library by Douglas Crockford. + * See: http://www.json.org/json2.js + */ + gadgets.json = function() { + + /** + * Formats integers to 2 digits. + * @param {number} n number to format. + * @return {string} the formatted number. + * @private + */ + function f(n) { + return n < 10 ? '0' + n : n; + } + + Date.prototype.toJSON = function() { + return [this.getUTCFullYear(), '-', + f(this.getUTCMonth() + 1), '-', + f(this.getUTCDate()), 'T', + f(this.getUTCHours()), ':', + f(this.getUTCMinutes()), ':', + f(this.getUTCSeconds()), 'Z'].join(''); + }; + + // table of character substitutions + /** + * @const + * @enum {string} + */ + var m = { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }; + + /** + * Converts a json object into a string. + * @param {*} value + * @return {string} + * @member gadgets.json + */ + function stringify(value) { + var a, // The array holding the partial texts. + i, // The loop counter. + k, // The member key. + l, // Length. + r = /[\"\\\x00-\x1f\x7f-\x9f]/g, + v; // The member value. + + switch (typeof value) { + case 'string': + // If the string contains no control characters, no quote characters, and no + // backslash characters, then we can safely slap some quotes around it. + // Otherwise we must also replace the offending characters with safe ones. + return r.test(value) ? + '"' + value.replace(r, function(a) { + var c = m[a]; + if (c) { + return c; + } + c = a.charCodeAt(); + return '\\u00' + Math.floor(c / 16).toString(16) + + (c % 16).toString(16); + }) + '"' : '"' + value + '"'; + case 'number': + // JSON numbers must be finite. Encode non-finite numbers as null. + return isFinite(value) ? String(value) : 'null'; + case 'boolean': + case 'null': + return String(value); + case 'object': + // Due to a specification blunder in ECMAScript, + // typeof null is 'object', so watch out for that case. + if (!value) { + return 'null'; + } + // toJSON check removed; re-implement when it doesn't break other libs. + a = []; + if (typeof value.length === 'number' && + !value.propertyIsEnumerable('length')) { + // The object is an array. Stringify every element. Use null as a + // placeholder for non-JSON values. + l = value.length; + for (i = 0; i < l; i += 1) { + a.push(stringify(value[i]) || 'null'); + } + // Join all of the elements together and wrap them in brackets. + return '[' + a.join(',') + ']'; + } + // Otherwise, iterate through all of the keys in the object. + for (k in value) { + if (/___$/.test(k)) + continue; + if (value.hasOwnProperty(k)) { + if (typeof k === 'string') { + v = stringify(value[k]); + if (v) { + a.push(stringify(k) + ':' + v); + } + } + } + } + // Join all of the member texts together and wrap them in braces. + return '{' + a.join(',') + '}'; + } + return ''; + } + + return { + stringify: stringify, + parse: function(text) { + // Parsing happens in three stages. In the first stage, we run the text against + // regular expressions that look for non-JSON patterns. We are especially + // concerned with '()' and 'new' because they can cause invocation, and '=' + // because it can cause mutation. But just to be safe, we want to reject all + // unexpected forms. + + // We split the first stage into 4 regexp operations in order to work around + // crippling inefficiencies in IE's and Safari's regexp engines. First we + // replace all backslash pairs with '@' (a non-JSON character). Second, we + // replace all simple value tokens with ']' characters. Third, we delete all + // open brackets that follow a colon or comma or that begin the text. Finally, + // we look to see that the remaining characters are only whitespace or ']' or + // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/.test(text.replace(/\\["\\\/b-u]/g, '@'). + replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). + replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + return eval('(' + text + ')'); + } + // If the text is not JSON parseable, then return false. + + return false; + } + }; + }(); +} Added: trunk/htdocs/js/apps/shindig/core.json/json-native.js =================================================================== --- trunk/htdocs/js/apps/shindig/core.json/json-native.js (rev 0) +++ trunk/htdocs/js/apps/shindig/core.json/json-native.js 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,79 @@ +/* + * 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 + * The global object gadgets.json contains two methods. + * + * gadgets.json.stringify(value) takes a JavaScript value and produces a JSON + * text. The value must not be cyclical. + * + * gadgets.json.parse(text) takes a JSON text and produces a JavaScript value. + * It will return false if there is an error. + */ + +/** + * @static + * @class Provides operations for translating objects to and from JSON. + * @name gadgets.json + */ + +/** + * Just wrap native JSON calls when available. + */ +if (window.JSON && window.JSON.parse && window.JSON.stringify) { + // HTML5 implementation, or already defined. + // Not a direct alias as the opensocial specification disagrees with the HTML5 JSON spec. + // JSON says to throw on parse errors and to support filtering functions. OS does not. + gadgets.json = (function() { + var endsWith___ = /___$/; + + function getOrigValue(key, value) { + var origValue = this[key]; + return origValue; + } + + return { + /* documented below */ + parse: function(str) { + try { + return window.JSON.parse(str); + } catch (e) { + return false; + } + }, + /* documented below */ + stringify: function(obj) { + var orig = window.JSON.stringify; + function patchedStringify(val) { + return orig.call(this, val, getOrigValue); + } + var stringifyFn = (Array.prototype.toJSON && orig([{x:1}]) === "\"[{\\\"x\\\": 1}]\"") ? + patchedStringify : orig; + try { + return stringifyFn(obj, function(k,v) { + return !endsWith___.test(k) ? v : void 0; + }); + } catch (e) { + return null; + } + } + }; + })(); +} Added: trunk/htdocs/js/apps/shindig/core.json/taming.js =================================================================== --- trunk/htdocs/js/apps/shindig/core.json/taming.js (rev 0) +++ trunk/htdocs/js/apps/shindig/core.json/taming.js 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,29 @@ +/* + * 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. + */ + +/** + * @class + * Tame and expose core gadgets.* API to cajoled gadgets + */ +tamings___.push(function(imports) { + caja___.tamesTo(gadgets.json.stringify, + caja___.getTameGlobal().safeJSON.stringify); + caja___.tamesTo(gadgets.json.parse, + caja___.getTameGlobal().safeJSON.parse); +}); Added: trunk/htdocs/js/apps/shindig/core.util/feature.xml =================================================================== --- trunk/htdocs/js/apps/shindig/core.util/feature.xml (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util/feature.xml 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,39 @@ +<?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>core.util</name> + <dependency>globals</dependency> + <dependency>taming</dependency> + <dependency>core.config</dependency> + <dependency>core.util.base</dependency> + <dependency>core.util.dom</dependency> + <dependency>core.util.event</dependency> + <dependency>core.util.onload</dependency> + <dependency>core.util.string</dependency> + <dependency>core.util.urlparams</dependency> + <all> + <script src="util.js"/> + <script src="taming.js" caja="1"/> + <api> + <exports type="js">gadgets.util.getFeatureParameters</exports> + <exports type="js">gadgets.util.hasFeature</exports> + <exports type="js">gadgets.util.getServices</exports> + </api> + </all> +</feature> Added: trunk/htdocs/js/apps/shindig/core.util/taming.js =================================================================== --- trunk/htdocs/js/apps/shindig/core.util/taming.js (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util/taming.js 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,29 @@ +/* + * 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. + */ + +/** + * @class + * Tame and expose core gadgets.* API to cajoled gadgets + */ +tamings___.push(function(imports) { + caja___.whitelistFuncs([ + [gadgets.util, 'getFeatureParameters'], + [gadgets.util, 'hasFeature'] + ]); +}); Added: trunk/htdocs/js/apps/shindig/core.util.base/base.js =================================================================== --- trunk/htdocs/js/apps/shindig/core.util.base/base.js (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util.base/base.js 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,77 @@ +/* + * 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 General purpose utilities that gadgets can use. + */ + + +/** + * @class Provides general-purpose utility functions. + */ +gadgets.util = gadgets.util || {}; + + +/** + * Creates a closure that is suitable for passing as a callback. + * Any number of arguments + * may be passed to the callback; + * they will be received in the order they are passed in. + * + * @param {Object} scope The execution scope; may be null if there is no + * need to associate a specific instance of an object with this + * callback. + * @param {function(Object,Object)} callback The callback to invoke when + * this is run; any arguments passed in will be passed after your initial + * arguments. + * @param {Object} var_args Initial arguments to be passed to the callback. + * @return {function()} a callback function. + */ +gadgets.util.makeClosure = function(scope, callback, var_args) { + // arguments isn't a real array, so we copy it into one. + var baseArgs = []; + for (var i = 2, j = arguments.length; i < j; ++i) { + baseArgs.push(arguments[i]); + } + return function() { + // append new arguments. + var tmpArgs = baseArgs.slice(); + for (var i = 0, j = arguments.length; i < j; ++i) { + tmpArgs.push(arguments[i]); + } + return callback.apply(scope, tmpArgs); + }; +}; + + +/** + * Utility function for generating an "enum" from an array. + * + * @param {Array.<string>} values The values to generate. + * @return {Object.<string,string>} An object with member fields to handle + * the enum. + */ +gadgets.util.makeEnum = function(values) { + var i, v, obj = {}; + for (i = 0; (v = values[i]); ++i) { + obj[v] = v; + } + return obj; +}; + Added: trunk/htdocs/js/apps/shindig/core.util.base/feature.xml =================================================================== --- trunk/htdocs/js/apps/shindig/core.util.base/feature.xml (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util.base/feature.xml 2011-09-12 08:20:17 UTC (rev 20020) @@ -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>core.util.base</name> + <dependency>globals</dependency> + <all> + <script src="base.js"/> + <api> + <exports type="js">gadgets.util.makeClosure</exports> + <exports type="js">gadgets.util.makeEnum</exports> + </api> + </all> +</feature> Added: trunk/htdocs/js/apps/shindig/core.util.dom/dom.js =================================================================== --- trunk/htdocs/js/apps/shindig/core.util.dom/dom.js (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util.dom/dom.js 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,125 @@ +/* + * 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 General purpose utilities that gadgets can use. + */ + + +/** + * @class Provides general-purpose utility functions. + */ +gadgets.util = gadgets.util || {}; + +(function() { + + var XHTML_SPEC = 'http://www.w3.org/1999/xhtml'; + + function attachAttributes(elem, opt_attribs) { + var attribs = opt_attribs || {}; + for (var attrib in attribs) { + if (attribs.hasOwnProperty(attrib)) { + elem[attrib] = attribs[attrib]; + } + } + } + + function stringifyElement(tagName, opt_attribs) { + var arr = ['<', tagName]; + var attribs = opt_attribs || {}; + for (var attrib in attribs) { + if (attribs.hasOwnProperty(attrib)) { + arr.push(' '); + arr.push(attrib); + arr.push('="'); + arr.push(gadgets.util.escapeString(attribs[attrib])); + arr.push('"'); + } + } + arr.push('></'); + arr.push(tagName); + arr.push('>'); + return arr.join(''); + } + + /** + * Creates an HTML or XHTML element. + * @param {string} tagName The type of element to construct. + * @return {Element} The newly constructed element. + */ + gadgets.util.createElement = function(tagName) { + var element; + if ((!document.body) || document.body.namespaceURI) { + try { + element = document.createElementNS(XHTML_SPEC, tagName); + } catch (nonXmlDomException) { + } + } + return element || document.createElement(tagName); + }; + + /** + * Creates an HTML or XHTML iframe element with attributes. + * @param {Object=} opt_attribs Optional set of attributes to attach. The + * only working attributes are spelled the same way in XHTML attribute + * naming (most strict, all-lower-case), HTML attribute naming (less strict, + * case-insensitive), and JavaScript property naming (some properties named + * incompatibly with XHTML/HTML). + * @return {Element} The DOM node representing body. + */ + gadgets.util.createIframeElement = function(opt_attribs) { + var frame = gadgets.util.createElement('iframe'); + try { + // TODO: provide automatic mapping to only set the needed + // and JS-HTML-XHTML compatible subset through stringifyElement (just + // 'name' and 'id', AFAIK). The values of the attributes will be + // stringified should the stringifyElement code path be taken (IE) + var tagString = stringifyElement('iframe', opt_attribs); + var ieFrame = gadgets.util.createElement(tagString); + if (ieFrame && + ((!frame) || + ((ieFrame.tagName == frame.tagName) && + (ieFrame.namespaceURI == frame.namespaceURI)))) { + frame = ieFrame; + } + } catch (nonStandardCallFailed) { + } + attachAttributes(frame, opt_attribs); + return frame; + }; + + /** + * Gets the HTML or XHTML body element. + * @return {Element} The DOM node representing body. + */ + gadgets.util.getBodyElement = function() { + if (document.body) { + return document.body; + } + try { + var xbodies = document.getElementsByTagNameNS(XHTML_SPEC, 'body'); + if (xbodies && (xbodies.length == 1)) { + return xbodies[0]; + } + } catch (nonXmlDomException) { + } + return document.documentElement || document; + }; + +})(); Added: trunk/htdocs/js/apps/shindig/core.util.dom/feature.xml =================================================================== --- trunk/htdocs/js/apps/shindig/core.util.dom/feature.xml (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util.dom/feature.xml 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,30 @@ +<?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>core.util.dom</name> + <dependency>globals</dependency> + <all> + <script src="dom.js"/> + <api> + <exports type="js">gadgets.util.createElement</exports> + <exports type="js">gadgets.util.createIframeElement</exports> + <exports type="js">gadgets.util.getBodyElement</exports> + </api> + </all> +</feature> Added: trunk/htdocs/js/apps/shindig/core.util.event/event.js =================================================================== --- trunk/htdocs/js/apps/shindig/core.util.event/event.js (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util.event/event.js 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,62 @@ +/* + * 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 General purpose utilities that gadgets can use. + */ + +gadgets.util = gadgets.util || {}; + +/** + * Attach an event listener to given DOM element (Not a gadget standard) + * + * @param {Object} elem DOM element on which to attach event. + * @param {string} eventName Event type to listen for. + * @param {function()} callback Invoked when specified event occurs. + * @param {boolean} useCapture If true, initiates capture. + */ +gadgets.util.attachBrowserEvent = function(elem, eventName, callback, useCapture) { + if (typeof elem.addEventListener != 'undefined') { + elem.addEventListener(eventName, callback, useCapture); + } else if (typeof elem.attachEvent != 'undefined') { + elem.attachEvent('on' + eventName, callback); + } else { + gadgets.warn('cannot attachBrowserEvent: ' + eventName); + } +}; + +/** + * Remove event listener. (Shindig internal implementation only) + * + * @param {Object} elem DOM element from which to remove event. + * @param {string} eventName Event type to remove. + * @param {function()} callback Listener to remove. + * @param {boolean} useCapture Specifies whether listener being removed was added with + * capture enabled. + */ +gadgets.util.removeBrowserEvent = function(elem, eventName, callback, useCapture) { + if (elem.removeEventListener) { + elem.removeEventListener(eventName, callback, useCapture); + } else if (elem.detachEvent) { + elem.detachEvent('on' + eventName, callback); + } else { + gadgets.warn('cannot removeBrowserEvent: ' + eventName); + } +}; + Added: trunk/htdocs/js/apps/shindig/core.util.event/feature.xml =================================================================== --- trunk/htdocs/js/apps/shindig/core.util.event/feature.xml (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util.event/feature.xml 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,31 @@ +<?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>core.util.event</name> + <dependency>globals</dependency> + <dependency>core.log</dependency> + <all> + <script src="event.js"/> + <api> + <exports type="js">gadgets.util.attachBrowserEvent</exports> + <exports type="js">gadgets.util.removeBrowserEvent</exports> + </api> + </all> +</feature> + Added: trunk/htdocs/js/apps/shindig/core.util.onload/feature.xml =================================================================== --- trunk/htdocs/js/apps/shindig/core.util.onload/feature.xml (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util.onload/feature.xml 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,31 @@ +<?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>core.util.onload</name> + <dependency>globals</dependency> + <all> + <script src="onload.js"/> + <script src="taming.js" caja="1"/> + <api> + <exports type="js">gadgets.util.registerOnLoadHandler</exports> + <exports type="js">gadgets.util.runOnLoadHandlers</exports> + </api> + </all> +</feature> + Added: trunk/htdocs/js/apps/shindig/core.util.onload/onload.js =================================================================== --- trunk/htdocs/js/apps/shindig/core.util.onload/onload.js (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util.onload/onload.js 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,53 @@ +/* + * 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 General purpose utilities that gadgets can use. + */ + + +/** + * @class Provides general-purpose utility functions for onload. + */ +gadgets.util = gadgets.util || {}; + +(function() { + + var onLoadHandlers = []; + + /** + * Registers an onload handler. + * @param {function()} callback The handler to run. + */ + gadgets.util.registerOnLoadHandler = function(callback) { + onLoadHandlers.push(callback); + }; + + /** + * Runs all functions registered via registerOnLoadHandler. + * @private Only to be used by the container, not gadgets. + */ + gadgets.util.runOnLoadHandlers = function() { + for (var i = 0, j = onLoadHandlers.length; i < j; ++i) { + onLoadHandlers[i](); + } + }; + +})(); + Added: trunk/htdocs/js/apps/shindig/core.util.onload/taming.js =================================================================== --- trunk/htdocs/js/apps/shindig/core.util.onload/taming.js (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util.onload/taming.js 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,29 @@ +/* + * 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. + */ + +/** + * @class + * Tame and expose core gadgets.* API to cajoled gadgets + */ +tamings___.push(function(imports) { + caja___.whitelistFuncs([ + [gadgets.util, 'registerOnLoadHandler'] + ]); +}); + Added: trunk/htdocs/js/apps/shindig/core.util.string/feature.xml =================================================================== --- trunk/htdocs/js/apps/shindig/core.util.string/feature.xml (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util.string/feature.xml 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,31 @@ +<?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>core.util.string</name> + <dependency>globals</dependency> + <all> + <script src="string.js"/> + <script src="taming.js" caja="1"/> + <api> + <exports type="js">gadgets.util.escape</exports> + <exports type="js">gadgets.util.escapeString</exports> + <exports type="js">gadgets.util.unescapeString</exports> + </api> + </all> +</feature> Added: trunk/htdocs/js/apps/shindig/core.util.string/string.js =================================================================== --- trunk/htdocs/js/apps/shindig/core.util.string/string.js (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util.string/string.js 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,177 @@ +/* + * 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 General purpose utilities that gadgets can use. + */ + + +/** + * @class Provides a thin method for parsing url parameters. + */ +gadgets.util = gadgets.util || {}; + +(function() { + + /** + * @enum {boolean} + * @const + * @private + * Maps code points to the value to replace them with. + * If the value is "false", the character is removed entirely, otherwise + * it will be replaced with an html entity. + */ + var escapeCodePoints = { + // nul; most browsers truncate because they use c strings under the covers. + 0 : false, + // new line + 10 : true, + // carriage return + 13 : true, + // double quote + 34 : true, + // single quote + 39 : true, + // less than + 60 : true, + // greater than + 62 : true, + // backslash + 92 : true, + // line separator + 8232 : true, + // paragraph separator + 8233 : true, + // fullwidth quotation mark + 65282 : true, + // fullwidth apostrophe + 65287 : true, + // fullwidth less-than sign + 65308 : true, + // fullwidth greater-than sign + 65310 : true, + // fullwidth reverse solidus + 65340 : true + }; + + /** + * Regular expression callback that returns strings from unicode code points. + * + * @param {Array} match Ignored. + * @param {number} value The codepoint value to convert. + * @return {string} The character corresponding to value. + */ + function unescapeEntity(match, value) { + // TODO: b0rked for UTF-16 and can easily be convinced to generate + // truncating NULs or completely invalid non-Unicode characters. Here's a + // fixed version (it handles entities for valid codepoints from U+0001 ... + // U+10FFFD, except for the non-character codepoints U+...FFFE and + // U+...FFFF; isolated UTF-16 surrogate pairs are supported for + // compatibility with previous versions of escapeString, 0 generates the + // empty string rather than a possibly-truncating '\0', and all other inputs + // generate U+FFFD (the replacement character, standard practice for + // non-signalling Unicode codecs like this one) + // return ( + // (value > 0) && + // (value <= 0x10fffd) && + // ((value & 0xffff) < 0xfffe)) ? + // ((value <= 0xffff) ? + // String.fromCharCode(value) : + // String.fromCharCode( + // ((value - 0x10000) >> 10) | 0xd800, + // ((value - 0x10000) & 0x3ff) | 0xdc00)) : + // ((value === 0) ? '' : '\ufffd'); + return String.fromCharCode(value); + } + + /** + * Escapes the input using html entities to make it safer. + * + * If the input is a string, uses gadgets.util.escapeString. + * If it is an array, calls escape on each of the array elements + * if it is an object, will only escape all the mapped keys and values if + * the opt_escapeObjects flag is set. This operation involves creating an + * entirely new object so only set the flag when the input is a simple + * string to string map. + * Otherwise, does not attempt to modify the input. + * + * @param {Object} input The object to escape. + * @param {boolean=} opt_escapeObjects Whether to escape objects. + * @return {Object} The escaped object. + * @private Only to be used by the container, not gadgets. + */ + gadgets.util.escape = function(input, opt_escapeObjects) { + if (!input) { + return input; + } else if (typeof input === 'string') { + return gadgets.util.escapeString(input); + } else if (typeof input === 'array') { + for (var i = 0, j = input.length; i < j; ++i) { + input[i] = gadgets.util.escape(input[i]); + } + } else if (typeof input === 'object' && opt_escapeObjects) { + var newObject = {}; + for (var field in input) { + if (input.hasOwnProperty(field)) { + newObject[gadgets.util.escapeString(field)] = + gadgets.util.escape(input[field], true); + } + } + return newObject; + } + return input; + }; + + /** + * Escapes the input using html entities to make it safer. + * + * Currently not in the spec -- future proposals may change + * how this is handled. + * + * @param {string} str The string to escape. + * @return {string} The escaped string. + */ + gadgets.util.escapeString = function(str) { + if (!str) return str; + var out = [], ch, shouldEscape; + for (var i = 0, j = str.length; i < j; ++i) { + ch = str.charCodeAt(i); + shouldEscape = escapeCodePoints[ch]; + if (shouldEscape === true) { + out.push('&#', ch, ';'); + } else if (shouldEscape !== false) { + // undefined or null are OK. + out.push(str.charAt(i)); + } + } + return out.join(''); + }; + + /** + * Reverses escapeString + * + * @param {string} str The string to unescape. + * @return {string} + */ + gadgets.util.unescapeString = function(str) { + if (!str) return str; + return str.replace(/&#([0-9]+);/g, unescapeEntity); + }; + +})(); Added: trunk/htdocs/js/apps/shindig/core.util.string/taming.js =================================================================== --- trunk/htdocs/js/apps/shindig/core.util.string/taming.js (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util.string/taming.js 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,30 @@ +/* + * 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. + */ + +/** + * @class + * Tame and expose core gadgets.* API to cajoled gadgets + */ +tamings___.push(function(imports) { + caja___.whitelistFuncs([ + [gadgets.util, 'escape'], + [gadgets.util, 'escapeString'], + [gadgets.util, 'unescapeString'] + ]); +}); Added: trunk/htdocs/js/apps/shindig/core.util.urlparams/feature.xml =================================================================== --- trunk/htdocs/js/apps/shindig/core.util.urlparams/feature.xml (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util.urlparams/feature.xml 2011-09-12 08:20:17 UTC (rev 20020) @@ -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>core.util.urlparams</name> + <dependency>globals</dependency> + <all> + <script src="urlparams.js"/> + <script src="taming.js" caja="1"/> + <api> + <exports type="js">gadgets.util.getUrlParameters</exports> + </api> + </all> +</feature> Added: trunk/htdocs/js/apps/shindig/core.util.urlparams/taming.js =================================================================== --- trunk/htdocs/js/apps/shindig/core.util.urlparams/taming.js (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util.urlparams/taming.js 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,28 @@ +/* + * 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. + */ + +/** + * @class + * Tame and expose core gadgets.* API to cajoled gadgets + */ +tamings___.push(function(imports) { + caja___.whitelistFuncs([ + [gadgets.util, 'getUrlParameters'] + ]); +}); Added: trunk/htdocs/js/apps/shindig/core.util.urlparams/urlparams.js =================================================================== --- trunk/htdocs/js/apps/shindig/core.util.urlparams/urlparams.js (rev 0) +++ trunk/htdocs/js/apps/shindig/core.util.urlparams/urlparams.js 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,98 @@ +/* + * 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 General purpose utilities that gadgets can use. + */ + + +/** + * @class Provides a thin method for parsing url parameters. + */ +gadgets.util = gadgets.util || {}; + +(function() { + var parameters = null; + + /** + * Parses URL parameters into an object. + * @param {string} url - the url parameters to parse. + * @return {Array.<string>} The parameters as an array. + */ + function parseUrlParams(url) { + // Get settings from url, 'hash' takes precedence over 'search' component + // don't use document.location.hash due to browser differences. + var query; + var queryIdx = url.indexOf('?'); + var hashIdx = url.indexOf('#'); + if (hashIdx === -1) { + query = url.substr(queryIdx + 1); + } else { + // essentially replaces "#" with "&" + query = [url.substr(queryIdx + 1, hashIdx - queryIdx - 1), '&', + url.substr(hashIdx + 1)].join(''); + } + return query.split('&'); + } + + /** + * Gets the URL parameters. + * + * @param {string=} opt_url Optional URL whose parameters to parse. + * Defaults to window's current URL. + * @return {Object} Parameters passed into the query string. + * @private Implementation detail. + */ + gadgets.util.getUrlParameters = function(opt_url) { + var no_opt_url = typeof opt_url === 'undefined'; + if (parameters !== null && no_opt_url) { + // "parameters" is a cache of current window params only. + return parameters; + } + var parsed = {}; + var pairs = parseUrlParams(opt_url || document.location.href); + var unesc = window.decodeURIComponent ? decodeURIComponent : unescape; + for (var i = 0, j = pairs.length; i < j; ++i) { + var pos = pairs[i].indexOf('='); + if (pos === -1) { + continue; + } + var argName = pairs[i].substring(0, pos); + var value = pairs[i].substring(pos + 1); + // difference to IG_Prefs, is that args doesn't replace spaces in + // argname. Unclear on if it should do: + // argname = argname.replace(/\+/g, " "); + value = value.replace(/\+/g, ' '); + try { + parsed[argName] = unesc(value); + } catch (e) { + // Undecodable/invalid value; ignore. + } + } + if (no_opt_url) { + // Cache current-window params in parameters var. + parameters = parsed; + } + return parsed; + }; +})(); + +// Initialize url parameters so that hash data is pulled in before it can be +// altered by a click. +gadgets.util.getUrlParameters(); Added: trunk/htdocs/js/apps/shindig/dynamic-height.height/dynamic-height-height.js =================================================================== --- trunk/htdocs/js/apps/shindig/dynamic-height.height/dynamic-height-height.js (rev 0) +++ trunk/htdocs/js/apps/shindig/dynamic-height.height/dynamic-height-height.js 2011-09-12 08:20:17 UTC (rev 20020) @@ -0,0 +1,270 @@ +/* + * 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 + continu... (truncated)