mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-08-11 02:42:27 +08:00
chore(client/ts): port syntax_highlight
This commit is contained in:
parent
5b82b750dc
commit
ebbf29b1a5
71
src/public/app/types.d.ts
vendored
71
src/public/app/types.d.ts
vendored
@ -285,12 +285,20 @@ declare global {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
type TextEditorElement = {};
|
interface Range {
|
||||||
|
toJSON(): object;
|
||||||
|
}
|
||||||
interface Writer {
|
interface Writer {
|
||||||
setAttribute(name: string, value: string, el: TextEditorElement);
|
setAttribute(name: string, value: string, el: CKNode);
|
||||||
createPositionAt(el: TextEditorElement, opt?: "end");
|
createPositionAt(el: CKNode, opt?: "end" | number);
|
||||||
setSelection(pos: number, pos?: number);
|
setSelection(pos: number, pos?: number);
|
||||||
insertText(text: string, opts: Record<string, unknown> | undefined, position?: TextPosition);
|
insertText(text: string, opts: Record<string, unknown> | undefined, position?: TextPosition);
|
||||||
|
addMarker(name: string, opts: {
|
||||||
|
range: Range;
|
||||||
|
usingOperation: boolean;
|
||||||
|
});
|
||||||
|
removeMarker(name: string);
|
||||||
|
createRange(start: number, end: number): Range;
|
||||||
}
|
}
|
||||||
interface TextNode {
|
interface TextNode {
|
||||||
previousSibling?: TextNode;
|
previousSibling?: TextNode;
|
||||||
@ -308,6 +316,37 @@ declare global {
|
|||||||
offset: number;
|
offset: number;
|
||||||
compareWith(pos: TextPosition): string;
|
compareWith(pos: TextPosition): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface TextRange {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Marker {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CKNode {
|
||||||
|
name: string;
|
||||||
|
childCount: number;
|
||||||
|
isEmpty: boolean;
|
||||||
|
toJSON(): object;
|
||||||
|
is(type: string, name?: string);
|
||||||
|
getAttribute(name: string): string;
|
||||||
|
getChild(index: number): CKNode;
|
||||||
|
data: string;
|
||||||
|
startOffset: number;
|
||||||
|
root: {
|
||||||
|
document: {
|
||||||
|
model: {
|
||||||
|
createRangeIn(el: CKNode): TextRange;
|
||||||
|
markers: {
|
||||||
|
getMarkersIntersectingRange(range: TextRange): Marker[];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
interface TextEditor {
|
interface TextEditor {
|
||||||
create(el: HTMLElement, config: {
|
create(el: HTMLElement, config: {
|
||||||
removePlugins?: string[];
|
removePlugins?: string[];
|
||||||
@ -321,10 +360,22 @@ declare global {
|
|||||||
model: {
|
model: {
|
||||||
document: {
|
document: {
|
||||||
on(event: string, cb: () => void);
|
on(event: string, cb: () => void);
|
||||||
getRoot(): TextEditorElement;
|
getRoot(): CKNode;
|
||||||
|
registerPostFixer(callback: (writer: Writer) => boolean);
|
||||||
selection: {
|
selection: {
|
||||||
getFirstPosition(): undefined | TextPosition;
|
getFirstPosition(): undefined | TextPosition;
|
||||||
getLastPosition(): undefined | TextPosition;
|
getLastPosition(): undefined | TextPosition;
|
||||||
|
};
|
||||||
|
differ: {
|
||||||
|
getChanges(): {
|
||||||
|
type: string;
|
||||||
|
name: string;
|
||||||
|
position: {
|
||||||
|
nodeAfter: CKNode;
|
||||||
|
parent: CKNode;
|
||||||
|
toJSON(): Object;
|
||||||
|
}
|
||||||
|
}[];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
insertContent(modelFragment: any, selection: any);
|
insertContent(modelFragment: any, selection: any);
|
||||||
@ -340,7 +391,7 @@ declare global {
|
|||||||
}) => void, opts?: {
|
}) => void, opts?: {
|
||||||
priority: "high"
|
priority: "high"
|
||||||
});
|
});
|
||||||
getRoot(): TextEditorElement
|
getRoot(): CKNode
|
||||||
},
|
},
|
||||||
domRoots: {
|
domRoots: {
|
||||||
values: () => {
|
values: () => {
|
||||||
@ -363,6 +414,16 @@ declare global {
|
|||||||
};
|
};
|
||||||
toModel(viewFeragment: any);
|
toModel(viewFeragment: any);
|
||||||
},
|
},
|
||||||
|
conversion: {
|
||||||
|
for(filter: string): {
|
||||||
|
markerToHighlight(data: {
|
||||||
|
model: string;
|
||||||
|
view: (data: {
|
||||||
|
markerName: string;
|
||||||
|
}) => void;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
getData(): string;
|
getData(): string;
|
||||||
setData(data: string): void;
|
setData(data: string): void;
|
||||||
getSelectedHtml(): string;
|
getSelectedHtml(): string;
|
||||||
|
@ -12,7 +12,7 @@ import library_loader from "../../../services/library_loader.js";
|
|||||||
import mime_types from "../../../services/mime_types.js";
|
import mime_types from "../../../services/mime_types.js";
|
||||||
import { isSyntaxHighlightEnabled } from "../../../services/syntax_highlight.js";
|
import { isSyntaxHighlightEnabled } from "../../../services/syntax_highlight.js";
|
||||||
|
|
||||||
export async function initSyntaxHighlighting(editor) {
|
export async function initSyntaxHighlighting(editor: TextEditor) {
|
||||||
if (!isSyntaxHighlightEnabled) {
|
if (!isSyntaxHighlightEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -25,39 +25,38 @@ const HIGHLIGHT_MAX_BLOCK_COUNT = 500;
|
|||||||
|
|
||||||
const tag = "SyntaxHighlightWidget";
|
const tag = "SyntaxHighlightWidget";
|
||||||
const debugLevels = ["error", "warn", "info", "log", "debug"];
|
const debugLevels = ["error", "warn", "info", "log", "debug"];
|
||||||
const debugLevel = "debug";
|
const debugLevel = debugLevels.indexOf("debug");
|
||||||
|
|
||||||
let warn = function () {};
|
let warn = function (...args: unknown[]) {};
|
||||||
if (debugLevel >= debugLevels.indexOf("warn")) {
|
if (debugLevel >= debugLevels.indexOf("warn")) {
|
||||||
warn = console.warn.bind(console, tag + ": ");
|
warn = console.warn.bind(console, tag + ": ");
|
||||||
}
|
}
|
||||||
|
|
||||||
let info = function () {};
|
let info = function (...args: unknown[]) {};
|
||||||
if (debugLevel >= debugLevels.indexOf("info")) {
|
if (debugLevel >= debugLevels.indexOf("info")) {
|
||||||
info = console.info.bind(console, tag + ": ");
|
info = console.info.bind(console, tag + ": ");
|
||||||
}
|
}
|
||||||
|
|
||||||
let log = function () {};
|
let log = function (...args: unknown[]) {};
|
||||||
if (debugLevel >= debugLevels.indexOf("log")) {
|
if (debugLevel >= debugLevels.indexOf("log")) {
|
||||||
log = console.log.bind(console, tag + ": ");
|
log = console.log.bind(console, tag + ": ");
|
||||||
}
|
}
|
||||||
|
|
||||||
let dbg = function () {};
|
let dbg = function (...args: unknown[]) {};
|
||||||
if (debugLevel >= debugLevels.indexOf("debug")) {
|
if (debugLevel >= debugLevels.indexOf("debug")) {
|
||||||
dbg = console.debug.bind(console, tag + ": ");
|
dbg = console.debug.bind(console, tag + ": ");
|
||||||
}
|
}
|
||||||
|
|
||||||
function assert(e, msg) {
|
function assert(e: boolean, msg?: string) {
|
||||||
console.assert(e, tag + ": " + msg);
|
console.assert(e, tag + ": " + msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Should this be scoped to note?
|
// TODO: Should this be scoped to note?
|
||||||
let markerCounter = 0;
|
let markerCounter = 0;
|
||||||
|
|
||||||
function initTextEditor(textEditor) {
|
function initTextEditor(textEditor: TextEditor) {
|
||||||
log("initTextEditor");
|
log("initTextEditor");
|
||||||
|
|
||||||
let widget = this;
|
|
||||||
const document = textEditor.model.document;
|
const document = textEditor.model.document;
|
||||||
|
|
||||||
// Create a conversion from model to view that converts
|
// Create a conversion from model to view that converts
|
||||||
@ -100,7 +99,7 @@ function initTextEditor(textEditor) {
|
|||||||
// See
|
// See
|
||||||
// https://github.com/ckeditor/ckeditor5/blob/b53d2a4b49679b072f4ae781ac094e7e831cfb14/packages/ckeditor5-block-quote/src/blockquoteediting.js#L54
|
// https://github.com/ckeditor/ckeditor5/blob/b53d2a4b49679b072f4ae781ac094e7e831cfb14/packages/ckeditor5-block-quote/src/blockquoteediting.js#L54
|
||||||
const changes = document.differ.getChanges();
|
const changes = document.differ.getChanges();
|
||||||
let dirtyCodeBlocks = new Set();
|
let dirtyCodeBlocks = new Set<CKNode>();
|
||||||
|
|
||||||
for (const change of changes) {
|
for (const change of changes) {
|
||||||
dbg("change " + JSON.stringify(change));
|
dbg("change " + JSON.stringify(change));
|
||||||
@ -151,7 +150,7 @@ function initTextEditor(textEditor) {
|
|||||||
* the formatting would be stored with the note and it would need a
|
* the formatting would be stored with the note and it would need a
|
||||||
* way to remove that formatting when editing back the note.
|
* way to remove that formatting when editing back the note.
|
||||||
*/
|
*/
|
||||||
function highlightCodeBlock(codeBlock, writer) {
|
function highlightCodeBlock(codeBlock: CKNode, writer: Writer) {
|
||||||
log("highlighting codeblock " + JSON.stringify(codeBlock.toJSON()));
|
log("highlighting codeblock " + JSON.stringify(codeBlock.toJSON()));
|
||||||
const model = codeBlock.root.document.model;
|
const model = codeBlock.root.document.model;
|
||||||
|
|
||||||
@ -291,16 +290,16 @@ function highlightCodeBlock(codeBlock, writer) {
|
|||||||
iHtml = html.indexOf(">", iHtml) + 1;
|
iHtml = html.indexOf(">", iHtml) + 1;
|
||||||
|
|
||||||
// push the span
|
// push the span
|
||||||
let posStart = writer.createPositionAt(codeBlock, child.startOffset + iChildText);
|
let posStart = writer.createPositionAt(codeBlock, (child?.startOffset ?? 0) + iChildText);
|
||||||
spanStack.push({ className: className, posStart: posStart });
|
spanStack.push({ className: className, posStart: posStart });
|
||||||
} else if (html[iHtml] == "<" && html[iHtml + 1] == "/") {
|
} else if (html[iHtml] == "<" && html[iHtml + 1] == "/") {
|
||||||
// Done with this span, pop the span and mark the range
|
// Done with this span, pop the span and mark the range
|
||||||
iHtml = html.indexOf(">", iHtml + 1) + 1;
|
iHtml = html.indexOf(">", iHtml + 1) + 1;
|
||||||
|
|
||||||
let stackTop = spanStack.pop();
|
let stackTop = spanStack.pop();
|
||||||
let posStart = stackTop.posStart;
|
let posStart = stackTop?.posStart;
|
||||||
let className = stackTop.className;
|
let className = stackTop?.className;
|
||||||
let posEnd = writer.createPositionAt(codeBlock, child.startOffset + iChildText);
|
let posEnd = writer.createPositionAt(codeBlock, (child?.startOffset ?? 0) + iChildText);
|
||||||
let range = writer.createRange(posStart, posEnd);
|
let range = writer.createRange(posStart, posEnd);
|
||||||
let markerName = "hljs:" + className + ":" + markerCounter;
|
let markerName = "hljs:" + className + ":" + markerCounter;
|
||||||
// Use an incrementing number for the uniqueId, random of
|
// Use an incrementing number for the uniqueId, random of
|
Loading…
x
Reference in New Issue
Block a user