summaryrefslogtreecommitdiffstats
path: root/src/adopter.js
blob: 61b1e837f6ebbfdd6e7e1750c34c1b77285e5f86 (plain)
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
import Base from './Base.js'
import {capitalize} from './helpers.js'
import {makeNode} from './tools.js'

const elements = {}
export const root = Symbol('root')

export function makeInstance (element) {
  if (element instanceof Base) return element

  if (typeof element === 'object') {
    return adopt(element)
  }

  if (element == null) {
    return new elements[root]()
  }

  if (typeof element === 'string' && element.charAt(0) !== '<') {
    return adopt(document.querySelector(element))
  }

  var node = makeNode('svg')
  node.innerHTML = element

  // We can use firstChild here because we know,
  // that the first char is < and thus an element
  element = adopt(node.firstChild)

  return element
}


// 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 instanceof window.SVGElement)) {
    return new elements.HtmlNode(node)
  }

  // initialize variables
  var element

  // adopt with element-specific settings
  if (node.nodeName === 'svg') {
    element = new elements[root](node)
  } else if (node.nodeName === 'linearGradient' || node.nodeName === 'radialGradient') {
    element = new elements.Gradient(node)
  } else if (elements[capitalize(node.nodeName)]) {
    element = new elements[capitalize(node.nodeName)](node)
  } else {
    element = new elements.Bare(node)
  }

  return element
}

export function register (element, name = element.name, asRoot = false) {
  elements[name] = element
  if (asRoot) elements[root] = element
  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 (var i = node.children.length - 1; i >= 0; i--) {
    assignNewId(node.children[i])
  }

  if (node.id) {
    return adopt(node).id(eid(node.nodeName))
  }

  return adopt(node)
}