123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- 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 doesn't have its wrapper attached
- wrapper.removeChild(wrapper.firstChild)
- return element
- }
-
- export function nodeOrNew(name, node) {
- return node &&
- (node instanceof globals.window.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)
- }
- }
- }
|