1 | /**
|
2 | * Used to determine if a vnode should be recycled.
|
3 | * @type {number}
|
4 | */
|
5 | export const RECYCLED_NODE = 0
|
6 |
|
7 | /**
|
8 | * Used in a vnode to indicate that it is a DOM node.
|
9 | * @type {number}
|
10 | */
|
11 | export const ELEMENT_NODE = 1
|
12 |
|
13 | /**
|
14 | * Used in a vnode to indicate that it is a text node.
|
15 | * @type {number}
|
16 | */
|
17 | export const TEXT_NODE = 3
|
18 |
|
19 | /**
|
20 | * Namespace for SVG elements with `xlink:href` attributes.
|
21 | * @type {string}
|
22 | */
|
23 | export const XLINK_NS = 'http://www.w3.org/1999/xlink'
|
24 |
|
25 | /**
|
26 | * Namespace for SVG elements.
|
27 | * @type {string}
|
28 | */
|
29 | export const SVG_NS = 'http://www.w3.org/2000/svg'
|
30 |
|
31 | /**
|
32 | * An empty object. Used as placeholder for `props` in VNode.
|
33 | * @type {{}} EMPTY_OBJECT
|
34 | */
|
35 | export const EMPTY_OBJECT = {}
|
36 |
|
37 | /**
|
38 | * An empty array. Used for access to array methods.
|
39 | * @type {any[]} EMPTY_ARRAY
|
40 | */
|
41 | export const EMPTY_ARRAY = []
|
42 |
|
43 | /**
|
44 | * Combine two objects, merging the second into the first. Any properties already existing in the first will be replaced by those of the second. Any properties in the second not in the first will be added to it.
|
45 | * @param {Object.<string, any>[]} objects
|
46 | * @return {Object.<string, any>} Object.<string, any>
|
47 | */
|
48 | export function merge(...objects) {
|
49 | // Clone both objects:
|
50 | const clones = objects.map(obj => JSON.parse(JSON.stringify(obj)))
|
51 | // Merge objects:
|
52 | return clones.reduce((a, b) => Object.assign({}, a, b))
|
53 | }
|
54 |
|
55 | /**
|
56 | * A function to test whether the data provided for updating a component creates a new virtual node or not.
|
57 | * @typedef {import('./vnode').VNode} VNode
|
58 | * @param {Object<string, any> | VNode} value1 The previous virtual node of a component.
|
59 | * @param {Object<string, any> | VNode} value2 The current virtual node of a component.
|
60 | * @return {boolean} boolean
|
61 | */
|
62 | export function areEqual(value1, value2) {
|
63 | if (getType(value1) !== 'Object' && getType(value2) !== 'Object') return
|
64 | return JSON.stringify(value1) === JSON.stringify(value2)
|
65 | }
|
66 |
|
67 | /**
|
68 | * Class to throw error message when attempting to insert Fragement tag directly into DOM.
|
69 | * @return {string} message
|
70 | */
|
71 | export class FragmentError {
|
72 | constructor() {
|
73 | this.message = 'Cannot insert Fragment tag directly into DOM.'
|
74 | this.toString = function() {
|
75 | return this.message
|
76 | }
|
77 | }
|
78 | }
|
79 |
|
80 | /**
|
81 | * Function to create an RFC4122 version 4 compliant uuid.
|
82 | * @return {string} string
|
83 | */
|
84 | export function uuid() {
|
85 | var d = new Date().getTime()
|
86 | if (
|
87 | typeof performance !== 'undefined' &&
|
88 | typeof performance.now === 'function'
|
89 | ) {
|
90 | d += performance.now() //use high-precision timer if available
|
91 | }
|
92 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
93 | var r = (d + Math.random() * 16) % 16 | 0
|
94 | d = Math.floor(d / 16)
|
95 | return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16)
|
96 | })
|
97 | }
|
98 |
|
99 | /**
|
100 | * Determine the type of the provided value.
|
101 | * @param {*} value
|
102 | * @return {string} string
|
103 | */
|
104 | export function getType(value) {
|
105 | // Capture NaN values:
|
106 | if (typeof value === 'number' && isNaN(value)) {
|
107 | return 'NaN'
|
108 | } else {
|
109 | return new RegExp('\\[object (.*)]').exec(toString.call(value))[1]
|
110 | }
|
111 | }
|