@@ -14,8 +14,6 @@ const unfreeze = (object, property, value = null) => {
14
14
} ) ;
15
15
} ;
16
16
17
-
18
-
19
17
export default {
20
18
abstract : true ,
21
19
name : 'Fragment' ,
@@ -24,64 +22,62 @@ export default {
24
22
name : {
25
23
type : String ,
26
24
default : ( ) => Math . floor ( Date . now ( ) * Math . random ( ) ) . toString ( 16 )
25
+ } ,
26
+ html : {
27
+ type : String ,
28
+ default : null
27
29
}
28
30
} ,
29
31
30
32
mounted ( ) {
31
- const container = this . $el ;
32
- const parent = container . parentNode ;
33
+ const container = this . $el
34
+ const parent = container . parentNode
35
+
36
+ container . __isFragment = true
37
+ container . __isMounted = false
33
38
34
39
const head = document . createComment ( `fragment#${ this . name } #head` )
35
40
const tail = document . createComment ( `fragment#${ this . name } #tail` )
36
41
37
- parent . insertBefore ( head , container )
38
- parent . insertBefore ( tail , container )
39
-
40
- container . appendChild = ( node ) => {
41
- parent . insertBefore ( node , tail )
42
- freeze ( node , 'parentNode' , container )
43
- }
44
-
45
- container . insertBefore = ( node , ref ) => {
46
- parent . insertBefore ( node , ref )
47
- freeze ( node , 'parentNode' , container )
48
- }
49
-
50
- container . removeChild = ( node ) => {
51
- parent . removeChild ( node )
52
- unfreeze ( node , 'parentNode' )
53
- }
42
+ container . __head = head
43
+ container . __tail = tail
44
+
45
+ // use document fragment to improve efficiency
46
+ let tpl = document . createDocumentFragment ( )
47
+ tpl . appendChild ( head )
54
48
55
49
Array . from ( container . childNodes )
56
- . forEach ( node => container . appendChild ( node ) )
50
+ . forEach ( node => {
51
+ // container.appendChild(node, true)
52
+ let notFrChild = ! node . hasOwnProperty ( '__isFragmentChild__' )
53
+ tpl . appendChild ( node )
54
+ if ( notFrChild ) {
55
+ freeze ( node , 'parentNode' , container )
56
+ freeze ( node , '__isFragmentChild__' , true )
57
+ }
58
+ } )
59
+
60
+ tpl . appendChild ( tail )
61
+
62
+ // embed html
63
+ if ( this . html ) {
64
+ let template = document . createElement ( 'template' )
65
+ template . innerHTML = this . html
66
+ // copy elements over
67
+ Array . from ( template . content . childNodes ) . forEach ( node => {
68
+ tpl . appendChild ( node )
69
+ } )
70
+ }
57
71
72
+ let next = container . nextSibling
73
+ parent . insertBefore ( tpl , container , true )
58
74
parent . removeChild ( container )
59
-
60
75
freeze ( container , 'parentNode' , parent )
61
- freeze ( container , 'nextSibling' , tail . nextSibling )
62
-
63
- const insertBefore = parent . insertBefore ;
64
- parent . insertBefore = ( node , ref ) => {
65
- insertBefore . call ( parent , node , ref !== container ? ref : head )
66
- }
67
-
68
- const removeChild = parent . removeChild ;
69
- parent . removeChild = ( node ) => {
70
- if ( node === container ) {
71
- while ( head . nextSibling !== tail )
72
- container . removeChild ( head . nextSibling )
76
+ freeze ( container , 'nextSibling' , next )
77
+ if ( next )
78
+ freeze ( next , 'previousSibling' , container )
73
79
74
- parent . removeChild ( head )
75
- parent . removeChild ( tail )
76
- unfreeze ( container , 'parentNode' )
77
-
78
- parent . insertBefore = insertBefore
79
- parent . removeChild = removeChild
80
- }
81
- else {
82
- removeChild . call ( parent , node )
83
- }
84
- }
80
+ container . __isMounted = true
85
81
} ,
86
82
87
83
render ( h ) {
0 commit comments