import { saveSelection, loadSelection } from "./caret.js"; import { normalizeName } from "./tools.js"; function setEditable() { let editModeButton = document.getElementById('editModeButton'); let cheezenotes = document.getElementById('cheezenotes'); if (editModeButton.classList.contains('buttonoff')) { cheezenotes.contentEditable = false; window.getSelection().removeAllRanges(); } else { cheezenotes.contentEditable = true; } } function load(textarea, div) { div.innerHTML = ''; let lines = textarea.value.split('\n'); for (let i = 0; i < lines.length; i++) { let line = lines[i]; line.replace('<', '<'); let elem = formatLine(line); div.append(elem); } redrawTables(div, 0); } function appendData(div, data) { const selection = window.getSelection(); selection.deleteFromDocument(); let ret = saveSelection(); let line = ret[0]; let position = ret[1]; if (line == null) { return; } let lineBegin = line.innerText.substring(0, position); let lineEnd = line.innerText.substring(position, line.innerText.length); let lines = data.split('\n'); let newline; if (lines.length == 1) { newline = formatLine(lineBegin + lines[0] + lineEnd); line.parentNode.replaceChild(newline, line); position = position + lines[0].length; } else { newline = formatLine(lineBegin + lines[0]); line.parentNode.replaceChild(newline, line); let prevline = newline; for (let i = 1; i < lines.length - 1; i++) { newline = formatLine(lines[i]); prevline.after(newline); prevline = newline; } newline = formatLine(lines[lines.length - 1] + lineEnd); prevline.after(newline); position = lines[lines.length - 1].length; } loadSelection([newline, position, newline, position]); redrawTables(div, dpwidth(div)); } var _dpwidth = null; function dpwidth(div) { if (_dpwidth != null) { return _dpwidth; } let dp = document.createElement('span'); dp.classList.add('tokenfictif'); div.append(dp); dp.innerText = ':'; _dpwidth = dp.getBoundingClientRect().width; div.removeChild(dp); return _dpwidth; } function save(textarea, div) { let lines = div.children; let text = ''; for (let i = 0; i < lines.length; i++) { if (lines[i].innerText != '\n') { text += lines[i].innerText.replace(emsp(), '\t'); } if (i < lines.length - 1) { text += '\n'; } } textarea.value = text; return text; } function emsp() { return ' '; } function onlinkin(e) { let link = e.currentTarget; if (document.getElementById('cheezenotes') !== document.activeElement) { document.getElementById('cheezenotes').contentEditable = false; window.getSelection().removeAllRanges(); } } function onlink(e) { let cheezenotes = document.getElementById('cheezenotes'); if (cheezenotes.contentEditable == 'false') { e.preventDefault(); setEditable(); let link = e.currentTarget; let datahref = link.getAttribute('data-href'); if (datahref.includes('/')) { open(link.href); } else { fetch(link.href + '?data=&fromDomain=' + window.domain + '&fromPage=' + window.page + '&libelle=' + link.innerText).then((response) => { let ta = document.getElementById('ta'); response.text().then((data) => { let content = document.getElementById('content'); let left = content.scrollLeft; let top = content.scrollTop; window.history.replaceState({ top: top, left: left }, ""); window.history.pushState({}, "", link.href); document.title = 'CheezeNotes - ' + datahref; ta.value = data; let url = datahref.split(':'); let page = url[0]; let domain = window.domain; if (url.length == 3) { domain = url[1]; page = url[2]; } window.domain = domain; window.page = page; load(document.getElementById('ta'), cheezenotes); content.scrollTop = 0; content.scrollLeft = 0; }); }).catch((error) => { alert(error); }); } return false; } else { return true; } } function onlinkout(e) { let cheezenotes = document.getElementById('cheezenotes'); if (cheezenotes.contentEditable == 'false') { setEditable(); } } function onclickcheckbox(e) { let cheezenotes = document.getElementById('cheezenotes'); cheezenotes.contentEditable = false; window.getSelection().removeAllRanges(); console.log("onclickcheckbox"); } function oncheckbox(e) { /*let cheezenotes = document.getElementById('cheezenotes'); cheezenotes.contentEditable = false; window.getSelection().removeAllRanges();*/ console.log("oncheckbox"); let cb = e.currentTarget; let line = cb.parentNode; let text = line.innerText; if (cb.checked) { text = text.replace(/^(\s*)(\[\])/, "$1[v]"); } else { text = text.replace(/^(\s*)(\[[vVxX]\])/, "$1[]"); } let newline = formatLine(text); line.parentNode.replaceChild(newline, line); } function formatLine(line) { let token = null; let elem = document.createElement('div'); elem.classList.add('cheezenotes_line'); if (line == '' || line == '\n') { elem.classList.add('body'); elem.innerHTML = '
'; return elem; } line = line.replace(/\t/, emsp()); line = line.replace('&', '&'); line = line.replace('<', '<'); let ret = removeMono(line); line = ret[0]; let listMono = ret[1]; ret = removeLink(line); line = ret[0]; let listLink = ret[1]; if (line.match(/^\s*_{3,}\s*$/)) { token = /^(\s*_{3,}\s*)$/ elem.classList.add('line'); } else if (line.match(/^\s*######(\s|$)/i)) { token = /^(\s*######(\s|$))/i; elem.classList.add('h6'); elem.classList.add('h'); } else if (line.match(/^\s*#####(\s|$)/i)) { token = /^(\s*#####(\s|$))/i; elem.classList.add('h5'); elem.classList.add('h'); } else if (line.match(/^\s*####(\s|$)/i)) { token = /^(\s*####(\s|$))/i; elem.classList.add('h4'); elem.classList.add('h'); } else if (line.match(/^\s*###(\s|$)/i)) { token = /^(\s*###(\s|$))/i; elem.classList.add('h3'); elem.classList.add('h'); } else if (line.match(/^\s*##(\s|$)/)) { token = /^(\s*##(\s|$))/i; elem.classList.add('h2'); elem.classList.add('h'); } else if (line.match(/^\s*#(\s|$)/i)) { token = /^(\s*#(\s|$))/i; elem.classList.add('h1'); elem.classList.add('h'); } else if (line.match(/^\s*>\s*>\s*>(\s|$)/i)) { token = /^(\s*>\s*>\s*>(\s|$))/i; elem.classList.add('bq3'); elem.classList.add('bq'); } else if (line.match(/^\s*>\s*>(\s|$)/i)) { token = /^(\s*>\s*>(\s|$))/i; elem.classList.add('bq2'); elem.classList.add('bq'); } else if (line.match(/^\s*>(\s|$)/i)) { token = /^(\s*>(\s|$))/i; elem.classList.add('bq1'); elem.classList.add('bq'); } else if (line.match(/^\s*\[[xXvV]?\]\s+/i)) { //token = /^(\s*\[[xXvV]?\]\s+)/i; let checked = ''; if (line.match(/^\s*\[[xXvV]\]\s+/i)) { checked = ' checked="checked"'; } line = line.replace(/^(\s*\[[xXvV]?\]\s+)/i, '$1') elem.classList.add('checkbox'); } else { elem.classList.add('body'); } if (elem.classList.contains('bq') || elem.classList.contains('body')) { if (line.match(/^\s*((>\s*){0,3}\s)?([\*\-+]\s*){3}(\s|$)/i)) { token = /^(\s*(>\s*){0,3}([\*\-+]\s*){3}(\s|$))/i; elem.classList.add('ul3'); elem.classList.remove('body'); } else if (line.match(/^\s*((>\s*){0,3}\s)?([\*\-+]\s*){2}(\s|$)/i)) { token = /^(\s*(>\s*){0,3}([\*\-+]\s*){2}(\s|$))/i; elem.classList.add('ul2'); elem.classList.remove('body'); } else if (line.match(/^\s*((>\s*){0,3}\s)?[\*\-+](\s|$)/i)) { token = /^(\s*(>\s*){0,3}[\*\-+](\s*|$))/; elem.classList.add('ul1'); elem.classList.remove('body'); } else if (line.match(/^\s*((>\s*){0,3}\s)?([0-9]+\.){3}(\s|$)/i)) { token = /^(\s*(>\s*){0,3}(\s*|$))/; elem.classList.add('ol3'); elem.classList.remove('body'); } else if (line.match(/^\s*((>\s*){0,3}\s)?([0-9]+\.){2}(\s|$)/i)) { token = /^(\s*(>\s*){0,3}(\s*|$))/; elem.classList.add('ol2'); elem.classList.remove('body'); } else if (line.match(/^\s*((>\s*){0,3}\s)?[0-9]+\.(\s|$)/i)) { token = /^(\s*(>\s*){0,3}(\s*|$))/; elem.classList.add('ol1'); elem.classList.remove('body'); } } if (token != null) { line = line.replace(token, '$1'); } line = addBold(line); line = addItalic(line); line = addStrike(line); line = addTableLine(line); line = addLink(line, listLink); line = addMono(line, listMono); elem.innerHTML = line; let checkboxes = elem.getElementsByClassName('checkbox'); for (let i = 0; i < checkboxes.length; i++) { let checkbox = checkboxes[i]; checkbox.addEventListener('mouseover', onlinkin); checkbox.addEventListener('click', onclickcheckbox); checkbox.addEventListener('change', oncheckbox); checkbox.addEventListener('mouseout', onlinkout); } if (elem.getElementsByClassName('tablerow').length > 0) { if (elem.childNodes[0].childNodes.length > 0) { let child = elem.childNodes[0].childNodes[0]; while (child != null) { if (child.nodeType == 3) { let newchild = document.createElement('span'); newchild.innerText = child.nodeValue; child.parentNode.replaceChild(newchild, child); child = newchild; } child = child.nextSibling; } } elem.classList.remove('body'); elem.classList.add('tablerow'); } let links = elem.getElementsByClassName('link'); for (let i = 0; i < links.length; i++) { let link = links[i]; link.addEventListener('mouseover', onlinkin); link.addEventListener('click', onlink); link.addEventListener('mouseout', onlinkout); } return elem; } function addTableLine(line) { if (line.match(/^\s*\|:{0,1}(\s*.*?:{0,1}\|:{0,1})*/)) { let cpt = 0; let re = /:{0,1}\|:{0,1}/g; let match; let matches = []; let lengthes = [] while ((match = re.exec(line)) != null) { matches[cpt] = match; if (cpt > 1000) { continue; } cpt++; } matches = matches.reverse(); for (let i = 0; i < matches.length; i++) { let match = matches[i]; if (i == matches.length - 1) { // premier | let leftdp = ' data-dp="false"'; if (match[0].length == 2) { leftdp = ' data-dp="true"'; } let line1 = line.substring(0, match.index); let line2 = '' + match[0] + '' let line3 = line.substring(match.index + match[0].length, line.length); line = line1 + line2 + line3; } else if (i == 0 && match.index == line.length - 1) { // dernier | let rightdp = ' data-dp="false"'; if (match[0].charAt(0) == ':') { rightdp = ' data-dp="true"'; } let line1 = line.substring(0, match.index); let line2 = '' + match[0] + '' let line3 = line.substring(match.index + match[0].length, line.length); line = line1 + line2 + line3; } else { let rightdp = ' data-dp="false"'; let leftdp = ' data-dp="false"'; if (match[0].length == 3) { rightdp = ' data-dp="true"'; leftdp = ' data-dp="true"'; } else if (match[0].length == 2) { if (match[0].charAt(0) == ':') { rightdp = ' data-dp="true"'; } else { leftdp = ' data-dp="true"'; } } let line1 = line.substring(0, match.index); let line2 = '' + match[0] + ''; let line3 = line.substring(match.index + match[0].length, line.length); line = line1 + line2 + line3; } } line = '' + line + ''; } return line; } function redrawTables(cheezenotes, dpwidth = 0) { if (cheezenotes.childNodes.length == 0) { return; } let child = cheezenotes.childNodes[0]; let firsttableline = null; while (child != null) { if (firsttableline == null) { if (child.classList.contains('tablerow')) { firsttableline = child; } } else { if (!child.classList.contains('tablerow')) { formatTable(firsttableline, dpwidth); firsttableline = null; } } child = child.nextSibling; } if (firsttableline != null) { formatTable(firsttableline, dpwidth); } } function formatTable(line, dpwidth = 0) { if (!line.classList.contains('tablerow')) { return; } let firstline = line; let lastline = line; while (firstline.previousSibling !== null && firstline.previousSibling.classList.contains('tablerow')) { firstline = firstline.previousSibling; firstline.classList.remove('firsttablerow'); firstline.classList.remove('lasttablerow'); } while (lastline.nextSibling !== null && lastline.nextSibling.classList.contains('tablerow')) { lastline = lastline.nextSibling; lastline.classList.remove('firsttablerow'); lastline.classList.remove('lasttablerow'); } firstline.classList.add('firsttablerow'); lastline.classList.add('lasttablerow'); resizeTableCols(firstline, lastline, dpwidth) } function resizeTableCols(firstline, lastline, dpwidth) { let colsmaxwidth = []; let colsjustif = []; let currentline = firstline; while (currentline !== null && currentline.classList.contains('tablerow')) { let tablerow = currentline.getElementsByClassName('tablerow')[0]; let childNodes = tablerow.childNodes; let currentwidth = 0; let col = 0; let currentleft; for (let i = 0; i < childNodes.length; i++) { let child = childNodes[i]; if (child.classList != null && child.classList.contains('lefttablespacer')) { currentleft = child; } else if (child.classList != null && child.classList.contains('righttablespacer')) { let leftdp = currentleft.getAttribute('data-dp'); let rightdp = child.getAttribute('data-dp'); if (colsjustif[col] == null) { if (leftdp == 'true' && rightdp == 'true') { colsjustif[col] = 'c'; } else if (leftdp == 'true' && rightdp == 'false') { colsjustif[col] = 'l'; } else if (leftdp == 'false' && rightdp == 'true') { colsjustif[col] = 'r'; } } if (colsmaxwidth[col] == null || colsmaxwidth[col] < currentwidth) { colsmaxwidth[col] = currentwidth; } child.dataWidth = currentwidth; currentleft.dataWidth = currentwidth; currentleft = null; currentwidth = 0; col += 1; } else if (currentleft != null) { let width = child.getBoundingClientRect().width; currentwidth += width; } } currentline = currentline.nextSibling; } for (let i = 0; i < colsmaxwidth.length; i++) { if (colsjustif[i] == null) { colsjustif[i] = 'l'; } } currentline = firstline; while (currentline !== null && currentline.classList.contains('tablerow')) { let tablerow = currentline.getElementsByClassName('tablerow')[0]; let childNodes = tablerow.childNodes; let col = 0; let currentleft; for (let i = 0; i < childNodes.length; i++) { let child = childNodes[i]; if (child.classList != null && child.classList.contains('lefttablespacer')) { currentleft = child; } else if (child.classList != null && child.classList.contains('righttablespacer')) { let lplus = dpwidth; let rplus = dpwidth; let justif = 'l'; let leftdp = currentleft.getAttribute('data-dp'); let rightdp = child.getAttribute('data-dp'); if (leftdp == 'true' && rightdp == 'true') { justif = 'c'; lplus = 0; rplus = 0; } else if (leftdp == 'true' && rightdp == 'false') { justif = 'l'; lplus = 0; } else if (leftdp == 'false' && rightdp == 'true') { justif = 'r'; rplus = 0; } else { justif = colsjustif[col]; } colsjustif[col] = justif; let leftwidth = 10 + lplus; let rightwidth = Math.round(colsmaxwidth[col] - child.dataWidth + 10 + rplus); if (justif == 'c') { leftwidth = Math.round((colsmaxwidth[col] - child.dataWidth) / 2 + 10 + lplus); rightwidth = Math.round((colsmaxwidth[col] - child.dataWidth) / 2 + 10 + rplus); } else if (justif == 'r') { leftwidth = Math.round(colsmaxwidth[col] - child.dataWidth + 10 + lplus); rightwidth = 10 + rplus; } currentleft.style.width = '' + leftwidth + 'px'; child.style.width = '' + rightwidth + 'px'; currentleft = null; col += 1; } } currentline = currentline.nextSibling; } } function removeMono(line) { let listMono = line.match(/`(`|.*?)`/g); if (listMono == null) { return [line, null]; } line = line.replace(/`(`|.*?)`/g, "``"); return [line, listMono.reverse()]; } function addMono(line, listMono) { if (listMono == null) { return line; } let cpt = 0; let match; let matches = []; let re = /``/g; while ((match = re.exec(line)) != null) { matches[cpt] = match.index; if (cpt > 1000) { continue; } cpt++; } matches = matches.reverse(); for (let i = 0; i < matches.length; i++) { let mono = listMono[i]; mono = mono.substring(1, mono.length - 1); line = line.substring(0, matches[i]) + '`' + mono + '`' + line.substring(matches[i] + 2, line.length); } return line; } function removeLink(line) { let listLink = line.match(/(\[([^\]]*?)\]\(([^\)]*?)\))/g); if (listLink == null) { return [line, null]; } line = line.replace(/(\[([^\]]*?)\]\(([^\)]*?)\))/g, "[]()"); return [line, listLink.reverse()]; } function addLink(line, listLink) { if (listLink == null) { return line; } let cpt = 0; let match; let matches = []; let re = /\[\]\(\)/g; while ((match = re.exec(line)) != null) { matches[cpt] = match.index; if (cpt > 1000) { continue; } cpt++; } matches = matches.reverse(); for (let i = 0; i < matches.length; i++) { line = line.substring(0, matches[i]) + formatLink(listLink[i]) + line.substring(matches[i] + 4, line.length); } return line; } function formatLink(link) { let matches = link.match(/\[(.*)\]\((.*)\)/); let libelle = matches[1]; let url = matches[2]; if (url == '' && libelle == '') { return link; } let href = url; if (href == '') { href = libelle; } let datahref = href; if (href.match(/\:\/\//)) { datahref = href; } else { let dh = datahref.split(':'); if (dh.length === 1) { datahref = window.domain + ":" + datahref; } datahref = normalizeName(datahref); href = window.base_url + datahref; } if (libelle == '') { return '[](' + url + ')'; } else { if (libelle.startsWith('!')) { return '[' + libelle + '](' + url + ')'; } else { return '[' + libelle + '](' + url + ')'; } } } function addBold(line) { line = line.replace(/\*\*([^\s].*?)\*\*/ig, '**$1**'); line = line.replace(/__([^\s].*?)__/ig, '__$1__'); return line; } function addItalic(line) { line = line.replace(/(^|[^\*])\*([^\*\s].*?[^\*\s]|[^\*\s])\*([^\*]|$)/ig, '$1*$2*$3'); line = line.replace(/(^|[\s^*])_([^_\s].*?[^_\s]|[^_\s])_([^_]|$)/ig, '$1_$2_$3'); return line; } function addStrike(line) { line = line.replace(/~~([^\s].*?)~~/ig, '~~$1~~'); return line; } export { load, save, formatLine, formatTable, redrawTables, dpwidth, appendData };