@@ -170,19 +170,26 @@ var TAG_NAME_REGEXP = /<([\w:-]+)/;
170170var XHTML_TAG_REGEXP = / < (? ! a r e a | b r | c o l | e m b e d | h r | i m g | i n p u t | l i n k | m e t a | p a r a m ) ( ( [ \w : - ] + ) [ ^ > ] * ) \/ > / gi;
171171
172172var wrapMap = {
173- 'option' : [ 1 , '<select multiple="multiple">' , '</select>' ] ,
174173
175- 'thead' : [ 1 , '<table>' , '</table>' ] ,
176- 'col' : [ 2 , '<table><colgroup>' , '</colgroup></table>' ] ,
177- 'tr' : [ 2 , '<table><tbody>' , '</tbody></table>' ] ,
178- 'td' : [ 3 , '<table><tbody><tr>' , '</tr></tbody></table>' ] ,
179- '_default' : [ 0 , '' , '' ]
174+ thead : [ 'table' ] ,
175+ col : [ 'colgroup' , 'table' ] ,
176+ tr : [ 'tbody' , 'table' ] ,
177+ td : [ 'tr' , 'tbody' , 'table' ]
180178} ;
181179
182- wrapMap . optgroup = wrapMap . option ;
183180wrapMap . tbody = wrapMap . tfoot = wrapMap . colgroup = wrapMap . caption = wrapMap . thead ;
184181wrapMap . th = wrapMap . td ;
185182
183+ var wrapMapIE9 = {
184+ option : [ 1 , '<select multiple="multiple">' , '</select>' ] ,
185+ _default : [ 0 , '' , '' ]
186+ } ;
187+ for ( var key in wrapMap ) {
188+ var wrapMapValueClosing = wrapMap [ key ] ;
189+ var wrapMapValue = wrapMapValueClosing . slice ( ) . reverse ( ) ;
190+ wrapMapIE9 [ key ] = [ wrapMapValue . length , '<' + wrapMapValue . join ( '><' ) + '>' , '</' + wrapMapValueClosing . join ( '></' ) + '>' ] ;
191+ }
192+ wrapMapIE9 . optgroup = wrapMapIE9 . option ;
186193
187194function jqLiteIsTextNode ( html ) {
188195 return ! HTML_REGEXP . test ( html ) ;
@@ -203,7 +210,7 @@ function jqLiteHasData(node) {
203210}
204211
205212function jqLiteBuildFragment ( html , context ) {
206- var tmp , tag , wrap ,
213+ var tmp , tag , wrap , finalHtml ,
207214 fragment = context . createDocumentFragment ( ) ,
208215 nodes = [ ] , i ;
209216
@@ -214,13 +221,29 @@ function jqLiteBuildFragment(html, context) {
214221 // Convert html into DOM nodes
215222 tmp = fragment . appendChild ( context . createElement ( 'div' ) ) ;
216223 tag = ( TAG_NAME_REGEXP . exec ( html ) || [ '' , '' ] ) [ 1 ] . toLowerCase ( ) ;
217- wrap = wrapMap [ tag ] || wrapMap . _default ;
218- tmp . innerHTML = wrap [ 1 ] + html . replace ( XHTML_TAG_REGEXP , '<$1></$2>' ) + wrap [ 2 ] ;
224+ finalHtml = JQLite . legacyXHTMLReplacement ?
225+ html . replace ( XHTML_TAG_REGEXP , '<$1></$2>' ) :
226+ html ;
227+ if ( msie < 10 ) {
228+ wrap = wrapMapIE9 [ tag ] || wrapMapIE9 . _default ;
229+ tmp . innerHTML = wrap [ 1 ] + finalHtml + wrap [ 2 ] ;
219230
220231 // Descend through wrappers to the right content
221232 i = wrap [ 0 ] ;
222233 while ( i -- ) {
223- tmp = tmp . lastChild ;
234+ tmp = tmp . firstChild ;
235+ }
236+ } else {
237+ wrap = wrapMap [ tag ] || [ ] ;
238+
239+ // Create wrappers & descend into them
240+ i = wrap . length ;
241+ while ( -- i > - 1 ) {
242+ tmp . appendChild ( window . document . createElement ( wrap [ i ] ) ) ;
243+ tmp = tmp . firstChild ;
244+ }
245+
246+ tmp . innerHTML = finalHtml ;
224247 }
225248
226249 nodes = concat ( nodes , tmp . childNodes ) ;
@@ -311,6 +334,23 @@ function jqLiteDealoc(element, onlyDescendants) {
311334 }
312335}
313336
337+ function isEmptyObject ( obj ) {
338+ var name ;
339+ for ( name in obj ) {
340+ return false ;
341+ }
342+ return true ;
343+ }
344+ function removeIfEmptyData ( element ) {
345+ var expandoId = element . ng339 ;
346+ var expandoStore = expandoId && jqCache [ expandoId ] ;
347+ var events = expandoStore && expandoStore . events ;
348+ var data = expandoStore && expandoStore . data ;
349+ if ( ( ! data || isEmptyObject ( data ) ) && ( ! events || isEmptyObject ( events ) ) ) {
350+ delete jqCache [ expandoId ] ;
351+ element . ng339 = undefined ; // don't delete DOM expandos. IE and Chrome don't like it
352+ }
353+ }
314354function jqLiteOff ( element , type , fn , unsupported ) {
315355 if ( isDefined ( unsupported ) ) throw jqLiteMinErr ( 'offargs' , 'jqLite#off() does not support the `selector` argument' ) ;
316356
@@ -347,6 +387,7 @@ function jqLiteOff(element, type, fn, unsupported) {
347387 }
348388 } ) ;
349389 }
390+ removeIfEmptyData ( element ) ;
350391}
351392
352393function jqLiteRemoveData ( element , name ) {
@@ -356,17 +397,12 @@ function jqLiteRemoveData(element, name) {
356397 if ( expandoStore ) {
357398 if ( name ) {
358399 delete expandoStore . data [ name ] ;
359- return ;
360- }
400+ } else {
361401
362- if ( expandoStore . handle ) {
363- if ( expandoStore . events . $destroy ) {
364- expandoStore . handle ( { } , '$destroy' ) ;
402+ expandoStore . data = { } ;
365403 }
366- jqLiteOff ( element ) ;
367- }
368- delete jqCache [ expandoId ] ;
369- element . ng339 = undefined ; // don't delete DOM expandos. IE and Chrome don't like it
404+
405+ removeIfEmptyData ( element ) ;
370406 }
371407}
372408
@@ -616,6 +652,7 @@ forEach({
616652 cleanData : function jqLiteCleanData ( nodes ) {
617653 for ( var i = 0 , ii = nodes . length ; i < ii ; i ++ ) {
618654 jqLiteRemoveData ( nodes [ i ] ) ;
655+ jqLiteOff ( nodes [ i ] ) ;
619656 }
620657 }
621658} , function ( fn , name ) {
0 commit comments