feat: auto detect vector type by tagName

This commit is contained in:
bubkoo
2021-04-13 10:22:27 +08:00
parent 636a73ccde
commit 9f4d361f08
4 changed files with 45 additions and 13 deletions

View File

@ -6,6 +6,8 @@ export namespace Registry {
let root: Definition
const cache: Record<string, Definition> = {}
const ucfirst = (s: string) => s.charAt(0).toUpperCase() + s.substring(1)
export function register(
ctor: Definition,
name = ctor.name,
@ -34,8 +36,7 @@ export namespace Registry {
}
const nodeName = node.nodeName
// ucfirst
let className = nodeName.charAt(0).toUpperCase() + nodeName.substring(1)
let className = ucfirst(nodeName)
if (nodeName === '#document-fragment') {
className = 'Fragment'
@ -65,4 +66,9 @@ export namespace Registry {
}
return null
}
export function isRegisted(tagName: string) {
const name = ucfirst(tagName)
return cache[name] != null
}
}

View File

@ -6,22 +6,42 @@ describe('Dom', () => {
describe('constructor', () => {
it('should create element with the given node', () => {
const div = new Dom(document.createElement('div'), { tabIndex: 1 })
expect(div.type).toEqual('DIV')
expect(div.type.toLowerCase()).toEqual('div')
expect(div.attr('tabIndex')).toEqual(1)
})
it('should create element with the given tagName', () => {
const div = new Dom('div', { tabIndex: 1 })
expect(div.type).toEqual('DIV')
expect(div.type.toLowerCase()).toEqual('div')
expect(div.attr('tabIndex')).toEqual(1)
})
it('should create a div by default', () => {
const div = new Dom()
expect(div.type.toLowerCase()).toEqual('div')
expect(div.node).toBeInstanceOf(HTMLDivElement)
})
it('should create element with the given tagName and return the correct type', () => {
const g = new Dom('g')
expect(g.type.toLowerCase()).toEqual('g')
expect(g.node).toBeInstanceOf(SVGGElement)
const svg = new Dom('svg', { x: 10, y: 10 } as any)
expect(svg.type.toLowerCase()).toEqual('svg')
expect(svg.node).toBeInstanceOf(SVGSVGElement)
expect(svg.attr('x')).toEqual(10)
expect(svg.attr('y')).toEqual(10)
})
it('should create element with auto detected tagName', () => {
const g = new G()
expect(g.type).toEqual('g')
expect(g.type.toLowerCase()).toEqual('g')
expect(g.node).toBeInstanceOf(SVGGElement)
const svg = new Svg({ x: 10, y: 10 })
expect(svg.type).toEqual('svg')
expect(svg.type.toLowerCase()).toEqual('svg')
expect(svg.node).toBeInstanceOf(SVGSVGElement)
expect(svg.attr('x')).toEqual(10)
expect(svg.attr('y')).toEqual(10)
})

View File

@ -1,4 +1,4 @@
import { isNode, createHTMLNode } from '../../util'
import { isNode, createHTMLNode, createSVGNode } from '../../util'
import { Base } from '../common/base'
import { Registry } from '../common/registry'
import { Affix } from './affix'
@ -51,12 +51,18 @@ export class Primer<TElement extends Element> extends Base<TElement> {
attributes = attrs
} else {
const ctor = this.constructor as Registry.Definition
const tagName =
let tagName =
typeof nodeOrAttrs === 'string'
? nodeOrAttrs
: Registry.getTagName(ctor)
if (tagName) {
this.node = this.createNode(tagName)
if (tagName === 'dom') {
// return new Dom('div') by dafault
tagName = 'div'
}
this.node = Registry.isRegisted(tagName)
? createSVGNode<any>(tagName)
: createHTMLNode<any>(tagName)
attributes =
nodeOrAttrs != null && typeof nodeOrAttrs !== 'string'
? nodeOrAttrs
@ -75,10 +81,6 @@ export class Primer<TElement extends Element> extends Base<TElement> {
this.restoreAffix()
Adopter.cache(this.node, this)
}
protected createNode(tagName: string): TElement {
return createHTMLNode(tagName) as any
}
}
export interface Primer<TElement extends Element>

View File

@ -7,6 +7,10 @@ import { Dom } from '../../dom'
export class Vector<
TSVGElement extends SVGElement = SVGElement
> extends Dom<TSVGElement> {
// protected createNode(tagName: string) {
// return createSVGNode(tagName) as any
// }
width(): number
width(width: string | number | null): this
width(width?: string | number | null) {