OXIESEC PANEL
- Current Dir:
/
/
var
/
www
/
reader
/
_backup
/
tinymce
/
tinymce
/
src
/
core
/
main
/
ts
/
delete
Server IP: 139.59.38.164
Upload:
Create Dir:
Name
Size
Modified
Perms
📁
..
-
02/20/2020 05:44:43 AM
rwxr-xr-x
📄
BlockBoundaryDelete.ts
950 bytes
02/20/2020 05:42:46 AM
rw-r--r--
📄
BlockMergeBoundary.ts
3.03 KB
02/20/2020 05:42:46 AM
rw-r--r--
📄
BlockRangeDelete.ts
2.51 KB
02/20/2020 05:42:47 AM
rw-r--r--
📄
CefBoundaryDelete.ts
3.77 KB
02/20/2020 05:42:47 AM
rw-r--r--
📄
CefDelete.ts
3.16 KB
02/20/2020 05:42:48 AM
rw-r--r--
📄
CefDeleteAction.ts
5.63 KB
02/20/2020 05:42:49 AM
rw-r--r--
📄
DeleteCommands.ts
2.09 KB
02/20/2020 05:42:49 AM
rw-r--r--
📄
DeleteElement.ts
6.5 KB
02/20/2020 05:42:50 AM
rw-r--r--
📄
DeleteUtils.ts
2.39 KB
02/20/2020 05:42:50 AM
rw-r--r--
📄
ImageBlockDelete.ts
1.23 KB
02/20/2020 05:42:51 AM
rw-r--r--
📄
InlineBoundaryDelete.ts
4.91 KB
02/20/2020 05:42:52 AM
rw-r--r--
📄
InlineFormatDelete.ts
2.38 KB
02/20/2020 05:42:52 AM
rw-r--r--
📄
MergeBlocks.ts
3.69 KB
02/20/2020 05:42:53 AM
rw-r--r--
📄
MergeText.ts
2.9 KB
02/20/2020 05:42:53 AM
rw-r--r--
📄
TableDelete.ts
5.81 KB
02/20/2020 05:42:54 AM
rw-r--r--
📄
TableDeleteAction.ts
4.26 KB
02/20/2020 05:42:54 AM
rw-r--r--
Editing: CefDeleteAction.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 { Node, Range } from '@ephox/dom-globals'; import { Adt, Fun , Option } from '@ephox/katamari'; import { Element } from '@ephox/sugar'; import CaretFinder from '../caret/CaretFinder'; import CaretPosition from '../caret/CaretPosition'; import * as CaretUtils from '../caret/CaretUtils'; import DeleteUtils from './DeleteUtils'; import Empty from '../dom/Empty'; import NodeType from '../dom/NodeType'; import * as ElementType from '../dom/ElementType'; import { findPreviousBr, findNextBr, isAfterBr, isBeforeBr } from '../caret/CaretBr'; import { isAfterContentEditableFalse, isBeforeContentEditableFalse } from '../caret/CaretPositionPredicates'; const isCompoundElement = (node: Node) => ElementType.isTableCell(Element.fromDom(node)) || ElementType.isListItem(Element.fromDom(node)); const DeleteAction = Adt.generate([ { remove: [ 'element' ] }, { moveToElement: [ 'element' ] }, { moveToPosition: [ 'position' ] } ]); const isAtContentEditableBlockCaret = (forward: boolean, from: CaretPosition) => { const elm = from.getNode(forward === false); const caretLocation = forward ? 'after' : 'before'; return NodeType.isElement(elm) && elm.getAttribute('data-mce-caret') === caretLocation; }; const isDeleteFromCefDifferentBlocks = (root: Node, forward: boolean, from: CaretPosition, to: CaretPosition) => { const inSameBlock = (elm) => ElementType.isInline(Element.fromDom(elm)) && !CaretUtils.isInSameBlock(from, to, root); return CaretUtils.getRelativeCefElm(!forward, from).fold( () => CaretUtils.getRelativeCefElm(forward, to).fold(Fun.constant(false), inSameBlock), inSameBlock ); }; const deleteEmptyBlockOrMoveToCef = (root: Node, forward: boolean, from: CaretPosition, to: CaretPosition) => { const toCefElm = to.getNode(forward === false); return DeleteUtils.getParentBlock(Element.fromDom(root), Element.fromDom(from.getNode())).map(function (blockElm) { return Empty.isEmpty(blockElm) ? DeleteAction.remove(blockElm.dom()) : DeleteAction.moveToElement(toCefElm); }).orThunk(function () { return Option.some(DeleteAction.moveToElement(toCefElm)); }); }; const findCefPosition = (root: Node, forward: boolean, from: CaretPosition) => { return CaretFinder.fromPosition(forward, root, from).bind(function (to) { if (isCompoundElement(to.getNode())) { return Option.none(); } else if (isDeleteFromCefDifferentBlocks(root, forward, from, to)) { return Option.none(); } else if (forward && NodeType.isContentEditableFalse(to.getNode())) { return deleteEmptyBlockOrMoveToCef(root, forward, from, to); } else if (forward === false && NodeType.isContentEditableFalse(to.getNode(true))) { return deleteEmptyBlockOrMoveToCef(root, forward, from, to); } else if (forward && isAfterContentEditableFalse(from)) { return Option.some(DeleteAction.moveToPosition(to)); } else if (forward === false && isBeforeContentEditableFalse(from)) { return Option.some(DeleteAction.moveToPosition(to)); } else { return Option.none(); } }); }; const getContentEditableBlockAction = (forward: boolean, elm: Node) => { if (forward && NodeType.isContentEditableFalse(elm.nextSibling)) { return Option.some(DeleteAction.moveToElement(elm.nextSibling)); } else if (forward === false && NodeType.isContentEditableFalse(elm.previousSibling)) { return Option.some(DeleteAction.moveToElement(elm.previousSibling)); } else { return Option.none(); } }; const skipMoveToActionFromInlineCefToContent = (root: Node, from: CaretPosition, deleteAction) => { return deleteAction.fold( function (elm) { return Option.some(DeleteAction.remove(elm)); }, function (elm) { return Option.some(DeleteAction.moveToElement(elm)); }, function (to) { if (CaretUtils.isInSameBlock(from, to, root)) { return Option.none(); } else { return Option.some(DeleteAction.moveToPosition(to)); } } ); }; const getContentEditableAction = (root: Node, forward: boolean, from: CaretPosition) => { if (isAtContentEditableBlockCaret(forward, from)) { return getContentEditableBlockAction(forward, from.getNode(forward === false)) .fold( function () { return findCefPosition(root, forward, from); }, Option.some ); } else { return findCefPosition(root, forward, from).bind(function (deleteAction) { return skipMoveToActionFromInlineCefToContent(root, from, deleteAction); }); } }; const read = (root: Node, forward: boolean, rng: Range): Option<any> => { const normalizedRange = CaretUtils.normalizeRange(forward ? 1 : -1, root, rng); const from = CaretPosition.fromRangeStart(normalizedRange); const rootElement = Element.fromDom(root); if (forward === false && isAfterContentEditableFalse(from)) { return Option.some(DeleteAction.remove(from.getNode(true))); } else if (forward && isBeforeContentEditableFalse(from)) { return Option.some(DeleteAction.remove(from.getNode())); } else if (forward === false && isBeforeContentEditableFalse(from) && isAfterBr(rootElement, from)) { return findPreviousBr(rootElement, from).map((br) => DeleteAction.remove(br.getNode())); } else if (forward && isAfterContentEditableFalse(from) && isBeforeBr(rootElement, from)) { return findNextBr(rootElement, from).map((br) => DeleteAction.remove(br.getNode())); } else { return getContentEditableAction(root, forward, from); } }; export { read };