UNPKG

activator-oce-exporter

Version:

Extract Activator binder and convert it to valid OCE mono pacakge

300 lines (264 loc) 7.62 kB
import { html } from '@polymer/lit-element'; import { FusionBase } from '../../base'; import { FusionApi } from '../../api'; import { store } from '../../../store'; import { applyToObject } from '../../utils'; import { applyMixins, SlideComponent } from '../../mixins'; const placeholdersTypes = { text: { props: { width: '980px', height: '100px', }, styles: { top: '300px', left: '20px', }, template: 'Click to add text', }, list: { props: { width: '400px', height: '400px', }, styles: { top: '150px', left: '20px', }, template: 'Click to add list', }, table: { props: { width: '560px', height: '400px', }, styles: { top: '150px', left: '440px', }, template: 'Click to add table', }, audio: { props: { width: '400px', height: '50px', }, styles: { top: '570px', left: '20px', }, template: 'Click to add audio', }, }; const types = []; const typesConfig = { list: 'fusion-list', table: 'fusion-table', text: 'fusion-text', audio: 'fusion-audio-player', }; const getComponentByTag = tagName => customElements.get(tagName); const getComponentTagByType = type => typesConfig[type]; const setPlaceholderTypes = components => Object.keys(typesConfig) .filter(item => components.includes(typesConfig[item])) .forEach(item => types.push(item)); document.addEventListener('ComponentsRegistrar:allComponentsRegistered', () => { const components = store.getState().app.registeredComponents; setPlaceholderTypes(components); }); class FusionPlaceholder extends applyMixins(FusionBase, [SlideComponent]) { static get properties() { return { width: { type: String, fieldType: 'Number', value: '980px', }, height: { type: String, fieldType: 'Number', value: '100px', }, placeholderType: { type: String, fieldType: 'Select', value: 'text', prop: true, selectOptions: types, }, }; } static get options() { return { componentName: 'fusion-placeholder', componentType: 'static', componentCategory: 'UI', componentUIName: 'Placeholder', componentScope: 'standard', componentDescription: 'Component for placing other components', componentDomain: 'slide', isRootNested: true, isTextEdit: false, nestedTypes: [], nestedComponents: [], defaultTemplate: '', resizable: 'all', draggable: 'xy', rotatable: true, sortable: false, }; } connectedCallback() { super.connectedCallback(); this.componentDisconnectedhandler = this.componentDisconnected.bind(this); this.placeholderDbClickHandler = this.initPlaceholderComponent.bind(this); } initComponentListeners() { this.component = this.getPlaceholderComponent(); if (this.component) { const disconnectedHandler = `${this.component.constructor.options.componentName}:disconnected`; this.component.addEventListener(disconnectedHandler, this.componentDisconnectedhandler); } } initPlaceholder() { this.initAttr(); this.initTemplate(); } initComponentStyle(style) { this.component.style[style] = this.style[style]; } initPlaceholderStyle(style) { this.style[style] = placeholdersTypes[this.placeholderType].styles[style]; } initPlaceholderProp(prop) { const value = placeholdersTypes[this.placeholderType].props[prop]; this.setElementProp(prop, value); this.setAttribute(prop, value); } async initPlaceholderComponent() { await this.initComponent(); this.initComponentStyles(); this.initComponentListeners(); this.hide(); } getPlaceholderComponent() { return this.component || document.querySelector(`[data-placeholder=${this.id}`); } initComponentStyles() { const { styles } = placeholdersTypes[this.placeholderType]; applyToObject(styles, this.initComponentStyle.bind(this)); this.saveComponentStyles(styles); } saveComponentStyles(styles) { const componentStyles = {}; Object.keys(styles).map((style) => { componentStyles[style] = this.style[style]; return componentStyles; }); FusionApi.saveStyles(`#${this.component.id}`, componentStyles); } initAttr() { const { props, styles } = placeholdersTypes[this.placeholderType]; applyToObject(props, this.initPlaceholderProp.bind(this)); applyToObject(styles, this.initPlaceholderStyle.bind(this)); } initTemplate() { this.innerHTML = placeholdersTypes[this.placeholderType].template; } setupPlaceholderProps(componentProps) { const { props } = placeholdersTypes[this.placeholderType]; Object.keys(props) .filter(prop => componentProps[prop]) .map((prop) => { componentProps[prop].value = this[prop]; return componentProps; }); return componentProps; } async initComponent() { const parent = document.querySelector('article.slide'); const componentTagName = getComponentTagByType(this.placeholderType); const component = getComponentByTag(componentTagName); const { componentName, defaultTemplate } = component.options; const ownProps = { 'data-placeholder': { value: this.id } }; const componentProps = { ...component.properties, ...ownProps }; const props = this.setupPlaceholderProps(componentProps); this.component = await FusionApi.createElement( componentName, props, defaultTemplate, parent, 'article.slide', {}, ); } hide() { this.setAttribute('placeholder-visibility', 'hidden'); FusionApi.saveAttributes(`#${this.id}`, { 'placeholder-visibility': 'hidden' }); } show() { this.setAttribute('placeholder-visibility', 'visible'); FusionApi.saveAttributes(`#${this.id}`, { 'placeholder-visibility': 'visible' }); } componentDisconnected() { this.component = null; this.show(); } initListeners() { this.addEventListener('dblclick', this.placeholderDbClickHandler); } isFirstRender() { const { styles } = placeholdersTypes[this.placeholderType]; return Object.keys(styles).every(style => !this.style[style]); } needReInit(changedProps) { return this.isTypeChanged(changedProps) || this.isFirstRender(); } isTypeChanged(changedProps) { const prevType = changedProps.get('placeholderType'); return prevType && this.placeholderType !== prevType; } update(changedProps) { super.update(changedProps); if (this.needReInit(changedProps)) { this.initPlaceholder(); } } firstUpdated(changedProps) { super.firstUpdated(changedProps); this.initListeners(); this.initComponentListeners(); } disconnectedCallback() { super.disconnectedCallback(); this.removeEventListener('dblclick', this.placeholderDbClickHandler); } static getStyle() { const styleRoot = super.getStyle(); return ` ${styleRoot} :host { display: block; border: 1px solid #bbbbbb; } :host([placeholder-visibility='hidden']){ display: none; } :host .placeholder{ width: 100%; height: 100%; }`; } render() { super.render(); return html` <style> ${FusionPlaceholder.getStyle()} </style> <div class='placeholder'> <slot></slot> </div> ${FusionPlaceholder.getSystemSlotTemplate()}`; } } export { FusionPlaceholder };