@pfmcodes/caret 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -22
- package/commonjs/editor.js +280 -0
- package/commonjs/index.js +10 -0
- package/commonjs/languages.js +97 -0
- package/commonjs/theme.js +18 -0
- package/esm/editor.js +75 -20
- package/esm/languages.js +54 -3
- package/package.json +2 -2
- package/types/editor.d.ts +156 -16
- package/types/language-utils.d.ts +428 -0
- package/types/languages.d.ts +128 -13
- package/types/types.d.ts +347 -0
package/esm/editor.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import hljs from "../highlight.js/es/core.js"; // Use default export
|
|
2
|
-
import languages from "./languages.js"
|
|
2
|
+
import languages from "./languages.js";
|
|
3
3
|
|
|
4
4
|
languages.init();
|
|
5
5
|
|
|
@@ -18,9 +18,15 @@ async function createEditor(editor, data) {
|
|
|
18
18
|
highlighted.id = "Caret-highlighted";
|
|
19
19
|
caret.id = "Caret-caret";
|
|
20
20
|
lineCounter.id = "Caret-lineCounter";
|
|
21
|
+
editor1.style.backgroundColor = isDark ? "#222" : "#fff";
|
|
21
22
|
let code = data.value || "";
|
|
22
23
|
let language = data.language;
|
|
23
24
|
let theme = data.theme;
|
|
25
|
+
if (!languages.registeredLanguages.includes(language)) {
|
|
26
|
+
const mod = await import(`../highlight.js/es/languages/${language}.js`);
|
|
27
|
+
languages.registerLanguage(language, mod.default);
|
|
28
|
+
languages.registeredLanguages.push(language);
|
|
29
|
+
}
|
|
24
30
|
if (theme) {
|
|
25
31
|
let themeLink = document.getElementById("Caret-theme")
|
|
26
32
|
if (!themeLink) {
|
|
@@ -54,7 +60,7 @@ async function createEditor(editor, data) {
|
|
|
54
60
|
editor1.style.paddingTop = "-9px";
|
|
55
61
|
highlighted.innerHTML = hljs.highlight(code, { language: language }).value;
|
|
56
62
|
}
|
|
57
|
-
|
|
63
|
+
const keyDown = (e) => {
|
|
58
64
|
if (e.key !== "Tab") return;
|
|
59
65
|
|
|
60
66
|
e.preventDefault();
|
|
@@ -110,7 +116,8 @@ async function createEditor(editor, data) {
|
|
|
110
116
|
highlighted.innerHTML = hljs.highlight(editor1.value, { language }).value;
|
|
111
117
|
updateLineNumbers();
|
|
112
118
|
updateCaret();
|
|
113
|
-
}
|
|
119
|
+
}
|
|
120
|
+
editor1.addEventListener("keydown", keyDown);
|
|
114
121
|
editor.appendChild(lineCounter);
|
|
115
122
|
editor.appendChild(highlighted);
|
|
116
123
|
editor.appendChild(editor1);
|
|
@@ -141,15 +148,18 @@ async function createEditor(editor, data) {
|
|
|
141
148
|
height: metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent
|
|
142
149
|
};
|
|
143
150
|
}
|
|
144
|
-
|
|
145
|
-
editor1.addEventListener("focus", () => {
|
|
151
|
+
const focus = () => {
|
|
146
152
|
caret.style.opacity = "1";
|
|
147
153
|
caret.style.background = caretColor;
|
|
148
|
-
}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
editor1.addEventListener("focus", focus);
|
|
149
157
|
|
|
150
|
-
|
|
158
|
+
const blur = () => {
|
|
151
159
|
caret.style.opacity = "0";
|
|
152
|
-
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
editor1.addEventListener("blur", blur);
|
|
153
163
|
|
|
154
164
|
function updateCaret() {
|
|
155
165
|
const start = editor1.selectionStart;
|
|
@@ -179,22 +189,22 @@ async function createEditor(editor, data) {
|
|
|
179
189
|
|
|
180
190
|
caret.style.height = `${lineHeight}px`;
|
|
181
191
|
}
|
|
182
|
-
|
|
183
|
-
editor1.addEventListener("input", () => {
|
|
192
|
+
const input = () => {
|
|
184
193
|
caret.style.opacity = "1";
|
|
185
194
|
highlighted.innerHTML = hljs.highlight(editor1.value, { language: language }).value;
|
|
186
195
|
updateLineNumbers();
|
|
187
196
|
updateCaret();
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
|
|
197
|
+
};
|
|
198
|
+
editor1.addEventListener("input", input);
|
|
199
|
+
const scroll = () => {
|
|
191
200
|
const x = -editor1.scrollLeft;
|
|
192
201
|
const y = -editor1.scrollTop;
|
|
193
202
|
|
|
194
203
|
highlighted.style.transform = `translate(${x}px, ${y}px)`;
|
|
195
204
|
caret.style.transform = `translate(${x}px, ${y}px)`;
|
|
196
205
|
lineCounter.style.transform = `translateY(${y}px)`;
|
|
197
|
-
}
|
|
206
|
+
};
|
|
207
|
+
editor1.addEventListener("scroll", scroll);
|
|
198
208
|
|
|
199
209
|
updateFontMetrics();
|
|
200
210
|
getFontMetrics();
|
|
@@ -208,12 +218,43 @@ async function createEditor(editor, data) {
|
|
|
208
218
|
|
|
209
219
|
// Focus the editor
|
|
210
220
|
editor1.focus();
|
|
221
|
+
function destroy() {
|
|
222
|
+
editor1.removeEventListener('click', updateCaret);
|
|
223
|
+
editor1.removeEventListener('keyup', updateCaret);
|
|
224
|
+
editor1.removeEventListener('scroll', scroll);
|
|
225
|
+
editor1.removeEventListener('keydown', keyDown);
|
|
226
|
+
editor.innerHTML = "";
|
|
227
|
+
}
|
|
228
|
+
function refresh() {
|
|
229
|
+
highlighted.innerHTML = hljs.highlight(editor1.value, { language }).value;
|
|
230
|
+
updateLineNumbers();
|
|
231
|
+
updateCaret();
|
|
232
|
+
}
|
|
233
|
+
function getValue() {
|
|
234
|
+
return editor1.value;
|
|
235
|
+
}
|
|
236
|
+
function setValue(i) {
|
|
237
|
+
editor1.value = i;
|
|
238
|
+
refresh();
|
|
239
|
+
}
|
|
240
|
+
async function setLanguage(l) {
|
|
241
|
+
if (!languages.registeredLanguages.includes(l)) {
|
|
242
|
+
if (l === "html" || l === "svg") {
|
|
243
|
+
language = "xml";
|
|
244
|
+
l = "xml";
|
|
245
|
+
}
|
|
246
|
+
const mod = await import(`../highlight.js/es/languages/${l}.js`);
|
|
247
|
+
|
|
248
|
+
}
|
|
249
|
+
language = l;
|
|
250
|
+
refresh();
|
|
251
|
+
}
|
|
211
252
|
return {
|
|
212
|
-
getValue
|
|
213
|
-
setValue
|
|
214
|
-
focus
|
|
215
|
-
setLanguage
|
|
216
|
-
destroy
|
|
253
|
+
getValue,
|
|
254
|
+
setValue,
|
|
255
|
+
focus,
|
|
256
|
+
setLanguage,
|
|
257
|
+
destroy
|
|
217
258
|
};
|
|
218
259
|
}
|
|
219
260
|
|
|
@@ -221,4 +262,18 @@ const editor = {
|
|
|
221
262
|
createEditor
|
|
222
263
|
};
|
|
223
264
|
|
|
224
|
-
export default editor;
|
|
265
|
+
export default editor;
|
|
266
|
+
|
|
267
|
+
/*
|
|
268
|
+
|
|
269
|
+
createEditor: creates the main editor, using html Elements like, textarea and etc.
|
|
270
|
+
refresh: refreshs the editor
|
|
271
|
+
getValue: return the current value from the editor
|
|
272
|
+
setValue: sets a certain value to the editor's value
|
|
273
|
+
focus: focusses the editor
|
|
274
|
+
destroy: destroys and removeEventListeners
|
|
275
|
+
updateCaret: updates the caret positon, height and other metrics using math
|
|
276
|
+
updateLineNumbers: just add new line numbers
|
|
277
|
+
getFontMetrics: returns back the font's metrics like height
|
|
278
|
+
updateFontMetrics: update the fontMetrics
|
|
279
|
+
*/
|
package/esm/languages.js
CHANGED
|
@@ -18,7 +18,9 @@ import bash from "../highlight.js/es/languages/bash.js";
|
|
|
18
18
|
import plaintext from "../highlight.js/es/languages/plaintext.js";
|
|
19
19
|
import hljs from "../highlight.js/es/core.js";
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
let registeredLanguages = [];
|
|
22
|
+
|
|
23
|
+
function init() {
|
|
22
24
|
// Register all languages
|
|
23
25
|
hljs.registerLanguage("javascript", javascript);
|
|
24
26
|
hljs.registerLanguage("xml", xml);
|
|
@@ -40,7 +42,56 @@ export function init() {
|
|
|
40
42
|
hljs.registerLanguage("bash", bash);
|
|
41
43
|
hljs.registerLanguage("shell", bash);
|
|
42
44
|
hljs.registerLanguage("sh", bash);
|
|
43
|
-
hljs.registerLanguage("plaintext", plaintext)
|
|
45
|
+
hljs.registerLanguage("plaintext", plaintext);
|
|
46
|
+
registeredLanguages = [
|
|
47
|
+
"javascript",
|
|
48
|
+
"js",
|
|
49
|
+
"xml",
|
|
50
|
+
"html",
|
|
51
|
+
"svg",
|
|
52
|
+
"python",
|
|
53
|
+
"java",
|
|
54
|
+
"csharp",
|
|
55
|
+
"cpp",
|
|
56
|
+
"ruby",
|
|
57
|
+
"php",
|
|
58
|
+
"go",
|
|
59
|
+
"c",
|
|
60
|
+
"rust",
|
|
61
|
+
"kotlin",
|
|
62
|
+
"swift",
|
|
63
|
+
"typescript",
|
|
64
|
+
"json",
|
|
65
|
+
"bash",
|
|
66
|
+
"shell",
|
|
67
|
+
"sh",
|
|
68
|
+
"plaintext"
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function registerLanguage(name, definition) {
|
|
73
|
+
hljs.registerLanguage(name, definition);
|
|
74
|
+
if (!registeredLanguages.includes(name)) {
|
|
75
|
+
registeredLanguages.push(name);
|
|
76
|
+
}
|
|
44
77
|
}
|
|
45
78
|
|
|
46
|
-
|
|
79
|
+
const languages = {
|
|
80
|
+
init,
|
|
81
|
+
registeredLanguages,
|
|
82
|
+
registerLanguage,
|
|
83
|
+
hljs
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export default languages;
|
|
87
|
+
|
|
88
|
+
/*
|
|
89
|
+
|
|
90
|
+
registeredLannguage: added for the editor.js can check if the langauge provided already is regsitered or not
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
init: just registers some languages and updates the registeredLangauges variable
|
|
94
|
+
|
|
95
|
+
registerLanguage: just registers a language
|
|
96
|
+
|
|
97
|
+
*/
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pfmcodes/caret",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "The official code editor engine for lexius",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.cjs",
|
|
7
|
-
"types": "./types/
|
|
7
|
+
"types": "./types/types.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
10
|
"import": "./esm/index.js",
|
package/types/editor.d.ts
CHANGED
|
@@ -1,27 +1,167 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Caret Editor - TypeScript Type Definitions
|
|
3
|
+
* A lightweight code editor with syntax highlighting and custom caret rendering
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Configuration options for creating a Caret editor instance
|
|
8
|
+
*/
|
|
9
|
+
export interface CaretEditorConfig {
|
|
10
|
+
/**
|
|
11
|
+
* Initial code content to display in the editor
|
|
12
|
+
* @default ""
|
|
13
|
+
*/
|
|
3
14
|
value?: string;
|
|
4
15
|
|
|
5
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Programming language for syntax highlighting
|
|
18
|
+
* Must be a language supported by Highlight.js
|
|
19
|
+
* @example "javascript", "python", "html", "css"
|
|
20
|
+
*/
|
|
6
21
|
language: string;
|
|
7
22
|
|
|
8
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Highlight.js theme name for syntax highlighting
|
|
25
|
+
* Can be any theme available in the highlight.js/styles directory
|
|
26
|
+
* @example "hybrid", "monokai", "github", "atom-one-dark"
|
|
27
|
+
* @default "hybrid"
|
|
28
|
+
*/
|
|
9
29
|
theme?: string;
|
|
10
30
|
}
|
|
11
31
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Font metrics information returned by getFontMetrics
|
|
34
|
+
*/
|
|
35
|
+
export interface FontMetrics {
|
|
36
|
+
/**
|
|
37
|
+
* Height of the ascender (portion of characters above baseline)
|
|
38
|
+
*/
|
|
39
|
+
ascent: number;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Height of the descender (portion of characters below baseline)
|
|
43
|
+
*/
|
|
44
|
+
descent: number;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Total height of the font (ascent + descent)
|
|
48
|
+
*/
|
|
49
|
+
height: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Caret editor instance returned by createEditor
|
|
54
|
+
*/
|
|
55
|
+
export interface CaretEditorInstance {
|
|
56
|
+
/**
|
|
57
|
+
* Get the current value/content of the editor
|
|
58
|
+
* @returns The current code content as a string
|
|
59
|
+
*/
|
|
60
|
+
getValue(): string;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Set the value/content of the editor
|
|
64
|
+
* @param value - The new code content to set
|
|
65
|
+
*/
|
|
66
|
+
setValue(value: string): void;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Focus the editor textarea
|
|
70
|
+
*/
|
|
71
|
+
focus(): void;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Change the programming language for syntax highlighting
|
|
75
|
+
* @param language - The new language identifier (e.g., "javascript", "python")
|
|
76
|
+
*/
|
|
77
|
+
setLanguage(language: string): void;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Destroy the editor instance and remove all event listeners
|
|
81
|
+
* Cleans up the DOM and prepares for garbage collection
|
|
82
|
+
*/
|
|
83
|
+
destroy(): void;
|
|
16
84
|
}
|
|
17
85
|
|
|
18
86
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* @param editor DOM element that will contain the editor
|
|
22
|
-
* @param data Initial editor configuration
|
|
87
|
+
* Language manager for registering and initializing Highlight.js languages
|
|
23
88
|
*/
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
89
|
+
export interface LanguageManager {
|
|
90
|
+
/**
|
|
91
|
+
* Initialize the language manager
|
|
92
|
+
*/
|
|
93
|
+
init(): void;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Register a new language for syntax highlighting
|
|
97
|
+
* @param language - The language identifier to register
|
|
98
|
+
*/
|
|
99
|
+
registerLanguage(language: string): void;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* List of currently registered languages
|
|
103
|
+
*/
|
|
104
|
+
registeredLanguages: string[];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Main editor object containing the createEditor function
|
|
109
|
+
*/
|
|
110
|
+
export interface CaretEditor {
|
|
111
|
+
/**
|
|
112
|
+
* Create a new Caret editor instance
|
|
113
|
+
*
|
|
114
|
+
* @param container - The HTMLElement that will contain the editor
|
|
115
|
+
* @param config - Configuration options for the editor
|
|
116
|
+
* @returns A CaretEditorInstance with methods to control the editor
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* import editor from 'caret';
|
|
121
|
+
*
|
|
122
|
+
* const editorContainer = document.getElementById('editor');
|
|
123
|
+
* const instance = await editor.createEditor(editorContainer, {
|
|
124
|
+
* value: 'console.log("Hello, World!");',
|
|
125
|
+
* language: 'javascript',
|
|
126
|
+
* theme: 'monokai'
|
|
127
|
+
* });
|
|
128
|
+
*
|
|
129
|
+
* // Get current value
|
|
130
|
+
* const code = instance.getValue();
|
|
131
|
+
*
|
|
132
|
+
* // Update the content
|
|
133
|
+
* instance.setValue('const x = 42;');
|
|
134
|
+
*
|
|
135
|
+
* // Change language
|
|
136
|
+
* instance.setLanguage('typescript');
|
|
137
|
+
*
|
|
138
|
+
* // Clean up when done
|
|
139
|
+
* instance.destroy();
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
createEditor(
|
|
143
|
+
container: HTMLElement,
|
|
144
|
+
config: CaretEditorConfig
|
|
145
|
+
): Promise<CaretEditorInstance>;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Default export - the main Caret editor object
|
|
150
|
+
*/
|
|
151
|
+
declare const editor: CaretEditor;
|
|
152
|
+
|
|
153
|
+
export default editor;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Module augmentation for importing Highlight.js
|
|
157
|
+
*/
|
|
158
|
+
declare module "../highlight.js/es/core.js" {
|
|
159
|
+
import type { HLJSApi } from "highlight.js";
|
|
160
|
+
const hljs: HLJSApi;
|
|
161
|
+
export default hljs;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
declare module "./languages.js" {
|
|
165
|
+
const languages: LanguageManager;
|
|
166
|
+
export default languages;
|
|
167
|
+
}
|