1 | import { createElement, render } from 'preact';
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | function ContextProvider(props) {
|
7 | this.getChildContext = () => props.context;
|
8 | return props.children;
|
9 | }
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | function Portal(props) {
|
19 | const _this = this;
|
20 | let container = props._container;
|
21 |
|
22 | _this.componentWillUnmount = function() {
|
23 | render(null, _this._temp);
|
24 | _this._temp = null;
|
25 | _this._container = null;
|
26 | };
|
27 |
|
28 |
|
29 |
|
30 | if (_this._container && _this._container !== container) {
|
31 | _this.componentWillUnmount();
|
32 | }
|
33 |
|
34 |
|
35 |
|
36 | if (props._vnode) {
|
37 | if (!_this._temp) {
|
38 | _this._container = container;
|
39 |
|
40 |
|
41 | _this._temp = {
|
42 | nodeType: 1,
|
43 | parentNode: container,
|
44 | childNodes: [],
|
45 | appendChild(child) {
|
46 | this.childNodes.push(child);
|
47 | _this._container.appendChild(child);
|
48 | },
|
49 | insertBefore(child, before) {
|
50 | this.childNodes.push(child);
|
51 | _this._container.appendChild(child);
|
52 | },
|
53 | removeChild(child) {
|
54 | this.childNodes.splice(this.childNodes.indexOf(child) >>> 1, 1);
|
55 | _this._container.removeChild(child);
|
56 | }
|
57 | };
|
58 | }
|
59 |
|
60 |
|
61 | render(
|
62 | createElement(ContextProvider, { context: _this.context }, props._vnode),
|
63 | _this._temp
|
64 | );
|
65 | }
|
66 |
|
67 |
|
68 | else if (_this._temp) {
|
69 | _this.componentWillUnmount();
|
70 | }
|
71 | }
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 | export function createPortal(vnode, container) {
|
79 | const el = createElement(Portal, { _vnode: vnode, _container: container });
|
80 | el.containerInfo = container;
|
81 | return el;
|
82 | }
|