UNPKG

activator-oce-exporter

Version:

Extract Activator binder and convert it to valid OCE mono pacakge

367 lines (330 loc) 8.53 kB
import { html } from '@polymer/lit-element'; import { FusionBase } from '../../base'; import { FusionApi } from '../../api'; import { FusionLogger } from '../../services/fusion-logger'; import { applyMixins, SlideComponent } from '../../mixins'; class FusionAction extends applyMixins(FusionBase, [SlideComponent]) { static get animationAttr() { return 'data-anijs'; } static get properties() { return { if: { type: String, fieldType: 'Select', value: 'click', selectOptions: [ 'click', 'dblclick', 'enter', 'exit', 'focus', 'blur', 'scroll', 'animationstart', 'animationend', 'transitionstart', 'transitionend', 'dragstart', 'drag', 'dragend', 'loadNotification', '$custom', ], }, on: { type: String, fieldType: 'Select', value: 'root', selectOptions: [ 'root', '$element', 'notifier', ], }, to: { type: String, fieldType: 'Select', value: '', selectOptions: [ 'target', '$element', '$parent', '$closest', '$find', '$children', '$slide', '$binder', ], }, do: { type: String, fieldType: 'Select', value: '', selectOptions: [ '$navigate', '$next', '$previous', 'toggleActivation', 'activate', 'inactivate', '$applyState', '$removeState', '$toggleState', '$setStates', 'nextState', 'previousState', // '$clone', // '$remove', 'bounce', 'fadeIn', 'fadeOut', 'pulse', 'slideInLeft', 'slideInRight', // '$addClass', // '$removeClass', // '$toggleClass', ], }, binder: { type: String, fieldType: 'String', value: '', }, slide: { type: String, fieldType: 'String', value: '', }, state: { type: String, fieldType: 'String', value: '', }, width: { type: String, fieldType: 'Number', value: '1px', }, height: { type: String, fieldType: 'Number', value: '1px', }, }; } static get options() { return { componentName: 'fusion-action', componentUIName: 'Action', componentScope: 'standard', componentType: 'system', componentCategory: 'other', componentDescription: 'Adds interactions and animations to components and other elements', componentDomain: 'slide', isTextEdit: false, isRootNested: false, nestedTypes: [], nestedComponents: [], isAction: true, defaultTemplate: '', goToProps: { binder: '', slide: '', }, stateProps: { state: '', }, }; } static get SUPPORTED_METHODS() { return { enter: '_open', exit: '_close', toggleActivation: '_toggleActivation', nextState: '_nextState', previousState: '_previousState', $applyState: '_applyState', $removeState: '_removeState', $toggleState: '_toggleState', $setStates: '_setStates', $navigate: '_navigate', $next: '_next', $previous: '_previous', }; } static get SUPPORTED_ANIMATIONS() { return [ 'bounce', 'fadeIn', 'fadeOut', 'pulse', 'slideInLeft', 'slideInRight', ]; } async createBehavior() { const todo = FusionAction.getAction(this.do); const actionHandler = FusionAction.getActionHandler(todo[0]); let target = this.getTarget(); // Translate into AniJS strings // @todo simplify this logic if (this.if === 'loadNotification') { this.if = 'onRunFinished'; } if (this.on === 'notifier') { this.on = '$AniJSNotifier'; } if (this.on === '$AniJSNotifier') { target = true; } if (target && actionHandler) { this.listenerHandler = this[actionHandler].bind(this); if (this.if === 'onRunFinished') { await this.untilPublished; this.listenerHandler(); } else { target.addEventListener(this.if, (e) => { this.listenerHandler(); e.stopPropagation(); }); this.removeAnimation(); } } else if (target) { this.setAnimation(); } else { FusionLogger.error(`Target not found: ${this.on}`, 'fusion-action'); } } getTargetFromRoot(root) { if (this.isInnerShadowRootAction()) { root = this.getRootNode(); } return root.querySelector(this.on); } isRootTarget() { return this.on === 'root'; } isInnerShadowRootAction() { const actionTarget = document.querySelector(this.on); // NOTE: should be `getElementById` because `.contains` doesn't work on iPad return !document.contains(actionTarget) && !document.getElementById(this.id); } getTarget() { const root = FusionApi.getRootNode(); return this.isRootTarget() ? root : this.getTargetFromRoot(root); } static getAction(todo) { return todo.split(' '); } static getActionHandler(todo) { return FusionAction.SUPPORTED_METHODS[todo]; } isAnimation() { return window.AniJS && this.getAttribute(FusionAction.animationAttr); } async setAnimation() { const attrValue = `if: ${this.if}, on: ${this.on}, do: ${this.do} animated, to: ${this.to}`; if (attrValue !== this.getAttribute(FusionAction.animationAttr)) { this.setAttribute(FusionAction.animationAttr, attrValue); await this.untilPublished; FusionApi.saveAttributes(`#${this.id}`, { [FusionAction.animationAttr]: attrValue }); } } removeAnimation() { if (this.isAnimation()) { this.removeAttribute(FusionAction.animationAttr); FusionApi.saveAttributes(`#${this.id}`, { [FusionAction.animationAttr]: '' }); } } removeListener() { if (this.listenerHandler) { const target = this.getTarget(); target.removeEventListener(this.if, this.listenerHandler); } } isActionChanged(changedProps) { return this.do && changedProps.get('do'); } isStateChanged(changedProps) { return this.state && changedProps.get('state'); } changeHandler(changedProps) { const doValue = changedProps.get('do') || this.do; const oldAction = FusionAction.getAction(doValue)[0]; if (FusionAction.getActionHandler(oldAction)) { this.removeListener(); } } update(changedProps) { super.update(changedProps); if (this.isActionChanged(changedProps) || this.isStateChanged(changedProps)) { this.changeHandler(changedProps); } this.createBehavior(); } disconnectedCallback() { super.disconnectedCallback(); this.removeListener(); } _applyState() { this.pushState(this.state, '', false); } _removeState() { this.removeState(this.state, '', false); } _toggleState() { FusionApi.toggleState(this.state, ''); } _setStates() { this.setStates(this.state, '', false); } _nextState() { this.nextState(); } _previousState() { this.previousState(); } _navigate() { FusionApi.goTo(this.slide, this.binder); } _next() { FusionApi.goTo(this.slide, this.binder, 'next'); } _previous() { FusionApi.goTo(this.slide, this.binder, 'previous'); } // Activate a stateful element _open() { const el = document.querySelector(this.to); if (el && el.activate) el.activate(); this.emitCustomEvent('activateStateful'); } // Inactivate a stateful element _close() { const el = document.querySelector(this.to); if (el && el.inactivate) el.inactivate(); } // Toggle activation in stateful element _toggleActivation() { const el = document.querySelector(this.to); if (el && el.inactivate && el.activate) { if (el.active) { this.emitCustomEvent('inactivateStateful'); el.inactivate(); } else { this.emitCustomEvent('activateStateful'); el.activate(); } } } _createRoot() { return this; } render() { super.render(); return html``; } } export { FusionAction };