mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-08-10 02:02:29 +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 {
|
||||
setAttribute(name: string, value: string, el: TextEditorElement);
|
||||
createPositionAt(el: TextEditorElement, opt?: "end");
|
||||
setAttribute(name: string, value: string, el: CKNode);
|
||||
createPositionAt(el: CKNode, opt?: "end" | number);
|
||||
setSelection(pos: number, pos?: number);
|
||||
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 {
|
||||
previousSibling?: TextNode;
|
||||
@ -308,6 +316,37 @@ declare global {
|
||||
offset: number;
|
||||
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 {
|
||||
create(el: HTMLElement, config: {
|
||||
removePlugins?: string[];
|
||||
@ -321,10 +360,22 @@ declare global {
|
||||
model: {
|
||||
document: {
|
||||
on(event: string, cb: () => void);
|
||||
getRoot(): TextEditorElement;
|
||||
getRoot(): CKNode;
|
||||
registerPostFixer(callback: (writer: Writer) => boolean);
|
||||
selection: {
|
||||
getFirstPosition(): undefined | TextPosition;
|
||||
getLastPosition(): undefined | TextPosition;
|
||||
};
|
||||
differ: {
|
||||
getChanges(): {
|
||||
type: string;
|
||||
name: string;
|
||||
position: {
|
||||
nodeAfter: CKNode;
|
||||
parent: CKNode;
|
||||
toJSON(): Object;
|
||||
}
|
||||
}[];
|
||||
}
|
||||
},
|
||||
insertContent(modelFragment: any, selection: any);
|
||||
@ -340,7 +391,7 @@ declare global {
|
||||
}) => void, opts?: {
|
||||
priority: "high"
|
||||
});
|
||||
getRoot(): TextEditorElement
|
||||
getRoot(): CKNode
|
||||
},
|
||||
domRoots: {
|
||||
values: () => {
|
||||
@ -363,6 +414,16 @@ declare global {
|
||||
};
|
||||
toModel(viewFeragment: any);
|
||||
},
|
||||
conversion: {
|
||||
for(filter: string): {
|
||||
markerToHighlight(data: {
|
||||
model: string;
|
||||
view: (data: {
|
||||
markerName: string;
|
||||
}) => void;
|
||||
})
|
||||
}
|
||||
}
|
||||
getData(): string;
|
||||
setData(data: string): void;
|
||||
getSelectedHtml(): string;
|
||||
|
@ -12,7 +12,7 @@ import library_loader from "../../../services/library_loader.js";
|
||||
import mime_types from "../../../services/mime_types.js";
|
||||
import { isSyntaxHighlightEnabled } from "../../../services/syntax_highlight.js";
|
||||
|
||||
export async function initSyntaxHighlighting(editor) {
|
||||
export async function initSyntaxHighlighting(editor: TextEditor) {
|
||||
if (!isSyntaxHighlightEnabled) {
|
||||
return;
|
||||
}
|
||||
@ -25,39 +25,38 @@ const HIGHLIGHT_MAX_BLOCK_COUNT = 500;
|
||||
|
||||
const tag = "SyntaxHighlightWidget";
|
||||
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")) {
|
||||
warn = console.warn.bind(console, tag + ": ");
|
||||
}
|
||||
|
||||
let info = function () {};
|
||||
let info = function (...args: unknown[]) {};
|
||||
if (debugLevel >= debugLevels.indexOf("info")) {
|
||||
info = console.info.bind(console, tag + ": ");
|
||||
}
|
||||
|
||||
let log = function () {};
|
||||
let log = function (...args: unknown[]) {};
|
||||
if (debugLevel >= debugLevels.indexOf("log")) {
|
||||
log = console.log.bind(console, tag + ": ");
|
||||
}
|
||||
|
||||
let dbg = function () {};
|
||||
let dbg = function (...args: unknown[]) {};
|
||||
if (debugLevel >= debugLevels.indexOf("debug")) {
|
||||
dbg = console.debug.bind(console, tag + ": ");
|
||||
}
|
||||
|
||||
function assert(e, msg) {
|
||||
function assert(e: boolean, msg?: string) {
|
||||
console.assert(e, tag + ": " + msg);
|
||||
}
|
||||
|
||||
// TODO: Should this be scoped to note?
|
||||
let markerCounter = 0;
|
||||
|
||||
function initTextEditor(textEditor) {
|
||||
function initTextEditor(textEditor: TextEditor) {
|
||||
log("initTextEditor");
|
||||
|
||||
let widget = this;
|
||||
const document = textEditor.model.document;
|
||||
|
||||
// Create a conversion from model to view that converts
|
||||
@ -100,7 +99,7 @@ function initTextEditor(textEditor) {
|
||||
// See
|
||||
// https://github.com/ckeditor/ckeditor5/blob/b53d2a4b49679b072f4ae781ac094e7e831cfb14/packages/ckeditor5-block-quote/src/blockquoteediting.js#L54
|
||||
const changes = document.differ.getChanges();
|
||||
let dirtyCodeBlocks = new Set();
|
||||
let dirtyCodeBlocks = new Set<CKNode>();
|
||||
|
||||
for (const change of changes) {
|
||||
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
|
||||
* 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()));
|
||||
const model = codeBlock.root.document.model;
|
||||
|
||||
@ -291,16 +290,16 @@ function highlightCodeBlock(codeBlock, writer) {
|
||||
iHtml = html.indexOf(">", iHtml) + 1;
|
||||
|
||||
// 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 });
|
||||
} else if (html[iHtml] == "<" && html[iHtml + 1] == "/") {
|
||||
// Done with this span, pop the span and mark the range
|
||||
iHtml = html.indexOf(">", iHtml + 1) + 1;
|
||||
|
||||
let stackTop = spanStack.pop();
|
||||
let posStart = stackTop.posStart;
|
||||
let className = stackTop.className;
|
||||
let posEnd = writer.createPositionAt(codeBlock, child.startOffset + iChildText);
|
||||
let posStart = stackTop?.posStart;
|
||||
let className = stackTop?.className;
|
||||
let posEnd = writer.createPositionAt(codeBlock, (child?.startOffset ?? 0) + iChildText);
|
||||
let range = writer.createRange(posStart, posEnd);
|
||||
let markerName = "hljs:" + className + ":" + markerCounter;
|
||||
// Use an incrementing number for the uniqueId, random of
|
Loading…
x
Reference in New Issue
Block a user