How to use @ephox/sand - 10 common examples

To help you get started, we’ve selected a few @ephox/sand examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github tinymce / tinymce / modules / tinymce / src / themes / silver / main / ts / ui / selector / TableSelectorHandles.ts View on Github external
import { AlloyComponent, Attachment, Behaviour, Boxes, Button, DragCoord, Dragging, DraggingTypes, GuiFactory, Memento, Unselecting } from '@ephox/alloy';
import { ClientRect } from '@ephox/dom-globals';
import { Arr, Cell, Option } from '@ephox/katamari';
import { PlatformDetection } from '@ephox/sand';
import { Compare, Css, Element, Position, Traverse } from '@ephox/sugar';

import Editor from 'tinymce/core/api/Editor';

const platform = PlatformDetection.detect();

const snapWidth = 40;
const snapOffset = snapWidth / 2;

// const insertDebugDiv = (left, top, width, height, color, clazz) => {
//   const debugArea = Element.fromHtml(`<div class="${clazz}"></div>`);
//   Css.setAll(debugArea, {
//     'left': left.toString() + 'px',
//     'top': top.toString() + 'px',
//     'background-color': color,
//     'position': 'absolute',
//     'width': width.toString() + 'px',
//     'height': height.toString() + 'px',
//     'opacity': '0.2'
//   });
//   Insert.append(Body.body(), debugArea);
github tinymce / tinymce / modules / tinymce / src / themes / silver / main / ts / ui / menus / contextmenu / platform / MobileContextMenu.ts View on Github external
export const initAndShow = (editor: Editor, e: EditorEvent, buildMenu: () =&gt; MenuItems, backstage: UiFactoryBackstage, contextmenu: AlloyComponent, isTriggeredByKeyboardEvent: boolean): void =&gt; {
  const detection = PlatformDetection.detect();
  const isiOS = detection.os.isiOS();
  const isOSX = detection.os.isOSX();
  const isAndroid = detection.os.isAndroid();

  const open = () =&gt; {
    const items = buildMenu();
    show(editor, e, items, backstage, contextmenu, isTriggeredByKeyboardEvent);
  };

  // On iOS/iPadOS if we've long pressed on a ranged selection then we've already selected the content
  // and just need to open the menu. Otherwise we need to wait for a selection change to occur as long
  // press triggers a ranged selection on iOS.
  if ((isOSX || isiOS) &amp;&amp; !isTriggeredByKeyboardEvent) {
    const openiOS = () =&gt; {
      setupiOSOverrides(editor);
      open();
github tinymce / tinymce / src / core / main / ts / keyboard / InputKeys.ts View on Github external
/**
 * 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 Editor from '../api/Editor';
import { normalizeNbspsInEditor } from './Nbsps';
import { PlatformDetection } from '@ephox/sand';
import { Throttler } from '@ephox/katamari';

const browser = PlatformDetection.detect().browser;

const setupIeInput = (editor: Editor) =&gt; {
  // We need to delay this since the normalization should happen after typing a letter
  // for example typing ab in a paragraph would otherwise result in a a&nbsp;b
  const keypressThrotter = Throttler.first(() =&gt; {
    // We only care about non composing inputs since moving the caret or modifying the text node will blow away the IME
    if (!editor.composing) {
      normalizeNbspsInEditor(editor);
    }
  }, 0);

  if (browser.isIE()) {
    // IE doesn't have the input event so we need to fake that with a keypress on IE keypress is only fired on alpha numeric keys
    editor.on('keypress', (e) =&gt; {
      keypressThrotter.throttle();
    });
github tinymce / tinymce / modules / tinymce / src / themes / silver / main / ts / ui / alien / DialogTabHeight.ts View on Github external
const setTabviewHeight = (tabview: Element, height: number) =&gt; {
  // Set both height and flex-basis as some browsers don't support flex-basis. However don't set it on
  // IE 11 since it incorrectly includes margins in the flex-basis calculations so it can't be relied on.
  Css.set(tabview, 'height', height + 'px');
  if (!PlatformDetection.detect().browser.isIE()) {
    Css.set(tabview, 'flex-basis', height + 'px');
  } else {
    Css.remove(tabview, 'flex-basis');
  }
};
github tinymce / tinymce / modules / tinymce / src / core / main / ts / selection / SelectionRestore.ts View on Github external
const registerEditorEvents = function (editor: Editor, throttledStore) {
  const browser = PlatformDetection.detect().browser;

  if (browser.isIE()) {
    registerFocusOut(editor);
  } else {
    registerMouseUp(editor, throttledStore);
  }

  editor.on('keyup NodeChange', function (e) {
    if (!isManualNodeChange(e)) {
      SelectionBookmark.store(editor);
    }
  });
};
github tinymce / tinymce / modules / tinymce / src / themes / silver / main / ts / ContextToolbar.ts View on Github external
const register = (editor: Editor, registryContextToolbars, sink, extras) =&gt; {
  const isTouch = PlatformDetection.detect().deviceType.isTouch;

  const contextbar = GuiFactory.build(
    renderContextToolbar({
      sink,
      onEscape: () =&gt; {
        editor.focus();
        return Option.some(true);
      }
    })
  );

  const getBounds = () =&gt; ContextToolbarBounds.getContextToolbarBounds(editor);

  const isRangeOverlapping = (aTop: number, aBottom: number, bTop: number, bBottom: number) =&gt; {
    return Math.max(aTop, bTop) &lt;= Math.min(aBottom, bBottom);
  };
github tinymce / tinymce / modules / tinymce / src / themes / mobile / main / ts / Theme.ts View on Github external
const renderUI = function () {
    const targetNode = editor.getElement();
    const cssUrls = CssUrls.derive(editor);

    if (Settings.isSkinDisabled(editor) === false) {
      editor.contentCSS.push(cssUrls.content);
      DOMUtils.DOM.styleSheetLoader.load(cssUrls.ui, SkinLoaded.fireSkinLoaded(editor));
    } else {
      SkinLoaded.fireSkinLoaded(editor)();
    }

    const doScrollIntoView = function () {
      editor.fire('ScrollIntoView');
    };

    const realm = PlatformDetection.detect().os.isAndroid() ? AndroidRealm(doScrollIntoView) : IosRealm(doScrollIntoView);
    const original = Element.fromDom(targetNode);
    Attachment.attachSystemAfter(original, realm.system());

    const findFocusIn = function (elem) {
      return Focus.search(elem).bind(function (focused) {
        return realm.system().getByDom(focused).toOption();
      });
    };
    const outerWindow = targetNode.ownerDocument.defaultView;
    const orientation = Orientation.onChange(outerWindow, {
      onChange () {
        const alloy = realm.system();
        alloy.broadcastOn([ TinyChannels.orientationChanged() ], { width: Orientation.getActualWidth(outerWindow) });
      },
      onReady: Fun.noop
    });
github tinymce / tinymce / modules / tinymce / src / core / main / ts / keyboard / EnterKey.ts View on Github external
/**
 * 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 { KeyboardEvent } from '@ephox/dom-globals';
import { PlatformDetection } from '@ephox/sand';

import Editor from '../api/Editor';
import UndoManager from '../api/UndoManager';
import { EditorEvent } from '../api/util/EventDispatcher';
import VK from '../api/util/VK';
import InsertNewLine from '../newline/InsertNewLine';

const platform = PlatformDetection.detect();
const browser = platform.browser;
const isTouch = platform.deviceType.isTouch();
const isSafari = browser.isSafari();

const endTypingLevel = function (undoManager: UndoManager) {
  if (undoManager.typing) {
    undoManager.typing = false;
    undoManager.add();
  }
};

const handleEnterKeyEvent = function (editor: Editor, event: EditorEvent) {

  if (event.isDefaultPrevented() || isSafari &amp;&amp; isTouch) {
    return;
  }
github tinymce / tinymce / modules / tinymce / src / core / main / ts / selection / SelectionBookmark.ts View on Github external
/**
 * 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 { document, Range } from '@ephox/dom-globals';
import { Option } from '@ephox/katamari';
import { PlatformDetection } from '@ephox/sand';
import { Compare, Element, Node, Text, Traverse, Selection } from '@ephox/sugar';
import Editor from '../api/Editor';
import NodeType from '../dom/NodeType';

const browser = PlatformDetection.detect().browser;

const clamp = function (offset, element) {
  const max = Node.isText(element) ? Text.get(element).length : Traverse.children(element).length + 1;

  if (offset &gt; max) {
    return max;
  } else if (offset &lt; 0) {
    return 0;
  }

  return offset;
};

const normalizeRng = function (rng) {
  return Selection.range(
    rng.start(),
github tinymce / tinymce / modules / tinymce / src / themes / mobile / main / ts / android / core / AndroidEvents.ts View on Github external
/**
 * 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 { Toggling } from '@ephox/alloy';
import { Arr, Fun } from '@ephox/katamari';
import { PlatformDetection } from '@ephox/sand';
import { Compare, DomEvent, Element, Focus, Node, Traverse } from '@ephox/sugar';

import TappingEvent from '../../util/TappingEvent';
import { HTMLInputElement } from '@ephox/dom-globals';

const isAndroid6 = PlatformDetection.detect().os.version.major >= 6;
/*

  `selectionchange` on the iframe document. If the selection is *ranged*, then we add the margin, because we
  assume that the context menu has appeared. If it is collapsed, then the context menu shouldn't appear
  (there is no selected text to format), so we reset the margin to `0px`. Note, when adding a margin,
  we add `23px` --- this is most likely based on trial and error. We may need to work out how to get
  this value properly.

  2. `select` on the outer document. This will also need to add the margin if the selection is ranged within
  an input or textarea

*/
const initEvents = function (editorApi, toolstrip, alloy) {

  const tapping = TappingEvent.monitor(editorApi);
  const outerDoc = Traverse.owner(toolstrip);

@ephox/sand

Platform detection library

MIT
Latest version published 3 months ago

Package Health Score

93 / 100
Full package analysis