OLD | NEW |
1 /** | 1 /** |
2 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. | 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://polyme
r.github.io/LICENSE.txt | 3 * This code may only be used under the BSD style license found at http://polyme
r.github.io/LICENSE.txt |
4 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.
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/CON
TRIBUTORS.txt | 5 * The complete set of contributors may be found at http://polymer.github.io/CON
TRIBUTORS.txt |
6 * Code distributed by Google as part of the polymer project is also | 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/PA
TENTS.txt | 7 * subject to an additional IP rights grant found at http://polymer.github.io/PA
TENTS.txt |
8 */ | 8 */ |
9 | 9 |
10 window.Platform = window.Platform || {}; | 10 window.Platform = window.Platform || {}; |
(...skipping 28 matching lines...) Expand all Loading... |
39 // other truthy value, or failure to detect native | 39 // other truthy value, or failure to detect native |
40 // ShadowDOM, results in polyfill | 40 // ShadowDOM, results in polyfill |
41 flags.shadow = flags.shadow || flags.shadowdom || flags.polyfill; | 41 flags.shadow = flags.shadow || flags.shadowdom || flags.polyfill; |
42 if (flags.shadow === 'native') { | 42 if (flags.shadow === 'native') { |
43 flags.shadow = false; | 43 flags.shadow = false; |
44 } else { | 44 } else { |
45 flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot; | 45 flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot; |
46 } | 46 } |
47 | 47 |
48 if (flags.shadow && document.querySelectorAll('script').length > 1) { | 48 if (flags.shadow && document.querySelectorAll('script').length > 1) { |
49 console.warn('platform.js is not the first script on the page. ' + | 49 console.log('Warning: platform.js is not the first script on the page. ' + |
50 'See http://www.polymer-project.org/docs/start/platform.html#setup ' + | 50 'See http://www.polymer-project.org/docs/start/platform.html#setup ' + |
51 'for details.'); | 51 'for details.'); |
52 } | 52 } |
53 | 53 |
54 // CustomElements polyfill flag | 54 // CustomElements polyfill flag |
55 if (flags.register) { | 55 if (flags.register) { |
56 window.CustomElements = window.CustomElements || {flags: {}}; | 56 window.CustomElements = window.CustomElements || {flags: {}}; |
57 window.CustomElements.flags.register = flags.register; | 57 window.CustomElements.flags.register = flags.register; |
58 } | 58 } |
59 | 59 |
(...skipping 21 matching lines...) Expand all Loading... |
81 this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__'); | 81 this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__'); |
82 }; | 82 }; |
83 | 83 |
84 WeakMap.prototype = { | 84 WeakMap.prototype = { |
85 set: function(key, value) { | 85 set: function(key, value) { |
86 var entry = key[this.name]; | 86 var entry = key[this.name]; |
87 if (entry && entry[0] === key) | 87 if (entry && entry[0] === key) |
88 entry[1] = value; | 88 entry[1] = value; |
89 else | 89 else |
90 defineProperty(key, this.name, {value: [key, value], writable: true}); | 90 defineProperty(key, this.name, {value: [key, value], writable: true}); |
| 91 return this; |
91 }, | 92 }, |
92 get: function(key) { | 93 get: function(key) { |
93 var entry; | 94 var entry; |
94 return (entry = key[this.name]) && entry[0] === key ? | 95 return (entry = key[this.name]) && entry[0] === key ? |
95 entry[1] : undefined; | 96 entry[1] : undefined; |
96 }, | 97 }, |
97 delete: function(key) { | 98 delete: function(key) { |
98 var entry = key[this.name]; | 99 var entry = key[this.name]; |
99 if (!entry) return false; | 100 if (!entry) return false; |
100 var hasValue = entry[0] === key; | 101 var hasValue = entry[0] === key; |
(...skipping 4401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4502 // are no shadow trees below or above the context node. | 4503 // are no shadow trees below or above the context node. |
4503 var s = ''; | 4504 var s = ''; |
4504 for (var child = this.firstChild; child; child = child.nextSibling) { | 4505 for (var child = this.firstChild; child; child = child.nextSibling) { |
4505 if (child.nodeType != Node.COMMENT_NODE) { | 4506 if (child.nodeType != Node.COMMENT_NODE) { |
4506 s += child.textContent; | 4507 s += child.textContent; |
4507 } | 4508 } |
4508 } | 4509 } |
4509 return s; | 4510 return s; |
4510 }, | 4511 }, |
4511 set textContent(textContent) { | 4512 set textContent(textContent) { |
| 4513 if (textContent == null) textContent = ''; |
4512 var removedNodes = snapshotNodeList(this.childNodes); | 4514 var removedNodes = snapshotNodeList(this.childNodes); |
4513 | 4515 |
4514 if (this.invalidateShadowRenderer()) { | 4516 if (this.invalidateShadowRenderer()) { |
4515 removeAllChildNodes(this); | 4517 removeAllChildNodes(this); |
4516 if (textContent !== '') { | 4518 if (textContent !== '') { |
4517 var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textCon
tent); | 4519 var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textCon
tent); |
4518 this.appendChild(textNode); | 4520 this.appendChild(textNode); |
4519 } | 4521 } |
4520 } else { | 4522 } else { |
4521 clearChildNodes(this); | 4523 clearChildNodes(this); |
(...skipping 4984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9506 return this._isInvalid || !this._fragment || '#' == this._fragment ? | 9508 return this._isInvalid || !this._fragment || '#' == this._fragment ? |
9507 '' : this._fragment; | 9509 '' : this._fragment; |
9508 }, | 9510 }, |
9509 set hash(hash) { | 9511 set hash(hash) { |
9510 if (this._isInvalid) | 9512 if (this._isInvalid) |
9511 return; | 9513 return; |
9512 this._fragment = '#'; | 9514 this._fragment = '#'; |
9513 if ('#' == hash[0]) | 9515 if ('#' == hash[0]) |
9514 hash = hash.slice(1); | 9516 hash = hash.slice(1); |
9515 parse.call(this, hash, 'fragment'); | 9517 parse.call(this, hash, 'fragment'); |
| 9518 }, |
| 9519 |
| 9520 get origin() { |
| 9521 var host; |
| 9522 if (this._isInvalid || !this._scheme) { |
| 9523 return ''; |
| 9524 } |
| 9525 // javascript: Gecko returns String(""), WebKit/Blink String("null") |
| 9526 // Gecko throws error for "data://" |
| 9527 // data: Gecko returns "", Blink returns "data://", WebKit returns "null" |
| 9528 // Gecko returns String("") for file: mailto: |
| 9529 // WebKit/Blink returns String("SCHEME://") for file: mailto: |
| 9530 switch (this._scheme) { |
| 9531 case 'data': |
| 9532 case 'file': |
| 9533 case 'javascript': |
| 9534 case 'mailto': |
| 9535 return 'null'; |
| 9536 } |
| 9537 host = this.host; |
| 9538 if (!host) { |
| 9539 return ''; |
| 9540 } |
| 9541 return this._scheme + '://' + host; |
9516 } | 9542 } |
9517 }; | 9543 }; |
9518 | 9544 |
9519 // Copy over the static methods | 9545 // Copy over the static methods |
9520 var OriginalURL = scope.URL; | 9546 var OriginalURL = scope.URL; |
9521 if (OriginalURL) { | 9547 if (OriginalURL) { |
9522 jURL.createObjectURL = function(blob) { | 9548 jURL.createObjectURL = function(blob) { |
9523 // IE extension allows a second optional options argument. | 9549 // IE extension allows a second optional options argument. |
9524 // http://msdn.microsoft.com/en-us/library/ie/hh772302(v=vs.85).aspx | 9550 // http://msdn.microsoft.com/en-us/library/ie/hh772302(v=vs.85).aspx |
9525 return OriginalURL.createObjectURL.apply(OriginalURL, arguments); | 9551 return OriginalURL.createObjectURL.apply(OriginalURL, arguments); |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10120 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. | 10146 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. |
10121 * This code may only be used under the BSD style license found at http://polyme
r.github.io/LICENSE.txt | 10147 * This code may only be used under the BSD style license found at http://polyme
r.github.io/LICENSE.txt |
10122 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.
txt | 10148 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.
txt |
10123 * The complete set of contributors may be found at http://polymer.github.io/CON
TRIBUTORS.txt | 10149 * The complete set of contributors may be found at http://polymer.github.io/CON
TRIBUTORS.txt |
10124 * Code distributed by Google as part of the polymer project is also | 10150 * Code distributed by Google as part of the polymer project is also |
10125 * subject to an additional IP rights grant found at http://polymer.github.io/PA
TENTS.txt | 10151 * subject to an additional IP rights grant found at http://polymer.github.io/PA
TENTS.txt |
10126 */ | 10152 */ |
10127 | 10153 |
10128 (function(scope) { | 10154 (function(scope) { |
10129 | 10155 |
10130 var hasNative = ('import' in document.createElement('link')); | 10156 var IMPORT_LINK_TYPE = 'import'; |
| 10157 var hasNative = (IMPORT_LINK_TYPE in document.createElement('link')); |
10131 var useNative = hasNative; | 10158 var useNative = hasNative; |
10132 | 10159 var isIE = /Trident/.test(navigator.userAgent); |
10133 isIE = /Trident/.test(navigator.userAgent); | |
10134 | 10160 |
10135 // TODO(sorvell): SD polyfill intrusion | 10161 // TODO(sorvell): SD polyfill intrusion |
10136 var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill); | 10162 var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill); |
10137 var wrap = function(node) { | 10163 var wrap = function(node) { |
10138 return hasShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node) : node; | 10164 return hasShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node) : node; |
10139 }; | 10165 }; |
10140 var mainDoc = wrap(document); | 10166 |
| 10167 var rootDocument = wrap(document); |
10141 | 10168 |
10142 // NOTE: We cannot polyfill document.currentScript because it's not possible | 10169 // NOTE: We cannot polyfill document.currentScript because it's not possible |
10143 // both to override and maintain the ability to capture the native value; | 10170 // both to override and maintain the ability to capture the native value; |
10144 // therefore we choose to expose _currentScript both when native imports | 10171 // therefore we choose to expose _currentScript both when native imports |
10145 // and the polyfill are in use. | 10172 // and the polyfill are in use. |
10146 var currentScriptDescriptor = { | 10173 var currentScriptDescriptor = { |
10147 get: function() { | 10174 get: function() { |
10148 var script = HTMLImports.currentScript || document.currentScript || | 10175 var script = HTMLImports.currentScript || document.currentScript || |
10149 // NOTE: only works when called in synchronously executing code. | 10176 // NOTE: only works when called in synchronously executing code. |
10150 // readyState should check if `loading` but IE10 is | 10177 // readyState should check if `loading` but IE10 is |
10151 // interactive when scripts run so we cheat. | 10178 // interactive when scripts run so we cheat. |
10152 (document.readyState !== 'complete' ? | 10179 (document.readyState !== 'complete' ? |
10153 document.scripts[document.scripts.length - 1] : null); | 10180 document.scripts[document.scripts.length - 1] : null); |
10154 return wrap(script); | 10181 return wrap(script); |
10155 }, | 10182 }, |
10156 configurable: true | 10183 configurable: true |
10157 }; | 10184 }; |
10158 | 10185 |
10159 Object.defineProperty(document, '_currentScript', currentScriptDescriptor); | 10186 Object.defineProperty(document, '_currentScript', currentScriptDescriptor); |
10160 Object.defineProperty(mainDoc, '_currentScript', currentScriptDescriptor); | 10187 Object.defineProperty(rootDocument, '_currentScript', currentScriptDescriptor); |
10161 | 10188 |
10162 // call a callback when all HTMLImports in the document at call (or at least | 10189 // call a callback when all HTMLImports in the document at call (or at least |
10163 // document ready) time have loaded. | 10190 // document ready) time have loaded. |
10164 // 1. ensure the document is in a ready state (has dom), then | 10191 // 1. ensure the document is in a ready state (has dom), then |
10165 // 2. watch for loading of imports and call callback when done | 10192 // 2. watch for loading of imports and call callback when done |
10166 function whenImportsReady(callback, doc) { | 10193 function whenReady(callback, doc) { |
10167 doc = doc || mainDoc; | 10194 doc = doc || rootDocument; |
10168 // if document is loading, wait and try again | 10195 // if document is loading, wait and try again |
10169 whenDocumentReady(function() { | 10196 whenDocumentReady(function() { |
10170 watchImportsLoad(callback, doc); | 10197 watchImportsLoad(callback, doc); |
10171 }, doc); | 10198 }, doc); |
10172 } | 10199 } |
10173 | 10200 |
10174 // call the callback when the document is in a ready state (has dom) | 10201 // call the callback when the document is in a ready state (has dom) |
10175 var requiredReadyState = isIE ? 'complete' : 'interactive'; | 10202 var requiredReadyState = isIE ? 'complete' : 'interactive'; |
10176 var READY_EVENT = 'readystatechange'; | 10203 var READY_EVENT = 'readystatechange'; |
10177 function isDocumentReady(doc) { | 10204 function isDocumentReady(doc) { |
(...skipping 19 matching lines...) Expand all Loading... |
10197 | 10224 |
10198 function markTargetLoaded(event) { | 10225 function markTargetLoaded(event) { |
10199 event.target.__loaded = true; | 10226 event.target.__loaded = true; |
10200 } | 10227 } |
10201 | 10228 |
10202 // call <callback> when we ensure all imports have loaded | 10229 // call <callback> when we ensure all imports have loaded |
10203 function watchImportsLoad(callback, doc) { | 10230 function watchImportsLoad(callback, doc) { |
10204 var imports = doc.querySelectorAll('link[rel=import]'); | 10231 var imports = doc.querySelectorAll('link[rel=import]'); |
10205 var loaded = 0, l = imports.length; | 10232 var loaded = 0, l = imports.length; |
10206 function checkDone(d) { | 10233 function checkDone(d) { |
10207 if (loaded == l) { | 10234 if ((loaded == l) && callback) { |
10208 callback && callback(); | 10235 callback(); |
10209 } | 10236 } |
10210 } | 10237 } |
10211 function loadedImport(e) { | 10238 function loadedImport(e) { |
10212 markTargetLoaded(e); | 10239 markTargetLoaded(e); |
10213 loaded++; | 10240 loaded++; |
10214 checkDone(); | 10241 checkDone(); |
10215 } | 10242 } |
10216 if (l) { | 10243 if (l) { |
10217 for (var i=0, imp; (i<l) && (imp=imports[i]); i++) { | 10244 for (var i=0, imp; (i<l) && (imp=imports[i]); i++) { |
10218 if (isImportLoaded(imp)) { | 10245 if (isImportLoaded(imp)) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10291 } | 10318 } |
10292 } | 10319 } |
10293 })(); | 10320 })(); |
10294 | 10321 |
10295 } | 10322 } |
10296 | 10323 |
10297 // Fire the 'HTMLImportsLoaded' event when imports in document at load time | 10324 // Fire the 'HTMLImportsLoaded' event when imports in document at load time |
10298 // have loaded. This event is required to simulate the script blocking | 10325 // have loaded. This event is required to simulate the script blocking |
10299 // behavior of native imports. A main document script that needs to be sure | 10326 // behavior of native imports. A main document script that needs to be sure |
10300 // imports have loaded should wait for this event. | 10327 // imports have loaded should wait for this event. |
10301 whenImportsReady(function() { | 10328 whenReady(function() { |
10302 HTMLImports.ready = true; | 10329 HTMLImports.ready = true; |
10303 HTMLImports.readyTime = new Date().getTime(); | 10330 HTMLImports.readyTime = new Date().getTime(); |
10304 mainDoc.dispatchEvent( | 10331 rootDocument.dispatchEvent( |
10305 new CustomEvent('HTMLImportsLoaded', {bubbles: true}) | 10332 new CustomEvent('HTMLImportsLoaded', {bubbles: true}) |
10306 ); | 10333 ); |
10307 }); | 10334 }); |
10308 | 10335 |
10309 // exports | 10336 // exports |
10310 scope.useNative = useNative; | 10337 scope.useNative = useNative; |
10311 scope.isImportLoaded = isImportLoaded; | 10338 scope.isImportLoaded = isImportLoaded; |
10312 scope.whenReady = whenImportsReady; | 10339 scope.whenReady = whenReady; |
| 10340 scope.rootDocument = rootDocument; |
| 10341 scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE; |
10313 scope.isIE = isIE; | 10342 scope.isIE = isIE; |
10314 | 10343 |
10315 // deprecated | |
10316 scope.whenImportsReady = whenImportsReady; | |
10317 | |
10318 })(window.HTMLImports); | 10344 })(window.HTMLImports); |
10319 /* | 10345 /* |
10320 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. | 10346 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. |
10321 * This code may only be used under the BSD style license found at http://polyme
r.github.io/LICENSE.txt | 10347 * This code may only be used under the BSD style license found at http://polyme
r.github.io/LICENSE.txt |
10322 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.
txt | 10348 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.
txt |
10323 * The complete set of contributors may be found at http://polymer.github.io/CON
TRIBUTORS.txt | 10349 * The complete set of contributors may be found at http://polymer.github.io/CON
TRIBUTORS.txt |
10324 * Code distributed by Google as part of the polymer project is also | 10350 * Code distributed by Google as part of the polymer project is also |
10325 * subject to an additional IP rights grant found at http://polymer.github.io/PA
TENTS.txt | 10351 * subject to an additional IP rights grant found at http://polymer.github.io/PA
TENTS.txt |
10326 */ | 10352 */ |
10327 (function(scope) { | 10353 (function(scope) { |
10328 | 10354 |
10329 // imports | 10355 // imports |
10330 var path = scope.path; | 10356 var path = scope.path; |
10331 var xhr = scope.xhr; | 10357 var xhr = scope.xhr; |
10332 var flags = scope.flags; | 10358 var flags = scope.flags; |
10333 | 10359 |
10334 // TODO(sorvell): this loader supports a dynamic list of urls | 10360 // TODO(sorvell): this loader supports a dynamic list of urls |
10335 // and an oncomplete callback that is called when the loader is done. | 10361 // and an oncomplete callback that is called when the loader is done. |
10336 // The polyfill currently does *not* need this dynamism or the onComplete | 10362 // The polyfill currently does *not* need this dynamism or the onComplete |
10337 // concept. Because of this, the loader could be simplified quite a bit. | 10363 // concept. Because of this, the loader could be simplified quite a bit. |
10338 var Loader = function(onLoad, onComplete) { | 10364 var Loader = function(onLoad, onComplete) { |
10339 this.cache = {}; | 10365 this.cache = {}; |
10340 this.onload = onLoad; | 10366 this.onload = onLoad; |
10341 this.oncomplete = onComplete; | 10367 this.oncomplete = onComplete; |
10342 this.inflight = 0; | 10368 this.inflight = 0; |
10343 this.pending = {}; | 10369 this.pending = {}; |
10344 }; | 10370 }; |
10345 | 10371 |
10346 Loader.prototype = { | 10372 Loader.prototype = { |
| 10373 |
10347 addNodes: function(nodes) { | 10374 addNodes: function(nodes) { |
10348 // number of transactions to complete | 10375 // number of transactions to complete |
10349 this.inflight += nodes.length; | 10376 this.inflight += nodes.length; |
10350 // commence transactions | 10377 // commence transactions |
10351 for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) { | 10378 for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) { |
10352 this.require(n); | 10379 this.require(n); |
10353 } | 10380 } |
10354 // anything to do? | 10381 // anything to do? |
10355 this.checkDone(); | 10382 this.checkDone(); |
10356 }, | 10383 }, |
| 10384 |
10357 addNode: function(node) { | 10385 addNode: function(node) { |
10358 // number of transactions to complete | 10386 // number of transactions to complete |
10359 this.inflight++; | 10387 this.inflight++; |
10360 // commence transactions | 10388 // commence transactions |
10361 this.require(node); | 10389 this.require(node); |
10362 // anything to do? | 10390 // anything to do? |
10363 this.checkDone(); | 10391 this.checkDone(); |
10364 }, | 10392 }, |
| 10393 |
10365 require: function(elt) { | 10394 require: function(elt) { |
10366 var url = elt.src || elt.href; | 10395 var url = elt.src || elt.href; |
10367 // ensure we have a standard url that can be used | 10396 // ensure we have a standard url that can be used |
10368 // reliably for deduping. | 10397 // reliably for deduping. |
10369 // TODO(sjmiles): ad-hoc | 10398 // TODO(sjmiles): ad-hoc |
10370 elt.__nodeUrl = url; | 10399 elt.__nodeUrl = url; |
10371 // deduplication | 10400 // deduplication |
10372 if (!this.dedupe(url, elt)) { | 10401 if (!this.dedupe(url, elt)) { |
10373 // fetch this resource | 10402 // fetch this resource |
10374 this.fetch(url, elt); | 10403 this.fetch(url, elt); |
10375 } | 10404 } |
10376 }, | 10405 }, |
| 10406 |
10377 dedupe: function(url, elt) { | 10407 dedupe: function(url, elt) { |
10378 if (this.pending[url]) { | 10408 if (this.pending[url]) { |
10379 // add to list of nodes waiting for inUrl | 10409 // add to list of nodes waiting for inUrl |
10380 this.pending[url].push(elt); | 10410 this.pending[url].push(elt); |
10381 // don't need fetch | 10411 // don't need fetch |
10382 return true; | 10412 return true; |
10383 } | 10413 } |
10384 var resource; | 10414 var resource; |
10385 if (this.cache[url]) { | 10415 if (this.cache[url]) { |
10386 this.onload(url, elt, this.cache[url]); | 10416 this.onload(url, elt, this.cache[url]); |
10387 // finished this transaction | 10417 // finished this transaction |
10388 this.tail(); | 10418 this.tail(); |
10389 // don't need fetch | 10419 // don't need fetch |
10390 return true; | 10420 return true; |
10391 } | 10421 } |
10392 // first node waiting for inUrl | 10422 // first node waiting for inUrl |
10393 this.pending[url] = [elt]; | 10423 this.pending[url] = [elt]; |
10394 // need fetch (not a dupe) | 10424 // need fetch (not a dupe) |
10395 return false; | 10425 return false; |
10396 }, | 10426 }, |
| 10427 |
10397 fetch: function(url, elt) { | 10428 fetch: function(url, elt) { |
10398 flags.load && console.log('fetch', url, elt); | 10429 flags.load && console.log('fetch', url, elt); |
10399 if (url.match(/^data:/)) { | 10430 if (url.match(/^data:/)) { |
10400 // Handle Data URI Scheme | 10431 // Handle Data URI Scheme |
10401 var pieces = url.split(','); | 10432 var pieces = url.split(','); |
10402 var header = pieces[0]; | 10433 var header = pieces[0]; |
10403 var body = pieces[1]; | 10434 var body = pieces[1]; |
10404 if(header.indexOf(';base64') > -1) { | 10435 if(header.indexOf(';base64') > -1) { |
10405 body = atob(body); | 10436 body = atob(body); |
10406 } else { | 10437 } else { |
(...skipping 15 matching lines...) Expand all Loading... |
10422 // to avoid the bug above. | 10453 // to avoid the bug above. |
10423 /* | 10454 /* |
10424 if (isDocumentLink(elt)) { | 10455 if (isDocumentLink(elt)) { |
10425 xhr.loadDocument(url, receiveXhr); | 10456 xhr.loadDocument(url, receiveXhr); |
10426 } else { | 10457 } else { |
10427 xhr.load(url, receiveXhr); | 10458 xhr.load(url, receiveXhr); |
10428 } | 10459 } |
10429 */ | 10460 */ |
10430 } | 10461 } |
10431 }, | 10462 }, |
| 10463 |
10432 receive: function(url, elt, err, resource, redirectedUrl) { | 10464 receive: function(url, elt, err, resource, redirectedUrl) { |
10433 this.cache[url] = resource; | 10465 this.cache[url] = resource; |
10434 var $p = this.pending[url]; | 10466 var $p = this.pending[url]; |
10435 for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) { | 10467 for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) { |
10436 // If url was redirected, use the redirected location so paths are | 10468 // If url was redirected, use the redirected location so paths are |
10437 // calculated relative to that. | 10469 // calculated relative to that. |
10438 this.onload(url, p, resource, err, redirectedUrl); | 10470 this.onload(url, p, resource, err, redirectedUrl); |
10439 this.tail(); | 10471 this.tail(); |
10440 } | 10472 } |
10441 this.pending[url] = null; | 10473 this.pending[url] = null; |
10442 }, | 10474 }, |
| 10475 |
10443 tail: function() { | 10476 tail: function() { |
10444 --this.inflight; | 10477 --this.inflight; |
10445 this.checkDone(); | 10478 this.checkDone(); |
10446 }, | 10479 }, |
| 10480 |
10447 checkDone: function() { | 10481 checkDone: function() { |
10448 if (!this.inflight) { | 10482 if (!this.inflight) { |
10449 this.oncomplete(); | 10483 this.oncomplete(); |
10450 } | 10484 } |
10451 } | 10485 } |
| 10486 |
10452 }; | 10487 }; |
10453 | 10488 |
10454 xhr = xhr || { | 10489 xhr = xhr || { |
10455 async: true, | 10490 async: true, |
| 10491 |
10456 ok: function(request) { | 10492 ok: function(request) { |
10457 return (request.status >= 200 && request.status < 300) | 10493 return (request.status >= 200 && request.status < 300) |
10458 || (request.status === 304) | 10494 || (request.status === 304) |
10459 || (request.status === 0); | 10495 || (request.status === 0); |
10460 }, | 10496 }, |
| 10497 |
10461 load: function(url, next, nextContext) { | 10498 load: function(url, next, nextContext) { |
10462 var request = new XMLHttpRequest(); | 10499 var request = new XMLHttpRequest(); |
10463 if (scope.flags.debug || scope.flags.bust) { | 10500 if (scope.flags.debug || scope.flags.bust) { |
10464 url += '?' + Math.random(); | 10501 url += '?' + Math.random(); |
10465 } | 10502 } |
10466 request.open('GET', url, xhr.async); | 10503 request.open('GET', url, xhr.async); |
10467 request.addEventListener('readystatechange', function(e) { | 10504 request.addEventListener('readystatechange', function(e) { |
10468 if (request.readyState === 4) { | 10505 if (request.readyState === 4) { |
10469 // Servers redirecting an import can add a Location header to help us | 10506 // Servers redirecting an import can add a Location header to help us |
10470 // polyfill correctly. | 10507 // polyfill correctly. |
10471 var locationHeader = request.getResponseHeader("Location"); | 10508 var locationHeader = request.getResponseHeader("Location"); |
10472 var redirectedUrl = null; | 10509 var redirectedUrl = null; |
10473 if (locationHeader) { | 10510 if (locationHeader) { |
10474 var redirectedUrl = (locationHeader.substr( 0, 1 ) === "/") | 10511 var redirectedUrl = (locationHeader.substr( 0, 1 ) === "/") |
10475 ? location.origin + locationHeader // Location is a relative path | 10512 ? location.origin + locationHeader // Location is a relative path |
10476 : locationHeader; // Full path | 10513 : locationHeader; // Full path |
10477 } | 10514 } |
10478 next.call(nextContext, !xhr.ok(request) && request, | 10515 next.call(nextContext, !xhr.ok(request) && request, |
10479 request.response || request.responseText, redirectedUrl); | 10516 request.response || request.responseText, redirectedUrl); |
10480 } | 10517 } |
10481 }); | 10518 }); |
10482 request.send(); | 10519 request.send(); |
10483 return request; | 10520 return request; |
10484 }, | 10521 }, |
| 10522 |
10485 loadDocument: function(url, next, nextContext) { | 10523 loadDocument: function(url, next, nextContext) { |
10486 this.load(url, next, nextContext).responseType = 'document'; | 10524 this.load(url, next, nextContext).responseType = 'document'; |
10487 } | 10525 } |
| 10526 |
10488 }; | 10527 }; |
10489 | 10528 |
10490 // exports | 10529 // exports |
10491 scope.xhr = xhr; | 10530 scope.xhr = xhr; |
10492 scope.Loader = Loader; | 10531 scope.Loader = Loader; |
10493 | 10532 |
10494 })(window.HTMLImports); | 10533 })(window.HTMLImports); |
10495 | 10534 |
10496 /* | 10535 /* |
10497 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. | 10536 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. |
10498 * This code may only be used under the BSD style license found at http://polyme
r.github.io/LICENSE.txt | 10537 * This code may only be used under the BSD style license found at http://polyme
r.github.io/LICENSE.txt |
10499 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.
txt | 10538 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.
txt |
10500 * The complete set of contributors may be found at http://polymer.github.io/CON
TRIBUTORS.txt | 10539 * The complete set of contributors may be found at http://polymer.github.io/CON
TRIBUTORS.txt |
10501 * Code distributed by Google as part of the polymer project is also | 10540 * Code distributed by Google as part of the polymer project is also |
10502 * subject to an additional IP rights grant found at http://polymer.github.io/PA
TENTS.txt | 10541 * subject to an additional IP rights grant found at http://polymer.github.io/PA
TENTS.txt |
10503 */ | 10542 */ |
10504 (function(scope) { | 10543 (function(scope) { |
10505 | 10544 |
10506 var IMPORT_LINK_TYPE = 'import'; | 10545 // imports |
| 10546 var rootDocument = scope.rootDocument; |
10507 var flags = scope.flags; | 10547 var flags = scope.flags; |
10508 var isIE = scope.isIE; | 10548 var isIE = scope.isIE; |
10509 // TODO(sorvell): SD polyfill intrusion | 10549 var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE; |
10510 var mainDoc = window.ShadowDOMPolyfill ? | |
10511 window.ShadowDOMPolyfill.wrapIfNeeded(document) : document; | |
10512 | 10550 |
10513 // importParser | 10551 // importParser |
10514 // highlander object to manage parsing of imports | 10552 // highlander object to manage parsing of imports |
10515 // parses import related elements | 10553 // parses import related elements |
10516 // and ensures proper parse order | 10554 // and ensures proper parse order |
10517 // parse order is enforced by crawling the tree and monitoring which elements | 10555 // parse order is enforced by crawling the tree and monitoring which elements |
10518 // have been parsed; async parsing is also supported. | 10556 // have been parsed; async parsing is also supported. |
10519 | 10557 |
10520 // highlander object for parsing a document tree | 10558 // highlander object for parsing a document tree |
10521 var importParser = { | 10559 var importParser = { |
| 10560 |
10522 // parse selectors for main document elements | 10561 // parse selectors for main document elements |
10523 documentSelectors: 'link[rel=' + IMPORT_LINK_TYPE + ']', | 10562 documentSelectors: 'link[rel=' + IMPORT_LINK_TYPE + ']', |
| 10563 |
10524 // parse selectors for import document elements | 10564 // parse selectors for import document elements |
10525 importsSelectors: [ | 10565 importsSelectors: [ |
10526 'link[rel=' + IMPORT_LINK_TYPE + ']', | 10566 'link[rel=' + IMPORT_LINK_TYPE + ']', |
10527 'link[rel=stylesheet]', | 10567 'link[rel=stylesheet]', |
10528 'style', | 10568 'style', |
10529 'script:not([type])', | 10569 'script:not([type])', |
10530 'script[type="text/javascript"]' | 10570 'script[type="text/javascript"]' |
10531 ].join(','), | 10571 ].join(','), |
| 10572 |
10532 map: { | 10573 map: { |
10533 link: 'parseLink', | 10574 link: 'parseLink', |
10534 script: 'parseScript', | 10575 script: 'parseScript', |
10535 style: 'parseStyle' | 10576 style: 'parseStyle' |
10536 }, | 10577 }, |
| 10578 |
| 10579 dynamicElements: [], |
| 10580 |
10537 // try to parse the next import in the tree | 10581 // try to parse the next import in the tree |
10538 parseNext: function() { | 10582 parseNext: function() { |
10539 var next = this.nextToParse(); | 10583 var next = this.nextToParse(); |
10540 if (next) { | 10584 if (next) { |
10541 this.parse(next); | 10585 this.parse(next); |
10542 } | 10586 } |
10543 }, | 10587 }, |
| 10588 |
10544 parse: function(elt) { | 10589 parse: function(elt) { |
10545 if (this.isParsed(elt)) { | 10590 if (this.isParsed(elt)) { |
10546 flags.parse && console.log('[%s] is already parsed', elt.localName); | 10591 flags.parse && console.log('[%s] is already parsed', elt.localName); |
10547 return; | 10592 return; |
10548 } | 10593 } |
10549 var fn = this[this.map[elt.localName]]; | 10594 var fn = this[this.map[elt.localName]]; |
10550 if (fn) { | 10595 if (fn) { |
10551 this.markParsing(elt); | 10596 this.markParsing(elt); |
10552 fn.call(this, elt); | 10597 fn.call(this, elt); |
10553 } | 10598 } |
10554 }, | 10599 }, |
| 10600 |
| 10601 parseDynamic: function(elt, quiet) { |
| 10602 this.dynamicElements.push(elt); |
| 10603 if (!quiet) { |
| 10604 this.parseNext(); |
| 10605 } |
| 10606 }, |
| 10607 |
10555 // only 1 element may be parsed at a time; parsing is async so each | 10608 // only 1 element may be parsed at a time; parsing is async so each |
10556 // parsing implementation must inform the system that parsing is complete | 10609 // parsing implementation must inform the system that parsing is complete |
10557 // via markParsingComplete. | 10610 // via markParsingComplete. |
10558 // To prompt the system to parse the next element, parseNext should then be | 10611 // To prompt the system to parse the next element, parseNext should then be |
10559 // called. | 10612 // called. |
10560 // Note, parseNext used to be included at the end of markParsingComplete, but | 10613 // Note, parseNext used to be included at the end of markParsingComplete, but |
10561 // we must not do this so that, for example, we can (1) mark parsing complete | 10614 // we must not do this so that, for example, we can (1) mark parsing complete |
10562 // then (2) fire an import load event, and then (3) parse the next resource. | 10615 // then (2) fire an import load event, and then (3) parse the next resource. |
10563 markParsing: function(elt) { | 10616 markParsing: function(elt) { |
10564 flags.parse && console.log('parsing', elt); | 10617 flags.parse && console.log('parsing', elt); |
10565 this.parsingElement = elt; | 10618 this.parsingElement = elt; |
10566 }, | 10619 }, |
| 10620 |
10567 markParsingComplete: function(elt) { | 10621 markParsingComplete: function(elt) { |
10568 elt.__importParsed = true; | 10622 elt.__importParsed = true; |
| 10623 this.markDynamicParsingComplete(elt); |
10569 if (elt.__importElement) { | 10624 if (elt.__importElement) { |
10570 elt.__importElement.__importParsed = true; | 10625 elt.__importElement.__importParsed = true; |
| 10626 this.markDynamicParsingComplete(elt.__importElement); |
10571 } | 10627 } |
10572 this.parsingElement = null; | 10628 this.parsingElement = null; |
10573 flags.parse && console.log('completed', elt); | 10629 flags.parse && console.log('completed', elt); |
10574 }, | 10630 }, |
10575 invalidateParse: function(doc) { | 10631 |
10576 if (doc && doc.__importLink) { | 10632 markDynamicParsingComplete: function(elt) { |
10577 doc.__importParsed = doc.__importLink.__importParsed = false; | 10633 var i = this.dynamicElements.indexOf(elt); |
10578 this.parseSoon(); | 10634 if (i >= 0) { |
| 10635 this.dynamicElements.splice(i, 1); |
10579 } | 10636 } |
10580 }, | 10637 }, |
10581 parseSoon: function() { | 10638 |
10582 if (this._parseSoon) { | |
10583 cancelAnimationFrame(this._parseDelay); | |
10584 } | |
10585 var parser = this; | |
10586 this._parseSoon = requestAnimationFrame(function() { | |
10587 parser.parseNext(); | |
10588 }); | |
10589 }, | |
10590 parseImport: function(elt) { | 10639 parseImport: function(elt) { |
10591 // TODO(sorvell): consider if there's a better way to do this; | 10640 // TODO(sorvell): consider if there's a better way to do this; |
10592 // expose an imports parsing hook; this is needed, for example, by the | 10641 // expose an imports parsing hook; this is needed, for example, by the |
10593 // CustomElements polyfill. | 10642 // CustomElements polyfill. |
10594 if (HTMLImports.__importsParsingHook) { | 10643 if (HTMLImports.__importsParsingHook) { |
10595 HTMLImports.__importsParsingHook(elt); | 10644 HTMLImports.__importsParsingHook(elt); |
10596 } | 10645 } |
10597 if (elt.import) { | 10646 if (elt.import) { |
10598 elt.import.__importParsed = true; | 10647 elt.import.__importParsed = true; |
10599 } | 10648 } |
(...skipping 10 matching lines...) Expand all Loading... |
10610 var fn; | 10659 var fn; |
10611 while (elt.__pending.length) { | 10660 while (elt.__pending.length) { |
10612 fn = elt.__pending.shift(); | 10661 fn = elt.__pending.shift(); |
10613 if (fn) { | 10662 if (fn) { |
10614 fn({target: elt}); | 10663 fn({target: elt}); |
10615 } | 10664 } |
10616 } | 10665 } |
10617 } | 10666 } |
10618 this.parseNext(); | 10667 this.parseNext(); |
10619 }, | 10668 }, |
| 10669 |
10620 parseLink: function(linkElt) { | 10670 parseLink: function(linkElt) { |
10621 if (nodeIsImport(linkElt)) { | 10671 if (nodeIsImport(linkElt)) { |
10622 this.parseImport(linkElt); | 10672 this.parseImport(linkElt); |
10623 } else { | 10673 } else { |
10624 // make href absolute | 10674 // make href absolute |
10625 linkElt.href = linkElt.href; | 10675 linkElt.href = linkElt.href; |
10626 this.parseGeneric(linkElt); | 10676 this.parseGeneric(linkElt); |
10627 } | 10677 } |
10628 }, | 10678 }, |
| 10679 |
10629 parseStyle: function(elt) { | 10680 parseStyle: function(elt) { |
10630 // TODO(sorvell): style element load event can just not fire so clone styles | 10681 // TODO(sorvell): style element load event can just not fire so clone styles |
10631 var src = elt; | 10682 var src = elt; |
10632 elt = cloneStyle(elt); | 10683 elt = cloneStyle(elt); |
10633 elt.__importElement = src; | 10684 elt.__importElement = src; |
10634 this.parseGeneric(elt); | 10685 this.parseGeneric(elt); |
10635 }, | 10686 }, |
| 10687 |
10636 parseGeneric: function(elt) { | 10688 parseGeneric: function(elt) { |
10637 this.trackElement(elt); | 10689 this.trackElement(elt); |
10638 this.addElementToDocument(elt); | 10690 this.addElementToDocument(elt); |
10639 }, | 10691 }, |
| 10692 |
10640 rootImportForElement: function(elt) { | 10693 rootImportForElement: function(elt) { |
10641 var n = elt; | 10694 var n = elt; |
10642 while (n.ownerDocument.__importLink) { | 10695 while (n.ownerDocument.__importLink) { |
10643 n = n.ownerDocument.__importLink; | 10696 n = n.ownerDocument.__importLink; |
10644 } | 10697 } |
10645 return n; | 10698 return n; |
10646 }, | 10699 }, |
| 10700 |
10647 addElementToDocument: function(elt) { | 10701 addElementToDocument: function(elt) { |
10648 var port = this.rootImportForElement(elt.__importElement || elt); | 10702 var port = this.rootImportForElement(elt.__importElement || elt); |
10649 var l = port.__insertedElements = port.__insertedElements || 0; | 10703 var l = port.__insertedElements = port.__insertedElements || 0; |
10650 var refNode = port.nextElementSibling; | 10704 var refNode = port.nextElementSibling; |
10651 for (var i=0; i < l; i++) { | 10705 for (var i=0; i < l; i++) { |
10652 refNode = refNode && refNode.nextElementSibling; | 10706 refNode = refNode && refNode.nextElementSibling; |
10653 } | 10707 } |
10654 port.parentNode.insertBefore(elt, refNode); | 10708 port.parentNode.insertBefore(elt, refNode); |
10655 }, | 10709 }, |
| 10710 |
10656 // tracks when a loadable element has loaded | 10711 // tracks when a loadable element has loaded |
10657 trackElement: function(elt, callback) { | 10712 trackElement: function(elt, callback) { |
10658 var self = this; | 10713 var self = this; |
10659 var done = function(e) { | 10714 var done = function(e) { |
10660 if (callback) { | 10715 if (callback) { |
10661 callback(e); | 10716 callback(e); |
10662 } | 10717 } |
10663 self.markParsingComplete(elt); | 10718 self.markParsingComplete(elt); |
10664 self.parseNext(); | 10719 self.parseNext(); |
10665 }; | 10720 }; |
(...skipping 19 matching lines...) Expand all Loading... |
10685 fakeLoad = fakeLoad && Boolean(r.styleSheet); | 10740 fakeLoad = fakeLoad && Boolean(r.styleSheet); |
10686 } | 10741 } |
10687 } | 10742 } |
10688 } | 10743 } |
10689 // dispatch a fake load event and continue parsing | 10744 // dispatch a fake load event and continue parsing |
10690 if (fakeLoad) { | 10745 if (fakeLoad) { |
10691 elt.dispatchEvent(new CustomEvent('load', {bubbles: false})); | 10746 elt.dispatchEvent(new CustomEvent('load', {bubbles: false})); |
10692 } | 10747 } |
10693 } | 10748 } |
10694 }, | 10749 }, |
| 10750 |
10695 // NOTE: execute scripts by injecting them and watching for the load/error | 10751 // NOTE: execute scripts by injecting them and watching for the load/error |
10696 // event. Inline scripts are handled via dataURL's because browsers tend to | 10752 // event. Inline scripts are handled via dataURL's because browsers tend to |
10697 // provide correct parsing errors in this case. If this has any compatibility | 10753 // provide correct parsing errors in this case. If this has any compatibility |
10698 // issues, we can switch to injecting the inline script with textContent. | 10754 // issues, we can switch to injecting the inline script with textContent. |
10699 // Scripts with dataURL's do not appear to generate load events and therefore | 10755 // Scripts with dataURL's do not appear to generate load events and therefore |
10700 // we assume they execute synchronously. | 10756 // we assume they execute synchronously. |
10701 parseScript: function(scriptElt) { | 10757 parseScript: function(scriptElt) { |
10702 var script = document.createElement('script'); | 10758 var script = document.createElement('script'); |
10703 script.__importElement = scriptElt; | 10759 script.__importElement = scriptElt; |
10704 script.src = scriptElt.src ? scriptElt.src : | 10760 script.src = scriptElt.src ? scriptElt.src : |
10705 generateScriptDataUrl(scriptElt); | 10761 generateScriptDataUrl(scriptElt); |
10706 scope.currentScript = scriptElt; | 10762 scope.currentScript = scriptElt; |
10707 this.trackElement(script, function(e) { | 10763 this.trackElement(script, function(e) { |
10708 script.parentNode.removeChild(script); | 10764 script.parentNode.removeChild(script); |
10709 scope.currentScript = null; | 10765 scope.currentScript = null; |
10710 }); | 10766 }); |
10711 this.addElementToDocument(script); | 10767 this.addElementToDocument(script); |
10712 }, | 10768 }, |
| 10769 |
10713 // determine the next element in the tree which should be parsed | 10770 // determine the next element in the tree which should be parsed |
10714 nextToParse: function() { | 10771 nextToParse: function() { |
10715 this._mayParse = []; | 10772 this._mayParse = []; |
10716 return !this.parsingElement && this.nextToParseInDoc(mainDoc); | 10773 return !this.parsingElement && (this.nextToParseInDoc(rootDocument) || |
| 10774 this.nextToParseDynamic()); |
10717 }, | 10775 }, |
| 10776 |
10718 nextToParseInDoc: function(doc, link) { | 10777 nextToParseInDoc: function(doc, link) { |
10719 // use `marParse` list to avoid looping into the same document again | 10778 // use `marParse` list to avoid looping into the same document again |
10720 // since it could cause an iloop. | 10779 // since it could cause an iloop. |
10721 if (doc && this._mayParse.indexOf(doc) < 0) { | 10780 if (doc && this._mayParse.indexOf(doc) < 0) { |
10722 this._mayParse.push(doc); | 10781 this._mayParse.push(doc); |
10723 var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc)); | 10782 var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc)); |
10724 for (var i=0, l=nodes.length, p=0, n; (i<l) && (n=nodes[i]); i++) { | 10783 for (var i=0, l=nodes.length, p=0, n; (i<l) && (n=nodes[i]); i++) { |
10725 if (!this.isParsed(n)) { | 10784 if (!this.isParsed(n)) { |
10726 if (this.hasResource(n)) { | 10785 if (this.hasResource(n)) { |
10727 return nodeIsImport(n) ? this.nextToParseInDoc(n.import, n) : n; | 10786 return nodeIsImport(n) ? this.nextToParseInDoc(n.import, n) : n; |
10728 } else { | 10787 } else { |
10729 return; | 10788 return; |
10730 } | 10789 } |
10731 } | 10790 } |
10732 } | 10791 } |
10733 } | 10792 } |
10734 // all nodes have been parsed, ready to parse import, if any | 10793 // all nodes have been parsed, ready to parse import, if any |
10735 return link; | 10794 return link; |
10736 }, | 10795 }, |
| 10796 |
| 10797 nextToParseDynamic: function() { |
| 10798 return this.dynamicElements[0]; |
| 10799 }, |
| 10800 |
10737 // return the set of parse selectors relevant for this node. | 10801 // return the set of parse selectors relevant for this node. |
10738 parseSelectorsForNode: function(node) { | 10802 parseSelectorsForNode: function(node) { |
10739 var doc = node.ownerDocument || node; | 10803 var doc = node.ownerDocument || node; |
10740 return doc === mainDoc ? this.documentSelectors : this.importsSelectors; | 10804 return doc === rootDocument ? this.documentSelectors : |
| 10805 this.importsSelectors; |
10741 }, | 10806 }, |
| 10807 |
10742 isParsed: function(node) { | 10808 isParsed: function(node) { |
10743 return node.__importParsed; | 10809 return node.__importParsed; |
10744 }, | 10810 }, |
| 10811 |
| 10812 needsDynamicParsing: function(elt) { |
| 10813 return (this.dynamicElements.indexOf(elt) >= 0); |
| 10814 }, |
| 10815 |
10745 hasResource: function(node) { | 10816 hasResource: function(node) { |
10746 if (nodeIsImport(node) && (node.import === undefined)) { | 10817 if (nodeIsImport(node) && (node.import === undefined)) { |
10747 return false; | 10818 return false; |
10748 } | 10819 } |
10749 return true; | 10820 return true; |
10750 } | 10821 } |
| 10822 |
10751 }; | 10823 }; |
10752 | 10824 |
10753 function nodeIsImport(elt) { | 10825 function nodeIsImport(elt) { |
10754 return (elt.localName === 'link') && (elt.rel === IMPORT_LINK_TYPE); | 10826 return (elt.localName === 'link') && (elt.rel === IMPORT_LINK_TYPE); |
10755 } | 10827 } |
10756 | 10828 |
10757 function generateScriptDataUrl(script) { | 10829 function generateScriptDataUrl(script) { |
10758 var scriptContent = generateScriptContent(script); | 10830 var scriptContent = generateScriptContent(script); |
10759 return 'data:text/javascript;charset=utf-8,' + encodeURIComponent(scriptConten
t); | 10831 return 'data:text/javascript;charset=utf-8,' + encodeURIComponent(scriptConten
t); |
10760 } | 10832 } |
(...skipping 29 matching lines...) Expand all Loading... |
10790 path.resolveUrlsInStyle(clone); | 10862 path.resolveUrlsInStyle(clone); |
10791 return clone; | 10863 return clone; |
10792 } | 10864 } |
10793 | 10865 |
10794 // path fixup: style elements in imports must be made relative to the main | 10866 // path fixup: style elements in imports must be made relative to the main |
10795 // document. We fixup url's in url() and @import. | 10867 // document. We fixup url's in url() and @import. |
10796 var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g; | 10868 var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g; |
10797 var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g; | 10869 var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g; |
10798 | 10870 |
10799 var path = { | 10871 var path = { |
| 10872 |
10800 resolveUrlsInStyle: function(style) { | 10873 resolveUrlsInStyle: function(style) { |
10801 var doc = style.ownerDocument; | 10874 var doc = style.ownerDocument; |
10802 var resolver = doc.createElement('a'); | 10875 var resolver = doc.createElement('a'); |
10803 style.textContent = this.resolveUrlsInCssText(style.textContent, resolver); | 10876 style.textContent = this.resolveUrlsInCssText(style.textContent, resolver); |
10804 return style; | 10877 return style; |
10805 }, | 10878 }, |
| 10879 |
10806 resolveUrlsInCssText: function(cssText, urlObj) { | 10880 resolveUrlsInCssText: function(cssText, urlObj) { |
10807 var r = this.replaceUrls(cssText, urlObj, CSS_URL_REGEXP); | 10881 var r = this.replaceUrls(cssText, urlObj, CSS_URL_REGEXP); |
10808 r = this.replaceUrls(r, urlObj, CSS_IMPORT_REGEXP); | 10882 r = this.replaceUrls(r, urlObj, CSS_IMPORT_REGEXP); |
10809 return r; | 10883 return r; |
10810 }, | 10884 }, |
| 10885 |
10811 replaceUrls: function(text, urlObj, regexp) { | 10886 replaceUrls: function(text, urlObj, regexp) { |
10812 return text.replace(regexp, function(m, pre, url, post) { | 10887 return text.replace(regexp, function(m, pre, url, post) { |
10813 var urlPath = url.replace(/["']/g, ''); | 10888 var urlPath = url.replace(/["']/g, ''); |
10814 urlObj.href = urlPath; | 10889 urlObj.href = urlPath; |
10815 urlPath = urlObj.href; | 10890 urlPath = urlObj.href; |
10816 return pre + '\'' + urlPath + '\'' + post; | 10891 return pre + '\'' + urlPath + '\'' + post; |
10817 }); | 10892 }); |
10818 } | 10893 } |
10819 } | 10894 |
| 10895 }; |
10820 | 10896 |
10821 // exports | 10897 // exports |
10822 scope.parser = importParser; | 10898 scope.parser = importParser; |
10823 scope.path = path; | 10899 scope.path = path; |
10824 | 10900 |
10825 })(HTMLImports); | 10901 })(HTMLImports); |
10826 | 10902 |
10827 /* | 10903 /* |
10828 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. | 10904 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. |
10829 * This code may only be used under the BSD style license found at http://polyme
r.github.io/LICENSE.txt | 10905 * This code may only be used under the BSD style license found at http://polyme
r.github.io/LICENSE.txt |
10830 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.
txt | 10906 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.
txt |
10831 * The complete set of contributors may be found at http://polymer.github.io/CON
TRIBUTORS.txt | 10907 * The complete set of contributors may be found at http://polymer.github.io/CON
TRIBUTORS.txt |
10832 * Code distributed by Google as part of the polymer project is also | 10908 * Code distributed by Google as part of the polymer project is also |
10833 * subject to an additional IP rights grant found at http://polymer.github.io/PA
TENTS.txt | 10909 * subject to an additional IP rights grant found at http://polymer.github.io/PA
TENTS.txt |
10834 */ | 10910 */ |
10835 (function(scope) { | 10911 (function(scope) { |
10836 | 10912 |
| 10913 // imports |
10837 var useNative = scope.useNative; | 10914 var useNative = scope.useNative; |
10838 var flags = scope.flags; | 10915 var flags = scope.flags; |
10839 var IMPORT_LINK_TYPE = 'import'; | 10916 var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE; |
10840 | |
10841 // TODO(sorvell): SD polyfill intrusion | |
10842 var mainDoc = window.ShadowDOMPolyfill ? | |
10843 ShadowDOMPolyfill.wrapIfNeeded(document) : document; | |
10844 | 10917 |
10845 if (!useNative) { | 10918 if (!useNative) { |
10846 | 10919 |
10847 // imports | 10920 // imports |
| 10921 var rootDocument = scope.rootDocument; |
10848 var xhr = scope.xhr; | 10922 var xhr = scope.xhr; |
10849 var Loader = scope.Loader; | 10923 var Loader = scope.Loader; |
10850 var parser = scope.parser; | 10924 var parser = scope.parser; |
10851 | 10925 |
10852 // importer | 10926 // importer |
10853 // highlander object to manage loading of imports | 10927 // highlander object to manage loading of imports |
10854 | 10928 |
10855 // for any document, importer: | 10929 // for any document, importer: |
10856 // - loads any linked import documents (with deduping) | 10930 // - loads any linked import documents (with deduping) |
10857 | 10931 |
10858 var importer = { | 10932 var importer = { |
| 10933 |
10859 documents: {}, | 10934 documents: {}, |
| 10935 |
10860 // nodes to load in the mian document | 10936 // nodes to load in the mian document |
10861 documentPreloadSelectors: 'link[rel=' + IMPORT_LINK_TYPE + ']', | 10937 documentPreloadSelectors: 'link[rel=' + IMPORT_LINK_TYPE + ']', |
| 10938 |
10862 // nodes to load in imports | 10939 // nodes to load in imports |
10863 importsPreloadSelectors: [ | 10940 importsPreloadSelectors: [ |
10864 'link[rel=' + IMPORT_LINK_TYPE + ']' | 10941 'link[rel=' + IMPORT_LINK_TYPE + ']' |
10865 ].join(','), | 10942 ].join(','), |
| 10943 |
10866 loadNode: function(node) { | 10944 loadNode: function(node) { |
10867 importLoader.addNode(node); | 10945 importLoader.addNode(node); |
10868 }, | 10946 }, |
| 10947 |
10869 // load all loadable elements within the parent element | 10948 // load all loadable elements within the parent element |
10870 loadSubtree: function(parent) { | 10949 loadSubtree: function(parent) { |
10871 var nodes = this.marshalNodes(parent); | 10950 var nodes = this.marshalNodes(parent); |
10872 // add these nodes to loader's queue | 10951 // add these nodes to loader's queue |
10873 importLoader.addNodes(nodes); | 10952 importLoader.addNodes(nodes); |
10874 }, | 10953 }, |
| 10954 |
10875 marshalNodes: function(parent) { | 10955 marshalNodes: function(parent) { |
10876 // all preloadable nodes in inDocument | 10956 // all preloadable nodes in inDocument |
10877 return parent.querySelectorAll(this.loadSelectorsForNode(parent)); | 10957 return parent.querySelectorAll(this.loadSelectorsForNode(parent)); |
10878 }, | 10958 }, |
| 10959 |
10879 // find the proper set of load selectors for a given node | 10960 // find the proper set of load selectors for a given node |
10880 loadSelectorsForNode: function(node) { | 10961 loadSelectorsForNode: function(node) { |
10881 var doc = node.ownerDocument || node; | 10962 var doc = node.ownerDocument || node; |
10882 return doc === mainDoc ? this.documentPreloadSelectors : | 10963 return doc === rootDocument ? this.documentPreloadSelectors : |
10883 this.importsPreloadSelectors; | 10964 this.importsPreloadSelectors; |
10884 }, | 10965 }, |
| 10966 |
10885 loaded: function(url, elt, resource, err, redirectedUrl) { | 10967 loaded: function(url, elt, resource, err, redirectedUrl) { |
10886 flags.load && console.log('loaded', url, elt); | 10968 flags.load && console.log('loaded', url, elt); |
10887 // store generic resource | 10969 // store generic resource |
10888 // TODO(sorvell): fails for nodes inside <template>.content | 10970 // TODO(sorvell): fails for nodes inside <template>.content |
10889 // see https://code.google.com/p/chromium/issues/detail?id=249381. | 10971 // see https://code.google.com/p/chromium/issues/detail?id=249381. |
10890 elt.__resource = resource; | 10972 elt.__resource = resource; |
10891 elt.__error = err; | 10973 elt.__error = err; |
10892 if (isDocumentLink(elt)) { | 10974 if (isDocumentLink(elt)) { |
10893 var doc = this.documents[url]; | 10975 var doc = this.documents[url]; |
10894 // if we've never seen a document at this url | 10976 // if we've never seen a document at this url |
10895 if (doc === undefined) { | 10977 if (doc === undefined) { |
10896 // generate an HTMLDocument from data | 10978 // generate an HTMLDocument from data |
10897 doc = err ? null : makeDocument(resource, redirectedUrl || url); | 10979 doc = err ? null : makeDocument(resource, redirectedUrl || url); |
10898 if (doc) { | 10980 if (doc) { |
10899 doc.__importLink = elt; | 10981 doc.__importLink = elt; |
10900 // note, we cannot use MO to detect parsed nodes because | 10982 // note, we cannot use MO to detect parsed nodes because |
10901 // SD polyfill does not report these as mutations. | 10983 // SD polyfill does not report these as mutations. |
10902 this.bootDocument(doc); | 10984 this.bootDocument(doc); |
10903 } | 10985 } |
10904 // cache document | 10986 // cache document |
10905 this.documents[url] = doc; | 10987 this.documents[url] = doc; |
10906 } | 10988 } |
10907 // don't store import record until we're actually loaded | 10989 // don't store import record until we're actually loaded |
10908 // store document resource | 10990 // store document resource |
10909 elt.import = doc; | 10991 elt.import = doc; |
10910 } | 10992 } |
10911 parser.parseNext(); | 10993 parser.parseNext(); |
10912 }, | 10994 }, |
| 10995 |
10913 bootDocument: function(doc) { | 10996 bootDocument: function(doc) { |
10914 this.loadSubtree(doc); | 10997 this.loadSubtree(doc); |
10915 this.observe(doc); | 10998 this.observe(doc); |
10916 parser.parseNext(); | 10999 parser.parseNext(); |
10917 }, | 11000 }, |
| 11001 |
10918 loadedAll: function() { | 11002 loadedAll: function() { |
10919 parser.parseNext(); | 11003 parser.parseNext(); |
10920 } | 11004 } |
| 11005 |
10921 }; | 11006 }; |
10922 | 11007 |
10923 // loader singleton | 11008 // loader singleton |
10924 var importLoader = new Loader(importer.loaded.bind(importer), | 11009 var importLoader = new Loader(importer.loaded.bind(importer), |
10925 importer.loadedAll.bind(importer)); | 11010 importer.loadedAll.bind(importer)); |
10926 | 11011 |
10927 function isDocumentLink(elt) { | 11012 function isDocumentLink(elt) { |
10928 return isLinkRel(elt, IMPORT_LINK_TYPE); | 11013 return isLinkRel(elt, IMPORT_LINK_TYPE); |
10929 } | 11014 } |
10930 | 11015 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10978 if (!document.baseURI) { | 11063 if (!document.baseURI) { |
10979 var baseURIDescriptor = { | 11064 var baseURIDescriptor = { |
10980 get: function() { | 11065 get: function() { |
10981 var base = document.querySelector('base'); | 11066 var base = document.querySelector('base'); |
10982 return base ? base.href : window.location.href; | 11067 return base ? base.href : window.location.href; |
10983 }, | 11068 }, |
10984 configurable: true | 11069 configurable: true |
10985 }; | 11070 }; |
10986 | 11071 |
10987 Object.defineProperty(document, 'baseURI', baseURIDescriptor); | 11072 Object.defineProperty(document, 'baseURI', baseURIDescriptor); |
10988 Object.defineProperty(mainDoc, 'baseURI', baseURIDescriptor); | 11073 Object.defineProperty(rootDocument, 'baseURI', baseURIDescriptor); |
10989 } | 11074 } |
10990 | 11075 |
10991 // IE shim for CustomEvent | 11076 // IE shim for CustomEvent |
10992 if (typeof window.CustomEvent !== 'function') { | 11077 if (typeof window.CustomEvent !== 'function') { |
10993 window.CustomEvent = function(inType, dictionary) { | 11078 window.CustomEvent = function(inType, dictionary) { |
10994 var e = document.createEvent('HTMLEvents'); | 11079 var e = document.createEvent('HTMLEvents'); |
10995 e.initEvent(inType, | 11080 e.initEvent(inType, |
10996 dictionary.bubbles === false ? false : true, | 11081 dictionary.bubbles === false ? false : true, |
10997 dictionary.cancelable === false ? false : true, | 11082 dictionary.cancelable === false ? false : true, |
10998 dictionary.detail); | 11083 dictionary.detail); |
10999 return e; | 11084 return e; |
11000 }; | 11085 }; |
11001 } | 11086 } |
11002 | 11087 |
11003 } else { | 11088 } else { |
11004 // do nothing if using native imports | 11089 // do nothing if using native imports |
11005 var importer = {}; | 11090 var importer = {}; |
11006 } | 11091 } |
11007 | 11092 |
11008 // exports | 11093 // exports |
11009 scope.importer = importer; | 11094 scope.importer = importer; |
11010 scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE; | 11095 scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE; |
11011 scope.importLoader = importLoader; | 11096 scope.importLoader = importLoader; |
11012 | 11097 |
11013 | |
11014 })(window.HTMLImports); | 11098 })(window.HTMLImports); |
11015 | 11099 |
11016 /* | 11100 /* |
11017 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. | 11101 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. |
11018 * This code may only be used under the BSD style license found at http://polyme
r.github.io/LICENSE.txt | 11102 * This code may only be used under the BSD style license found at http://polyme
r.github.io/LICENSE.txt |
11019 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.
txt | 11103 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.
txt |
11020 * The complete set of contributors may be found at http://polymer.github.io/CON
TRIBUTORS.txt | 11104 * The complete set of contributors may be found at http://polymer.github.io/CON
TRIBUTORS.txt |
11021 * Code distributed by Google as part of the polymer project is also | 11105 * Code distributed by Google as part of the polymer project is also |
11022 * subject to an additional IP rights grant found at http://polymer.github.io/PA
TENTS.txt | 11106 * subject to an additional IP rights grant found at http://polymer.github.io/PA
TENTS.txt |
11023 */ | 11107 */ |
11024 (function(scope){ | 11108 (function(scope){ |
11025 | 11109 |
| 11110 // imports |
11026 var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE; | 11111 var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE; |
11027 var importSelector = 'link[rel=' + IMPORT_LINK_TYPE + ']'; | |
11028 var importer = scope.importer; | 11112 var importer = scope.importer; |
11029 var parser = scope.parser; | 11113 var parser = scope.parser; |
11030 | 11114 |
| 11115 var importSelector = 'link[rel=' + IMPORT_LINK_TYPE + ']'; |
| 11116 |
| 11117 |
11031 // we track mutations for addedNodes, looking for imports | 11118 // we track mutations for addedNodes, looking for imports |
11032 function handler(mutations) { | 11119 function handler(mutations) { |
11033 for (var i=0, l=mutations.length, m; (i<l) && (m=mutations[i]); i++) { | 11120 for (var i=0, l=mutations.length, m; (i<l) && (m=mutations[i]); i++) { |
11034 if (m.type === 'childList' && m.addedNodes.length) { | 11121 if (m.type === 'childList' && m.addedNodes.length) { |
11035 addedNodes(m.addedNodes); | 11122 addedNodes(m.addedNodes); |
11036 } | 11123 } |
11037 } | 11124 } |
11038 } | 11125 } |
11039 | 11126 |
11040 // find loadable elements and add them to the importer | 11127 // find loadable elements and add them to the importer |
| 11128 // IFF the owning document has already parsed, then parsable elements |
| 11129 // need to be marked for dynamic parsing. |
11041 function addedNodes(nodes) { | 11130 function addedNodes(nodes) { |
11042 var owner; | 11131 var owner, parsed; |
11043 for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) { | 11132 for (var i=0, l=nodes.length, n, loading; (i<l) && (n=nodes[i]); i++) { |
11044 owner = owner || n.ownerDocument; | 11133 if (!owner) { |
11045 if (shouldLoadNode(n)) { | 11134 owner = n.ownerDocument; |
| 11135 parsed = parser.isParsed(owner); |
| 11136 } |
| 11137 // note: the act of loading kicks the parser, so we use parseDynamic's |
| 11138 // 2nd argument to control if this added node needs to kick the parser. |
| 11139 loading = shouldLoadNode(n); |
| 11140 if (loading) { |
11046 importer.loadNode(n); | 11141 importer.loadNode(n); |
11047 } | 11142 } |
| 11143 if (shouldParseNode(n) && parsed) { |
| 11144 parser.parseDynamic(n, loading); |
| 11145 } |
11048 if (n.children && n.children.length) { | 11146 if (n.children && n.children.length) { |
11049 addedNodes(n.children); | 11147 addedNodes(n.children); |
11050 } | 11148 } |
11051 } | 11149 } |
11052 // TODO(sorvell): This is not the right approach here. We shouldn't need to | |
11053 // invalidate parsing when an element is added. Disabling this code | |
11054 // until a better approach is found. | |
11055 /* | |
11056 if (owner) { | |
11057 parser.invalidateParse(owner); | |
11058 } | |
11059 */ | |
11060 } | 11150 } |
11061 | 11151 |
11062 function shouldLoadNode(node) { | 11152 function shouldLoadNode(node) { |
11063 return (node.nodeType === 1) && matches.call(node, | 11153 return (node.nodeType === 1) && matches.call(node, |
11064 importer.loadSelectorsForNode(node)); | 11154 importer.loadSelectorsForNode(node)); |
11065 } | 11155 } |
11066 | 11156 |
| 11157 function shouldParseNode(node) { |
| 11158 return (node.nodeType === 1) && matches.call(node, |
| 11159 parser.parseSelectorsForNode(node)); |
| 11160 } |
| 11161 |
11067 // x-plat matches | 11162 // x-plat matches |
11068 var matches = HTMLElement.prototype.matches || | 11163 var matches = HTMLElement.prototype.matches || |
11069 HTMLElement.prototype.matchesSelector || | 11164 HTMLElement.prototype.matchesSelector || |
11070 HTMLElement.prototype.webkitMatchesSelector || | 11165 HTMLElement.prototype.webkitMatchesSelector || |
11071 HTMLElement.prototype.mozMatchesSelector || | 11166 HTMLElement.prototype.mozMatchesSelector || |
11072 HTMLElement.prototype.msMatchesSelector; | 11167 HTMLElement.prototype.msMatchesSelector; |
11073 | 11168 |
11074 var observer = new MutationObserver(handler); | 11169 var observer = new MutationObserver(handler); |
11075 | 11170 |
11076 // observe the given root for loadable elements | 11171 // observe the given root for loadable elements |
(...skipping 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12345 // exports | 12440 // exports |
12346 | 12441 |
12347 scope.marshal = marshal; | 12442 scope.marshal = marshal; |
12348 // `module` confuses commonjs detectors | 12443 // `module` confuses commonjs detectors |
12349 scope.modularize = module; | 12444 scope.modularize = module; |
12350 scope.using = using; | 12445 scope.using = using; |
12351 | 12446 |
12352 })(window); | 12447 })(window); |
12353 | 12448 |
12354 //# sourceMappingURL=platform.concat.js.map | 12449 //# sourceMappingURL=platform.concat.js.map |
OLD | NEW |