UNPKG

on-codemerge

Version:

A WYSIWYG editor for on-codemerge is a user-friendly interface that allows users to edit and view their code in real time, exactly as it will appear in the final product

108 lines (107 loc) 4.09 kB
class f { constructor(e) { this.container = e; } getSelectedRoot(e, r = !1) { const n = e.getRangeAt(0); return !n.collapsed || this.hasContentInRange(n) ? this.getDeepestNodes(n, r) : r ? [] : this.handleCollapsedRange(e, n); } getDeepestNodes(e, r) { const n = [], s = []; if (!this.container.contains(e.commonAncestorContainer)) return []; const o = document.createTreeWalker( e.commonAncestorContainer, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT, null ); let t = o.currentNode = e.startContainer; for (; t; ) { if (t !== this.container && t.nodeType === Node.TEXT_NODE && t.textContent && t.textContent.trim().length > 0 && e.intersectsNode(t)) { const i = t.parentElement; i && this.isStyledTextNode(i) && !this.isTableNode(i) && !this.isBlockNode(i) ? s.includes(i) || s.push(i) : n.push(t); } if (t === e.endContainer) break; t = o.nextNode(); } if (!r) for (const i of n) { const l = this.createSpanIfNeeded(i, e); l && !s.includes(l) && s.push(l); } return s; } handleCollapsedRange(e, r) { var o; const n = e.anchorNode; if (!n || !this.container.contains(n)) return []; let s = document.createElement("span"); return n.nodeType === Node.ELEMENT_NODE && n.tagName === "SPAN" ? s = n : (s.textContent = " ​", (o = n.parentNode) == null || o.insertBefore(s, n.nextSibling)), r.setStart(s, 1), r.setEnd(s, 1), e.removeAllRanges(), e.addRange(r), [s]; } hasContentInRange(e) { return e.toString().trim().length > 0 || e.cloneContents().childNodes.length > 0; } createSpanIfNeeded(e, r) { var i; if (e.nodeType !== Node.TEXT_NODE || !e.textContent) return null; const { textContent: n } = e, s = e === r.startContainer ? r.startOffset : 0, o = e === r.endContainer ? r.endOffset : n.length; if (o === 0 || s === n.length || s === o) return null; const t = document.createElement("span"); t.textContent = n.substring(s, o), this.replaceNodeWithSpan(e, t, s, o); try { const l = window.getSelection(); if (l) { const a = document.createRange(), c = t.firstChild; c && c.nodeType === Node.TEXT_NODE && (a.setStart(c, 0), a.setEnd(c, ((i = c.textContent) == null ? void 0 : i.length) || 0), l.removeAllRanges(), l.addRange(a)); } } catch (l) { console.error(l); } return t; } replaceNodeWithSpan(e, r, n, s) { const { textContent: o } = e, t = e.parentNode; if (!t || !o) return; const i = document.createTextNode(o.substring(0, n)), l = document.createTextNode(o.substring(s)); t.insertBefore(i, e), t.insertBefore(r, e), t.insertBefore(l, e), t.removeChild(e); } isStyledTextNode(e) { return e ? !e.classList.contains("html-editor") : !1; } isTableNode(e) { return e ? !!(e.closest("table") || e.closest("tr") || e.closest("td") || e.closest("th")) : !1; } isBlockNode(e) { return e ? e.classList.contains("block-content") : !1; } applyStyleToNode(e, r, n) { e.nodeType === Node.ELEMENT_NODE && n(e, r); } removeStyleFromNode(e, r, n) { var s; if (e.nodeType === Node.ELEMENT_NODE) { const o = e; if (this.isStyledTextNode(o) && (n(o, r), !o.getAttribute("style") && o.classList.length === 0 && o.tagName === "SPAN")) { const t = document.createDocumentFragment(); for (; o.firstChild; ) t.appendChild(o.firstChild); const i = o.parentNode, l = t.firstChild, a = t.lastChild; i == null || i.replaceChild(t, o); try { if (l && a && l.nodeType === Node.TEXT_NODE && a.nodeType === Node.TEXT_NODE) { const c = window.getSelection(); if (c) { const d = document.createRange(); d.setStart(l, 0), d.setEnd(a, ((s = a.textContent) == null ? void 0 : s.length) || 0), c.removeAllRanges(), c.addRange(d); } } } catch (c) { console.error(c); } } } } } export { f as DomUtils };