blob: 0257a86b7de254d82cccf48e8c087354c931d11c [file] [log] [blame]
<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at https://polymer.github.io/LICENSE.txt
The complete set of authors may be found at https://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at https://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 https://polymer.github.io/PATENTS.txt
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="google-js-api.html">
<!--
Element for loading a specific client Google API with the JavaScript client library.
For loading `gapi.client` libraries
##### Example
<google-client-loader id="shortener"
name="urlshortener"
version="v1"></google-client-loader>
<script>
var shortener = document.getElementById('shortener');
shortener.addEventListener('google-api-load', function(event) {
var request = shortener.api.url.get({
shortUrl: 'http://goo.gl/fbsS'
});
request.execute(function(resp) {
console.log(resp);
});
});
</script>
@demo
-->
<script>
(function() {
'use strict';
// Stores whether the API client is done loading.
var _clientLoaded = false;
// Loaders and loading statuses for all APIs, indexed by API name.
// This helps prevent multiple loading requests being fired at the same time
// by multiple google-api-loader elements.
var _statuses = {};
var _loaders = {};
Polymer({
is: 'google-client-loader',
/**
* Fired when the requested API is loaded. Override this name
* by setting `successEventName`.
* @event google-api-load
*/
/**
* Fired if an error occurs while loading the requested API. Override this name
* by setting `errorEventName`.
* @event google-api-load-error
*/
properties: {
/**
* Name of the API to load, e.g. 'urlshortener'.
*
* You can find the full list of APIs on the
* <a href="https://developers.google.com/apis-explorer"> Google APIs
* Explorer</a>.
*/
name: String,
/**
* Version of the API to load, e.g. 'v1'.
*/
version: String,
/**
* App Engine application ID for loading a Google Cloud Endpoints API.
*/
appId: String,
/**
* Root URL where to load the API from, e.g. 'http://host/apis'.
* For App Engine dev server this would be something like:
* 'http://localhost:8080/_ah/api'.
* Overrides 'appId' if both are specified.
*/
apiRoot: String,
/**
* Name of the event fired when API library is loaded.
*/
successEventName: {
type: String,
value: 'google-api-load'
},
/**
* Name of the event fired when there is an error loading the library.
*/
errorEventName: {
type: String,
value: 'google-api-load-error'
}
},
hostAttributes: {
hidden: true // remove from rendering tree.
},
// Used to fix events potentially being fired multiple times by
// iron-jsonp-library.
_waiting: false,
/**
* Returns the loaded API.
*/
get api() {
if (window.gapi && window.gapi.client &&
window.gapi.client[this.name]) {
return window.gapi.client[this.name];
} else {
return undefined;
}
},
/**
* Wrapper for `gapi.auth`.
*/
get auth() {
return gapi.auth;
},
ready: function() {
this._loader = document.createElement('google-js-api');
this.listen(this._loader, 'js-api-load', '_loadClient');
},
detached: function() {
this.unlisten(this._loader, 'js-api-load', '_loadClient');
},
_loadClient: function() {
gapi.load('client', this._doneLoadingClient.bind(this));
},
_handleLoadResponse: function(response) {
if (response && response.error) {
_statuses[this.name] = 'error';
this._fireError(response);
} else {
_statuses[this.name] = 'loaded';
this._fireSuccess();
}
},
_fireSuccess: function() {
this.fire(this.successEventName,
{ 'name': this.name, 'version': this.version });
},
_fireError: function(response) {
if (response && response.error) {
this.fire(this.errorEventName, {
'name': this.name,
'version': this.version,
'error': response.error });
} else {
this.fire(this.errorEventName, {
'name': this.name,
'version': this.version });
}
},
_doneLoadingClient: function() {
_clientLoaded = true;
// Fix for API client load event being fired multiple times by
// iron-jsonp-library.
if (!this._waiting) {
this._loadApi();
}
},
_createSelfRemovingListener: function(eventName) {
var handler = function () {
_loaders[this.name].removeEventListener(eventName, handler);
this._loadApi();
}.bind(this);
return handler;
},
_loadApi: function() {
if (_clientLoaded && this.name && this.version) {
this._waiting = false;
// Is this API already loaded?
if (_statuses[this.name] == 'loaded') {
this._fireSuccess();
// Is a different google-api-loader already loading this API?
} else if (_statuses[this.name] == 'loading') {
this._waiting = true;
_loaders[this.name].addEventListener(this.successEventName,
this._createSelfRemovingListener(this.successEventName));
_loaders[this.name].addEventListener(this.errorEventName,
this._createSelfRemovingListener(this.errorEventName));
// Did we get an error when we tried to load this API before?
} else if (_statuses[this.name] == 'error') {
this._fireError(null);
// Otherwise, looks like we're loading a new API.
} else {
var root;
if (this.apiRoot) {
root = this.apiRoot;
} else if (this.appId) {
root = 'https://' + this.appId + '.appspot.com/_ah/api';
}
_statuses[this.name] = 'loading';
_loaders[this.name] = this;
gapi.client.load(this.name, this.version,
this._handleLoadResponse.bind(this), root);
}
}
}
});
})();
</script>