]> BookStack Code Mirror - bookstack/blob - resources/js/code/themes.js
CM6: Aligned styling with existing, improved theme handling
[bookstack] / resources / js / code / themes.js
1 import {tags} from "@lezer/highlight";
2 import {HighlightStyle, syntaxHighlighting} from "@codemirror/language";
3 import {EditorView} from "@codemirror/view";
4 import {oneDarkHighlightStyle, oneDarkTheme} from "@codemirror/theme-one-dark";
5
6 const defaultLightHighlightStyle = HighlightStyle.define([
7     { tag: tags.meta,
8         color: "#388938" },
9     { tag: tags.link,
10         textDecoration: "underline" },
11     { tag: tags.heading,
12         textDecoration: "underline",
13         fontWeight: "bold" },
14     { tag: tags.emphasis,
15         fontStyle: "italic" },
16     { tag: tags.strong,
17         fontWeight: "bold" },
18     { tag: tags.strikethrough,
19         textDecoration: "line-through" },
20     { tag: tags.keyword,
21         color: "#708" },
22     { tag: [tags.atom, tags.bool, tags.url, tags.contentSeparator, tags.labelName],
23         color: "#219" },
24     { tag: [tags.literal, tags.inserted],
25         color: "#164" },
26     { tag: [tags.string, tags.deleted],
27         color: "#a11" },
28     { tag: [tags.regexp, tags.escape, tags.special(tags.string)],
29         color: "#e40" },
30     { tag: tags.definition(tags.variableName),
31         color: "#00f" },
32     { tag: tags.local(tags.variableName),
33         color: "#30a" },
34     { tag: [tags.typeName, tags.namespace],
35         color: "#085" },
36     { tag: tags.className,
37         color: "#167" },
38     { tag: [tags.special(tags.variableName), tags.macroName],
39         color: "#256" },
40     { tag: tags.definition(tags.propertyName),
41         color: "#00c" },
42     { tag: tags.compareOperator,
43         color: "#708" },
44     { tag: tags.comment,
45         color: "#940" },
46     { tag: tags.invalid,
47         color: "#f00" }
48 ]);
49
50 const defaultThemeSpec = {
51     "&": {
52         color: "#000",
53     },
54     "&.cm-focused": {
55         outline: "none",
56     },
57     ".cm-line": {
58         lineHeight: "1.6",
59     },
60 };
61
62 /**
63  * Get the theme extension to use for editor view instance.
64  * @returns {Extension[]}
65  */
66 export function getTheme(viewParentEl) {
67     const darkMode = document.documentElement.classList.contains('dark-mode');
68     let viewTheme = darkMode ? oneDarkTheme : EditorView.theme(defaultThemeSpec);
69     let highlightStyle = darkMode ? oneDarkHighlightStyle : defaultLightHighlightStyle;
70
71     const eventData = {
72         darkModeActive: darkMode,
73         registerViewTheme(builder) {
74             const spec = builder();
75             if (spec) {
76                 viewTheme = EditorView.theme(spec);
77             }
78         },
79         registerHighlightStyle(builder) {
80             const tagStyles = builder(tags) || [];
81             if (tagStyles.length) {
82                 highlightStyle = HighlightStyle.define(tagStyles);
83             }
84         }
85     };
86
87     window.$events.emitPublic(viewParentEl, 'library-cm6::configure-theme', eventData);
88
89     return [viewTheme, syntaxHighlighting(highlightStyle)];
90 }