UNPKG

jodit

Version:

Jodit is awesome and usefully wysiwyg editor with filebrowser

227 lines (193 loc) 4.67 kB
/*! * Jodit Editor (https://xdsoft.net/jodit/) * Released under MIT see LICENSE.txt in the project root for license information. * Copyright (c) 2013-2020 Valeriy Chupurnov. All rights reserved. https://xdsoft.net */ import { IDictionary, Attributes, Children, ICreate, CanUndef, NodeFunction } from '../types'; import { isPlainObject, each, asArray, css, isFunction, kebabCase, refs } from './helpers/'; import { Dom } from './dom'; export class Create implements ICreate { private get doc(): Document { return isFunction(this.document) ? this.document() : this.document; } constructor( readonly document: Document | (() => Document), readonly createAttributes?: CanUndef< IDictionary<Attributes | NodeFunction> > ) {} /** * Apply some object key-value to HTMLElement * * @param elm * @param attrs */ private applyAttributes = (elm: HTMLElement, attrs: Attributes) => { each(attrs, (key: string, value) => { if (isPlainObject(value) && key === 'style') { css(elm, value as IDictionary<string>); } else { if (key === 'className') { key = 'class'; } elm.setAttribute(kebabCase(key), value.toString()); } }); }; element<K extends keyof HTMLElementTagNameMap>( tagName: K, children?: Children ): HTMLElementTagNameMap[K]; element<K extends keyof HTMLElementTagNameMap>( tagName: K, attributes?: Attributes, children?: Children ): HTMLElementTagNameMap[K]; element( tagName: string, childrenOrAttributes?: Attributes | Children, children?: Children ): HTMLElement { const elm = this.doc.createElement(tagName.toLowerCase()); if (this.createAttributes) { const ca = this.createAttributes; if (ca && ca[tagName.toLowerCase()]) { const attrs = ca[tagName.toLowerCase()]; if (isFunction(attrs)) { attrs(elm); } else if (isPlainObject(attrs)) { this.applyAttributes(elm, attrs); } } } if (childrenOrAttributes) { if (isPlainObject(childrenOrAttributes)) { this.applyAttributes(elm, childrenOrAttributes as Attributes); } else { children = childrenOrAttributes as Children; } } if (children) { asArray(children).forEach((child: string | Node) => elm.appendChild( typeof child === 'string' ? this.fromHTML(child) : child ) ); } return elm; } div(className?: string, childrenOrAttributes?: Children): HTMLDivElement; div( className?: string, childrenOrAttributes?: Attributes, children?: Children ): HTMLDivElement; div( className?: string, childrenOrAttributes?: Attributes | Children, children?: Children ): HTMLDivElement { const div = this.element('div', childrenOrAttributes as any, children); if (className) { div.className = className; } return div; } span(className?: string, childrenOrAttributes?: Children): HTMLSpanElement; span( className?: string, childrenOrAttributes?: Attributes, children?: Children ): HTMLSpanElement; span( className?: string, childrenOrAttributes?: Attributes | Children, children?: Children ): HTMLSpanElement { const span = this.element( 'span', childrenOrAttributes as any, children ); if (className) { span.className = className; } return span; } a(className?: string, children?: Children): HTMLAnchorElement; a( className?: string, childrenOrAttributes?: Attributes, children?: Children ): HTMLAnchorElement; a( className?: string, childrenOrAttributes?: Attributes | Children, children?: Children ): HTMLAnchorElement { const a = this.element('a', childrenOrAttributes as any, children); if (className) { a.className = className; } return a; } /** * Create text node * * @param value */ text(value: string): Text { return this.doc.createTextNode(value); } /** * Create HTML Document fragment element */ fragment(): DocumentFragment { return this.doc.createDocumentFragment(); } /** * Create DOM element from HTML text * * @param html * @param refsToggleElement * * @return HTMLElement */ fromHTML( html: string | number, refsToggleElement?: IDictionary<boolean | void> ): HTMLElement { const div: HTMLDivElement = this.div(); div.innerHTML = html.toString(); const child: HTMLElement = div.firstChild !== div.lastChild || !div.firstChild ? div : (div.firstChild as HTMLElement); Dom.safeRemove(child); if (refsToggleElement) { const refElements = refs(child); Object.keys(refsToggleElement).forEach(key => { const elm = refElements[key]; if (elm && refsToggleElement[key] === false) { Dom.hide(elm); } }); } return child; } }