Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
export const insertNode: InsertNode = (core: EditorCore, node: Node, option: InsertOption) => {
option = option || {
position: ContentPosition.SelectionStart,
insertOnNewLine: false,
updateCursor: true,
replaceSelection: true,
};
let contentDiv = core.contentDiv;
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
// Otherwise, leave it as it is as we don't want to change the style for existing data
// unless the block was just created by the keyboard event (e.g. ctrl+a & start typing)
const shouldSetNodeStyles =
isNodeEmpty(formatNode) ||
(event && this.wasNodeJustCreatedByKeyboardEvent(event, formatNode));
formatNode = formatNode && shouldSetNodeStyles ? formatNode : null;
} else {
// Only reason we don't get the selection block is that we have an empty content div
// which can happen when users removes everything (i.e. select all and DEL, or backspace from very end to begin)
// The fix is to add a DIV wrapping, apply default format and move cursor over
formatNode = fromHtml(
Browser.isEdge ? '<div><span><br></span></div>' : '<div><br></div>',
this.editor.getDocument()
)[0] as HTMLElement;
this.editor.insertNode(formatNode, {
position: ContentPosition.End,
updateCursor: false,
replaceSelection: false,
insertOnNewLine: false,
});
// element points to a wrapping node we added "<div><br></div>". We should move the selection left to <br>
result = new Position(formatNode.firstChild, PositionType.Begin);
}
if (formatNode) {
applyFormat(formatNode, this.editor.getDefaultFormat(), this.editor.isDarkMode());
}
return result;
}
export const insertNode: InsertNode = (core: EditorCore, node: Node, option: InsertOption) => {
option = option || {
position: ContentPosition.SelectionStart,
insertOnNewLine: false,
updateCursor: true,
replaceSelection: true,
};
let contentDiv = core.contentDiv;
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
public getStartInlineElement(): InlineElement {
if (this.block) {
switch (this.startFrom) {
case ContentPosition.Begin:
case ContentPosition.End:
case ContentPosition.DomEnd:
return getFirstLastInlineElementFromBlockElement(
this.block,
this.startFrom == ContentPosition.Begin
);
case ContentPosition.SelectionStart:
// Get the inline before selection start point, and ensure it falls in the selection block
let startInline = getInlineElementAfter(this.rootNode, this.position);
return startInline && this.block.contains(startInline.getContainerNode())
? startInline
: new EmptyInlineElement(this.position, this.block);
}
}
return null;
}
onClick={() => this.setPosition(ContentPosition.End)}
/>
<div>
<input id="insertBegin" checked="{this.state.position" name="position" type="radio"> this.setPosition(ContentPosition.Begin)}
/>
<label>Begin</label>
</div>
<div>
<input id="insertEnd" checked="{this.state.position" name="position" type="radio"> this.setPosition(ContentPosition.End)}
/>
<label>End</label>
</div>
<div>
<input id="insertSelectionStart" checked="{this.state.position" name="position" type="radio"> this.setPosition(ContentPosition.SelectionStart)}
/>
<label>SelectionStart</label>
</div>
<div>
</div>