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
public onPluginEvent(event: PluginEvent) {
switch (event.eventType) {
case PluginEventType.ContentChanged:
if (event.source == ChangeSource.SetContent && this.dataProvider.onContentChanged) {
// Stop suggesting since content is fully changed
if (this.isSuggesting) {
this.setIsSuggesting(false);
}
// Undos and other major changes to document content fire this type of event.
// Inform the data provider of the current picker placed elements in the body.
let elementIds: string[] = [];
this.editor.queryElements(
"[id^='" + this.pickerOptions.elementIdPrefix + "']",
element => {
if (element.id) {
elementIds.push(element.id);
}
}
? cacheGetEventData(event, 'LINK_DATA', () => {
// First try to match link from the whole paste string from the plain text in clipboard.
// This helps when we paste a link next to some existing character, and the text we got
// from clipboard will only contain what we pasted, any existing characters will not
// be included.
let clipboardData =
event.eventType == PluginEventType.ContentChanged &&
event.source == ChangeSource.Paste &&
(event.data as ClipboardData);
let link = matchLink((clipboardData.text || '').trim());
let searcher = cacheGetContentSearcher(event, editor);
// In case the matched link is already inside a <a> tag, we do a range search.
// getRangeFromText will return null if the given text is already in a LinkInlineElement
if (link && searcher.getRangeFromText(link.originalUrl, false /*exactMatch*/)) {
return link;
}
let word = searcher && searcher.getWordBefore();
if (word && word.length > MINIMUM_LENGTH) {
// Check for trailing punctuation
let trailingPunctuations = word.match(TRAILING_PUNCTUATION_REGEX);
let trailingPunctuation = (trailingPunctuations || [])[0] || '';
</a>
private onPasteComplete = (clipboardData: ClipboardData) => {
let pasteHandler = this.pasteHandler || this.defaultPasteHandler;
if (clipboardData) {
// if any clipboard data exists, call into pasteHandler
pasteHandler(clipboardData);
}
// add undo snapshot after paste
// broadcast contentChangedEvent to ensure the snapshot actually gets added
let contentChangedEvent: PluginEvent = { eventType: PluginEventType.ContentChanged };
this.editor.triggerEvent(contentChangedEvent, true /* broadcast */);
this.editor.addUndoSnapshot();
};
// There is already list node, setIndentation() will increase/decrease the list level,
// so we need to process the list when change indentation
newNode = processList(editor, command);
} else {
// No existing list node, browser will create <blockquote> node for indentation.
// We need to set top and bottom margin to 0 to avoid unnecessary spaces
editor.getDocument().execCommand(command, false, null);
editor.queryElements('BLOCKQUOTE', QueryScope.OnSelection, node => {
newNode = newNode || node;
node.style.marginTop = '0px';
node.style.marginBottom = '0px';
});
}
return newNode;
}, ChangeSource.Format);
}
</blockquote>
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;
}