Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
public resolve(
node: Node,
rootNode: Node,
parentBlock: BlockElement,
inlineElementFactory: InlineElementFactory
): InlineElement {
// Create LinkInlineElement or ImageInlineElement depending on the tag, and resort to TextInlineElement at last
let inlineElement: InlineElement = null;
let tag = getTagOfNode(node);
if (tag == 'A') {
inlineElement = new LinkInlineElement(node, parentBlock);
} else if (tag == 'IMG') {
inlineElement = new ImageInlineElement(node, parentBlock);
} else if (node.nodeType == NodeType.Text) {
inlineElement = new TextInlineElement(node, parentBlock);
}
return inlineElement;
}
}
if (option.updateCursor) {
core.api.focus(core);
}
switch (option.position) {
case ContentPosition.Begin:
case ContentPosition.End: {
let isBegin = option.position == ContentPosition.Begin;
let block = getFirstLastBlockElement(contentDiv, isBegin);
let insertedNode: Node;
if (block) {
let refNode = isBegin ? block.getStartNode() : block.getEndNode();
if (
option.insertOnNewLine ||
refNode.nodeType == NodeType.Text ||
isVoidHtmlElement(refNode)
) {
// For insert on new line, or refNode is text or void html element (HR, BR etc.)
// which cannot have children, i.e. <div>hello<br>world</div>. 'hello', 'world' are the
// first and last node. Insert before 'hello' or after 'world', but still inside DIV
insertedNode = refNode.parentNode.insertBefore(
node,
isBegin ? refNode : refNode.nextSibling
);
} else {
// if the refNode can have child, use appendChild (which is like to insert as first/last child)
// i.e. <div>hello</div>, the content will be inserted before/after hello
insertedNode = refNode.insertBefore(node, isBegin ? refNode.firstChild : null);
}
} else {
// No first block, this can happen when editor is empty. Use appendChild to insert the content in contentDiv
function selectEditorPoint(core: EditorCore, container: Node, offset: number): boolean {
if (!container || !contains(core.contentDiv, container)) {
return false;
}
let range = core.document.createRange();
if (container.nodeType == NodeType.Text && offset <= container.nodeValue.length) {
range.setStart(container, offset);
} else if (offset == NodeBoundary.Begin) {
range.setStartBefore(container);
} else {
range.setStartAfter(container);
}
range.collapse(true /* toStart */);
return updateSelection(core, range);
}
}
// 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
// depending on what offset says
if (adjustedContainer.hasChildNodes()) {
if (adjustedOffset == 0) {
while (adjustedContainer.firstChild) {
adjustedContainer = adjustedContainer.firstChild;
}
} else {
// adjustedOffset == 1 meaning end of node
while (adjustedContainer.lastChild) {
adjustedContainer = adjustedContainer.lastChild;
adjustedOffset =
adjustedContainer.nodeType == NodeType.Text
? adjustedContainer.nodeValue.length
: NodeBoundary.End;
}
}
}
return { containerNode: adjustedContainer, offset: adjustedOffset };
}
editorPoint: EditorPoint,
inlineElementFactory: InlineElementFactory
) {
let inlineElement: InlineElement;
let containerNode = editorPoint.containerNode;
let offset = editorPoint.offset;
if (containerNode) {
let isPartial = false;
if (
(containerNode.nodeType == NodeType.Text && offset == containerNode.nodeValue.length) ||
(containerNode.nodeType == NodeType.Element && offset == NodeBoundary.End)
) {
// The point is at the end of container element
containerNode = getNextLeafSibling(rootNode, containerNode);
} else if (
containerNode.nodeType == NodeType.Text &&
offset > NodeBoundary.Begin &&
offset < containerNode.nodeValue.length
) {
// Run across a text node, this inline has to be partial
isPartial = true;
}
if (containerNode && shouldSkipNode(containerNode)) {
containerNode = getNextLeafSibling(rootNode, containerNode);
}
inlineElement = containerNode
? getInlineElementAtNode(rootNode, containerNode, inlineElementFactory)
: null;
// if the inline element we get in the end wraps (contains) the editor point, this has to be a partial
treatSameNodeAsContain?: boolean
): boolean {
if (!container || !contained) {
return false;
}
if (treatSameNodeAsContain && container == contained) {
return true;
}
if (!(contained instanceof Node)) {
contained = contained && contained.commonAncestorContainer;
treatSameNodeAsContain = true;
}
if (contained && contained.nodeType == NodeType.Text) {
contained = contained.parentNode;
treatSameNodeAsContain = true;
}
if (container.nodeType != NodeType.Element) {
return !!treatSameNodeAsContain && container == contained;
}
return !!(treatSameNodeAsContain || container != contained) && container.contains(contained);
}
function getPositionPath(position: NodePosition, rootNode: HTMLElement): number[] {
if (!position || !rootNode) {
return [];
}
let { node, offset } = position;
let result: number[] = [];
let parent: Node;
if (!contains(rootNode, node, true)) {
return [];
}
if (node.nodeType == NodeType.Text) {
parent = node.parentNode;
while (node.previousSibling && node.previousSibling.nodeType == NodeType.Text) {
offset += node.previousSibling.nodeValue.length;
node = node.previousSibling;
}
result.unshift(offset);
} else {
parent = node;
node = node.childNodes[offset];
}
do {
offset = 0;
let isPreviousText = false;
for (let c: Node = parent.firstChild; c && c != node; c = c.nextSibling) {
function getPositionPath(position: NodePosition, rootNode: HTMLElement): number[] {
if (!position || !rootNode) {
return [];
}
let { node, offset } = position;
let result: number[] = [];
let parent: Node;
if (!contains(rootNode, node, true)) {
return [];
}
if (node.nodeType == NodeType.Text) {
parent = node.parentNode;
while (node.previousSibling && node.previousSibling.nodeType == NodeType.Text) {
offset += node.previousSibling.nodeValue.length;
node = node.previousSibling;
}
result.unshift(offset);
} else {
parent = node;
node = node.childNodes[offset];
}
do {
offset = 0;
let isPreviousText = false;
for (let c: Node = parent.firstChild; c && c != node; c = c.nextSibling) {
if (c.nodeType == NodeType.Text) {
if (c.nodeValue.length == 0 || isPreviousText) {
export function isBlockQuoteAtNode(editor: Editor, node: Node): boolean {
let startNode = node && node.nodeType == NodeType.Text ? node.parentNode : node;
while (startNode && editor.contains(startNode)) {
let tagName = getTagOfNode(startNode);
if (tagName == 'BLOCKQUOTE') {
return true;
}
startNode = startNode.parentNode;
}
return false;
}