| Index: third_party/polymer/components/iron-ajax/iron-ajax.html
 | 
| diff --git a/third_party/polymer/components/iron-ajax/iron-ajax.html b/third_party/polymer/components/iron-ajax/iron-ajax.html
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..fa2fcc68fcde9e6de6f7eb2243b245d9787e16c9
 | 
| --- /dev/null
 | 
| +++ b/third_party/polymer/components/iron-ajax/iron-ajax.html
 | 
| @@ -0,0 +1,533 @@
 | 
| +<!--
 | 
| +@license
 | 
| +Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
 | 
| +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 | 
| +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 | 
| +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 | 
| +Code distributed by Google as part of the polymer project is also
 | 
| +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 | 
| +-->
 | 
| +
 | 
| +<link rel="import" href="../polymer/polymer.html">
 | 
| +<link rel="import" href="iron-request.html">
 | 
| +
 | 
| +<!--
 | 
| +The `iron-ajax` element exposes network request functionality.
 | 
| +
 | 
| +    <iron-ajax
 | 
| +        auto
 | 
| +        url="https://www.googleapis.com/youtube/v3/search"
 | 
| +        params='{"part":"snippet", "q":"polymer", "key": "YOUTUBE_API_KEY", "type": "video"}'
 | 
| +        handle-as="json"
 | 
| +        on-response="handleResponse"
 | 
| +        debounce-duration="300"></iron-ajax>
 | 
| +
 | 
| +With `auto` set to `true`, the element performs a request whenever
 | 
| +its `url`, `params` or `body` properties are changed. Automatically generated
 | 
| +requests will be debounced in the case that multiple attributes are changed
 | 
| +sequentially.
 | 
| +
 | 
| +Note: The `params` attribute must be double quoted JSON.
 | 
| +
 | 
| +You can trigger a request explicitly by calling `generateRequest` on the
 | 
| +element.
 | 
| +
 | 
| +@demo demo/index.html
 | 
| +@hero hero.svg
 | 
| +-->
 | 
| +
 | 
| +<script>
 | 
| +  'use strict';
 | 
| +
 | 
| +  Polymer({
 | 
| +
 | 
| +    is: 'iron-ajax',
 | 
| +
 | 
| +    /**
 | 
| +     * Fired when a request is sent.
 | 
| +     *
 | 
| +     * @event request
 | 
| +     * @event iron-ajax-request
 | 
| +     */
 | 
| +
 | 
| +    /**
 | 
| +     * Fired when a response is received.
 | 
| +     *
 | 
| +     * @event response
 | 
| +     * @event iron-ajax-response
 | 
| +     */
 | 
| +
 | 
| +    /**
 | 
| +     * Fired when an error is received.
 | 
| +     *
 | 
| +     * @event error
 | 
| +     * @event iron-ajax-error
 | 
| +     */
 | 
| +
 | 
| +    hostAttributes: {
 | 
| +      hidden: true
 | 
| +    },
 | 
| +
 | 
| +    properties: {
 | 
| +      /**
 | 
| +       * The URL target of the request.
 | 
| +       */
 | 
| +      url: {
 | 
| +        type: String
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * An object that contains query parameters to be appended to the
 | 
| +       * specified `url` when generating a request. If you wish to set the body
 | 
| +       * content when making a POST request, you should use the `body` property
 | 
| +       * instead.
 | 
| +       */
 | 
| +      params: {
 | 
| +        type: Object,
 | 
| +        value: function() {
 | 
| +          return {};
 | 
| +        }
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * The HTTP method to use such as 'GET', 'POST', 'PUT', or 'DELETE'.
 | 
| +       * Default is 'GET'.
 | 
| +       */
 | 
| +      method: {
 | 
| +        type: String,
 | 
| +        value: 'GET'
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * HTTP request headers to send.
 | 
| +       *
 | 
| +       * Example:
 | 
| +       *
 | 
| +       *     <iron-ajax
 | 
| +       *         auto
 | 
| +       *         url="http://somesite.com"
 | 
| +       *         headers='{"X-Requested-With": "XMLHttpRequest"}'
 | 
| +       *         handle-as="json"></iron-ajax>
 | 
| +       *
 | 
| +       * Note: setting a `Content-Type` header here will override the value
 | 
| +       * specified by the `contentType` property of this element.
 | 
| +       */
 | 
| +      headers: {
 | 
| +        type: Object,
 | 
| +        value: function() {
 | 
| +          return {};
 | 
| +        }
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * Content type to use when sending data. If the `contentType` property
 | 
| +       * is set and a `Content-Type` header is specified in the `headers`
 | 
| +       * property, the `headers` property value will take precedence.
 | 
| +       *
 | 
| +       * Varies the handling of the `body` param.
 | 
| +       */
 | 
| +      contentType: {
 | 
| +        type: String,
 | 
| +        value: null
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * Body content to send with the request, typically used with "POST"
 | 
| +       * requests.
 | 
| +       *
 | 
| +       * If body is a string it will be sent unmodified.
 | 
| +       *
 | 
| +       * If Content-Type is set to a value listed below, then
 | 
| +       * the body will be encoded accordingly.
 | 
| +       *
 | 
| +       *    * `content-type="application/json"`
 | 
| +       *      * body is encoded like `{"foo":"bar baz","x":1}`
 | 
| +       *    * `content-type="application/x-www-form-urlencoded"`
 | 
| +       *      * body is encoded like `foo=bar+baz&x=1`
 | 
| +       *
 | 
| +       * Otherwise the body will be passed to the browser unmodified, and it
 | 
| +       * will handle any encoding (e.g. for FormData, Blob, ArrayBuffer).
 | 
| +       *
 | 
| +       * @type (ArrayBuffer|ArrayBufferView|Blob|Document|FormData|null|string|undefined|Object)
 | 
| +       */
 | 
| +      body: {
 | 
| +        type: Object,
 | 
| +        value: null
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * Toggle whether XHR is synchronous or asynchronous. Don't change this
 | 
| +       * to true unless You Know What You Are Doing™.
 | 
| +       */
 | 
| +      sync: {
 | 
| +        type: Boolean,
 | 
| +        value: false
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * Specifies what data to store in the `response` property, and
 | 
| +       * to deliver as `event.detail.response` in `response` events.
 | 
| +       *
 | 
| +       * One of:
 | 
| +       *
 | 
| +       *    `text`: uses `XHR.responseText`.
 | 
| +       *
 | 
| +       *    `xml`: uses `XHR.responseXML`.
 | 
| +       *
 | 
| +       *    `json`: uses `XHR.responseText` parsed as JSON.
 | 
| +       *
 | 
| +       *    `arraybuffer`: uses `XHR.response`.
 | 
| +       *
 | 
| +       *    `blob`: uses `XHR.response`.
 | 
| +       *
 | 
| +       *    `document`: uses `XHR.response`.
 | 
| +       */
 | 
| +      handleAs: {
 | 
| +        type: String,
 | 
| +        value: 'json'
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * Set the withCredentials flag on the request.
 | 
| +       */
 | 
| +      withCredentials: {
 | 
| +        type: Boolean,
 | 
| +        value: false
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * Set the timeout flag on the request.
 | 
| +       */
 | 
| +      timeout: {
 | 
| +        type: Number,
 | 
| +        value: 0
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * If true, automatically performs an Ajax request when either `url` or
 | 
| +       * `params` changes.
 | 
| +       */
 | 
| +      auto: {
 | 
| +        type: Boolean,
 | 
| +        value: false
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * If true, error messages will automatically be logged to the console.
 | 
| +       */
 | 
| +      verbose: {
 | 
| +        type: Boolean,
 | 
| +        value: false
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * The most recent request made by this iron-ajax element.
 | 
| +       */
 | 
| +      lastRequest: {
 | 
| +        type: Object,
 | 
| +        notify: true,
 | 
| +        readOnly: true
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * True while lastRequest is in flight.
 | 
| +       */
 | 
| +      loading: {
 | 
| +        type: Boolean,
 | 
| +        notify: true,
 | 
| +        readOnly: true
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * lastRequest's response.
 | 
| +       *
 | 
| +       * Note that lastResponse and lastError are set when lastRequest finishes,
 | 
| +       * so if loading is true, then lastResponse and lastError will correspond
 | 
| +       * to the result of the previous request.
 | 
| +       *
 | 
| +       * The type of the response is determined by the value of `handleAs` at
 | 
| +       * the time that the request was generated.
 | 
| +       *
 | 
| +       * @type {Object}
 | 
| +       */
 | 
| +      lastResponse: {
 | 
| +        type: Object,
 | 
| +        notify: true,
 | 
| +        readOnly: true
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * lastRequest's error, if any.
 | 
| +       *
 | 
| +       * @type {Object}
 | 
| +       */
 | 
| +      lastError: {
 | 
| +        type: Object,
 | 
| +        notify: true,
 | 
| +        readOnly: true
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * An Array of all in-flight requests originating from this iron-ajax
 | 
| +       * element.
 | 
| +       */
 | 
| +      activeRequests: {
 | 
| +        type: Array,
 | 
| +        notify: true,
 | 
| +        readOnly: true,
 | 
| +        value: function() {
 | 
| +          return [];
 | 
| +        }
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * Length of time in milliseconds to debounce multiple automatically generated requests.
 | 
| +       */
 | 
| +      debounceDuration: {
 | 
| +        type: Number,
 | 
| +        value: 0,
 | 
| +        notify: true
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * Prefix to be stripped from a JSON response before parsing it.
 | 
| +       *
 | 
| +       * In order to prevent an attack using CSRF with Array responses
 | 
| +       * (http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx/)
 | 
| +       * many backends will mitigate this by prefixing all JSON response bodies
 | 
| +       * with a string that would be nonsensical to a JavaScript parser.
 | 
| +       *
 | 
| +       */
 | 
| +      jsonPrefix: {
 | 
| +        type: String,
 | 
| +        value: ''
 | 
| +      },
 | 
| +
 | 
| +      /**
 | 
| +       * By default, iron-ajax's events do not bubble. Setting this attribute will cause its
 | 
| +       * request and response events as well as its iron-ajax-request, -response,  and -error
 | 
| +       * events to bubble to the window object. The vanilla error event never bubbles when
 | 
| +       * using shadow dom even if this.bubbles is true because a scoped flag is not passed with
 | 
| +       * it (first link) and because the shadow dom spec did not used to allow certain events,
 | 
| +       * including events named error, to leak outside of shadow trees (second link).
 | 
| +       * https://www.w3.org/TR/shadow-dom/#scoped-flag
 | 
| +       * https://www.w3.org/TR/2015/WD-shadow-dom-20151215/#events-that-are-not-leaked-into-ancestor-trees
 | 
| +       */
 | 
| +      bubbles: {
 | 
| +        type: Boolean,
 | 
| +        value: false
 | 
| +      },
 | 
| +
 | 
| +      _boundHandleResponse: {
 | 
| +        type: Function,
 | 
| +        value: function() {
 | 
| +          return this._handleResponse.bind(this);
 | 
| +        }
 | 
| +      }
 | 
| +    },
 | 
| +
 | 
| +    observers: [
 | 
| +      '_requestOptionsChanged(url, method, params.*, headers, contentType, ' +
 | 
| +          'body, sync, handleAs, jsonPrefix, withCredentials, timeout, auto)'
 | 
| +    ],
 | 
| +
 | 
| +    /**
 | 
| +     * The query string that should be appended to the `url`, serialized from
 | 
| +     * the current value of `params`.
 | 
| +     *
 | 
| +     * @return {string}
 | 
| +     */
 | 
| +    get queryString () {
 | 
| +      var queryParts = [];
 | 
| +      var param;
 | 
| +      var value;
 | 
| +
 | 
| +      for (param in this.params) {
 | 
| +        value = this.params[param];
 | 
| +        param = window.encodeURIComponent(param);
 | 
| +
 | 
| +        if (Array.isArray(value)) {
 | 
| +          for (var i = 0; i < value.length; i++) {
 | 
| +            queryParts.push(param + '=' + window.encodeURIComponent(value[i]));
 | 
| +          }
 | 
| +        } else if (value !== null) {
 | 
| +          queryParts.push(param + '=' + window.encodeURIComponent(value));
 | 
| +        } else {
 | 
| +          queryParts.push(param);
 | 
| +        }
 | 
| +      }
 | 
| +
 | 
| +      return queryParts.join('&');
 | 
| +    },
 | 
| +
 | 
| +    /**
 | 
| +     * The `url` with query string (if `params` are specified), suitable for
 | 
| +     * providing to an `iron-request` instance.
 | 
| +     *
 | 
| +     * @return {string}
 | 
| +     */
 | 
| +    get requestUrl() {
 | 
| +      var queryString = this.queryString;
 | 
| +      var url = this.url || '';
 | 
| +
 | 
| +      if (queryString) {
 | 
| +        var bindingChar = url.indexOf('?') >= 0 ? '&' : '?';
 | 
| +        return url + bindingChar + queryString;
 | 
| +      }
 | 
| +
 | 
| +      return url;
 | 
| +    },
 | 
| +
 | 
| +    /**
 | 
| +     * An object that maps header names to header values, first applying the
 | 
| +     * the value of `Content-Type` and then overlaying the headers specified
 | 
| +     * in the `headers` property.
 | 
| +     *
 | 
| +     * @return {Object}
 | 
| +     */
 | 
| +    get requestHeaders() {
 | 
| +      var headers = {};
 | 
| +      var contentType = this.contentType;
 | 
| +      if (contentType == null && (typeof this.body === 'string')) {
 | 
| +        contentType = 'application/x-www-form-urlencoded';
 | 
| +      }
 | 
| +      if (contentType) {
 | 
| +        headers['content-type'] = contentType;
 | 
| +      }
 | 
| +      var header;
 | 
| +
 | 
| +      if (this.headers instanceof Object) {
 | 
| +        for (header in this.headers) {
 | 
| +          headers[header] = this.headers[header].toString();
 | 
| +        }
 | 
| +      }
 | 
| +
 | 
| +      return headers;
 | 
| +    },
 | 
| +
 | 
| +    /**
 | 
| +     * Request options suitable for generating an `iron-request` instance based
 | 
| +     * on the current state of the `iron-ajax` instance's properties.
 | 
| +     *
 | 
| +     * @return {{
 | 
| +     *   url: string,
 | 
| +     *   method: (string|undefined),
 | 
| +     *   async: (boolean|undefined),
 | 
| +     *   body: (ArrayBuffer|ArrayBufferView|Blob|Document|FormData|null|string|undefined|Object),
 | 
| +     *   headers: (Object|undefined),
 | 
| +     *   handleAs: (string|undefined),
 | 
| +     *   jsonPrefix: (string|undefined),
 | 
| +     *   withCredentials: (boolean|undefined)}}
 | 
| +     */
 | 
| +    toRequestOptions: function() {
 | 
| +      return {
 | 
| +        url: this.requestUrl || '',
 | 
| +        method: this.method,
 | 
| +        headers: this.requestHeaders,
 | 
| +        body: this.body,
 | 
| +        async: !this.sync,
 | 
| +        handleAs: this.handleAs,
 | 
| +        jsonPrefix: this.jsonPrefix,
 | 
| +        withCredentials: this.withCredentials,
 | 
| +        timeout: this.timeout
 | 
| +      };
 | 
| +    },
 | 
| +
 | 
| +    /**
 | 
| +     * Performs an AJAX request to the specified URL.
 | 
| +     *
 | 
| +     * @return {!IronRequestElement}
 | 
| +     */
 | 
| +    generateRequest: function() {
 | 
| +      var request = /** @type {!IronRequestElement} */ (document.createElement('iron-request'));
 | 
| +      var requestOptions = this.toRequestOptions();
 | 
| +
 | 
| +      this.push('activeRequests', request);
 | 
| +
 | 
| +      request.completes.then(
 | 
| +        this._boundHandleResponse
 | 
| +      ).catch(
 | 
| +        this._handleError.bind(this, request)
 | 
| +      ).then(
 | 
| +        this._discardRequest.bind(this, request)
 | 
| +      );
 | 
| +
 | 
| +      request.send(requestOptions);
 | 
| +
 | 
| +      this._setLastRequest(request);
 | 
| +      this._setLoading(true);
 | 
| +
 | 
| +      this.fire('request', {
 | 
| +        request: request,
 | 
| +        options: requestOptions
 | 
| +      }, {bubbles: this.bubbles});
 | 
| +
 | 
| +      this.fire('iron-ajax-request', {
 | 
| +        request: request,
 | 
| +        options: requestOptions
 | 
| +      }, {bubbles: this.bubbles});
 | 
| +
 | 
| +      return request;
 | 
| +    },
 | 
| +
 | 
| +    _handleResponse: function(request) {
 | 
| +      if (request === this.lastRequest) {
 | 
| +        this._setLastResponse(request.response);
 | 
| +        this._setLastError(null);
 | 
| +        this._setLoading(false);
 | 
| +      }
 | 
| +      this.fire('response', request, {bubbles: this.bubbles});
 | 
| +      this.fire('iron-ajax-response', request, {bubbles: this.bubbles});
 | 
| +    },
 | 
| +
 | 
| +    _handleError: function(request, error) {
 | 
| +      if (this.verbose) {
 | 
| +        Polymer.Base._error(error);
 | 
| +      }
 | 
| +
 | 
| +      if (request === this.lastRequest) {
 | 
| +        this._setLastError({
 | 
| +          request: request,
 | 
| +          error: error,
 | 
| +          status: request.xhr.status,
 | 
| +          statusText: request.xhr.statusText,
 | 
| +          response: request.xhr.response
 | 
| +        });
 | 
| +        this._setLastResponse(null);
 | 
| +        this._setLoading(false);
 | 
| +      }
 | 
| +
 | 
| +      // Tests fail if this goes after the normal this.fire('error', ...)
 | 
| +      this.fire('iron-ajax-error', {
 | 
| +        request: request,
 | 
| +        error: error
 | 
| +      }, {bubbles: this.bubbles});
 | 
| +
 | 
| +      this.fire('error', {
 | 
| +        request: request,
 | 
| +        error: error
 | 
| +      }, {bubbles: this.bubbles});
 | 
| +    },
 | 
| +
 | 
| +    _discardRequest: function(request) {
 | 
| +      var requestIndex = this.activeRequests.indexOf(request);
 | 
| +
 | 
| +      if (requestIndex > -1) {
 | 
| +        this.splice('activeRequests', requestIndex, 1);
 | 
| +      }
 | 
| +    },
 | 
| +
 | 
| +    _requestOptionsChanged: function() {
 | 
| +      this.debounce('generate-request', function() {
 | 
| +        if (this.url == null) {
 | 
| +          return;
 | 
| +        }
 | 
| +
 | 
| +        if (this.auto) {
 | 
| +          this.generateRequest();
 | 
| +        }
 | 
| +      }, this.debounceDuration);
 | 
| +    },
 | 
| +
 | 
| +  });
 | 
| +</script>
 | 
| 
 |