@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/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
- editor1.addEventListener("keydown", (e) => {
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
- editor1.addEventListener("blur", () => {
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
- editor1.addEventListener("scroll", () => {
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: () => editor1.value,
213
- setValue: v => { editor1.value = v; /* refresh */ },
214
- focus: () => editor1.focus(),
215
- setLanguage: lang => { language = lang; refresh(); },
216
- destroy: () => editor.innerHTML = ""
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
- export function init() {
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
- export default { init, registerLanguage: hljs.registerLanguage.bind(hljs), hljs };
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.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/index.d.ts",
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
- export interface EditorInitData {
2
- /** Initial code value */
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
- /** Language id registered in Highlight.js */
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
- /** Highlight.js theme name (without .css) */
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
- export interface CaretEditorElements {
13
- textarea: HTMLTextAreaElement;
14
- highlighted: HTMLPreElement;
15
- caret: HTMLDivElement;
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
- * Creates a Caret editor inside the given container.
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 function createEditor(
25
- editor: HTMLElement,
26
- data: EditorInitData
27
- ): Promise<void>;
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
+ }