1 | import { patch, createElement } from './vdom'
|
2 | import { vnodeFromElement } from './vnode'
|
3 | import { FragmentError } from './utils'
|
4 |
|
5 | /**
|
6 | * A function to create and inject a virtual node into the document. The node will be appended to the container. The first argument can be either a JSX tag or an h function. After mounting, use the render function and the element returned by mount to udate the DOM.
|
7 | * @example
|
8 | *
|
9 | * ```
|
10 | * // Insert Title tag into section:
|
11 | * const title = mount(<Title message='Hello World!'/>, 'section').
|
12 | * // Update the node with new prop value and reference to DOM from mount:
|
13 | * render(<Title message='New stuff'/>, title)
|
14 | ```
|
15 | * @typedef {import('./vnode').VNode} VNode
|
16 | * @param {Object | Function} tag A JSX tag or hyperscript function to render.
|
17 | * @param {Element | string} [container] The element into which the tag will be rendered.
|
18 | * @param {string | Element} [elementToHydrate] A server-rendered element to hydrate during initial load.
|
19 | * @return {VNode} The base element of the rendered tag.
|
20 | */
|
21 | export function mount(tag, container, elementToHydrate) {
|
22 | if (typeof container === 'string')
|
23 | container = document.querySelector(container)
|
24 | if (!container) container = document.body
|
25 | const lifecycle = []
|
26 | if (Array.isArray(tag)) throw new FragmentError()
|
27 |
|
28 | if (elementToHydrate) {
|
29 | if (typeof elementToHydrate === 'string') {
|
30 | elementToHydrate = document.querySelector(elementToHydrate)
|
31 | }
|
32 | const nodeToRecycle = vnodeFromElement(elementToHydrate)
|
33 | patch(tag, nodeToRecycle, container)
|
34 | } else {
|
35 | const element = createElement(tag, lifecycle)
|
36 | container.appendChild(element)
|
37 | tag.element = element
|
38 | }
|
39 | tag.element['isMounted'] = true
|
40 | while (lifecycle.length > 0) lifecycle.pop()()
|
41 | return tag
|
42 | }
|