aboutsummaryrefslogtreecommitdiff
path: root/catapult/third_party/polymer/components/iron-jsonp-library/iron-jsonp-library.html
diff options
context:
space:
mode:
Diffstat (limited to 'catapult/third_party/polymer/components/iron-jsonp-library/iron-jsonp-library.html')
-rw-r--r--catapult/third_party/polymer/components/iron-jsonp-library/iron-jsonp-library.html271
1 files changed, 271 insertions, 0 deletions
diff --git a/catapult/third_party/polymer/components/iron-jsonp-library/iron-jsonp-library.html b/catapult/third_party/polymer/components/iron-jsonp-library/iron-jsonp-library.html
new file mode 100644
index 00000000..09277da4
--- /dev/null
+++ b/catapult/third_party/polymer/components/iron-jsonp-library/iron-jsonp-library.html
@@ -0,0 +1,271 @@
+<!--
+@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">
+
+<script>
+(function() {
+ "use strict";
+ /**
+ * `Polymer.IronJsonpLibraryBehavior` loads a jsonp library.
+ * Multiple components can request same library, only one copy will load.
+ *
+ * Some libraries require a specific global function be defined.
+ * If this is the case, specify the `callbackName` property.
+ *
+ * You should use an HTML Import to load library dependencies
+ * when possible instead of using this element.
+ *
+ * @hero hero.svg
+ * @demo demo/index.html
+ * @polymerBehavior
+ */
+ Polymer.IronJsonpLibraryBehavior = {
+
+ properties: {
+ /**
+ * True if library has been successfully loaded
+ */
+ libraryLoaded: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ readOnly: true
+ },
+ /**
+ * Not null if library has failed to load
+ */
+ libraryErrorMessage: {
+ type: String,
+ value: null,
+ notify: true,
+ readOnly: true
+ }
+ // Following properties are to be set by behavior users
+ /**
+ * Library url. Must contain string `%%callback%%`.
+ *
+ * `%%callback%%` is a placeholder for jsonp wrapper function name
+ *
+ * Ex: https://maps.googleapis.com/maps/api/js?callback=%%callback%%
+ * @property libraryUrl
+ */
+ /**
+ * Set if library requires specific callback name.
+ * Name will be automatically generated if not set.
+ * @property callbackName
+ */
+ /**
+ * name of event to be emitted when library loads. Standard is `api-load`
+ * @property notifyEvent
+ */
+ /**
+ * event with name specified in `notifyEvent` attribute
+ * will fire upon successful load2
+ * @event `notifyEvent`
+ */
+ },
+
+ observers: [
+ '_libraryUrlChanged(libraryUrl)'
+ ],
+
+ _libraryUrlChanged: function(libraryUrl) {
+ // can't load before ready because notifyEvent might not be set
+ if (this._isReady && this.libraryUrl)
+ this._loadLibrary();
+ },
+
+ _libraryLoadCallback: function(err, result) {
+ if (err) {
+ Polymer.Base._warn("Library load failed:", err.message);
+ this._setLibraryErrorMessage(err.message);
+ }
+ else {
+ this._setLibraryErrorMessage(null);
+ this._setLibraryLoaded(true);
+ if (this.notifyEvent)
+ this.fire(this.notifyEvent, result, {composed: true});
+ }
+ },
+
+ /** loads the library, and fires this.notifyEvent upon completion */
+ _loadLibrary: function() {
+ LoaderMap.require(
+ this.libraryUrl,
+ this._libraryLoadCallback.bind(this),
+ this.callbackName
+ );
+ },
+
+ ready: function() {
+ this._isReady = true;
+ if (this.libraryUrl)
+ this._loadLibrary();
+ }
+ };
+
+ /**
+ * LoaderMap keeps track of all Loaders
+ */
+ var LoaderMap = {
+ apiMap: {}, // { hash -> Loader }
+
+ /**
+ * @param {Function} notifyCallback loaded callback fn(result)
+ * @param {string} jsonpCallbackName name of jsonpcallback. If API does not provide it, leave empty. Optional.
+ */
+ require: function(url, notifyCallback, jsonpCallbackName) {
+
+ // make hashable string form url
+ var name = this.nameFromUrl(url);
+
+ // create a loader as needed
+ if (!this.apiMap[name])
+ this.apiMap[name] = new Loader(name, url, jsonpCallbackName);
+
+ // ask for notification
+ this.apiMap[name].requestNotify(notifyCallback);
+ },
+
+ nameFromUrl: function(url) {
+ return url.replace(/[\:\/\%\?\&\.\=\-\,]/g, '_') + '_api';
+ }
+ };
+
+ /** @constructor */
+ var Loader = function(name, url, callbackName) {
+ this.notifiers = []; // array of notifyFn [ notifyFn* ]
+
+ // callback is specified either as callback name
+ // or computed dynamically if url has callbackMacro in it
+ if (!callbackName) {
+ if (url.indexOf(this.callbackMacro) >= 0) {
+ callbackName = name + '_loaded';
+ url = url.replace(this.callbackMacro, callbackName);
+ } else {
+ this.error = new Error('IronJsonpLibraryBehavior a %%callback%% parameter is required in libraryUrl');
+ // TODO(sjmiles): we should probably fallback to listening to script.load
+ return;
+ }
+ }
+ this.callbackName = callbackName;
+ window[this.callbackName] = this.success.bind(this);
+ this.addScript(url);
+ };
+
+ Loader.prototype = {
+
+ callbackMacro: '%%callback%%',
+ loaded: false,
+
+ addScript: function(src) {
+ var script = document.createElement('script');
+ script.src = src;
+ script.onerror = this.handleError.bind(this);
+ var s = document.querySelector('script') || document.body;
+ s.parentNode.insertBefore(script, s);
+ this.script = script;
+ },
+
+ removeScript: function() {
+ if (this.script.parentNode) {
+ this.script.parentNode.removeChild(this.script);
+ }
+ this.script = null;
+ },
+
+ handleError: function(ev) {
+ this.error = new Error("Library failed to load");
+ this.notifyAll();
+ this.cleanup();
+ },
+
+ success: function() {
+ this.loaded = true;
+ this.result = Array.prototype.slice.call(arguments);
+ this.notifyAll();
+ this.cleanup();
+ },
+
+ cleanup: function() {
+ delete window[this.callbackName];
+ },
+
+ notifyAll: function() {
+ this.notifiers.forEach( function(notifyCallback) {
+ notifyCallback(this.error, this.result);
+ }.bind(this));
+ this.notifiers = [];
+ },
+
+ requestNotify: function(notifyCallback) {
+ if (this.loaded || this.error) {
+ notifyCallback( this.error, this.result);
+ } else {
+ this.notifiers.push(notifyCallback);
+ }
+ }
+ };
+})();
+</script>
+
+<!--
+ Loads specified jsonp library.
+
+ Example:
+
+ <iron-jsonp-library
+ library-url="https://apis.google.com/js/plusone.js?onload=%%callback%%"
+ notify-event="api-load"
+ library-loaded="{{loaded}}"></iron-jsonp-library>
+
+ Will emit 'api-load' event when loaded, and set 'loaded' to true
+
+ Implemented by Polymer.IronJsonpLibraryBehavior. Use it
+ to create specific library loader elements.
+
+ @demo
+-->
+<script>
+ Polymer({
+
+ is: 'iron-jsonp-library',
+
+ behaviors: [ Polymer.IronJsonpLibraryBehavior ],
+
+ properties: {
+ /**
+ * Library url. Must contain string `%%callback%%`.
+ *
+ * `%%callback%%` is a placeholder for jsonp wrapper function name
+ *
+ * Ex: https://maps.googleapis.com/maps/api/js?callback=%%callback%%
+ */
+ libraryUrl: String,
+ /**
+ * Set if library requires specific callback name.
+ * Name will be automatically generated if not set.
+ */
+ callbackName: String,
+ /**
+ * event with name specified in 'notifyEvent' attribute
+ * will fire upon successful load
+ */
+ notifyEvent: String
+ /**
+ * event with name specified in 'notifyEvent' attribute
+ * will fire upon successful load
+ * @event `notifyEvent`
+ */
+
+ }
+ });
+
+</script>