You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
258 lines
6.6 KiB
JavaScript
258 lines
6.6 KiB
JavaScript
/**
|
|
* @description :: Basic operation
|
|
*/
|
|
|
|
export default new class Base {
|
|
constructor (){}
|
|
|
|
getState (cm, pos = cm.getCursor("start")){
|
|
let stat = cm.getTokenAt(pos);
|
|
if(!stat.type) return {};
|
|
const typeMap = {
|
|
'strong': () => ({bold: true}),
|
|
'variable-2': () => ({[/^\s*\d+\.\s/.test(cm.getLine(pos.line))? 'ordered-list': 'unordered-list']: true}),
|
|
'atom': () => ({quote: true}),
|
|
'em': () => ({italic: true}),
|
|
'quote': () => ({quote: true}),
|
|
'strikethrough': () => ({strikethrough: true}),
|
|
'comment': () => ({code: true}),
|
|
'link': () => ({link: true}),
|
|
'tag': () => ({image: true}),
|
|
'_other': v => v.match(/^header(\-[1-6])?$/)? ({[v.replace("header", "heading")]: true}): ({})
|
|
}
|
|
const objectResult = stat.type.split(" ")
|
|
.map(v => typeMap[v]? typeMap[v](): typeMap['_other'](v))
|
|
.reduce((pv, cv) => Object.assign(pv, cv), {})
|
|
|
|
return objectResult;
|
|
}
|
|
|
|
toggleBlock (editor, type, start_chars, end_chars){
|
|
if(/editor-preview-active/.test(editor.codemirror.getWrapperElement().lastChild.className)) return;
|
|
|
|
end_chars = (typeof end_chars === "undefined") ? start_chars : end_chars;
|
|
let cm = editor.codemirror;
|
|
let stat = this.getState(cm);
|
|
|
|
let text;
|
|
let start = start_chars;
|
|
let end = end_chars;
|
|
|
|
let startPoint = cm.getCursor("start");
|
|
let endPoint = cm.getCursor("end");
|
|
|
|
if(stat[type]) {
|
|
text = cm.getLine(startPoint.line);
|
|
start = text.slice(0, startPoint.ch);
|
|
end = text.slice(startPoint.ch);
|
|
if(type == "bold") {
|
|
start = start.replace(/(\*\*|__)(?![\s\S]*(\*\*|__))/, "");
|
|
end = end.replace(/(\*\*|__)/, "");
|
|
} else if(type == "italic") {
|
|
start = start.replace(/(\*|_)(?![\s\S]*(\*|_))/, "");
|
|
end = end.replace(/(\*|_)/, "");
|
|
} else if(type == "strikethrough") {
|
|
start = start.replace(/(\*\*|~~)(?![\s\S]*(\*\*|~~))/, "");
|
|
end = end.replace(/(\*\*|~~)/, "");
|
|
}
|
|
cm.replaceRange(start + end, {
|
|
line: startPoint.line,
|
|
ch: 0
|
|
}, {
|
|
line: startPoint.line,
|
|
ch: 99999999999999
|
|
});
|
|
|
|
if(type == "bold" || type == "strikethrough") {
|
|
startPoint.ch -= 2;
|
|
if(startPoint !== endPoint) {
|
|
endPoint.ch -= 2;
|
|
}
|
|
} else if(type == "italic") {
|
|
startPoint.ch -= 1;
|
|
if(startPoint !== endPoint) {
|
|
endPoint.ch -= 1;
|
|
}
|
|
}
|
|
} else {
|
|
text = cm.getSelection();
|
|
if(type == "bold") {
|
|
text = text.split("**").join("");
|
|
text = text.split("__").join("");
|
|
} else if(type == "italic") {
|
|
text = text.split("*").join("");
|
|
text = text.split("_").join("");
|
|
} else if(type == "strikethrough") {
|
|
text = text.split("~~").join("");
|
|
}
|
|
cm.replaceSelection(start + text + end);
|
|
|
|
startPoint.ch += start_chars.length;
|
|
endPoint.ch = startPoint.ch + text.length;
|
|
}
|
|
|
|
cm.setSelection(startPoint, endPoint);
|
|
cm.focus();
|
|
}
|
|
|
|
replaceSelection (cm, active, startEnd, url){
|
|
if(/editor-preview-active/.test(cm.getWrapperElement().lastChild.className))
|
|
return;
|
|
|
|
let text;
|
|
let start = startEnd[0];
|
|
let end = startEnd[1];
|
|
let startPoint = cm.getCursor("start");
|
|
let endPoint = cm.getCursor("end");
|
|
if(url) {
|
|
end = end.replace("#url#", url);
|
|
}
|
|
if(active) {
|
|
text = cm.getLine(startPoint.line);
|
|
start = text.slice(0, startPoint.ch);
|
|
end = text.slice(startPoint.ch);
|
|
cm.replaceRange(start + end, {
|
|
line: startPoint.line,
|
|
ch: 0
|
|
});
|
|
} else {
|
|
text = cm.getSelection();
|
|
cm.replaceSelection(start + text + end);
|
|
|
|
startPoint.ch += start.length;
|
|
if(startPoint !== endPoint) {
|
|
endPoint.ch += start.length;
|
|
}
|
|
}
|
|
cm.setSelection(startPoint, endPoint);
|
|
cm.focus();
|
|
}
|
|
|
|
toggleHeading (cm, direction, size){
|
|
if(/editor-preview-active/.test(cm.getWrapperElement().lastChild.className))
|
|
return;
|
|
|
|
const startPoint = cm.getCursor("start");
|
|
const endPoint = cm.getCursor("end");
|
|
for(let i = startPoint.line; i <= endPoint.line; i++) {
|
|
(function(i) {
|
|
let text = cm.getLine(i);
|
|
let currHeadingLevel = text.search(/[^#]/);
|
|
|
|
if(direction !== undefined) {
|
|
if(currHeadingLevel <= 0) {
|
|
if(direction == "bigger") {
|
|
text = "###### " + text;
|
|
} else {
|
|
text = "# " + text;
|
|
}
|
|
} else if(currHeadingLevel == 6 && direction == "smaller") {
|
|
text = text.substr(7);
|
|
} else if(currHeadingLevel == 1 && direction == "bigger") {
|
|
text = text.substr(2);
|
|
} else {
|
|
if(direction == "bigger") {
|
|
text = text.substr(1);
|
|
} else {
|
|
text = "#" + text;
|
|
}
|
|
}
|
|
} else {
|
|
if(size == 1) {
|
|
if(currHeadingLevel <= 0) {
|
|
text = "# " + text;
|
|
} else if(currHeadingLevel == size) {
|
|
text = text.substr(currHeadingLevel + 1);
|
|
} else {
|
|
text = "# " + text.substr(currHeadingLevel + 1);
|
|
}
|
|
} else if(size == 2) {
|
|
if(currHeadingLevel <= 0) {
|
|
text = "## " + text;
|
|
} else if(currHeadingLevel == size) {
|
|
text = text.substr(currHeadingLevel + 1);
|
|
} else {
|
|
text = "## " + text.substr(currHeadingLevel + 1);
|
|
}
|
|
} else {
|
|
if(currHeadingLevel <= 0) {
|
|
text = "### " + text;
|
|
} else if(currHeadingLevel == size) {
|
|
text = text.substr(currHeadingLevel + 1);
|
|
} else {
|
|
text = "### " + text.substr(currHeadingLevel + 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
cm.replaceRange(text, {
|
|
line: i,
|
|
ch: 0
|
|
}, {
|
|
line: i,
|
|
ch: 99999999999999
|
|
});
|
|
})(i);
|
|
}
|
|
cm.focus();
|
|
}
|
|
|
|
toggleLine (cm, name){
|
|
if(/editor-preview-active/.test(cm.getWrapperElement().lastChild.className)) return;
|
|
|
|
let stat = this.getState(cm);
|
|
const startPoint = cm.getCursor("start");
|
|
const endPoint = cm.getCursor("end");
|
|
const repl = {
|
|
"quote": /^(\s*)\>\s+/,
|
|
"unordered-list": /^(\s*)(\*|\-|\+)\s+/,
|
|
"ordered-list": /^(\s*)\d+\.\s+/
|
|
};
|
|
const map = {
|
|
"quote": "> ",
|
|
"unordered-list": "* ",
|
|
"ordered-list": "1. "
|
|
};
|
|
for(let i = startPoint.line; i <= endPoint.line; i++) {
|
|
(function(i) {
|
|
let text = cm.getLine(i);
|
|
if(stat[name]) {
|
|
text = text.replace(repl[name], "$1");
|
|
} else {
|
|
text = map[name] + text;
|
|
}
|
|
cm.replaceRange(text, {
|
|
line: i,
|
|
ch: 0
|
|
}, {
|
|
line: i,
|
|
ch: 99999999999999
|
|
});
|
|
})(i);
|
|
}
|
|
cm.focus();
|
|
}
|
|
|
|
cleanBlock (cm){
|
|
if(/editor-preview-active/.test(cm.getWrapperElement().lastChild.className))
|
|
return;
|
|
|
|
const startPoint = cm.getCursor("start");
|
|
const endPoint = cm.getCursor("end");
|
|
let text;
|
|
|
|
for(let line = startPoint.line; line <= endPoint.line; line++) {
|
|
text = cm.getLine(line);
|
|
text = text.replace(/^[ ]*([# ]+|\*|\-|[> ]+|[0-9]+(.|\)))[ ]*/, "");
|
|
|
|
cm.replaceRange(text, {
|
|
line: line,
|
|
ch: 0
|
|
}, {
|
|
line: line,
|
|
ch: 99999999999999
|
|
});
|
|
}
|
|
}
|
|
|
|
} |