import { saveSelection, loadSelection } from "./caret.js";
function setEditable() {
let editModeButton = document.getElementById('editModeButton');
let cheezenotes = document.getElementById('cheezenotes');
if (editModeButton.classList.contains('buttonoff')) {
cheezenotes.contentEditable = false;
} 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;
}
}
function onlink(e) {
let cheezenotes = document.getElementById('cheezenotes');
if (cheezenotes.contentEditable == 'false') {
e.preventDefault();
setEditable();
let link = e.currentTarget;
if (link.host !== document.location.host) {
open(link.href);
} else {
fetch(link.href + '?data=&fromDomain=' + window.domain + '&fromPage=' + window.page).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 - ' + link.getAttribute('data-href');
ta.value = data;
let url = link.getAttribute('data-href').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 oncheckbox(e) {
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('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;
}
if (href.match(/^[^\:\/]+\/.*$/)) {
href = '/' + href;
}
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 };