|
1 |
| -import component from './component' |
2 |
| -import ssr from './ssr' |
| 1 | +import component, { freeze, unfreeze } from './component' |
| 2 | +import ssr from './ssr' |
3 | 3 |
|
4 | 4 | export const Fragment = component
|
5 | 5 |
|
6 | 6 | export const SSR = ssr
|
7 | 7 |
|
8 | 8 | export const Plugin = {
|
9 |
| - install: function(Vue) { |
| 9 | + install: function (Vue) { |
| 10 | + const orgRemoveChild = window.Node.prototype.removeChild |
| 11 | + window.Node.prototype.removeChild = function (node) { |
| 12 | + if (this.__isFragment) { |
| 13 | + if (this.parentNode) { |
| 14 | + let ret = this.parentNode.removeChild(node) |
| 15 | + unfreeze(node, 'parentNode') |
| 16 | + return ret |
| 17 | + } |
| 18 | + } else if (node.__isFragment && node.__isMounted) { |
| 19 | + while (node.__head.nextSibling !== node.__tail) orgRemoveChild.call(this, node.__head.nextSibling) |
| 20 | + |
| 21 | + orgRemoveChild.call(this, node.__head) |
| 22 | + orgRemoveChild.call(this, node.__tail) |
| 23 | + let prev = node.__head.previousSibling, |
| 24 | + next = node.__tail.nextSibling |
| 25 | + if (prev) freeze(prev, 'nextSibling', next) |
| 26 | + if (next) freeze(next, 'previousSibling', prev) |
| 27 | + |
| 28 | + unfreeze(node, 'parentNode') |
| 29 | + return node |
| 30 | + } else { |
| 31 | + let prev = node.previousSibling, |
| 32 | + next = node.nextSibling |
| 33 | + let ret = orgRemoveChild.call(this, node) |
| 34 | + if (prev) freeze(prev, 'nextSibling', next) |
| 35 | + if (next) freeze(next, 'previousSibling', prev) |
| 36 | + return ret |
| 37 | + } |
| 38 | + } |
| 39 | + |
| 40 | + const orgInsertBefore = window.Node.prototype.insertBefore |
| 41 | + window.Node.prototype.insertBefore = function (node, ref, inFragment = false) { |
| 42 | + let realRef = !!ref && !!ref.__isFragment && !!ref.__isMounted ? ref.__head : ref |
| 43 | + if (this.__isFragment) { |
| 44 | + let notFrChild = !node.hasOwnProperty('__isFragmentChild__'), |
| 45 | + freezeParent = !inFragment || notFrChild |
| 46 | + |
| 47 | + notFrChild && freeze(node, '__isFragmentChild__', true) |
| 48 | + let ret = this.parentNode ? this.parentNode.insertBefore(node, ref) : orgInsertBefore.call(this, node, realRef) |
| 49 | + freezeParent && freeze(node, 'parentNode', this) |
| 50 | + |
| 51 | + return ret |
| 52 | + } else if (node.__isFragment && node.__isMounted) { |
| 53 | + if (node === ref) { |
| 54 | + console.error('something must be wrong') |
| 55 | + return |
| 56 | + } |
| 57 | + freeze(node, 'parentNode', this) |
| 58 | + if (node.previousSibling) freeze(node.previousSibling, 'nextSibling', node.nextSibling) |
| 59 | + if (node.nextSibling) freeze(node.nextSibling, 'previousSibling', node.previousSibling) |
| 60 | + freeze(node, 'nextSibling', ref) |
| 61 | + freeze(node, 'previousSibling', ref.previousSibling) |
| 62 | + if (ref.previousSibling) freeze(ref.previousSibling, 'nextSibling', node) |
| 63 | + freeze(ref, 'previousSibling', node) |
| 64 | + |
| 65 | + let tpl = document.createDocumentFragment(), |
| 66 | + ele = node.__head |
| 67 | + while (ele !== node.__tail) { |
| 68 | + tpl.appendChild(ele) |
| 69 | + ele = ele.nextSibling |
| 70 | + } |
| 71 | + tpl.appendChild(node.__tail) |
| 72 | + orgInsertBefore.call(this, tpl, realRef) |
| 73 | + return node |
| 74 | + } else { |
| 75 | + return orgInsertBefore.call(this, node, realRef) |
| 76 | + } |
| 77 | + } |
| 78 | + |
| 79 | + const orgAppendChild = window.Node.prototype.appendChild |
| 80 | + window.Node.prototype.appendChild = function (node, inFragment = false) { |
| 81 | + if (this.__isFragment) { |
| 82 | + if (this.parentNode) { |
| 83 | + let notFrChild = !node.hasOwnProperty('__isFragmentChild__'), |
| 84 | + freezeParent = !inFragment || notFrChild |
| 85 | + |
| 86 | + notFrChild && freeze(node, '__isFragmentChild__', true) |
| 87 | + let ret = this.parentNode.insertBefore(node, this.__tail, inFragment) |
| 88 | + freezeParent && freeze(node, 'parentNode', this) |
| 89 | + |
| 90 | + return ret |
| 91 | + } |
| 92 | + } else { |
| 93 | + return orgAppendChild.call(this, node) |
| 94 | + } |
| 95 | + } |
10 | 96 | Vue.component('Fragment', component)
|
11 |
| - } |
| 97 | + }, |
12 | 98 | }
|
13 | 99 |
|
14 | 100 | export default {
|
15 |
| - Fragment, Plugin, SSR |
| 101 | + Fragment, |
| 102 | + Plugin, |
| 103 | + SSR, |
16 | 104 | }
|
0 commit comments