UNPKG

@textbus/adapter-viewfly

Version:

Textbus is a rich text editor and framework that is highly customizable and extensible to achieve rich wysiwyg effects.

178 lines (173 loc) 6.93 kB
'use strict'; var core = require('@textbus/core'); var core$1 = require('@viewfly/core'); var platformBrowser = require('@textbus/platform-browser'); var platformNode = require('@textbus/platform-node'); const adapterError = core.makeError('ViewflyDOMRenderer'); class ViewflyAdapter extends platformBrowser.DomAdapter { constructor(components, mount) { super({ createCompositionNode(compositionState, updateNativeCompositionNode) { const ref = core$1.createDynamicRef(node => { updateNativeCompositionNode(node); return () => { updateNativeCompositionNode(null); }; }); return new core.VElement('span', { style: { textDecoration: 'underline' }, ref }, [ new core.VTextNode(compositionState.text) ]); }, getParentNode(node) { return node.parentNode; }, getChildNodes(parentElement) { return Array.from(parentElement.childNodes); }, isNativeElementNode(node) { return node instanceof Element; }, getChildByIndex(parentElement, index) { return parentElement.childNodes[index]; }, getAndUpdateSlotRootNativeElement(vEle, update) { const currentRef = vEle.attrs.get('ref'); const ref = core$1.createDynamicRef(nativeNode => { update(nativeNode); return () => { update(null); }; }); if (currentRef instanceof core$1.DynamicRef) { vEle.attrs.set('ref', [currentRef, ref]); } else if (Array.isArray(currentRef)) { currentRef.push(ref); } else { vEle.attrs.set('ref', ref); } }, componentRender: (component) => { const comp = this.components[component.name] || this.components['*']; if (comp) { let ref = this.componentRefs.get(component); if (!ref) { ref = core$1.createDynamicRef(rootNode => { this.componentRootElementCaches.set(component, rootNode); return () => { this.componentRootElementCaches.remove(component); }; }); this.componentRefs.set(component, ref); } return core$1.jsx(comp, { component, rootRef: ref }, component.id); } throw adapterError(`cannot found view component \`${component.name}\`!`); }, vElementToViewElement(vNode, children) { const key = vNode.attrs.get('key'); vNode.attrs.delete('key'); const props = Object.assign({}, (Array.from(vNode.attrs).reduce((a, b) => { a[b[0]] = b[1]; return a; }, {}))); if (vNode.classes.size) { props.class = Array.from(vNode.classes).join(' '); } if (vNode.styles) { props.style = Array.from(vNode.styles).reduce((a, b) => { a[b[0]] = b[1]; return a; }, {}); } if (children.length) { props.children = children; } return core$1.jsx(vNode.tagName, props, key); } }, mount); Object.defineProperty(this, "components", { enumerable: true, configurable: true, writable: true, value: {} }); Object.defineProperty(this, "componentRefs", { enumerable: true, configurable: true, writable: true, value: new WeakMap() }); let isRoot = true; Object.entries(components).forEach(([key, viewFlyComponent]) => { this.components[key] = (props) => { const comp = core$1.getCurrentInstance(); const textbusComponent = props.component; const subscription = core.merge(textbusComponent.changeMarker.onChange, textbusComponent.changeMarker.onForceChange).subscribe(() => { if (textbusComponent.changeMarker.dirty) { comp.markAsDirtied(); } }); core$1.onUnmounted(() => { subscription.unsubscribe(); }); if (isRoot) { core$1.onUpdated(() => { this.onViewUpdated.next(); }); isRoot = false; } core$1.onUpdated(() => { textbusComponent.changeMarker.rendered(); if (!this.componentRootElementCaches.get(textbusComponent)) { // eslint-disable-next-line max-len throw adapterError(`Component \`${textbusComponent.name}\` is not bound to rootRef, you must bind rootRef to the root element node of the component view.`); } }); return viewFlyComponent(props); }; }); } render(rootComponent, injector) { const childInjector = new core$1.ReflectiveInjector(injector, [{ provide: core.Adapter, useValue: this }, { provide: platformBrowser.DomAdapter, useValue: this }, { provide: ViewflyAdapter, useValue: this }]); return super.render(rootComponent, childInjector); } copy() { document.execCommand('copy'); } } class ViewflyVDomAdapter extends platformNode.NodeViewAdapter { render(rootComponent, injector) { const childInjector = new core$1.ReflectiveInjector(injector, [{ provide: core.Adapter, useValue: this }, { provide: platformBrowser.DomAdapter, useValue: this }, { provide: ViewflyAdapter, useValue: this }]); return super.render(rootComponent, childInjector); } } exports.ViewflyAdapter = ViewflyAdapter; exports.ViewflyVDomAdapter = ViewflyVDomAdapter;