]> BookStack Code Mirror - bookstack/blob - resources/js/code/themes.js
Merge pull request #5627 from BookStackApp/lexical_20250525
[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     {
8         tag: tags.meta,
9         color: '#388938',
10     },
11     {
12         tag: tags.link,
13         textDecoration: 'underline',
14     },
15     {
16         tag: tags.heading,
17         textDecoration: 'underline',
18         fontWeight: 'bold',
19     },
20     {
21         tag: tags.emphasis,
22         fontStyle: 'italic',
23     },
24     {
25         tag: tags.strong,
26         fontWeight: 'bold',
27     },
28     {
29         tag: tags.strikethrough,
30         textDecoration: 'line-through',
31     },
32     {
33         tag: tags.keyword,
34         color: '#708',
35     },
36     {
37         tag: [tags.atom, tags.bool, tags.url, tags.contentSeparator, tags.labelName],
38         color: '#219',
39     },
40     {
41         tag: [tags.literal, tags.inserted],
42         color: '#164',
43     },
44     {
45         tag: [tags.string, tags.deleted],
46         color: '#a11',
47     },
48     {
49         tag: [tags.regexp, tags.escape, tags.special(tags.string)],
50         color: '#e40',
51     },
52     {
53         tag: tags.definition(tags.variableName),
54         color: '#00f',
55     },
56     {
57         tag: tags.local(tags.variableName),
58         color: '#30a',
59     },
60     {
61         tag: [tags.typeName, tags.namespace],
62         color: '#085',
63     },
64     {
65         tag: tags.className,
66         color: '#167',
67     },
68     {
69         tag: [tags.special(tags.variableName), tags.macroName],
70         color: '#256',
71     },
72     {
73         tag: tags.definition(tags.propertyName),
74         color: '#00c',
75     },
76     {
77         tag: tags.compareOperator,
78         color: '#708',
79     },
80     {
81         tag: tags.comment,
82         color: '#940',
83     },
84     {
85         tag: tags.invalid,
86         color: '#f00',
87     },
88 ]);
89
90 const defaultThemeSpec = {
91     '&': {
92         backgroundColor: '#FFF',
93         color: '#000',
94     },
95     '&.cm-focused': {
96         outline: 'none',
97     },
98     '.cm-line': {
99         lineHeight: '1.6',
100     },
101 };
102
103 /**
104  * Get the theme extension to use for editor view instance.
105  * @returns {Extension[]}
106  */
107 export function getTheme(viewParentEl) {
108     const darkMode = document.documentElement.classList.contains('dark-mode');
109     let viewTheme = darkMode ? oneDarkTheme : EditorView.theme(defaultThemeSpec);
110     let highlightStyle = darkMode ? oneDarkHighlightStyle : defaultLightHighlightStyle;
111
112     const eventData = {
113         darkModeActive: darkMode,
114         registerViewTheme(builder) {
115             const spec = builder();
116             if (spec) {
117                 viewTheme = EditorView.theme(spec);
118             }
119         },
120         registerHighlightStyle(builder) {
121             const tagStyles = builder(tags) || [];
122             if (tagStyles.length) {
123                 highlightStyle = HighlightStyle.define(tagStyles);
124             }
125         },
126     };
127
128     window.$events.emitPublic(viewParentEl, 'library-cm6::configure-theme', eventData);
129
130     return [viewTheme, syntaxHighlighting(highlightStyle)];
131 }
Morty Proxy This is a proxified and sanitized view of the page, visit original site.