@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
JavaScript
;
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;