Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
function setSelectionToBegin(core: EditorCore) {
let range: Range;
let firstNode = getFirstLeafNode(core.contentDiv);
if (firstNode) {
if (firstNode.nodeType == NodeType.Text) {
// First node is text, move range to the begin
range = core.document.createRange();
range.setStart(firstNode, 0);
} else if (firstNode.nodeType == NodeType.Element) {
if (isVoidHtmlElement(firstNode as HTMLElement)) {
// First node is a html void element (void elements cannot have child nodes), move range before it
range = core.document.createRange();
range.setStartBefore(firstNode);
} else {
// Other html element, move range inside it
range = core.document.createRange();
range.setStart(firstNode, 0);
}
}
} else {
// No first node, likely we have an empty content DIV, move range inside it
range = core.document.createRange();
range.setStart(core.contentDiv, 0);
}
export default function normalizeEditorPoint(container: Node, offset: number): EditorPoint {
let adjustedContainer = container;
let adjustedOffset = offset;
if (adjustedContainer.nodeType == NodeType.Element && adjustedContainer.hasChildNodes()) {
if (offset < adjustedContainer.childNodes.length) {
// offset points to a child node that exists
adjustedContainer = container.childNodes[offset];
adjustedOffset = NodeBoundary.Begin;
} else {
// offset points to end of container
adjustedContainer = container.childNodes[offset - 1];
adjustedOffset =
adjustedContainer.nodeType == NodeType.Text
? adjustedContainer.nodeValue.length
: NodeBoundary.End;
}
}
// Even we have an adjusted container, it does not mean it is a leaf
// Still need to do the check, and adjust a bit further to last or first child
function insertCursorMarkerToEditorPoint(
editor: Editor,
editorPoint: EditorPoint,
cursorMaker: Element
): void {
if (editor.contains(editorPoint.containerNode)) {
let containerNode = editorPoint.containerNode;
let offset = editorPoint.offset;
let parentNode = containerNode.parentNode;
if (editorPoint.offset == NodeBoundary.Begin) {
// For boundary_begin, insert the marker before the node
parentNode.insertBefore(cursorMaker, containerNode);
} else if (
containerNode.nodeType == NodeType.Element ||
(containerNode.nodeType == NodeType.Text &&
editorPoint.offset == containerNode.nodeValue.length)
) {
// otherwise, insert after
parentNode.insertBefore(cursorMaker, containerNode.nextSibling);
} else {
// This is for insertion in-between a text node
let insertionRange = editor.getDocument().createRange();
insertionRange.setStart(containerNode, offset);
insertionRange.collapse(true /* toStart */);
insertionRange.insertNode(cursorMaker);
}
}
}
function clearNodeFormat(
node: Node,
tagsToUnwrap: string[],
tagsToStopUnwrap: string[],
attributesToPreserve: string[]
): boolean {
if (node.nodeType != NodeType.Element || getTagOfNode(node) == 'BR') {
return false;
}
// 1. Recursively clear format of all its child nodes
let allChildrenAreBlock = ([].slice.call(node.childNodes) as Node[])
.map(n => clearNodeFormat(n, tagsToUnwrap, tagsToStopUnwrap, attributesToPreserve))
.reduce((previousValue, value) => previousValue && value, true);
if (!canCollapse(tagsToStopUnwrap, node)) {
return false;
}
let returnBlockElement = isBlockElement(node);
// 2. If we should unwrap this tag, put it into an array and unwrap it later
if (tagsToUnwrap.indexOf(getTagOfNode(node)) >= 0 || allChildrenAreBlock) {
export function setObject(customData: CustomData, element: Node, key: string, value: any) {
// Get the id for the element
if (element.nodeType == NodeType.Element) {
let id = getAndSetNodeId(customData, element as HTMLElement);
if (id != '') {
// Get the values for the element
if (!customData.dict[id]) {
// First time dictionary creation
customData.dict[id] = {};
}
customData.dict[id][key] = value;
}
}
}
export default function shouldSkipNode(node: Node): boolean {
if (node.nodeType == NodeType.Text) {
return !node.nodeValue || node.textContent == '' || CRLF.test(node.nodeValue);
} else if (node.nodeType == NodeType.Element) {
return getComputedStyle(node, 'display') == 'none';
} else {
return true;
}
}
export function getComputedStyles(
node: Node,
styleNames: string | string[] = ['font-family', 'font-size', 'color', 'background-color']
): string[] {
let result: string[] = [];
styleNames = styleNames instanceof Array ? styleNames : [styleNames];
if (node && node.nodeType == NodeType.Element) {
let win = node.ownerDocument.defaultView || window;
let styles = win.getComputedStyle(node as Element);
for (let style of styleNames) {
result.push(((styles && styles.getPropertyValue(style)) || '').toLowerCase());
}
}
return result;
}
editor.runAsync(() => {
let newContainer = editor.getElementAtCursor();
if (
contains(vtable.table, newContainer) &&
!contains(td, newContainer, true /*treatSameNodeAsContain*/)
) {
let newPos = targetTd
? new Position(targetTd, PositionType.Begin)
: new Position(vtable.table, isUp ? PositionType.Before : PositionType.After);
if (hasShiftKey) {
newPos =
newPos.node.nodeType == NodeType.Element && isVoidHtmlElement(newPos.node)
? new Position(
newPos.node,
newPos.isAtEnd ? PositionType.After : PositionType.Before
)
: newPos;
editor
.getSelection()
.setBaseAndExtent(anchorNode, anchorOffset, newPos.node, newPos.offset);
} else {
editor.select(newPos);
}
}
});
},
export default function isNodeEmpty(node: Node, trimContent?: boolean) {
if (!node) {
return false;
} else if (node.nodeType == NodeType.Text) {
return trim(node.nodeValue, trimContent) == '';
} else if (node.nodeType == NodeType.Element) {
let element = node as Element;
let textContent = trim(element.textContent, trimContent);
if (
textContent != '' ||
VISIBLE_ELEMENT_TAGS.indexOf(getTagOfNode(element)) >= 0 ||
element.querySelectorAll(VISIBLE_CHILD_ELEMENT_SELECTOR)[0]
) {
return false;
}
}
return true;
}