You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ft...@apache.org on 2015/09/17 17:28:56 UTC
[41/51] [abbrv] [partial] git commit: [flex-falcon]
[refs/heads/JsToAs] - Added GCL extern.
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/datasource/fastdatanode.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/datasource/fastdatanode.js b/externs/GCL/externs/goog/datasource/fastdatanode.js
new file mode 100644
index 0000000..c14750f
--- /dev/null
+++ b/externs/GCL/externs/goog/datasource/fastdatanode.js
@@ -0,0 +1,814 @@
+// Copyright 2007 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed 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
+ * Efficient implementation of DataNode API.
+ *
+ * The implementation consists of three concrete classes for modelling
+ * DataNodes with different characteristics: FastDataNode,
+ * FastPrimitiveDataNode and FastListNode.
+ *
+ * FastDataNode is for bean-like or map-like objects that consists of
+ * key/value mappings and where the primary access pattern is by key.
+ *
+ * FastPrimitiveDataNode wraps primitives like strings, boolean, and numbers.
+ *
+ * FastListNode is for array-like data nodes. It also supports key-based
+ * lookups if the data nodes have an "id" property or if child nodes are
+ * explicitly added by name. It is most efficient if these features are not
+ * used.
+ *
+ * FastDataNodes can be constructed from JSON-like objects via the function
+ * goog.ds.FastDataNode.fromJs.
+
+ */
+
+goog.provide('goog.ds.AbstractFastDataNode');
+goog.provide('goog.ds.FastDataNode');
+goog.provide('goog.ds.FastListNode');
+goog.provide('goog.ds.PrimitiveFastDataNode');
+
+goog.require('goog.ds.DataManager');
+goog.require('goog.ds.DataNodeList');
+goog.require('goog.ds.EmptyNodeList');
+goog.require('goog.string');
+
+/*
+ * Implementation note: In order to reduce the number of objects,
+ * FastDataNode stores its key/value mappings directly in the FastDataNode
+ * object iself (instead of a separate map). To make this work we have to
+ * sure that there are no name clashes with other attribute names used by
+ * FastDataNode (like dataName and parent). This is especially difficult in
+ * the light of automatic renaming by the JavaScript compiler. For this reason,
+ * all internal attributes start with "__" so that they are not renamed
+ * by the compiler.
+ */
+
+/**
+ * Creates a new abstract data node.
+ * @param {string} dataName Name of the datanode.
+ * @param {goog.ds.DataNode=} opt_parent Parent of this data node.
+ * @constructor
+ * @extends {goog.ds.DataNodeList}
+ */
+// TODO(arv): Use interfaces when available.
+goog.ds.AbstractFastDataNode = function(dataName, opt_parent) {
+ if (!dataName) {
+ throw Error('Cannot create a fast data node without a data name');
+ }
+ this['__dataName'] = dataName;
+ this['__parent'] = opt_parent;
+};
+
+
+/**
+ * Return the name of this data node.
+ * @return {string} Name of this data noden.
+ * @override
+ */
+goog.ds.AbstractFastDataNode.prototype.getDataName = function() {
+ return this['__dataName'];
+};
+
+
+/**
+ * Set the name of this data node.
+ * @param {string} value Name.
+ * @override
+ */
+goog.ds.AbstractFastDataNode.prototype.setDataName = function(value) {
+ this['__dataName'] = value;
+};
+
+
+/**
+ * Get the path leading to this data node.
+ * @return {string} Data path.
+ * @override
+ */
+goog.ds.AbstractFastDataNode.prototype.getDataPath = function() {
+ var parentPath;
+ if (this['__parent']) {
+ parentPath = this['__parent'].getDataPath() + goog.ds.STR_PATH_SEPARATOR;
+ } else {
+ parentPath = '';
+ }
+ return parentPath + this.getDataName();
+};
+
+
+
+/**
+ * Creates a new fast data node, using the properties of root.
+ * @param {Object} root JSON-like object to initialize data node from.
+ * @param {string} dataName Name of this data node.
+ * @param {goog.ds.DataNode=} opt_parent Parent of this data node.
+ * @extends {goog.ds.AbstractFastDataNode}
+ * @constructor
+ */
+goog.ds.FastDataNode = function(root, dataName, opt_parent) {
+ goog.ds.AbstractFastDataNode.call(this, dataName, opt_parent);
+ this.extendWith(root);
+};
+goog.inherits(goog.ds.FastDataNode, goog.ds.AbstractFastDataNode);
+
+
+/**
+ * Add all attributes of object to this data node.
+ * @param {Object} object Object to add attributes from.
+ * @protected
+ */
+goog.ds.FastDataNode.prototype.extendWith = function(object) {
+ for (var key in object) {
+ this[key] = object[key];
+ }
+};
+
+
+/**
+ * Creates a new FastDataNode structure initialized from object. This will
+ * return an instance of the most suitable sub-class of FastDataNode.
+ *
+ * You should not modify object after creating a fast data node from it
+ * or assume that changing object changes the data node. Doing so results
+ * in undefined behaviour.
+ *
+ * @param {Object|number|boolean|string} object Object to initialize data
+ * node from.
+ * @param {string} dataName Name of data node.
+ * @param {goog.ds.DataNode=} opt_parent Parent of data node.
+ * @return {!goog.ds.AbstractFastDataNode} Data node representing object.
+ */
+goog.ds.FastDataNode.fromJs = function(object, dataName, opt_parent) {
+ if (goog.isArray(object)) {
+ return new goog.ds.FastListNode(object, dataName, opt_parent);
+ } else if (goog.isObject(object)) {
+ return new goog.ds.FastDataNode(object, dataName, opt_parent);
+ } else {
+ return new goog.ds.PrimitiveFastDataNode(object || !!object,
+ dataName,
+ opt_parent);
+ }
+};
+
+
+/**
+ * Static instance of an empty list.
+ * @type {!goog.ds.EmptyNodeList}
+ * @private
+ */
+goog.ds.FastDataNode.emptyList_ = new goog.ds.EmptyNodeList();
+
+
+/**
+ * Not supported for normal FastDataNodes.
+ * @param {*} value Value to set data node to.
+ * @override
+ */
+goog.ds.FastDataNode.prototype.set = function(value) {
+ throw new Error('Not implemented yet');
+};
+
+
+/** @override */
+goog.ds.FastDataNode.prototype.getChildNodes = function(opt_selector) {
+ if (!opt_selector || opt_selector == goog.ds.STR_ALL_CHILDREN_SELECTOR) {
+ return this;
+ } else if (opt_selector.indexOf(goog.ds.STR_WILDCARD) == -1) {
+ var child = this.getChildNode(opt_selector);
+ return child ? new goog.ds.FastListNode([child], '') :
+ new goog.ds.EmptyNodeList();
+ } else {
+ throw Error('Unsupported selector: ' + opt_selector);
+ }
+};
+
+
+/**
+ * Makes sure that a named child is wrapped in a data node structure.
+ * @param {string} name Name of child to wrap.
+ * @private
+ */
+goog.ds.FastDataNode.prototype.wrapChild_ = function(name) {
+ var child = this[name];
+ if (child != null && !child.getDataName) {
+ this[name] = goog.ds.FastDataNode.fromJs(this[name], name, this);
+ }
+};
+
+
+/**
+ * Get a child node by name.
+ * @param {string} name Name of child node.
+ * @param {boolean=} opt_create Whether to create the child if it does not
+ * exist.
+ * @return {goog.ds.DataNode} Child node.
+ * @override
+ */
+goog.ds.FastDataNode.prototype.getChildNode = function(name, opt_create) {
+ this.wrapChild_(name);
+ // this[name] always is a data node object, so using "||" is fine.
+ var child = this[name] || null;
+ if (child == null && opt_create) {
+ child = new goog.ds.FastDataNode({}, name, this);
+ this[name] = child;
+ }
+ return child;
+};
+
+
+/**
+ * Sets a child node. Creates the child if it does not exist.
+ *
+ * Calling this function makes any child nodes previously obtained for name
+ * invalid. You should not use these child nodes but instead obtain a new
+ * instance by calling getChildNode.
+ *
+ * @override
+ */
+goog.ds.FastDataNode.prototype.setChildNode = function(name, value) {
+ if (value != null) {
+ this[name] = value;
+ } else {
+ delete this[name];
+ }
+ goog.ds.DataManager.getInstance().fireDataChange(this.getDataPath() +
+ goog.ds.STR_PATH_SEPARATOR + name);
+ return null;
+};
+
+
+/**
+ * Returns the value of a child node. By using this method you can avoid
+ * the need to create PrimitiveFastData nodes.
+ * @param {string} name Name of child node.
+ * @return {Object} Value of child node.
+ * @override
+ */
+goog.ds.FastDataNode.prototype.getChildNodeValue = function(name) {
+ var child = this[name];
+ if (child != null) {
+ return (child.getDataName ? child.get() : child);
+ } else {
+ return null;
+ }
+};
+
+
+/**
+ * Returns whether this data node is a list. Always returns false for
+ * instances of FastDataNode but may return true for subclasses.
+ * @return {boolean} Whether this data node is array-like.
+ * @override
+ */
+goog.ds.FastDataNode.prototype.isList = function() {
+ return false;
+};
+
+
+/**
+ * Returns a javascript object representation of this data node. You should
+ * not modify the object returned by this function.
+ * @return {!Object} Javascript object representation of this data node.
+ */
+goog.ds.FastDataNode.prototype.getJsObject = function() {
+ var result = {};
+ for (var key in this) {
+ if (!goog.string.startsWith(key, '__') && !goog.isFunction(this[key])) {
+ result[key] = (this[key]['__dataName'] ? this[key].getJsObject() :
+ this[key]);
+ }
+ }
+ return result;
+};
+
+
+/**
+ * Creates a deep copy of this data node.
+ * @return {goog.ds.FastDataNode} Clone of this data node.
+ */
+goog.ds.FastDataNode.prototype.clone = function() {
+ return /** @type {!goog.ds.FastDataNode} */(goog.ds.FastDataNode.fromJs(
+ this.getJsObject(), this.getDataName()));
+};
+
+
+/*
+ * Implementation of goog.ds.DataNodeList for FastDataNode.
+ */
+
+
+/**
+ * Adds a child to this data node.
+ * @param {goog.ds.DataNode} value Child node to add.
+ * @override
+ */
+goog.ds.FastDataNode.prototype.add = function(value) {
+ this.setChildNode(value.getDataName(), value);
+};
+
+
+/**
+ * Gets the value of this data node (if called without opt_key) or
+ * gets a child node (if called with opt_key).
+ * @param {string=} opt_key Name of child node.
+ * @return {*} This data node or a child node.
+ * @override
+ */
+goog.ds.FastDataNode.prototype.get = function(opt_key) {
+ if (!goog.isDef(opt_key)) {
+ // if there is no key, DataNode#get was called
+ return this;
+ } else {
+ return this.getChildNode(opt_key);
+ }
+};
+
+
+/**
+ * Gets a child node by index. This method has a complexity of O(n) where
+ * n is the number of children. If you need a faster implementation of this
+ * method, you should use goog.ds.FastListNode.
+ * @param {number} index Index of child node (starting from 0).
+ * @return {goog.ds.DataNode} Child node at specified index.
+ * @override
+ */
+goog.ds.FastDataNode.prototype.getByIndex = function(index) {
+ var i = 0;
+ for (var key in this) {
+ if (!goog.string.startsWith(key, '__') && !goog.isFunction(this[key])) {
+ if (i == index) {
+ this.wrapChild_(key);
+ return this[key];
+ }
+ ++i;
+ }
+ }
+ return null;
+};
+
+
+/**
+ * Gets the number of child nodes. This method has a complexity of O(n) where
+ * n is the number of children. If you need a faster implementation of this
+ * method, you should use goog.ds.FastListNode.
+ * @return {number} Number of child nodes.
+ * @override
+ */
+goog.ds.FastDataNode.prototype.getCount = function() {
+ var count = 0;
+ for (var key in this) {
+ if (!goog.string.startsWith(key, '__') && !goog.isFunction(this[key])) {
+ ++count;
+ }
+ }
+ // maybe cache this?
+ return count;
+};
+
+
+/**
+ * Sets a child node.
+ * @param {string} name Name of child node.
+ * @param {Object} value Value of child node.
+ * @override
+ */
+goog.ds.FastDataNode.prototype.setNode = function(name, value) {
+ this.setChildNode(name, value);
+};
+
+
+/**
+ * Removes a child node.
+ * @override
+ */
+goog.ds.FastDataNode.prototype.removeNode = function(name) {
+ delete this[name];
+ return false;
+};
+
+
+
+/**
+ * Creates a new data node wrapping a primitive value.
+ * @param {number|boolean|string} value Value the value to wrap.
+ * @param {string} dataName name Name of this data node.
+ * @param {goog.ds.DataNode=} opt_parent Parent of this data node.
+ * @extends {goog.ds.AbstractFastDataNode}
+ * @constructor
+ * @final
+ */
+goog.ds.PrimitiveFastDataNode = function(value, dataName, opt_parent) {
+ this.value_ = value;
+ goog.ds.AbstractFastDataNode.call(this, dataName, opt_parent);
+};
+goog.inherits(goog.ds.PrimitiveFastDataNode, goog.ds.AbstractFastDataNode);
+
+
+/**
+ * Returns the value of this data node.
+ * @return {(boolean|number|string)} Value of this data node.
+ * @override
+ */
+goog.ds.PrimitiveFastDataNode.prototype.get = function() {
+ return this.value_;
+};
+
+
+/**
+ * Sets this data node to a new value.
+ * @param {*} value Value to set data node to.
+ * @override
+ */
+goog.ds.PrimitiveFastDataNode.prototype.set = function(value) {
+ if (goog.isArray(value) || goog.isObject(value)) {
+ throw Error('can only set PrimitiveFastDataNode to primitive values');
+ }
+ this.value_ = value;
+ goog.ds.DataManager.getInstance().fireDataChange(this.getDataPath());
+};
+
+
+/**
+ * Returns child nodes of this data node. Always returns an unmodifiable,
+ * empty list.
+ * @return {!goog.ds.DataNodeList} (Empty) list of child nodes.
+ * @override
+ */
+goog.ds.PrimitiveFastDataNode.prototype.getChildNodes = function() {
+ return goog.ds.FastDataNode.emptyList_;
+};
+
+
+/**
+ * Get a child node by name. Always returns null.
+ * @param {string} name Name of child node.
+ * @return {goog.ds.DataNode} Child node.
+ * @override
+ */
+goog.ds.PrimitiveFastDataNode.prototype.getChildNode = function(name) {
+ return null;
+};
+
+
+/**
+ * Returns the value of a child node. Always returns null.
+ * @param {string} name Name of child node.
+ * @return {Object} Value of child node.
+ * @override
+ */
+goog.ds.PrimitiveFastDataNode.prototype.getChildNodeValue = function(name) {
+ return null;
+};
+
+
+/**
+ * Not supported by primitive data nodes.
+ * @param {string} name Name of child node.
+ * @param {Object} value Value of child node.
+ * @override
+ */
+goog.ds.PrimitiveFastDataNode.prototype.setChildNode =
+ function(name, value) {
+ throw Error('Cannot set a child node for a PrimitiveFastDataNode');
+};
+
+
+/**
+ * Returns whether this data node is a list. Always returns false for
+ * instances of PrimitiveFastDataNode.
+ * @return {boolean} Whether this data node is array-like.
+ * @override
+ */
+goog.ds.PrimitiveFastDataNode.prototype.isList = function() {
+ return false;
+};
+
+
+/**
+ * Returns a javascript object representation of this data node. You should
+ * not modify the object returned by this function.
+ * @return {*} Javascript object representation of this data node.
+ */
+goog.ds.PrimitiveFastDataNode.prototype.getJsObject = function() {
+ return this.value_;
+};
+
+
+/**
+ * Creates a new list node from an array.
+ * @param {Array<?>} values values hold by this list node.
+ * @param {string} dataName name of this node.
+ * @param {goog.ds.DataNode=} opt_parent parent of this node.
+ * @extends {goog.ds.AbstractFastDataNode}
+ * @constructor
+ * @final
+ */
+// TODO(arv): Use interfaces when available. This implements DataNodeList
+// as well.
+goog.ds.FastListNode = function(values, dataName, opt_parent) {
+ this.values_ = [];
+ for (var i = 0; i < values.length; ++i) {
+ var name = values[i].id || ('[' + i + ']');
+ this.values_.push(goog.ds.FastDataNode.fromJs(values[i], name, this));
+ if (values[i].id) {
+ if (!this.map_) {
+ this.map_ = {};
+ }
+ this.map_[values[i].id] = i;
+ }
+ }
+ goog.ds.AbstractFastDataNode.call(this, dataName, opt_parent);
+};
+goog.inherits(goog.ds.FastListNode, goog.ds.AbstractFastDataNode);
+
+
+/**
+ * Not supported for FastListNodes.
+ * @param {*} value Value to set data node to.
+ * @override
+ */
+goog.ds.FastListNode.prototype.set = function(value) {
+ throw Error('Cannot set a FastListNode to a new value');
+};
+
+
+/**
+ * Returns child nodes of this data node. Currently, only supports
+ * returning all children.
+ * @return {!goog.ds.DataNodeList} List of child nodes.
+ * @override
+ */
+goog.ds.FastListNode.prototype.getChildNodes = function() {
+ return this;
+};
+
+
+/**
+ * Get a child node by name.
+ * @param {string} key Name of child node.
+ * @param {boolean=} opt_create Whether to create the child if it does not
+ * exist.
+ * @return {goog.ds.DataNode} Child node.
+ * @override
+ */
+goog.ds.FastListNode.prototype.getChildNode = function(key, opt_create) {
+ var index = this.getKeyAsNumber_(key);
+ if (index == null && this.map_) {
+ index = this.map_[key];
+ }
+ if (index != null && this.values_[index]) {
+ return this.values_[index];
+ } else if (opt_create) {
+ this.setChildNode(key, {});
+ return this.getChildNode(key);
+ } else {
+ return null;
+ }
+};
+
+
+/**
+ * Returns the value of a child node.
+ * @param {string} key Name of child node.
+ * @return {*} Value of child node.
+ * @override
+ */
+goog.ds.FastListNode.prototype.getChildNodeValue = function(key) {
+ var child = this.getChildNode(key);
+ return (child ? child.get() : null);
+};
+
+
+/**
+ * Tries to interpret key as a numeric index enclosed by square brakcets.
+ * @param {string} key Key that should be interpreted as a number.
+ * @return {?number} Numeric index or null if key is not of the form
+ * described above.
+ * @private
+ */
+goog.ds.FastListNode.prototype.getKeyAsNumber_ = function(key) {
+ if (key.charAt(0) == '[' && key.charAt(key.length - 1) == ']') {
+ return Number(key.substring(1, key.length - 1));
+ } else {
+ return null;
+ }
+};
+
+
+/**
+ * Sets a child node. Creates the child if it does not exist. To set
+ * children at a certain index, use a key of the form '[index]'. Note, that
+ * you can only set values at existing numeric indices. To add a new node
+ * to this list, you have to use the add method.
+ *
+ * Calling this function makes any child nodes previously obtained for name
+ * invalid. You should not use these child nodes but instead obtain a new
+ * instance by calling getChildNode.
+ *
+ * @override
+ */
+goog.ds.FastListNode.prototype.setChildNode = function(key, value) {
+ var count = this.values_.length;
+ if (value != null) {
+ if (!value.getDataName) {
+ value = goog.ds.FastDataNode.fromJs(value, key, this);
+ }
+ var index = this.getKeyAsNumber_(key);
+ if (index != null) {
+ if (index < 0 || index >= this.values_.length) {
+ throw Error('List index out of bounds: ' + index);
+ }
+ this.values_[key] = value;
+ } else {
+ if (!this.map_) {
+ this.map_ = {};
+ }
+ this.values_.push(value);
+ this.map_[key] = this.values_.length - 1;
+ }
+ } else {
+ this.removeNode(key);
+ }
+ var dm = goog.ds.DataManager.getInstance();
+ dm.fireDataChange(this.getDataPath() + goog.ds.STR_PATH_SEPARATOR + key);
+ if (this.values_.length != count) {
+ this.listSizeChanged_();
+ }
+ return null;
+};
+
+
+/**
+ * Fire data changes that are appropriate when the size of this list changes.
+ * Should be called whenever the list size has changed.
+ * @private
+ */
+goog.ds.FastListNode.prototype.listSizeChanged_ = function() {
+ var dm = goog.ds.DataManager.getInstance();
+ dm.fireDataChange(this.getDataPath());
+ dm.fireDataChange(this.getDataPath() + goog.ds.STR_PATH_SEPARATOR +
+ 'count()');
+};
+
+
+/**
+ * Returns whether this data node is a list. Always returns true.
+ * @return {boolean} Whether this data node is array-like.
+ * @override
+ */
+goog.ds.FastListNode.prototype.isList = function() {
+ return true;
+};
+
+
+/**
+ * Returns a javascript object representation of this data node. You should
+ * not modify the object returned by this function.
+ * @return {!Object} Javascript object representation of this data node.
+ */
+goog.ds.FastListNode.prototype.getJsObject = function() {
+ var result = [];
+ for (var i = 0; i < this.values_.length; ++i) {
+ result.push(this.values_[i].getJsObject());
+ }
+ return result;
+};
+
+
+/*
+ * Implementation of goog.ds.DataNodeList for FastListNode.
+ */
+
+
+/**
+ * Adds a child to this data node
+ * @param {goog.ds.DataNode} value Child node to add.
+ * @override
+ */
+goog.ds.FastListNode.prototype.add = function(value) {
+ if (!value.getDataName) {
+ value = goog.ds.FastDataNode.fromJs(value,
+ String('[' + (this.values_.length) + ']'), this);
+ }
+ this.values_.push(value);
+ var dm = goog.ds.DataManager.getInstance();
+ dm.fireDataChange(this.getDataPath() + goog.ds.STR_PATH_SEPARATOR +
+ '[' + (this.values_.length - 1) + ']');
+ this.listSizeChanged_();
+};
+
+
+/**
+ * Gets the value of this data node (if called without opt_key) or
+ * gets a child node (if called with opt_key).
+ * @param {string=} opt_key Name of child node.
+ * @return {Array|goog.ds.DataNode} Array of child nodes (if called without
+ * opt_key), or a named child node otherwise.
+ * @override
+ */
+goog.ds.FastListNode.prototype.get = function(opt_key) {
+ // if there are no arguments, DataNode.get was called
+ if (!goog.isDef(opt_key)) {
+ return this.values_;
+ } else {
+ return this.getChildNode(opt_key);
+ }
+};
+
+
+/**
+ * Gets a child node by (numeric) index.
+ * @param {number} index Index of child node (starting from 0).
+ * @return {goog.ds.DataNode} Child node at specified index.
+ * @override
+ */
+goog.ds.FastListNode.prototype.getByIndex = function(index) {
+ var child = this.values_[index];
+ return (child != null ? child : null); // never return undefined
+};
+
+
+/**
+ * Gets the number of child nodes.
+ * @return {number} Number of child nodes.
+ * @override
+ */
+goog.ds.FastListNode.prototype.getCount = function() {
+ return this.values_.length;
+};
+
+
+/**
+ * Sets a child node.
+ * @param {string} name Name of child node.
+ * @param {Object} value Value of child node.
+ * @override
+ */
+goog.ds.FastListNode.prototype.setNode = function(name, value) {
+ throw Error('Setting child nodes of a FastListNode is not implemented, yet');
+};
+
+
+/**
+ * Removes a child node.
+ * @override
+ */
+goog.ds.FastListNode.prototype.removeNode = function(name) {
+ var index = this.getKeyAsNumber_(name);
+ if (index == null && this.map_) {
+ index = this.map_[name];
+ }
+ if (index != null) {
+ this.values_.splice(index, 1);
+ if (this.map_) {
+ var keyToDelete = null;
+ for (var key in this.map_) {
+ if (this.map_[key] == index) {
+ keyToDelete = key;
+ } else if (this.map_[key] > index) {
+ --this.map_[key];
+ }
+ }
+ if (keyToDelete) {
+ delete this.map_[keyToDelete];
+ }
+ }
+ var dm = goog.ds.DataManager.getInstance();
+ dm.fireDataChange(this.getDataPath() + goog.ds.STR_PATH_SEPARATOR +
+ '[' + index + ']');
+ this.listSizeChanged_();
+ }
+ return false;
+};
+
+
+/**
+ * Returns the index of a named child nodes. This method only works if
+ * this list uses mixed name/indexed lookup, i.e. if its child node have
+ * an 'id' attribute.
+ * @param {string} name Name of child node to determine index of.
+ * @return {number} Index of child node named name.
+ */
+goog.ds.FastListNode.prototype.indexOf = function(name) {
+ var index = this.getKeyAsNumber_(name);
+ if (index == null && this.map_) {
+ index = this.map_[name];
+ }
+ if (index == null) {
+ throw Error('Cannot determine index for: ' + name);
+ }
+ return /** @type {number} */(index);
+};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/datasource/jsdatasource.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/datasource/jsdatasource.js b/externs/GCL/externs/goog/datasource/jsdatasource.js
new file mode 100644
index 0000000..ccd469e
--- /dev/null
+++ b/externs/GCL/externs/goog/datasource/jsdatasource.js
@@ -0,0 +1,462 @@
+// Copyright 2006 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed 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 An implementation of DataNode for wrapping JS data.
+ *
+ */
+
+
+goog.provide('goog.ds.JsDataSource');
+goog.provide('goog.ds.JsPropertyDataSource');
+
+goog.require('goog.ds.BaseDataNode');
+goog.require('goog.ds.BasicNodeList');
+goog.require('goog.ds.DataManager');
+goog.require('goog.ds.DataNode');
+goog.require('goog.ds.EmptyNodeList');
+goog.require('goog.ds.LoadState');
+
+
+/**
+ * Data source whose backing is JavaScript data
+ *
+ * Names that are reserved for system use and shouldn't be used for data node
+ * names: eval, toSource, toString, unwatch, valueOf, watch. Behavior is
+ * undefined if these names are used.
+ *
+ * @param {Object} root The root JS node.
+ * @param {string} dataName The name of this node relative to the parent node.
+ * @param {Object=} opt_parent Optional parent of this JsDataSource.
+ *
+ * implements goog.ds.DataNode.
+ * @constructor
+ * @extends {goog.ds.DataNode}
+ */
+// TODO(arv): Use interfaces when available.
+goog.ds.JsDataSource = function(root, dataName, opt_parent) {
+ this.parent_ = opt_parent;
+ this.dataName_ = dataName;
+ this.setRoot(root);
+};
+
+
+/**
+ * The root JS object. Can be null.
+ * @type {*}
+ * @protected
+ * @suppress {underscore|visibility}
+ */
+goog.ds.JsDataSource.prototype.root_;
+
+
+/**
+ * Sets the root JS object
+ * @param {Object} root The root JS object. Can be null.
+ *
+ * @protected
+ */
+goog.ds.JsDataSource.prototype.setRoot = function(root) {
+ this.root_ = root;
+ this.childNodeList_ = null;
+};
+
+
+/**
+ * Set this data source to use list semantics. List data sources:
+ * - Are assumed to have child nodes of all of the same type of data
+ * - Fire data changes on the root node of the list whenever children
+ * are added or removed
+ * @param {?boolean} isList True to use list semantics.
+ * @private
+ */
+goog.ds.JsDataSource.prototype.setIsList_ = function(isList) {
+ this.isList_ = isList;
+};
+
+
+/** @override */
+goog.ds.JsDataSource.prototype.get = function() {
+ return !goog.isObject(this.root_) ? this.root_ : this.getChildNodes();
+};
+
+
+/**
+ * Set the value of the node
+ * @param {*} value The new value of the node.
+ * @override
+ */
+goog.ds.JsDataSource.prototype.set = function(value) {
+ if (value && goog.isObject(this.root_)) {
+ throw Error('Can\'t set group nodes to new values yet');
+ }
+
+ if (this.parent_) {
+ this.parent_.root_[this.dataName_] = value;
+ }
+ this.root_ = value;
+ this.childNodeList_ = null;
+
+ goog.ds.DataManager.getInstance().fireDataChange(this.getDataPath());
+};
+
+
+/**
+ * TODO(user) revisit lazy creation.
+ * @override
+ */
+goog.ds.JsDataSource.prototype.getChildNodes = function(opt_selector) {
+ if (!this.root_) {
+ return new goog.ds.EmptyNodeList();
+ }
+
+ if (!opt_selector || opt_selector == goog.ds.STR_ALL_CHILDREN_SELECTOR) {
+ this.createChildNodes_(false);
+ return this.childNodeList_;
+ } else if (opt_selector.indexOf(goog.ds.STR_WILDCARD) == -1) {
+ if (this.root_[opt_selector] != null) {
+ return new goog.ds.BasicNodeList([this.getChildNode(opt_selector)]);
+ } else {
+ return new goog.ds.EmptyNodeList();
+ }
+ } else {
+ throw Error('Selector not supported yet (' + opt_selector + ')');
+ }
+
+};
+
+
+/**
+ * Creates the DataNodeList with the child nodes for this element.
+ * Allows for only building list as needed.
+ *
+ * @param {boolean=} opt_force Whether to force recreating child nodes,
+ * defaults to false.
+ * @private
+ */
+goog.ds.JsDataSource.prototype.createChildNodes_ = function(opt_force) {
+ if (this.childNodeList_ && !opt_force) {
+ return;
+ }
+
+ if (!goog.isObject(this.root_)) {
+ this.childNodeList_ = new goog.ds.EmptyNodeList();
+ return;
+ }
+
+ var childNodeList = new goog.ds.BasicNodeList();
+ var newNode;
+ if (goog.isArray(this.root_)) {
+ var len = this.root_.length;
+ for (var i = 0; i < len; i++) {
+ // "id" is reserved node name that will map to a named child node
+ // TODO(user) Configurable logic for choosing id node
+ var node = this.root_[i];
+ var id = node.id;
+ var name = id != null ? String(id) : '[' + i + ']';
+ newNode = new goog.ds.JsDataSource(node, name, this);
+ childNodeList.add(newNode);
+ }
+ } else {
+ for (var name in this.root_) {
+ var obj = this.root_[name];
+ // If the node is already a datasource, then add it.
+ if (obj.getDataName) {
+ childNodeList.add(obj);
+ } else if (!goog.isFunction(obj)) {
+ newNode = new goog.ds.JsDataSource(obj, name, this);
+ childNodeList.add(newNode);
+ }
+ }
+ }
+ this.childNodeList_ = childNodeList;
+};
+
+
+/**
+ * Gets a named child node of the current node
+ * @param {string} name The node name.
+ * @param {boolean=} opt_canCreate If true, can create child node.
+ * @return {goog.ds.DataNode} The child node, or null if no node of
+ * this name exists.
+ * @override
+ */
+goog.ds.JsDataSource.prototype.getChildNode = function(name, opt_canCreate) {
+ if (!this.root_) {
+ return null;
+ }
+ var node = /** @type {goog.ds.DataNode} */ (this.getChildNodes().get(name));
+ if (!node && opt_canCreate) {
+ var newObj = {};
+ if (goog.isArray(this.root_)) {
+ newObj['id'] = name;
+ this.root_.push(newObj);
+ } else {
+ this.root_[name] = newObj;
+ }
+ node = new goog.ds.JsDataSource(newObj, name, this);
+ if (this.childNodeList_) {
+ this.childNodeList_.add(node);
+ }
+ }
+ return node;
+};
+
+
+/**
+ * Gets the value of a child node
+ * @param {string} name The node name.
+ * @return {Object} The value of the node, or null if no value or the child
+ * node doesn't exist.
+ * @override
+ */
+goog.ds.JsDataSource.prototype.getChildNodeValue = function(name) {
+ if (this.childNodeList_) {
+ var node = this.getChildNodes().get(name);
+ return node ? node.get() : null;
+ } else if (this.root_) {
+ return this.root_[name];
+ } else {
+ return null;
+ }
+};
+
+
+/**
+ * Sets a named child node of the current node.
+ * If value is null, removes the child node.
+ * @param {string} name The node name.
+ * @param {Object} value The value to set, can be DataNode, object,
+ * property, or null.
+ * @return {Object} The child node, if set.
+ * @override
+ */
+goog.ds.JsDataSource.prototype.setChildNode = function(name, value) {
+ var removedPath = null;
+ var node = null;
+ var addedNode = false;
+
+ // Set node to the DataNode to add - if the value isn't already a DataNode,
+ // creates a JsDataSource or JsPropertyDataSource wrapper
+ if (value != null) {
+ if (value.getDataName) {
+ // The value is a DataNode. We must update its parent.
+ node = value;
+ node.parent_ = this;
+ } else {
+ if (goog.isArray(value) || goog.isObject(value)) {
+ node = new goog.ds.JsDataSource(value, name, this);
+ } else {
+ node = new goog.ds.JsPropertyDataSource(
+ /** @type {goog.ds.DataNode} */ (this.root_), name, this);
+ }
+ }
+ }
+
+ // This logic will get cleaner once we can remove the backing array / object
+ // and just rely on the childNodeList_. This is needed until dependent code
+ // is cleaned up.
+ // TODO(user) Remove backing array / object and just use childNodeList_
+
+ if (goog.isArray(this.root_)) {
+ // To remove by name, need to create a map of the child nodes by ID
+ this.createChildNodes_();
+ var index = this.childNodeList_.indexOf(name);
+ if (value == null) {
+ // Remove the node
+ var nodeToRemove = this.childNodeList_.get(name);
+ if (nodeToRemove) {
+ removedPath = nodeToRemove.getDataPath();
+ }
+ this.root_.splice(index, 1);
+ } else {
+ // Add the node
+ if (index) {
+ this.root_[index] = value;
+ } else {
+ this.root_.push(value);
+ }
+ }
+ if (index == null) {
+ addedNode = true;
+ }
+ this.childNodeList_.setNode(name, /** @type {goog.ds.DataNode} */ (node));
+ } else if (goog.isObject(this.root_)) {
+ if (value == null) {
+ // Remove the node
+ this.createChildNodes_();
+ var nodeToRemove = this.childNodeList_.get(name);
+ if (nodeToRemove) {
+ removedPath = nodeToRemove.getDataPath();
+ }
+ delete this.root_[name];
+ } else {
+ // Add the node
+ if (!this.root_[name]) {
+ addedNode = true;
+ }
+ this.root_[name] = value;
+ }
+ // Only need to update childNodeList_ if has been created already
+ if (this.childNodeList_) {
+ this.childNodeList_.setNode(name, /** @type {goog.ds.DataNode} */ (node));
+ }
+ }
+
+ // Fire the event that the node changed
+ var dm = goog.ds.DataManager.getInstance();
+ if (node) {
+ dm.fireDataChange(node.getDataPath());
+ if (addedNode && this.isList()) {
+ dm.fireDataChange(this.getDataPath());
+ dm.fireDataChange(this.getDataPath() + '/count()');
+ }
+ } else if (removedPath) {
+ dm.fireDataChange(removedPath);
+ if (this.isList()) {
+ dm.fireDataChange(this.getDataPath());
+ dm.fireDataChange(this.getDataPath() + '/count()');
+ }
+ }
+ return node;
+};
+
+
+/**
+ * Get the name of the node relative to the parent node
+ * @return {string} The name of the node.
+ * @override
+ */
+goog.ds.JsDataSource.prototype.getDataName = function() {
+ return this.dataName_;
+};
+
+
+/**
+ * Setthe name of the node relative to the parent node
+ * @param {string} dataName The name of the node.
+ * @override
+ */
+goog.ds.JsDataSource.prototype.setDataName = function(dataName) {
+ this.dataName_ = dataName;
+};
+
+
+/**
+ * Gets the a qualified data path to this node
+ * @return {string} The data path.
+ * @override
+ */
+goog.ds.JsDataSource.prototype.getDataPath = function() {
+ var parentPath = '';
+ if (this.parent_) {
+ parentPath = this.parent_.getDataPath() + goog.ds.STR_PATH_SEPARATOR;
+ }
+
+ return parentPath + this.dataName_;
+};
+
+
+/**
+ * Load or reload the backing data for this node
+ * @override
+ */
+goog.ds.JsDataSource.prototype.load = function() {
+ // Nothing to do
+};
+
+
+/**
+ * Gets the state of the backing data for this node
+ * TODO(user) Discuss null value handling
+ * @return {goog.ds.LoadState} The state.
+ * @override
+ */
+goog.ds.JsDataSource.prototype.getLoadState = function() {
+ return (this.root_ == null) ? goog.ds.LoadState.NOT_LOADED :
+ goog.ds.LoadState.LOADED;
+};
+
+
+/**
+ * Whether the value of this node is a homogeneous list of data
+ * @return {boolean} True if a list.
+ * @override
+ */
+goog.ds.JsDataSource.prototype.isList = function() {
+ return this.isList_ != null ? this.isList_ : goog.isArray(this.root_);
+};
+
+
+
+/**
+ * Data source for JavaScript properties that arent objects. Contains reference
+ * to parent object so that you can set the vaule
+ *
+ * @param {goog.ds.DataNode} parent Parent object.
+ * @param {string} dataName Name of this property.
+ * @param {goog.ds.DataNode=} opt_parentDataNode The parent data node. If
+ * omitted, assumes that the parent object is the parent data node.
+ *
+ * @constructor
+ * @extends {goog.ds.BaseDataNode}
+ * @final
+ */
+goog.ds.JsPropertyDataSource = function(parent, dataName, opt_parentDataNode) {
+ goog.ds.BaseDataNode.call(this);
+ this.dataName_ = dataName;
+ this.parent_ = parent;
+ this.parentDataNode_ = opt_parentDataNode || this.parent_;
+};
+goog.inherits(goog.ds.JsPropertyDataSource, goog.ds.BaseDataNode);
+
+
+/**
+ * Get the value of the node
+ * @return {Object} The value of the node, or null if no value.
+ */
+goog.ds.JsPropertyDataSource.prototype.get = function() {
+ return this.parent_[this.dataName_];
+};
+
+
+/**
+ * Set the value of the node
+ * @param {Object} value The new value of the node.
+ * @override
+ */
+goog.ds.JsPropertyDataSource.prototype.set = function(value) {
+ var oldValue = this.parent_[this.dataName_];
+ this.parent_[this.dataName_] = value;
+
+ if (oldValue != value) {
+ goog.ds.DataManager.getInstance().fireDataChange(this.getDataPath());
+ }
+};
+
+
+/**
+ * Get the name of the node relative to the parent node
+ * @return {string} The name of the node.
+ * @override
+ */
+goog.ds.JsPropertyDataSource.prototype.getDataName = function() {
+ return this.dataName_;
+};
+
+
+/** @override */
+goog.ds.JsPropertyDataSource.prototype.getParent = function() {
+ return this.parentDataNode_;
+};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/datasource/jsondatasource.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/datasource/jsondatasource.js b/externs/GCL/externs/goog/datasource/jsondatasource.js
new file mode 100644
index 0000000..1621002
--- /dev/null
+++ b/externs/GCL/externs/goog/datasource/jsondatasource.js
@@ -0,0 +1,153 @@
+// Copyright 2006 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed 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 Implementation of DataNode for wrapping JSON data.
+ *
+ */
+
+
+goog.provide('goog.ds.JsonDataSource');
+
+goog.require('goog.Uri');
+goog.require('goog.dom');
+goog.require('goog.dom.TagName');
+goog.require('goog.ds.DataManager');
+goog.require('goog.ds.JsDataSource');
+goog.require('goog.ds.LoadState');
+goog.require('goog.ds.logger');
+goog.require('goog.log');
+
+
+
+/**
+ * Data source whose backing is a JSON-like service, in which
+ * retreiving the resource specified by URL with the additional parameter
+ * callback. The resource retreived is executable JavaScript that
+ * makes a call to the named function with a JavaScript object literal
+ * as the only parameter.
+ *
+ * Example URI could be:
+ * http://www.google.com/data/search?q=monkey&callback=mycb
+ * which might return the JS:
+ * mycb({searchresults:
+ * [{uri: 'http://www.monkey.com', title: 'Site About Monkeys'}]});
+ *
+ * TODO(user): Evaluate using goog.net.Jsonp here.
+ *
+ * A URI of an empty string will mean that no request is made
+ * and the data source will be a data source with no child nodes
+ *
+ * @param {string|goog.Uri} uri URI for the request.
+ * @param {string} name Name of the datasource.
+ * @param {string=} opt_callbackParamName The parameter name that is used to
+ * specify the callback. Defaults to 'callback'.
+ *
+ * @extends {goog.ds.JsDataSource}
+ * @constructor
+ * @final
+ */
+goog.ds.JsonDataSource = function(uri, name, opt_callbackParamName) {
+ goog.ds.JsDataSource.call(this, null, name, null);
+ if (uri) {
+ this.uri_ = new goog.Uri(uri);
+ } else {
+ this.uri_ = null;
+ }
+
+ /**
+ * This is the callback parameter name that is added to the uri.
+ * @type {string}
+ * @private
+ */
+ this.callbackParamName_ = opt_callbackParamName || 'callback';
+
+};
+goog.inherits(goog.ds.JsonDataSource, goog.ds.JsDataSource);
+
+
+/**
+ * Default load state is NOT_LOADED
+ * @private
+ */
+goog.ds.JsonDataSource.prototype.loadState_ = goog.ds.LoadState.NOT_LOADED;
+
+
+/**
+ * Map of all data sources, needed for callbacks
+ * Doesn't work unless dataSources is exported (not renamed)
+ */
+goog.ds.JsonDataSource['dataSources'] = {};
+
+
+/**
+ * Load or reload the backing data for this node.
+ * Fires the JsonDataSource
+ * @override
+ */
+goog.ds.JsonDataSource.prototype.load = function() {
+ if (this.uri_) {
+ // NOTE: "dataSources" is expose above by name so that it will not be
+ // renamed. It should therefore be accessed via array notation here so
+ // that it also doesn't get renamed and stops the compiler from complaining
+ goog.ds.JsonDataSource['dataSources'][this.dataName_] = this;
+ goog.log.info(goog.ds.logger, 'Sending JS request for DataSource ' +
+ this.getDataName() + ' to ' + this.uri_);
+
+ this.loadState_ = goog.ds.LoadState.LOADING;
+
+ var uriToCall = new goog.Uri(this.uri_);
+ uriToCall.setParameterValue(this.callbackParamName_,
+ 'JsonReceive.' + this.dataName_);
+
+ goog.global['JsonReceive'][this.dataName_] =
+ goog.bind(this.receiveData, this);
+
+ var scriptEl = goog.dom.createDom(goog.dom.TagName.SCRIPT,
+ {'src': uriToCall});
+ goog.dom.getElementsByTagNameAndClass(
+ goog.dom.TagName.HEAD)[0].appendChild(scriptEl);
+ } else {
+ this.root_ = {};
+ this.loadState_ = goog.ds.LoadState.NOT_LOADED;
+ }
+};
+
+
+/**
+ * Gets the state of the backing data for this node
+ * @return {goog.ds.LoadState} The state.
+ * @override
+ */
+goog.ds.JsonDataSource.prototype.getLoadState = function() {
+ return this.loadState_;
+};
+
+
+/**
+ * Receives data from a Json request
+ * @param {Object} obj The JSON data.
+ */
+goog.ds.JsonDataSource.prototype.receiveData = function(obj) {
+ this.setRoot(obj);
+ this.loadState_ = goog.ds.LoadState.LOADED;
+ goog.ds.DataManager.getInstance().fireDataChange(this.getDataName());
+};
+
+
+/**
+* Temp variable to hold callbacks
+* until BUILD supports multiple externs.js files
+*/
+goog.global['JsonReceive'] = {};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/datasource/jsxmlhttpdatasource.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/datasource/jsxmlhttpdatasource.js b/externs/GCL/externs/goog/datasource/jsxmlhttpdatasource.js
new file mode 100644
index 0000000..bd2a024
--- /dev/null
+++ b/externs/GCL/externs/goog/datasource/jsxmlhttpdatasource.js
@@ -0,0 +1,196 @@
+// Copyright 2006 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed 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
+ * DataSource implementation that uses XMLHttpRequest as transport, with
+ * response as serialized JS object (not required to be JSON) that can
+ * be evaluated and set to a variable.
+ *
+ * Response can have unexecutable starting/ending text to prevent inclusion
+ * using <script src="...">
+ *
+ */
+
+
+goog.provide('goog.ds.JsXmlHttpDataSource');
+
+goog.require('goog.Uri');
+goog.require('goog.ds.DataManager');
+goog.require('goog.ds.FastDataNode');
+goog.require('goog.ds.LoadState');
+goog.require('goog.ds.logger');
+goog.require('goog.events');
+goog.require('goog.log');
+goog.require('goog.net.EventType');
+goog.require('goog.net.XhrIo');
+
+
+
+/**
+ * Similar to JsonDataSource, with using XMLHttpRequest for transport
+ * Currently requires the result be a JS object that can be evaluated and
+ * set to a variable and doesn't require strict JSON notation.
+ *
+ * @param {(string|goog.Uri)} uri URI for the request.
+ * @param {string} name Name of the datasource.
+ * @param {string=} opt_startText Text to expect/strip before JS response.
+ * @param {string=} opt_endText Text to expect/strip after JS response.
+ * @param {boolean=} opt_usePost If true, use POST. Defaults to false (GET).
+ *
+ * @extends {goog.ds.FastDataNode}
+ * @constructor
+ * @final
+ */
+goog.ds.JsXmlHttpDataSource = function(uri, name, opt_startText, opt_endText,
+ opt_usePost) {
+ goog.ds.FastDataNode.call(this, {}, name, null);
+ if (uri) {
+ this.uri_ = new goog.Uri(uri);
+ this.xhr_ = new goog.net.XhrIo();
+ this.usePost_ = !!opt_usePost;
+
+ goog.events.listen(this.xhr_, goog.net.EventType.COMPLETE,
+ this.completed_, false, this);
+ } else {
+ this.uri_ = null;
+ }
+ this.startText_ = opt_startText;
+ this.endText_ = opt_endText;
+};
+goog.inherits(goog.ds.JsXmlHttpDataSource, goog.ds.FastDataNode);
+
+
+/**
+ * Delimiter for start of JSON data in response.
+ * null = starts at first character of response
+ * @type {string|undefined}
+ * @private
+ */
+goog.ds.JsXmlHttpDataSource.prototype.startText_;
+
+
+/**
+ * Delimiter for end of JSON data in response.
+ * null = ends at last character of response
+ * @type {string|undefined}
+ * @private
+ */
+goog.ds.JsXmlHttpDataSource.prototype.endText_;
+
+
+/**
+ * Gets the state of the backing data for this node
+ * @return {goog.ds.LoadState} The state.
+ * @override
+ */
+goog.ds.JsXmlHttpDataSource.prototype.getLoadState = function() {
+ return this.loadState_;
+};
+
+
+/**
+ * Sets the request data. This can be used if it is required to
+ * send a specific body rather than build the body from the query
+ * parameters. Only used in POST requests.
+ * @param {string} data The data to send in the request body.
+ */
+goog.ds.JsXmlHttpDataSource.prototype.setQueryData = function(data) {
+ this.queryData_ = data;
+};
+
+
+/**
+ * Load or reload the backing data for this node.
+ * Fires the JsonDataSource
+ * @override
+ */
+goog.ds.JsXmlHttpDataSource.prototype.load = function() {
+ goog.log.info(goog.ds.logger, 'Sending JS request for DataSource ' +
+ this.getDataName() + ' to ' + this.uri_);
+
+ if (this.uri_) {
+ if (this.usePost_) {
+
+ var queryData;
+ if (!this.queryData_) {
+ queryData = this.uri_.getQueryData().toString();
+ } else {
+ queryData = this.queryData_;
+ }
+
+ var uriNoQuery = this.uri_.clone();
+ uriNoQuery.setQueryData(null);
+ this.xhr_.send(String(uriNoQuery), 'POST', queryData);
+ } else {
+ this.xhr_.send(String(this.uri_));
+ }
+ } else {
+ this.loadState_ = goog.ds.LoadState.NOT_LOADED;
+ }
+};
+
+
+/**
+ * Called on successful request.
+ * @private
+ */
+goog.ds.JsXmlHttpDataSource.prototype.success_ = function() {
+ goog.ds.DataManager.getInstance().fireDataChange(this.getDataName());
+};
+
+
+/**
+ * Completed callback. Loads data if successful, otherwise sets
+ * state to FAILED
+ * @param {goog.events.Event} e Event object, Xhr is target.
+ * @private
+ */
+goog.ds.JsXmlHttpDataSource.prototype.completed_ = function(e) {
+ if (this.xhr_.isSuccess()) {
+ goog.log.info(goog.ds.logger,
+ 'Got data for DataSource ' + this.getDataName());
+ var text = this.xhr_.getResponseText();
+
+ // Look for start and end token and trim text
+ if (this.startText_) {
+ var startpos = text.indexOf(this.startText_);
+ text = text.substring(startpos + this.startText_.length);
+ }
+ if (this.endText_) {
+ var endpos = text.lastIndexOf(this.endText_);
+ text = text.substring(0, endpos);
+ }
+
+ // Eval result
+ /** @preserveTry */
+ try {
+ var jsonObj = /** @type {Object} */ (eval('[' + text + '][0]'));
+ this.extendWith(jsonObj);
+ this.loadState_ = goog.ds.LoadState.LOADED;
+ }
+ catch (ex) {
+ // Invalid JS
+ this.loadState_ = goog.ds.LoadState.FAILED;
+ goog.log.error(goog.ds.logger, 'Failed to parse data: ' + ex.message);
+ }
+
+ // Call on a timer to avoid threading issues on IE.
+ goog.global.setTimeout(goog.bind(this.success_, this), 0);
+ } else {
+ goog.log.info(goog.ds.logger, 'Data retrieve failed for DataSource ' +
+ this.getDataName());
+ this.loadState_ = goog.ds.LoadState.FAILED;
+ }
+};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/datasource/xmldatasource.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/datasource/xmldatasource.js b/externs/GCL/externs/goog/datasource/xmldatasource.js
new file mode 100644
index 0000000..5327269
--- /dev/null
+++ b/externs/GCL/externs/goog/datasource/xmldatasource.js
@@ -0,0 +1,417 @@
+// Copyright 2006 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed 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
+ * Implementations of DataNode for wrapping XML data.
+ *
+ */
+
+goog.provide('goog.ds.XmlDataSource');
+goog.provide('goog.ds.XmlHttpDataSource');
+
+goog.require('goog.Uri');
+goog.require('goog.dom.NodeType');
+goog.require('goog.dom.xml');
+goog.require('goog.ds.BasicNodeList');
+goog.require('goog.ds.DataManager');
+goog.require('goog.ds.DataNode');
+goog.require('goog.ds.LoadState');
+goog.require('goog.ds.logger');
+goog.require('goog.net.XhrIo');
+goog.require('goog.string');
+
+
+
+/**
+ * Data source whose backing is an xml node
+ *
+ * @param {Node} node The XML node. Can be null.
+ * @param {goog.ds.XmlDataSource} parent Parent of XML element. Can be null.
+ * @param {string=} opt_name The name of this node relative to the parent node.
+ *
+ * @extends {goog.ds.DataNode}
+ * @constructor
+ */
+// TODO(arv): Use interfaces when available.
+goog.ds.XmlDataSource = function(node, parent, opt_name) {
+ this.parent_ = parent;
+ this.dataName_ = opt_name || (node ? node.nodeName : '');
+ this.setNode_(node);
+};
+
+
+/**
+ * Constant to select XML attributes for getChildNodes
+ * @type {string}
+ * @private
+ */
+goog.ds.XmlDataSource.ATTRIBUTE_SELECTOR_ = '@*';
+
+
+/**
+ * Set the current root nodeof the data source.
+ * Can be an attribute node, text node, or element node
+ * @param {Node} node The node. Can be null.
+ *
+ * @private
+ */
+goog.ds.XmlDataSource.prototype.setNode_ = function(node) {
+ this.node_ = node;
+ if (node != null) {
+ switch (node.nodeType) {
+ case goog.dom.NodeType.ATTRIBUTE:
+ case goog.dom.NodeType.TEXT:
+ this.value_ = node.nodeValue;
+ break;
+ case goog.dom.NodeType.ELEMENT:
+ if (node.childNodes.length == 1 &&
+ node.firstChild.nodeType == goog.dom.NodeType.TEXT) {
+ this.value_ = node.firstChild.nodeValue;
+ }
+ }
+ }
+};
+
+
+/**
+ * Creates the DataNodeList with the child nodes for this element.
+ * Allows for only building list as needed.
+ *
+ * @private
+ */
+goog.ds.XmlDataSource.prototype.createChildNodes_ = function() {
+ if (this.childNodeList_) {
+ return;
+ }
+ var childNodeList = new goog.ds.BasicNodeList();
+ if (this.node_ != null) {
+ var childNodes = this.node_.childNodes;
+ for (var i = 0, childNode; childNode = childNodes[i]; i++) {
+ if (childNode.nodeType != goog.dom.NodeType.TEXT ||
+ !goog.ds.XmlDataSource.isEmptyTextNodeValue_(childNode.nodeValue)) {
+ var newNode = new goog.ds.XmlDataSource(childNode,
+ this, childNode.nodeName);
+ childNodeList.add(newNode);
+ }
+ }
+ }
+ this.childNodeList_ = childNodeList;
+};
+
+
+/**
+ * Creates the DataNodeList with the attributes for the element
+ * Allows for only building list as needed.
+ *
+ * @private
+ */
+goog.ds.XmlDataSource.prototype.createAttributes_ = function() {
+ if (this.attributes_) {
+ return;
+ }
+ var attributes = new goog.ds.BasicNodeList();
+ if (this.node_ != null && this.node_.attributes != null) {
+ var atts = this.node_.attributes;
+ for (var i = 0, att; att = atts[i]; i++) {
+ var newNode = new goog.ds.XmlDataSource(att, this, att.nodeName);
+ attributes.add(newNode);
+ }
+ }
+ this.attributes_ = attributes;
+};
+
+
+/**
+ * Get the value of the node
+ * @return {Object} The value of the node, or null if no value.
+ * @override
+ */
+goog.ds.XmlDataSource.prototype.get = function() {
+ this.createChildNodes_();
+ return this.value_;
+};
+
+
+/**
+ * Set the value of the node
+ * @param {*} value The new value of the node.
+ * @override
+ */
+goog.ds.XmlDataSource.prototype.set = function(value) {
+ throw Error('Can\'t set on XmlDataSource yet');
+};
+
+
+/** @override */
+goog.ds.XmlDataSource.prototype.getChildNodes = function(opt_selector) {
+ if (opt_selector && opt_selector ==
+ goog.ds.XmlDataSource.ATTRIBUTE_SELECTOR_) {
+ this.createAttributes_();
+ return this.attributes_;
+ } else if (opt_selector == null ||
+ opt_selector == goog.ds.STR_ALL_CHILDREN_SELECTOR) {
+ this.createChildNodes_();
+ return this.childNodeList_;
+ } else {
+ throw Error('Unsupported selector');
+ }
+
+};
+
+
+/**
+ * Gets a named child node of the current node
+ * @param {string} name The node name.
+ * @return {goog.ds.DataNode} The child node, or null if
+ * no node of this name exists.
+ * @override
+ */
+goog.ds.XmlDataSource.prototype.getChildNode = function(name) {
+ if (goog.string.startsWith(name, goog.ds.STR_ATTRIBUTE_START)) {
+ var att = this.node_.getAttributeNode(name.substring(1));
+ return att ? new goog.ds.XmlDataSource(att, this) : null;
+ } else {
+ return /** @type {goog.ds.DataNode} */ (this.getChildNodes().get(name));
+ }
+};
+
+
+/**
+ * Gets the value of a child node
+ * @param {string} name The node name.
+ * @return {*} The value of the node, or null if no value or the child node
+ * doesn't exist.
+ * @override
+ */
+goog.ds.XmlDataSource.prototype.getChildNodeValue = function(name) {
+ if (goog.string.startsWith(name, goog.ds.STR_ATTRIBUTE_START)) {
+ var node = this.node_.getAttributeNode(name.substring(1));
+ return node ? node.nodeValue : null;
+ } else {
+ var node = this.getChildNode(name);
+ return node ? node.get() : null;
+ }
+};
+
+
+/**
+ * Get the name of the node relative to the parent node
+ * @return {string} The name of the node.
+ * @override
+ */
+goog.ds.XmlDataSource.prototype.getDataName = function() {
+ return this.dataName_;
+};
+
+
+/**
+ * Setthe name of the node relative to the parent node
+ * @param {string} name The name of the node.
+ * @override
+ */
+goog.ds.XmlDataSource.prototype.setDataName = function(name) {
+ this.dataName_ = name;
+};
+
+
+/**
+ * Gets the a qualified data path to this node
+ * @return {string} The data path.
+ * @override
+ */
+goog.ds.XmlDataSource.prototype.getDataPath = function() {
+ var parentPath = '';
+ if (this.parent_) {
+ parentPath = this.parent_.getDataPath() +
+ (this.dataName_.indexOf(goog.ds.STR_ARRAY_START) != -1 ? '' :
+ goog.ds.STR_PATH_SEPARATOR);
+ }
+
+ return parentPath + this.dataName_;
+};
+
+
+/**
+ * Load or reload the backing data for this node
+ * @override
+ */
+goog.ds.XmlDataSource.prototype.load = function() {
+ // Nothing to do
+};
+
+
+/**
+ * Gets the state of the backing data for this node
+ * @return {goog.ds.LoadState} The state.
+ * @override
+ */
+goog.ds.XmlDataSource.prototype.getLoadState = function() {
+ return this.node_ ? goog.ds.LoadState.LOADED : goog.ds.LoadState.NOT_LOADED;
+};
+
+
+/**
+ * Check whether a node is an empty text node. Nodes consisting of only white
+ * space (#x20, #xD, #xA, #x9) can generally be collapsed to a zero length
+ * text string.
+ * @param {string} str String to match.
+ * @return {boolean} True if string equates to empty text node.
+ * @private
+ */
+goog.ds.XmlDataSource.isEmptyTextNodeValue_ = function(str) {
+ return /^[\r\n\t ]*$/.test(str);
+};
+
+
+/**
+ * Creates an XML document with one empty node.
+ * Useful for places where you need a node that
+ * can be queried against.
+ *
+ * @return {Document} Document with one empty node.
+ * @private
+ */
+goog.ds.XmlDataSource.createChildlessDocument_ = function() {
+ return goog.dom.xml.createDocument('nothing');
+};
+
+
+
+/**
+ * Data source whose backing is an XMLHttpRequest,
+ *
+ * A URI of an empty string will mean that no request is made
+ * and the data source will be a single, empty node.
+ *
+ * @param {(string|goog.Uri)} uri URL of the XMLHttpRequest.
+ * @param {string} name Name of the datasource.
+ *
+ * implements goog.ds.XmlHttpDataSource.
+ * @constructor
+ * @extends {goog.ds.XmlDataSource}
+ * @final
+ */
+goog.ds.XmlHttpDataSource = function(uri, name) {
+ goog.ds.XmlDataSource.call(this, null, null, name);
+ if (uri) {
+ this.uri_ = new goog.Uri(uri);
+ } else {
+ this.uri_ = null;
+ }
+};
+goog.inherits(goog.ds.XmlHttpDataSource, goog.ds.XmlDataSource);
+
+
+/**
+ * Default load state is NOT_LOADED
+ * @private
+ */
+goog.ds.XmlHttpDataSource.prototype.loadState_ = goog.ds.LoadState.NOT_LOADED;
+
+
+/**
+ * Load or reload the backing data for this node.
+ * Fires the XMLHttpRequest
+ * @override
+ */
+goog.ds.XmlHttpDataSource.prototype.load = function() {
+ if (this.uri_) {
+ goog.log.info(goog.ds.logger, 'Sending XML request for DataSource ' +
+ this.getDataName() + ' to ' + this.uri_);
+ this.loadState_ = goog.ds.LoadState.LOADING;
+
+ goog.net.XhrIo.send(this.uri_, goog.bind(this.complete_, this));
+ } else {
+ this.node_ = goog.ds.XmlDataSource.createChildlessDocument_();
+ this.loadState_ = goog.ds.LoadState.NOT_LOADED;
+ }
+};
+
+
+/**
+ * Gets the state of the backing data for this node
+ * @return {goog.ds.LoadState} The state.
+ * @override
+ */
+goog.ds.XmlHttpDataSource.prototype.getLoadState = function() {
+ return this.loadState_;
+};
+
+
+/**
+ * Handles the completion of an XhrIo request. Dispatches to success or load
+ * based on the result.
+ * @param {!goog.events.Event} e The XhrIo event object.
+ * @private
+ */
+goog.ds.XmlHttpDataSource.prototype.complete_ = function(e) {
+ var xhr = /** @type {goog.net.XhrIo} */ (e.target);
+ if (xhr && xhr.isSuccess()) {
+ this.success_(xhr);
+ } else {
+ this.failure_();
+ }
+};
+
+
+/**
+ * Success result. Checks whether valid XML was returned
+ * and sets the XML and loadstate.
+ *
+ * @param {!goog.net.XhrIo} xhr The successful XhrIo object.
+ * @private
+ */
+goog.ds.XmlHttpDataSource.prototype.success_ = function(xhr) {
+ goog.log.info(goog.ds.logger,
+ 'Got data for DataSource ' + this.getDataName());
+ var xml = xhr.getResponseXml();
+
+ // Fix for case where IE returns valid XML as text but
+ // doesn't parse by default
+ if (xml && !xml.hasChildNodes() &&
+ goog.isObject(xhr.getResponseText())) {
+ xml = goog.dom.xml.loadXml(xhr.getResponseText());
+ }
+ // Failure result
+ if (!xml || !xml.hasChildNodes()) {
+ this.loadState_ = goog.ds.LoadState.FAILED;
+ this.node_ = goog.ds.XmlDataSource.createChildlessDocument_();
+ } else {
+ this.loadState_ = goog.ds.LoadState.LOADED;
+ this.node_ = xml.documentElement;
+ }
+
+ if (this.getDataName()) {
+ goog.ds.DataManager.getInstance().fireDataChange(this.getDataName());
+ }
+};
+
+
+/**
+ * Failure result
+ *
+ * @private
+ */
+goog.ds.XmlHttpDataSource.prototype.failure_ = function() {
+ goog.log.info(goog.ds.logger, 'Data retrieve failed for DataSource ' +
+ this.getDataName());
+
+ this.loadState_ = goog.ds.LoadState.FAILED;
+ this.node_ = goog.ds.XmlDataSource.createChildlessDocument_();
+
+ if (this.getDataName()) {
+ goog.ds.DataManager.getInstance().fireDataChange(this.getDataName());
+ }
+};