1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
import { addMethodNames } from './methods.js'
import { capitalize } from './utils.js'
import { svg } from '../modules/core/namespaces.js'
import { globals } from '../utils/window.js'
import Base from '../types/Base.js'
const elements = {}
export const root = '___SYMBOL___ROOT___'
// Method for element creation
export function create (name, ns = svg) {
// create element
return globals.document.createElementNS(ns, name)
}
export function makeInstance (element, isHTML = false) {
if (element instanceof Base) return element
if (typeof element === 'object') {
return adopter(element)
}
if (element == null) {
return new elements[root]()
}
if (typeof element === 'string' && element.charAt(0) !== '<') {
return adopter(globals.document.querySelector(element))
}
// Make sure, that HTML elements are created with the correct namespace
const wrapper = isHTML ? globals.document.createElement('div') : create('svg')
wrapper.innerHTML = element
// We can use firstChild here because we know,
// that the first char is < and thus an element
element = adopter(wrapper.firstChild)
// make sure, that element doesnt have its wrapper attached
wrapper.removeChild(wrapper.firstChild)
return element
}
export function nodeOrNew (name, node) {
return (node && node.ownerDocument && node instanceof node.ownerDocument.defaultView.Node) ? node : create(name)
}
// Adopt existing svg elements
export function adopt (node) {
// check for presence of node
if (!node) return null
// make sure a node isn't already adopted
if (node.instance instanceof Base) return node.instance
if (node.nodeName === '#document-fragment') {
return new elements.Fragment(node)
}
// initialize variables
let className = capitalize(node.nodeName || 'Dom')
// Make sure that gradients are adopted correctly
if (className === 'LinearGradient' || className === 'RadialGradient') {
className = 'Gradient'
// Fallback to Dom if element is not known
} else if (!elements[className]) {
className = 'Dom'
}
return new elements[className](node)
}
let adopter = adopt
export function mockAdopt (mock = adopt) {
adopter = mock
}
export function register (element, name = element.name, asRoot = false) {
elements[name] = element
if (asRoot) elements[root] = element
addMethodNames(Object.getOwnPropertyNames(element.prototype))
return element
}
export function getClass (name) {
return elements[name]
}
// Element id sequence
let did = 1000
// Get next named element id
export function eid (name) {
return 'Svgjs' + capitalize(name) + (did++)
}
// Deep new id assignment
export function assignNewId (node) {
// do the same for SVG child nodes as well
for (let i = node.children.length - 1; i >= 0; i--) {
assignNewId(node.children[i])
}
if (node.id) {
node.id = eid(node.nodeName)
return node
}
return node
}
// Method for extending objects
export function extend (modules, methods) {
let key, i
modules = Array.isArray(modules) ? modules : [ modules ]
for (i = modules.length - 1; i >= 0; i--) {
for (key in methods) {
modules[i].prototype[key] = methods[key]
}
}
}
export function wrapWithAttrCheck (fn) {
return function (...args) {
const o = args[args.length - 1]
if (o && o.constructor === Object && !(o instanceof Array)) {
return fn.apply(this, args.slice(0, -1)).attr(o)
} else {
return fn.apply(this, args)
}
}
}
|