You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CheezeNotes/static/modules/caret.js

193 lines
5.1 KiB

function insertTextAtCaret(txtBefore, txtAfter = '') {
let ret = saveSelection();
let line = ret[0];
let start = ret[1];
let end = ret[3];
let txt = line.innerText;
let before = ''
if (start == 0) {
} else {
before = txt.substring(0, start);
}
let after = txt.substring(end, txt.length);
let selection = '';
if (end > start) {
selection = txt.substring(start, end);
}
line.innerHTML = before + txtBefore + selection + txtAfter + after;
let span = document.createElement('span');
if (start == end && ret[0] == ret[2]) {
span.innerHTML = txtBefore;
ret[1] = start + span.innerText.length;
ret[3] = ret[1];
} else {
span.innerHTML = txtBefore + txtAfter;
ret[3] = end + span.innerText.length;
}
loadSelection(ret);
}
function saveSelection() {
let ret = getStartPositionInLine();
let startLine = ret[0];
let startPosition = ret[1];
ret = getEndPositionInLine();
let endLine = ret[0];
let endPosition = ret[1];
return [startLine, startPosition, endLine, endPosition];
}
function loadSelection(sel) {
setStartPositionInLine(sel[0], sel[1]);
setEndPositionInLine(sel[2], sel[3]);
}
function getStartPositionInLine() {
let selection = window.getSelection();
if (selection.rangeCount == 0) {
return [null, 0];
}
let range = selection.getRangeAt(0).cloneRange();
let obj = range.startContainer;
let position = range.startOffset;
if (obj.nodeName == 'DIV' && obj.classList.contains('cheezenotes_line')) {
return [obj, position];
}
let line = null;
while (obj != null) {
if (obj.previousSibling != null) {
obj = obj.previousSibling;
if (obj.innerText != null) {
position += obj.innerText.length;
} else if (obj.length != null) {
position += obj.length;
}
} else if (obj.parentNode != null && obj.parentNode.classList != null && !obj.parentNode.classList.contains('cheezenotes_line')) {
obj = obj.parentNode;
} else if (obj.parentNode != null && obj.parentNode.classList != null && obj.parentNode.classList.contains('cheezenotes_line')) {
line = obj.parentNode;
obj = null;
} else {
obj = null;
}
}
return [line, position];
}
function setStartPositionInLine(line, position) {
setStartPositionInDiv(line, position)
}
function setStartPositionInDiv(obj, position) {
let temppos = position;
if (temppos > obj.innerText.length) {
return temppos - obj.innerText.length;
}
let children = obj.childNodes;
for (let i = 0; i < children.length; i++) {
let child = children[i];
if (child.nodeType == 3) {
temppos = setStartPositionInText(child, temppos);
} else {
temppos = setStartPositionInDiv(child, temppos);
}
if (temppos == 0) {
return temppos;
}
}
return temppos;
}
function setStartPositionInText(obj, position) {
if (position > obj.length) {
return position - obj.length;
}
let selection = window.getSelection();
selection.removeAllRanges();
let range = document.createRange();
range.setStart(obj, position);
selection.addRange(range);
return 0;
}
function getEndPositionInLine() {
let selection = window.getSelection();
if (selection.rangeCount == 0) {
return [null, 0];
}
let range = selection.getRangeAt(0).cloneRange();
let obj = range.endContainer;
let position = range.endOffset;
if (obj.nodeName == 'DIV' && obj.classList.contains('cheezenotes_line')) {
return [obj, position];
}
let line = null;
while (obj != null) {
if (obj.previousSibling != null) {
obj = obj.previousSibling;
if (obj.innerText != null) {
position += obj.innerText.length;
} else if (obj.length != null) {
position += obj.length;
}
} else if (obj.parentNode != null && obj.parentNode.classList != null && !obj.parentNode.classList.contains('cheezenotes_line')) {
obj = obj.parentNode;
} else if (obj.parentNode != null && obj.parentNode.classList != null && obj.parentNode.classList.contains('cheezenotes_line')) {
line = obj.parentNode;
obj = null;
} else {
obj = null;
}
}
return [line, position];
}
function setEndPositionInLine(line, position) {
setEndPositionInDiv(line, position)
}
function setEndPositionInDiv(obj, position) {
let temppos = position;
if (temppos > obj.innerText.length) {
return temppos - obj.innerText.length;
}
let children = obj.childNodes;
for (let i = 0; i < children.length; i++) {
let child = children[i];
if (child.nodeType == 3) {
temppos = setEndPositionInText(child, temppos);
} else {
temppos = setEndPositionInDiv(child, temppos);
}
if (temppos == 0) {
return temppos;
}
}
return temppos;
}
function setEndPositionInText(obj, position) {
if (position > obj.length) {
return position - obj.length;
}
let selection = window.getSelection();
let oldRange = selection.getRangeAt(0);
let range = document.createRange();
range.setStart(oldRange.startContainer, oldRange.startOffset);
range.setEnd(obj, position);
selection.removeAllRanges();
selection.addRange(range);
return 0;
}
export { saveSelection, loadSelection, insertTextAtCaret };