sutty/app/javascript/editor/utils.ts

67 lines
2 KiB
TypeScript
Raw Normal View History

import { Editor } from 'editor/editor'
export const blockNames = ['paragraph', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'unordered_list', 'ordered_list']
export const markNames = ['bold', 'italic', 'deleted', 'underline', 'sub', 'super', 'mark', 'a']
export const parentBlockNames = ['left', 'center', 'right']
export function moveChildren (from: Element, to: Element, toRef: Node | null) {
while (from.firstChild) to.insertBefore(from.firstChild, toRef)
}
export function isDirectChild (node: Node, supposedChild: Node): boolean {
for (const child of node.childNodes) {
if (child == supposedChild) return true
}
return false
}
export function safeGetSelection (editor: Editor): Selection | null {
const sel = window.getSelection()
if (!sel) return null
// XXX: no damos la selección si esta fuera o _es_ el contentEl, ¿quizás
// deberíamos mostrar un error?
if (
!editor.contentEl.contains(sel.anchorNode)
|| !editor.contentEl.contains(sel.focusNode)
|| sel.anchorNode == editor.contentEl
|| sel.focusNode == editor.contentEl
) return null
return sel
}
export function safeGetRangeAt (selection: Selection, num = 0): Range | null {
try {
return selection.getRangeAt(num)
} catch (error) {
return null
}
}
interface SplitNode {
range: Range,
node: Node,
}
export function splitNode (node: Element, range: Range): [SplitNode, SplitNode] {
const [left, right] = [
{ range: document.createRange(), node: node.cloneNode(false) },
{ range: document.createRange(), node: node.cloneNode(false) },
]
if (node.firstChild) left.range.setStartBefore(node.firstChild)
left.range.setEnd(range.startContainer, range.startOffset)
left.range.surroundContents(left.node)
right.range.setStart(range.endContainer, range.endOffset)
if (node.lastChild) right.range.setEndAfter(node.lastChild)
right.range.surroundContents(right.node)
if (!node.parentElement)
throw new Error('No pude separar los nodos por que no tiene parentNode')
moveChildren(node, node.parentElement, node)
node.parentElement.removeChild(node)
return [left, right]
}