/** * 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 { Attachment } from '@ephox/alloy'; import { Cell } from '@ephox/katamari'; import { Body, DomEvent, Element, Position, Css } from '@ephox/sugar'; import DOMUtils from 'tinymce/core/api/dom/DOMUtils'; import Editor from 'tinymce/core/api/Editor'; import Events from '../api/Events'; import * as Settings from '../api/Settings'; import { UiFactoryBackstage } from '../backstage/Backstage'; import { setupReadonlyModeSwitch } from '../ReadOnly'; import { ModeRenderInfo, RenderArgs, RenderUiComponents, RenderUiConfig } from '../Render'; import OuterContainer from '../ui/general/OuterContainer'; import { identifyMenus } from '../ui/menus/menubar/Integration'; import { iframe as loadIframeSkin } from './../ui/skin/Loader'; import { setToolbar } from './Toolbars'; import { PlatformDetection } from '@ephox/sand'; const DOM = DOMUtils.DOM; const detection = PlatformDetection.detect(); const isTouch = detection.deviceType.isTouch(); const setupEvents = (editor: Editor) => { const contentWindow = editor.getWin(); const initialDocEle = editor.getDoc().documentElement; const lastWindowDimensions = Cell(Position(contentWindow.innerWidth, contentWindow.innerHeight)); const lastDocumentDimensions = Cell(Position(initialDocEle.offsetWidth, initialDocEle.offsetHeight)); const resize = () => { // Don't use the initial doc ele, as there's a small chance it may have changed const docEle = editor.getDoc().documentElement; // Check if the window or document dimensions have changed and if so then trigger a content resize event const outer = lastWindowDimensions.get(); const inner = lastDocumentDimensions.get(); if (outer.left() !== contentWindow.innerWidth || outer.top() !== contentWindow.innerHeight) { lastWindowDimensions.set(Position(contentWindow.innerWidth, contentWindow.innerHeight)); Events.fireResizeContent(editor); } else if (inner.left() !== docEle.offsetWidth || inner.top() !== docEle.offsetHeight) { lastDocumentDimensions.set(Position(docEle.offsetWidth, docEle.offsetHeight)); Events.fireResizeContent(editor); } }; DOM.bind(contentWindow, 'resize', resize); // Bind to async load events and trigger a content resize event if the size has changed const elementLoad = DomEvent.capture(Element.fromDom(editor.getBody()), 'load', resize); editor.on('remove', () => { elementLoad.unbind(); DOM.unbind(contentWindow, 'resize', resize); }); }; const render = (editor: Editor, uiComponents: RenderUiComponents, rawUiConfig: RenderUiConfig, backstage: UiFactoryBackstage, args: RenderArgs): ModeRenderInfo => { const lastToolbarWidth = Cell(0); loadIframeSkin(editor); Attachment.attachSystemAfter(Element.fromDom(args.targetNode), uiComponents.mothership); Attachment.attachSystem(Body.body(), uiComponents.uiMothership); editor.on('init', () => { setToolbar(editor, uiComponents, rawUiConfig, backstage); lastToolbarWidth.set(editor.getWin().innerWidth); OuterContainer.setMenubar( uiComponents.outerContainer, identifyMenus(editor, rawUiConfig) ); OuterContainer.setSidebar( uiComponents.outerContainer, rawUiConfig.sidebar ); setupEvents(editor); }); const socket = OuterContainer.getSocket(uiComponents.outerContainer).getOrDie('Could not find expected socket element'); if (isTouch === true) { // TODO: move me, Setup mobile scrolling, Css.setAll(socket.element(), { 'overflow': 'scroll', '-webkit-overflow-scrolling': 'touch' // required for ios < 13 }); } setupReadonlyModeSwitch(editor, uiComponents); editor.addCommand('ToggleSidebar', (ui: boolean, value: string) => { OuterContainer.toggleSidebar(uiComponents.outerContainer, value); editor.fire('ToggleSidebar'); }); editor.addQueryValueHandler('ToggleSidebar', () => { return OuterContainer.whichSidebar(uiComponents.outerContainer); }); const drawer = Settings.getToolbarDrawer(editor); const refreshDrawer = () => { OuterContainer.refreshToolbar(uiComponents.outerContainer); }; if (drawer === Settings.ToolbarDrawer.sliding || drawer === Settings.ToolbarDrawer.floating) { editor.on('ResizeContent', () => { // Check if the width has changed, if so then refresh the toolbar drawer. We don't care if height changes. const width = editor.getWin().innerWidth; if (width !== lastToolbarWidth.get()) { refreshDrawer(); } lastToolbarWidth.set(width); }); } return { iframeContainer: socket.element().dom(), editorContainer: uiComponents.outerContainer.element().dom(), }; }; export default { render, getBehaviours: (_) => [] };