function change(evt) { reId(document.getElementById('mdnotes')); let res = getStartPositionInLine(); let line = res[0]; if (line == null) { return; } let position = res[1]; let id = line.id; toMD(); toHTML(); line = document.getElementById(id); setStartPositionInLine(line, position); return true; } function reId(obj) { let prevId = ''; let children = obj.childNodes; for (i = 0; i < children.length; i++) { let child = children[i]; if (child.classList.contains('mdnotes_line')) { if (prevId == child.id) { child.className = 'mdnotes_line'; } prevId = child.id; child.id = 'mdnotes_' + i; } } } function getStartPositionInLine() { let selection = window.getSelection(); let range = selection.getRangeAt(0).cloneRange(); let obj = range.startContainer; let position = range.startOffset; 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('mdnotes_line')) { obj = obj.parentNode; } else if (obj.parentNode != null && obj.parentNode.classList != null && obj.parentNode.classList.contains('mdnotes_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 (i = 0; i < children.length; i++) { let child = children[i]; if (child.nodeType == 3) { temppos = setStartPositionInText(child, position); } 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 toHTML() { let ta = document.getElementById('ta'); let mda = document.getElementById('mdnotes'); mda.innerHTML = ''; let lines = ta.value.split('\n'); for (var i = 0; i < lines.length; i++) { let obj = document.createElement('div'); let line = lines[i]; if (line == '') { let br = document.createElement('br'); obj.append(br); } let normLine = line.trim(); if (normLine.startsWith('#### ')) { obj.classList.add('h4'); } else if (normLine.startsWith('### ')) { obj.classList.add('h3'); } else if (normLine.startsWith('## ')) { obj.classList.add('h2'); } else if (normLine.startsWith('# ')) { obj.classList.add('h1'); } obj.classList.add('mdnotes_line'); if (line !== '') { obj.innerText = line; } obj.id = 'mdnotes_' + i; mda.append(obj); } } function toMD() { let mda = document.getElementById('mdnotes'); let content = mda.childNodes; let text = eltToMD(mda) let ta = document.getElementById('ta'); ta.value = text; } function eltToMD(elt) { let text = ''; if (getType(elt) == 'TEXT') { text = elt.nodeValue; } else if (elt.innerText.length == 0) { text = ''; } else { let children = elt.childNodes; let prevType = 'DIV'; for (let i = 0; i < children.length; i++) { let type = getType(children[i]); if (type == 'DIV' && prevType != 'DIV') { text += "\n"; } text += eltToMD(children[i]); if (type == 'DIV') { text += "\n"; } prevType = type; } } return text; } function getType(elt) { if (elt.nodeType == 3) { return 'TEXT' } else if (elt.nodeType == 1) { return elt.tagName; } else { return 'UNKNOWN'; } } toHTML();