activator-oce-exporter
Version:
Extract Activator binder and convert it to valid OCE mono pacakge
300 lines (264 loc) • 7.62 kB
JavaScript
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 };