--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cm/media/js/lib/yui/yui_3.10.3/build/autocomplete-sources/autocomplete-sources.js Tue Jul 16 14:29:46 2013 +0200
@@ -0,0 +1,482 @@
+/*
+YUI 3.10.3 (build 2fb5187)
+Copyright 2013 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+YUI.add('autocomplete-sources', function (Y, NAME) {
+
+/**
+Mixes support for JSONP and YQL result sources into AutoCompleteBase.
+
+@module autocomplete
+@submodule autocomplete-sources
+**/
+
+var ACBase = Y.AutoCompleteBase,
+ Lang = Y.Lang,
+
+ _SOURCE_SUCCESS = '_sourceSuccess',
+
+ MAX_RESULTS = 'maxResults',
+ REQUEST_TEMPLATE = 'requestTemplate',
+ RESULT_LIST_LOCATOR = 'resultListLocator';
+
+// Add prototype properties and methods to AutoCompleteBase.
+Y.mix(ACBase.prototype, {
+ /**
+ Regular expression used to determine whether a String source is a YQL query.
+
+ @property _YQL_SOURCE_REGEX
+ @type RegExp
+ @protected
+ @for AutoCompleteBase
+ **/
+ _YQL_SOURCE_REGEX: /^(?:select|set|use)\s+/i,
+
+ /**
+ Runs before AutoCompleteBase's `_createObjectSource()` method and augments
+ it to support additional object-based source types.
+
+ @method _beforeCreateObjectSource
+ @param {String} source
+ @protected
+ @for AutoCompleteBase
+ **/
+ _beforeCreateObjectSource: function (source) {
+ // If the object is a <select> node, use the options as the result
+ // source.
+ if (source instanceof Y.Node &&
+ source.get('nodeName').toLowerCase() === 'select') {
+
+ return this._createSelectSource(source);
+ }
+
+ // If the object is a JSONPRequest instance, try to use it as a JSONP
+ // source.
+ if (Y.JSONPRequest && source instanceof Y.JSONPRequest) {
+ return this._createJSONPSource(source);
+ }
+
+ // Fall back to a basic object source.
+ return this._createObjectSource(source);
+ },
+
+ /**
+ Creates a DataSource-like object that uses `Y.io` as a source. See the
+ `source` attribute for more details.
+
+ @method _createIOSource
+ @param {String} source URL.
+ @return {Object} DataSource-like object.
+ @protected
+ @for AutoCompleteBase
+ **/
+ _createIOSource: function (source) {
+ var ioSource = {type: 'io'},
+ that = this,
+ ioRequest, lastRequest, loading;
+
+ // Private internal _sendRequest method that will be assigned to
+ // ioSource.sendRequest once io-base and json-parse are available.
+ function _sendRequest(request) {
+ var cacheKey = request.request;
+
+ // Return immediately on a cached response.
+ if (that._cache && cacheKey in that._cache) {
+ that[_SOURCE_SUCCESS](that._cache[cacheKey], request);
+ return;
+ }
+
+ // Cancel any outstanding requests.
+ if (ioRequest && ioRequest.isInProgress()) {
+ ioRequest.abort();
+ }
+
+ ioRequest = Y.io(that._getXHRUrl(source, request), {
+ on: {
+ success: function (tid, response) {
+ var data;
+
+ try {
+ data = Y.JSON.parse(response.responseText);
+ } catch (ex) {
+ Y.error('JSON parse error', ex);
+ }
+
+ if (data) {
+ that._cache && (that._cache[cacheKey] = data);
+ that[_SOURCE_SUCCESS](data, request);
+ }
+ }
+ }
+ });
+ }
+
+ ioSource.sendRequest = function (request) {
+ // Keep track of the most recent request in case there are multiple
+ // requests while we're waiting for the IO module to load. Only the
+ // most recent request will be sent.
+ lastRequest = request;
+
+ if (loading) { return; }
+
+ loading = true;
+
+ // Lazy-load the io-base and json-parse modules if necessary,
+ // then overwrite the sendRequest method to bypass this check in
+ // the future.
+ Y.use('io-base', 'json-parse', function () {
+ ioSource.sendRequest = _sendRequest;
+ _sendRequest(lastRequest);
+ });
+ };
+
+ return ioSource;
+ },
+
+ /**
+ Creates a DataSource-like object that uses the specified JSONPRequest
+ instance as a source. See the `source` attribute for more details.
+
+ @method _createJSONPSource
+ @param {JSONPRequest|String} source URL string or JSONPRequest instance.
+ @return {Object} DataSource-like object.
+ @protected
+ @for AutoCompleteBase
+ **/
+ _createJSONPSource: function (source) {
+ var jsonpSource = {type: 'jsonp'},
+ that = this,
+ lastRequest, loading;
+
+ function _sendRequest(request) {
+ var cacheKey = request.request,
+ query = request.query;
+
+ if (that._cache && cacheKey in that._cache) {
+ that[_SOURCE_SUCCESS](that._cache[cacheKey], request);
+ return;
+ }
+
+ // Hack alert: JSONPRequest currently doesn't support
+ // per-request callbacks, so we're reaching into the protected
+ // _config object to make it happen.
+ //
+ // This limitation is mentioned in the following JSONP
+ // enhancement ticket:
+ //
+ // http://yuilibrary.com/projects/yui3/ticket/2529371
+ source._config.on.success = function (data) {
+ that._cache && (that._cache[cacheKey] = data);
+ that[_SOURCE_SUCCESS](data, request);
+ };
+
+ source.send(query);
+ }
+
+ jsonpSource.sendRequest = function (request) {
+ // Keep track of the most recent request in case there are multiple
+ // requests while we're waiting for the JSONP module to load. Only
+ // the most recent request will be sent.
+ lastRequest = request;
+
+ if (loading) { return; }
+
+ loading = true;
+
+ // Lazy-load the JSONP module if necessary, then overwrite the
+ // sendRequest method to bypass this check in the future.
+ Y.use('jsonp', function () {
+ // Turn the source into a JSONPRequest instance if it isn't
+ // one already.
+ if (!(source instanceof Y.JSONPRequest)) {
+ source = new Y.JSONPRequest(source, {
+ format: Y.bind(that._jsonpFormatter, that)
+ });
+ }
+
+ jsonpSource.sendRequest = _sendRequest;
+ _sendRequest(lastRequest);
+ });
+ };
+
+ return jsonpSource;
+ },
+
+ /**
+ Creates a DataSource-like object that uses the specified `<select>` node as
+ a source.
+
+ @method _createSelectSource
+ @param {Node} source YUI Node instance wrapping a `<select>` node.
+ @return {Object} DataSource-like object.
+ @protected
+ @for AutoCompleteBase
+ **/
+ _createSelectSource: function (source) {
+ var that = this;
+
+ return {
+ type: 'select',
+ sendRequest: function (request) {
+ var options = [];
+
+ source.get('options').each(function (option) {
+ options.push({
+ html : option.get('innerHTML'),
+ index : option.get('index'),
+ node : option,
+ selected: option.get('selected'),
+ text : option.get('text'),
+ value : option.get('value')
+ });
+ });
+
+ that[_SOURCE_SUCCESS](options, request);
+ }
+ };
+ },
+
+ /**
+ Creates a DataSource-like object that calls the specified URL or executes
+ the specified YQL query for results. If the string starts with "select ",
+ "use ", or "set " (case-insensitive), it's assumed to be a YQL query;
+ otherwise, it's assumed to be a URL (which may be absolute or relative).
+ URLs containing a "{callback}" placeholder are assumed to be JSONP URLs; all
+ others will use XHR. See the `source` attribute for more details.
+
+ @method _createStringSource
+ @param {String} source URL or YQL query.
+ @return {Object} DataSource-like object.
+ @protected
+ @for AutoCompleteBase
+ **/
+ _createStringSource: function (source) {
+ if (this._YQL_SOURCE_REGEX.test(source)) {
+ // Looks like a YQL query.
+ return this._createYQLSource(source);
+ } else if (source.indexOf('{callback}') !== -1) {
+ // Contains a {callback} param and isn't a YQL query, so it must be
+ // JSONP.
+ return this._createJSONPSource(source);
+ } else {
+ // Not a YQL query or JSONP, so we'll assume it's an XHR URL.
+ return this._createIOSource(source);
+ }
+ },
+
+ /**
+ Creates a DataSource-like object that uses the specified YQL query string to
+ create a YQL-based source. See the `source` attribute for details. If no
+ `resultListLocator` is defined, this method will set a best-guess locator
+ that might work for many typical YQL queries.
+
+ @method _createYQLSource
+ @param {String} source YQL query.
+ @return {Object} DataSource-like object.
+ @protected
+ @for AutoCompleteBase
+ **/
+ _createYQLSource: function (source) {
+ var that = this,
+ yqlSource = {type: 'yql'},
+ lastRequest, loading, yqlRequest;
+
+ if (!that.get(RESULT_LIST_LOCATOR)) {
+ that.set(RESULT_LIST_LOCATOR, that._defaultYQLLocator);
+ }
+
+ function _sendRequest(request) {
+ var query = request.query,
+ env = that.get('yqlEnv'),
+ maxResults = that.get(MAX_RESULTS),
+ callback, opts, yqlQuery;
+
+ yqlQuery = Lang.sub(source, {
+ maxResults: maxResults > 0 ? maxResults : 1000,
+ request : request.request,
+ query : query
+ });
+
+ if (that._cache && yqlQuery in that._cache) {
+ that[_SOURCE_SUCCESS](that._cache[yqlQuery], request);
+ return;
+ }
+
+ callback = function (data) {
+ that._cache && (that._cache[yqlQuery] = data);
+ that[_SOURCE_SUCCESS](data, request);
+ };
+
+ opts = {proto: that.get('yqlProtocol')};
+
+ // Only create a new YQLRequest instance if this is the
+ // first request. For subsequent requests, we'll reuse the
+ // original instance.
+ if (yqlRequest) {
+ yqlRequest._callback = callback;
+ yqlRequest._opts = opts;
+ yqlRequest._params.q = yqlQuery;
+
+ if (env) {
+ yqlRequest._params.env = env;
+ }
+ } else {
+ yqlRequest = new Y.YQLRequest(yqlQuery, {
+ on: {success: callback},
+ allowCache: false // temp workaround until JSONP has per-URL callback proxies
+ }, env ? {env: env} : null, opts);
+ }
+
+ yqlRequest.send();
+ }
+
+ yqlSource.sendRequest = function (request) {
+ // Keep track of the most recent request in case there are multiple
+ // requests while we're waiting for the YQL module to load. Only the
+ // most recent request will be sent.
+ lastRequest = request;
+
+ if (!loading) {
+ // Lazy-load the YQL module if necessary, then overwrite the
+ // sendRequest method to bypass this check in the future.
+ loading = true;
+
+ Y.use('yql', function () {
+ yqlSource.sendRequest = _sendRequest;
+ _sendRequest(lastRequest);
+ });
+ }
+ };
+
+ return yqlSource;
+ },
+
+ /**
+ Default resultListLocator used when a string-based YQL source is set and the
+ implementer hasn't already specified one.
+
+ @method _defaultYQLLocator
+ @param {Object} response YQL response object.
+ @return {Array}
+ @protected
+ @for AutoCompleteBase
+ **/
+ _defaultYQLLocator: function (response) {
+ var results = response && response.query && response.query.results,
+ values;
+
+ if (results && Lang.isObject(results)) {
+ // If there's only a single value on YQL's results object, that
+ // value almost certainly contains the array of results we want. If
+ // there are 0 or 2+ values, then the values themselves are most
+ // likely the results we want.
+ values = Y.Object.values(results) || [];
+ results = values.length === 1 ? values[0] : values;
+
+ if (!Lang.isArray(results)) {
+ results = [results];
+ }
+ } else {
+ results = [];
+ }
+
+ return results;
+ },
+
+ /**
+ Returns a formatted XHR URL based on the specified base _url_, _query_, and
+ the current _requestTemplate_ if any.
+
+ @method _getXHRUrl
+ @param {String} url Base URL.
+ @param {Object} request Request object containing `query` and `request`
+ properties.
+ @return {String} Formatted URL.
+ @protected
+ @for AutoCompleteBase
+ **/
+ _getXHRUrl: function (url, request) {
+ var maxResults = this.get(MAX_RESULTS);
+
+ if (request.query !== request.request) {
+ // Append the request template to the URL.
+ url += request.request;
+ }
+
+ return Lang.sub(url, {
+ maxResults: maxResults > 0 ? maxResults : 1000,
+ query : encodeURIComponent(request.query)
+ });
+ },
+
+ /**
+ URL formatter passed to `JSONPRequest` instances.
+
+ @method _jsonpFormatter
+ @param {String} url
+ @param {String} proxy
+ @param {String} query
+ @return {String} Formatted URL
+ @protected
+ @for AutoCompleteBase
+ **/
+ _jsonpFormatter: function (url, proxy, query) {
+ var maxResults = this.get(MAX_RESULTS),
+ requestTemplate = this.get(REQUEST_TEMPLATE);
+
+ if (requestTemplate) {
+ url += requestTemplate(query);
+ }
+
+ return Lang.sub(url, {
+ callback : proxy,
+ maxResults: maxResults > 0 ? maxResults : 1000,
+ query : encodeURIComponent(query)
+ });
+ }
+});
+
+// Add attributes to AutoCompleteBase.
+Y.mix(ACBase.ATTRS, {
+ /**
+ YQL environment file URL to load when the `source` is set to a YQL query.
+ Set this to `null` to use the default Open Data Tables environment file
+ (http://datatables.org/alltables.env).
+
+ @attribute yqlEnv
+ @type String
+ @default null
+ @for AutoCompleteBase
+ **/
+ yqlEnv: {
+ value: null
+ },
+
+ /**
+ URL protocol to use when the `source` is set to a YQL query.
+
+ @attribute yqlProtocol
+ @type String
+ @default 'http'
+ @for AutoCompleteBase
+ **/
+ yqlProtocol: {
+ value: 'http'
+ }
+});
+
+// Tell AutoCompleteBase about the new source types it can now support.
+Y.mix(ACBase.SOURCE_TYPES, {
+ io : '_createIOSource',
+ jsonp : '_createJSONPSource',
+ object: '_beforeCreateObjectSource', // Run our version before the base version.
+ select: '_createSelectSource',
+ string: '_createStringSource',
+ yql : '_createYQLSource'
+}, true);
+
+
+}, '3.10.3', {"optional": ["io-base", "json-parse", "jsonp", "yql"], "requires": ["autocomplete-base"]});