OXIESEC PANEL
- Current Dir:
/
/
var
/
www
/
reader
/
_backup
/
tinymce
/
tinymce
/
src
/
themes
/
silver
/
main
/
ts
/
ui
/
sidebar
Server IP: 139.59.38.164
Upload:
Create Dir:
Name
Size
Modified
Perms
📁
..
-
02/20/2020 06:40:48 AM
rwxr-xr-x
📄
Sidebar.ts
7.81 KB
02/20/2020 06:38:44 AM
rw-r--r--
Editing: Sidebar.ts
Close
/** * Copyright (c) Tiny Technologies, Inc. All rights reserved. * Licensed under the LGPL or a commercial license. * For LGPL see License.txt in the project root for license information. * For commercial licenses see https://www.tiny.cloud/ */ import { AddEventsBehaviour, AlloyComponent, AlloyEvents, AlloyTriggers, Behaviour, Composing, CustomEvent, Replacing, Sliding, SystemEvents, Tabstopping, Focusing, SlotContainer, SlotContainerTypes, } from '@ephox/alloy'; import { Sidebar as BridgeSidebar } from '@ephox/bridge'; import { HTMLElement } from '@ephox/dom-globals'; import { Arr, Id, Option, Obj, Cell, Fun } from '@ephox/katamari'; import { Css, Width } from '@ephox/sugar'; import Editor from 'tinymce/core/api/Editor'; import { ComposingConfigs } from '../alien/ComposingConfigs'; import { SimpleBehaviours } from '../alien/SimpleBehaviours'; import { onControlAttached, onControlDetached } from 'tinymce/themes/silver/ui/controls/Controls'; import { ValueSchema } from '@ephox/boulder'; export type SidebarConfig = Record<string, BridgeSidebar.SidebarApi>; const setup = (editor: Editor) => { const { sidebars } = editor.ui.registry.getAll(); // Setup each registered sidebar Arr.each(Obj.keys(sidebars), (name) => { const spec = sidebars[name]; const isActive = () => Option.from(editor.queryCommandValue('ToggleSidebar')).is(name); editor.ui.registry.addToggleButton(name, { icon: spec.icon, tooltip: spec.tooltip, onAction: (buttonApi) => { editor.execCommand('ToggleSidebar', false, name); buttonApi.setActive(isActive()); }, onSetup: (buttonApi) => { const handleToggle = () => buttonApi.setActive(isActive()); editor.on('ToggleSidebar', handleToggle); return () => { editor.off('ToggleSidebar', handleToggle); }; } }); }); }; const getApi = (comp: AlloyComponent): BridgeSidebar.SidebarInstanceApi => { return { element: (): HTMLElement => { return comp.element().dom(); } }; }; const makePanels = (parts: SlotContainerTypes.SlotContainerParts, panelConfigs: SidebarConfig) => { const specs = Arr.map(Obj.keys(panelConfigs), (name) => { const spec = panelConfigs[name]; const bridged = ValueSchema.getOrDie(BridgeSidebar.createSidebar(spec)); return { name, getApi, onSetup: bridged.onSetup, onShow: bridged.onShow, onHide: bridged.onHide }; }); return Arr.map(specs, (spec) => { const editorOffCell = Cell(Fun.noop); return parts.slot( spec.name, { dom: { tag: 'div', classes: ['tox-sidebar__pane'] }, behaviours: SimpleBehaviours.unnamedEvents([ onControlAttached(spec, editorOffCell), onControlDetached(spec, editorOffCell), AlloyEvents.run<SystemEvents.AlloySlotVisibilityEvent>(SystemEvents.slotVisibility(), (sidepanel, se) => { const data = se.event(); const optSidePanelSpec = Arr.find(specs, (config) => config.name === data.name()); optSidePanelSpec.each((sidePanelSpec) => { const handler = data.visible() ? sidePanelSpec.onShow : sidePanelSpec.onHide; handler(sidePanelSpec.getApi(sidepanel)); }); }) ]) } ); }); }; const makeSidebar = (panelConfigs: SidebarConfig) => SlotContainer.sketch((parts) => { return { dom: { tag: 'div', classes: ['tox-sidebar__pane-container'], }, components: makePanels(parts, panelConfigs), slotBehaviours: SimpleBehaviours.unnamedEvents([ AlloyEvents.runOnAttached((slotContainer) => SlotContainer.hideAllSlots(slotContainer)) ]) }; }); const setSidebar = (sidebar: AlloyComponent, panelConfigs: SidebarConfig) => { const optSlider = Composing.getCurrent(sidebar); optSlider.each((slider) => Replacing.set(slider, [makeSidebar(panelConfigs)])); }; const toggleSidebar = (sidebar: AlloyComponent, name: string) => { const optSlider = Composing.getCurrent(sidebar); optSlider.each((slider) => { const optSlotContainer = Composing.getCurrent(slider); optSlotContainer.each((slotContainer) => { if (Sliding.hasGrown(slider)) { if (SlotContainer.isShowing(slotContainer, name)) { // close the slider and then hide the slot after the animation finishes Sliding.shrink(slider); } else { SlotContainer.hideAllSlots(slotContainer); SlotContainer.showSlot(slotContainer, name); } } else { // Should already be hidden if the animation has finished but if it has not we hide them SlotContainer.hideAllSlots(slotContainer); SlotContainer.showSlot(slotContainer, name); Sliding.grow(slider); } }); }); }; const whichSidebar = (sidebar: AlloyComponent): Option<string> => { const optSlider = Composing.getCurrent(sidebar); return optSlider.bind((slider) => { const sidebarOpen = Sliding.isGrowing(slider) || Sliding.hasGrown(slider); if (sidebarOpen) { const optSlotContainer = Composing.getCurrent(slider); return optSlotContainer.bind((slotContainer) => Arr.find(SlotContainer.getSlotNames(slotContainer), (name) => SlotContainer.isShowing(slotContainer, name) ) ); } else { return Option.none(); } }); }; interface FixSizeEvent extends CustomEvent { width: () => string; } const fixSize = Id.generate('FixSizeEvent'); const autoSize = Id.generate('AutoSizeEvent'); const renderSidebar = (spec) => { return { uid: spec.uid, dom: { tag: 'div', classes: ['tox-sidebar'], attributes: { role: 'complementary' } }, components: [ { dom: { tag: 'div', classes: ['tox-sidebar__slider'] }, components: [ // this will be replaced on setSidebar ], behaviours: Behaviour.derive([ Tabstopping.config({ }), Focusing.config({ }), // TODO use Keying and use focusIn, but need to handle if sidebar contains nothing Sliding.config({ dimension: { property: 'width' }, closedClass: 'tox-sidebar--sliding-closed', openClass: 'tox-sidebar--sliding-open', shrinkingClass: 'tox-sidebar--sliding-shrinking', growingClass: 'tox-sidebar--sliding-growing', onShrunk: (slider: AlloyComponent) => { const optSlotContainer = Composing.getCurrent(slider); optSlotContainer.each(SlotContainer.hideAllSlots); AlloyTriggers.emit(slider, autoSize); }, onGrown: (slider: AlloyComponent) => { AlloyTriggers.emit(slider, autoSize); }, onStartGrow: (slider: AlloyComponent) => { AlloyTriggers.emitWith(slider, fixSize, { width: Css.getRaw(slider.element(), 'width').getOr('') }); }, onStartShrink: (slider: AlloyComponent) => { AlloyTriggers.emitWith(slider, fixSize, { width: Width.get(slider.element()) + 'px' }); } }), Replacing.config({}), Composing.config({ find: (comp: AlloyComponent) => { const children = Replacing.contents(comp); return Arr.head(children); } }) ]) } ], behaviours: Behaviour.derive([ ComposingConfigs.childAt(0), AddEventsBehaviour.config('sidebar-sliding-events', [ AlloyEvents.run<FixSizeEvent>(fixSize, (comp, se) => { Css.set(comp.element(), 'width', se.event().width()); }), AlloyEvents.run(autoSize, (comp, se) => { Css.remove(comp.element(), 'width'); }) ]) ]) }; }; export { setSidebar, toggleSidebar, whichSidebar, renderSidebar, setup };