7
7
( function ( scope ) {
8
8
9
9
var IMPORT_LINK_TYPE = 'import' ;
10
-
10
+ var isIe = / T r i d e n t / . test ( navigator . userAgent )
11
11
// highlander object for parsing a document tree
12
12
13
13
var importParser = {
@@ -21,16 +21,18 @@ var importParser = {
21
21
map : {
22
22
link : 'parseLink' ,
23
23
script : 'parseScript' ,
24
- style : 'parseGeneric '
24
+ style : 'parseStyle '
25
25
} ,
26
26
// TODO(sorvell): because dynamic imports are not supported, users are
27
27
// writing code like in https://github.com/Polymer/HTMLImports/issues/40
28
28
// as a workaround. The code here checking for the existence of
29
29
// document.scripts is here only to support the workaround.
30
- parse : function ( document ) {
30
+ parse : function ( document , done ) {
31
31
if ( ! document . __importParsed ) {
32
32
// only parse once
33
33
document . __importParsed = true ;
34
+ console . group ( 'parsing' , scope . path . getDocumentUrl ( document ) ) ;
35
+ var tracker = new LoadTracker ( document , done ) ;
34
36
// all parsable elements in inDocument (depth-first pre-order traversal)
35
37
var elts = document . querySelectorAll ( importParser . selectors ) ;
36
38
// memoize the number of scripts
@@ -48,21 +50,41 @@ var importParser = {
48
50
elts = document . querySelectorAll ( importParser . selectors ) ;
49
51
}
50
52
}
53
+ console . groupEnd ( 'parsing' , scope . path . getDocumentUrl ( document ) ) ;
54
+ tracker . open ( ) ;
55
+ } else if ( done ) {
56
+ done ( ) ;
51
57
}
52
58
} ,
53
59
parseLink : function ( linkElt ) {
54
60
if ( isDocumentLink ( linkElt ) ) {
61
+ this . trackElement ( linkElt ) ;
55
62
if ( linkElt . import ) {
56
- importParser . parse ( linkElt . import ) ;
57
- // fire load event
58
- linkElt . dispatchEvent ( new CustomEvent ( 'load' ) ) ;
63
+ importParser . parse ( linkElt . import , function ( ) {
64
+ // fire load event
65
+ linkElt . dispatchEvent ( new CustomEvent ( 'load' , { bubbles : false } ) ) ;
66
+ } ) ;
67
+ } else {
68
+ linkElt . dispatchEvent ( new CustomEvent ( 'error' , { bubbles : false } ) ) ;
59
69
}
60
70
} else {
61
71
this . parseGeneric ( linkElt ) ;
62
72
}
63
73
} ,
74
+ trackElement : function ( elt ) {
75
+ // IE doesn't fire load on style elements
76
+ if ( ! isIe || elt . localName !== 'style' ) {
77
+ elt . ownerDocument . __loadTracker . require ( elt ) ;
78
+ }
79
+ } ,
80
+ parseStyle : function ( elt ) {
81
+ // TODO(sorvell): style element load event can just not fire so clone styles
82
+ elt = needsMainDocumentContext ( elt ) ? cloneStyle ( elt ) : elt ;
83
+ this . parseGeneric ( elt ) ;
84
+ } ,
64
85
parseGeneric : function ( elt ) {
65
86
if ( needsMainDocumentContext ( elt ) ) {
87
+ this . trackElement ( elt ) ;
66
88
document . head . appendChild ( elt ) ;
67
89
}
68
90
} ,
@@ -95,6 +117,55 @@ var importParser = {
95
117
}
96
118
} ;
97
119
120
+ function cloneStyle ( style ) {
121
+ var clone = style . ownerDocument . createElement ( 'style' ) ;
122
+ clone . textContent = style . textContent ;
123
+ return clone ;
124
+ }
125
+
126
+ function LoadTracker ( doc , callback ) {
127
+ this . doc = doc ;
128
+ this . doc . __loadTracker = this ;
129
+ this . callback = callback ;
130
+ }
131
+
132
+ LoadTracker . prototype = {
133
+ pending : 0 ,
134
+ isOpen : false ,
135
+ open : function ( ) {
136
+ this . isOpen = true ;
137
+ this . checkDone ( ) ;
138
+ } ,
139
+ add : function ( ) {
140
+ this . pending ++ ;
141
+ } ,
142
+ require : function ( elt ) {
143
+ this . add ( ) ;
144
+ console . log ( 'require' , elt , this . pending ) ;
145
+ var names = [ 'load' , 'error' ] , self = this ;
146
+ for ( var i = 0 , l = names . length , n ; ( i < l ) && ( n = names [ i ] ) ; i ++ ) {
147
+ elt . addEventListener ( n , function ( e ) {
148
+ self . receive ( e ) ;
149
+ } ) ;
150
+ }
151
+ } ,
152
+ receive : function ( e ) {
153
+ this . pending -- ;
154
+ console . log ( 'receive' , e . target , this . pending ) ;
155
+ this . checkDone ( ) ;
156
+ } ,
157
+ checkDone : function ( ) {
158
+ if ( ! this . isOpen ) {
159
+ return ;
160
+ }
161
+ if ( this . pending <= 0 && this . callback ) {
162
+ console . log ( 'done!' , this . doc , scope . path . getDocumentUrl ( this . doc ) ) ;
163
+ this . isOpen = false ;
164
+ this . callback ( ) ;
165
+ }
166
+ }
167
+ }
168
+
98
169
var forEach = Array . prototype . forEach . call . bind ( Array . prototype . forEach ) ;
99
170
100
171
function isDocumentLink ( elt ) {
0 commit comments