2 Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
3 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
4 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
5 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
6 Code distributed by Google as part of the polymer project is also
7 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9 <link rel=
"import" href=
"../polymer/polymer.html">
12 Supports sharing a JSONP-based JavaScript library.
14 <core-shared-lib on-core-shared-lib-load="{{load}}" url="https://apis.google.com/js/plusone.js?onload=%%callback%%">
16 Multiple components can request a library using a `core-shared-lib` component and only one copy of that library will
17 loaded from the network.
19 Currently, the library must support JSONP to work as a shared-lib.
21 Some libraries require a specific global function be defined. If this is the case, specify the `callbackName` property.
23 Where possible, you should use an HTML Import to load library dependencies. Rather than using this element,
24 create an import (`<link rel="import" href="lib.html">`) that wraps loading the .js file:
28 <script src="lib.js"></script>
30 @group Polymer Core Elements
31 @element core-shared-lib
33 <polymer-element name=
"core-shared-lib" attributes=
"url notifyEvent callbackName">
39 notifyEvent
: 'core-shared-lib-load',
42 if (!this.url
&& this.defaultUrl
) {
43 this.url
= this.defaultUrl
;
47 urlChanged: function() {
48 require(this.url
, this, this.callbackName
);
56 this.fire(this.notifyEvent
, arguments
);
63 function require(url
, notifiee
, callbackName
) {
64 // make hashable string form url
65 var name
= nameFromUrl(url
);
66 // lookup existing loader instance
67 var loader
= apiMap
[name
];
68 // create a loader as needed
70 loader
= apiMap
[name
] = new Loader(name
, url
, callbackName
);
72 loader
.requestNotify(notifiee
);
75 function nameFromUrl(url
) {
76 return url
.replace(/[\:\/\%\?\&\.\=\-\,]/g, '_') + '_api';
79 var Loader = function(name
, url
, callbackName
) {
81 this.callbackName
= callbackName
;
82 if (this.callbackName
) {
83 window
[this.callbackName
] = this.success
.bind(this);
85 if (url
.indexOf(this.callbackMacro
) >= 0) {
86 this.callbackName
= name
+ '_loaded';
87 window
[this.callbackName
] = this.success
.bind(this);
88 url
= url
.replace(this.callbackMacro
, this.callbackName
);
90 // TODO(sjmiles): we should probably fallback to listening to script.load
91 throw 'core-shared-api: a %%callback%% parameter is required in the API url';
100 callbackMacro
: '%%callback%%',
103 addScript: function(src
) {
104 var script
= document
.createElement('script');
106 script
.onerror
= this.error
.bind(this);
107 var s
= document
.querySelector('script');
108 s
.parentNode
.insertBefore(script
, s
);
109 this.script
= script
;
112 removeScript: function() {
113 if (this.script
.parentNode
) {
114 this.script
.parentNode
.removeChild(this.script
);
123 success: function() {
126 this.result
= Array
.prototype.slice
.call(arguments
);
127 this.instances
.forEach(this.provide
, this);
128 this.instances
= null;
131 cleanup: function() {
132 delete window
[this.callbackName
];
135 provide: function(instance
) {
136 instance
.notify(instance
, this.result
);
139 requestNotify: function(instance
) {
141 this.provide(instance
);
143 this.instances
.push(instance
);