1- var ANode = require ( './a-node' ) ;
1+ /* global customElements */
2+ var ANode = require ( './a-node' ) . ANode ;
23var bind = require ( '../utils/bind' ) ;
34var debug = require ( '../utils/debug' ) ;
4- var registerElement = require ( './a-register-element' ) . registerElement ;
55var THREE = require ( '../lib/three' ) ;
66
77var fileLoader = new THREE . FileLoader ( ) ;
@@ -10,126 +10,129 @@ var warn = debug('core:a-assets:warn');
1010/**
1111 * Asset management system. Handles blocking on asset loading.
1212 */
13- module . exports = registerElement ( 'a-assets' , {
14- prototype : Object . create ( ANode . prototype , {
15- createdCallback : {
16- value : function ( ) {
17- this . isAssets = true ;
18- this . fileLoader = fileLoader ;
19- this . timeout = null ;
20- }
21- } ,
22-
23- attachedCallback : {
24- value : function ( ) {
25- var self = this ;
26- var i ;
27- var loaded = [ ] ;
28- var mediaEl ;
29- var mediaEls ;
30- var imgEl ;
31- var imgEls ;
32- var timeout ;
33-
34- if ( ! this . parentNode . isScene ) {
35- throw new Error ( '<a-assets> must be a child of a <a-scene>.' ) ;
36- }
13+ class AAssets extends ANode {
14+ constructor ( ) {
15+ super ( ) ;
16+ this . isAssets = true ;
17+ this . fileLoader = fileLoader ;
18+ this . timeout = null ;
19+ }
3720
38- // Wait for <img>s.
39- imgEls = this . querySelectorAll ( 'img' ) ;
40- for ( i = 0 ; i < imgEls . length ; i ++ ) {
41- imgEl = fixUpMediaElement ( imgEls [ i ] ) ;
42- loaded . push ( new Promise ( function ( resolve , reject ) {
43- // Set in cache because we won't be needing to call three.js loader if we have.
44- // a loaded media element.
45- THREE . Cache . add ( imgEls [ i ] . getAttribute ( 'src' ) , imgEl ) ;
46- imgEl . onload = resolve ;
47- imgEl . onerror = reject ;
48- } ) ) ;
49- }
21+ connectedCallback ( ) {
22+ // Defer if DOM is not ready.
23+ if ( document . readyState === 'loading' ) {
24+ document . addEventListener ( 'DOMContentLoaded' , this . connectedCallback . bind ( this ) ) ;
25+ return ;
26+ }
5027
51- // Wait for <audio>s and <video>s.
52- mediaEls = this . querySelectorAll ( 'audio, video' ) ;
53- for ( i = 0 ; i < mediaEls . length ; i ++ ) {
54- mediaEl = fixUpMediaElement ( mediaEls [ i ] ) ;
55- if ( ! mediaEl . src && ! mediaEl . srcObject ) {
56- warn ( 'Audio/video asset has neither `src` nor `srcObject` attributes.' ) ;
57- }
58- loaded . push ( mediaElementLoaded ( mediaEl ) ) ;
59- }
28+ this . doConnectedCallback ( ) ;
29+ }
6030
61- // Trigger loaded for scene to start rendering.
62- Promise . allSettled ( loaded ) . then ( bind ( this . load , this ) ) ;
63-
64- // Timeout to start loading anyways.
65- timeout = parseInt ( this . getAttribute ( 'timeout' ) , 10 ) || 3000 ;
66- this . timeout = setTimeout ( function ( ) {
67- if ( self . hasLoaded ) { return ; }
68- warn ( 'Asset loading timed out in ' , timeout , 'ms' ) ;
69- self . emit ( 'timeout' ) ;
70- self . load ( ) ;
71- } , timeout ) ;
72- }
73- } ,
31+ doConnectedCallback ( ) {
32+ var self = this ;
33+ var i ;
34+ var loaded = [ ] ;
35+ var mediaEl ;
36+ var mediaEls ;
37+ var imgEl ;
38+ var imgEls ;
39+ var timeout ;
7440
75- detachedCallback : {
76- value : function ( ) {
77- if ( this . timeout ) { clearTimeout ( this . timeout ) ; }
78- }
79- } ,
41+ super . connectedCallback ( ) ;
42+
43+ if ( ! this . parentNode . isScene ) {
44+ throw new Error ( '<a-assets> must be a child of a <a-scene>.' ) ;
45+ }
46+
47+ // Wait for <img>s.
48+ imgEls = this . querySelectorAll ( 'img' ) ;
49+ for ( i = 0 ; i < imgEls . length ; i ++ ) {
50+ imgEl = fixUpMediaElement ( imgEls [ i ] ) ;
51+ loaded . push ( new Promise ( function ( resolve , reject ) {
52+ // Set in cache because we won't be needing to call three.js loader if we have.
53+ // a loaded media element.
54+ THREE . Cache . add ( imgEls [ i ] . getAttribute ( 'src' ) , imgEl ) ;
55+ imgEl . onload = resolve ;
56+ imgEl . onerror = reject ;
57+ } ) ) ;
58+ }
8059
81- load : {
82- value : function ( ) {
83- ANode . prototype . load . call ( this , null , function waitOnFilter ( el ) {
84- return el . isAssetItem && el . hasAttribute ( 'src' ) ;
85- } ) ;
60+ // Wait for <audio>s and <video>s.
61+ mediaEls = this . querySelectorAll ( 'audio, video' ) ;
62+ for ( i = 0 ; i < mediaEls . length ; i ++ ) {
63+ mediaEl = fixUpMediaElement ( mediaEls [ i ] ) ;
64+ if ( ! mediaEl . src && ! mediaEl . srcObject ) {
65+ warn ( 'Audio/video asset has neither `src` nor `srcObject` attributes.' ) ;
8666 }
67+ loaded . push ( mediaElementLoaded ( mediaEl ) ) ;
8768 }
88- } )
89- } ) ;
69+
70+ // Trigger loaded for scene to start rendering.
71+ Promise . allSettled ( loaded ) . then ( bind ( this . load , this ) ) ;
72+
73+ // Timeout to start loading anyways.
74+ timeout = parseInt ( this . getAttribute ( 'timeout' ) , 10 ) || 3000 ;
75+ this . timeout = setTimeout ( function ( ) {
76+ if ( self . hasLoaded ) { return ; }
77+ warn ( 'Asset loading timed out in ' , timeout , 'ms' ) ;
78+ self . emit ( 'timeout' ) ;
79+ self . load ( ) ;
80+ } , timeout ) ;
81+ }
82+
83+ disconnectedCallback ( ) {
84+ super . disconnectedCallback ( ) ;
85+ if ( this . timeout ) { clearTimeout ( this . timeout ) ; }
86+ }
87+
88+ load ( ) {
89+ super . load . call ( this , null , function waitOnFilter ( el ) {
90+ return el . isAssetItem && el . hasAttribute ( 'src' ) ;
91+ } ) ;
92+ }
93+ }
94+
95+ customElements . define ( 'a-assets' , AAssets ) ;
9096
9197/**
9298 * Preload using XHRLoader for any type of asset.
9399 */
94- registerElement ( 'a-asset-item' , {
95- prototype : Object . create ( ANode . prototype , {
96- createdCallback : {
97- value : function ( ) {
98- this . data = null ;
99- this . isAssetItem = true ;
100- }
101- } ,
102-
103- attachedCallback : {
104- value : function ( ) {
105- var self = this ;
106- var src = this . getAttribute ( 'src' ) ;
107- fileLoader . setResponseType (
108- this . getAttribute ( 'response-type' ) || inferResponseType ( src ) ) ;
109- fileLoader . load ( src , function handleOnLoad ( response ) {
110- self . data = response ;
111- /*
112- Workaround for a Chrome bug. If another XHR is sent to the same url before the
113- previous one closes, the second request never finishes.
114- setTimeout finishes the first request and lets the logic triggered by load open
115- subsequent requests.
116- setTimeout can be removed once the fix for the bug below ships:
117- https://bugs.chromium.org/p/chromium/issues/detail?id=633696&q=component%3ABlink%3ENetwork%3EXHR%20&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified
118- */
119- setTimeout ( function load ( ) { ANode . prototype . load . call ( self ) ; } ) ;
120- } , function handleOnProgress ( xhr ) {
121- self . emit ( 'progress' , {
122- loadedBytes : xhr . loaded ,
123- totalBytes : xhr . total ,
124- xhr : xhr
125- } ) ;
126- } , function handleOnError ( xhr ) {
127- self . emit ( 'error' , { xhr : xhr } ) ;
128- } ) ;
129- }
130- }
131- } )
132- } ) ;
100+ class AAssetItem extends ANode {
101+ constructor ( ) {
102+ super ( ) ;
103+ this . data = null ;
104+ this . isAssetItem = true ;
105+ }
106+
107+ connectedCallback ( ) {
108+ var self = this ;
109+ var src = this . getAttribute ( 'src' ) ;
110+ fileLoader . setResponseType (
111+ this . getAttribute ( 'response-type' ) || inferResponseType ( src ) ) ;
112+ fileLoader . load ( src , function handleOnLoad ( response ) {
113+ self . data = response ;
114+ /*
115+ Workaround for a Chrome bug. If another XHR is sent to the same url before the
116+ previous one closes, the second request never finishes.
117+ setTimeout finishes the first request and lets the logic triggered by load open
118+ subsequent requests.
119+ setTimeout can be removed once the fix for the bug below ships:
120+ https://bugs.chromium.org/p/chromium/issues/detail?id=633696&q=component%3ABlink%3ENetwork%3EXHR%20&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified
121+ */
122+ setTimeout ( function load ( ) { ANode . prototype . load . call ( self ) ; } ) ;
123+ } , function handleOnProgress ( xhr ) {
124+ self . emit ( 'progress' , {
125+ loadedBytes : xhr . loaded ,
126+ totalBytes : xhr . total ,
127+ xhr : xhr
128+ } ) ;
129+ } , function handleOnError ( xhr ) {
130+ self . emit ( 'error' , { xhr : xhr } ) ;
131+ } ) ;
132+ }
133+ }
134+
135+ customElements . define ( 'a-asset-item' , AAssetItem ) ;
133136
134137/**
135138 * Create a Promise that resolves once the media element has finished buffering.
0 commit comments