Skip to content

Commit c4371d2

Browse files
author
WebCoder49
committed
Finish TypeScript bindings; Get ready for release 2.0
1 parent e096c3b commit c4371d2

File tree

9 files changed

+381
-75
lines changed

9 files changed

+381
-75
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
.vscode
2-
debug.html
2+
debug.html
3+
debug/

README.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
# code-input
2+
23
![Click to Switch](https://img.shields.io/static/v1?label=&message=Click%20to%20Switch:%20&color=grey&style=for-the-badge)[![GitHub](https://img.shields.io/static/v1?label=&message=GitHub&color=navy&style=for-the-badge&logo=github)](https://github.com/WebCoder49/code-input)[![NPM](https://img.shields.io/static/v1?label=&message=NPM&color=red&style=for-the-badge&logo=npm)](https://www.npmjs.com/package/@webcoder49/code-input)
34

45
[![View License](https://img.shields.io/github/license/webcoder49/code-input?style=for-the-badge)](LICENSE) [![View Releases](https://img.Shields.io/github/v/release/webcoder49/code-input?style=for-the-badge)](https://github.com/WebCoder49/code-input/releases) [![View the demo on CodePen](https://img.shields.io/static/v1?label=Demo&message=on%20CodePen&color=orange&logo=codepen&style=for-the-badge)](https://codepen.io/WebCoder49/details/jOypJOx)
56

6-
> ___Fully customisable syntax-highlighted textareas.___ [[🚀 View the Demo](https://codepen.io/WebCoder49/details/jOypJOx)]
7+
> ___Fully customisable, editable syntax-highlighted textareas that can be placed in any HTML form.___ [[🚀 View the Demo](https://codepen.io/WebCoder49/details/jOypJOx)]
78
89
![Using code-input with many different themes](https://user-images.githubusercontent.com/69071853/133924472-05edde5c-23e7-4350-a41b-5a74d2dc1a9a.gif)
910
*This demonstration uses themes from [Prism.js](https://prismjs.com/) and [highlight.js](https://highlightjs.org/), two syntax-highlighting programs which work well and have compatibility built-in with code-input.*
1011

12+
*A frontend JavaScript library, with:* [![TypeScript Bindings - Click to Use](https://img.shields.io/static/v1?label=TypeScript%20Bindings&message=Click%20to%Use&style=for-the-badge&logo=typescript&logoColor=white)](https://github.com/WebCoder49/code-input-for-typescript)
13+
14+
---
15+
1116
## What does it do?
1217
**`code-input`** lets you **turn any ordinary JavaScript syntax-highlighting theme and program into customisable syntax-highlighted textareas** using an HTML custom element. It uses vanilla CSS to superimpose a `textarea` on a `pre code` block, then handles indentations, scrolling and fixes any resulting bugs with JavaScript. To see how it works in more detail, please see [this CSS-Tricks article](https://css-tricks.com/creating-an-editable-textarea-that-supports-syntax-highlighted-code/ "Creating an Editable Textarea That Supports Syntax-Highlighted Code") I wrote.
1318

@@ -18,6 +23,8 @@ The `<code-input>` element works like a `<textarea>` and therefore **works in HT
1823

1924
## 🚀 Getting Started With `code-input` (in 4 simple steps)
2025

26+
## [`code-input` also supports TypeScript (click)](https://github.com/WebCoder49/code-input-for-typescript)
27+
2128
`code-input` is designed to be **both easy to use and customisable**. Here's how to use it to create syntax-highlighted textareas:
2229

2330
### 1. Import `code-input`
@@ -42,8 +49,8 @@ From JSDelivr CDN (click)
4249

4350
```html
4451
<!--In the <head>-->
45-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@1.3/code-input.min.js"></script>
46-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@1.3/code-input.min.css">
52+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.0/code-input.min.js"></script>
53+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.0/code-input.min.css">
4754
```
4855
</details>
4956

@@ -62,7 +69,7 @@ The next step is to set up a `template` to link `code-input` to your syntax-high
6269

6370
- *Custom:*
6471
```js
65-
codeInput.registerTemplate("syntax-highlighted", codeInput.templates.custom(
72+
codeInput.registerTemplate("syntax-highlighted", new codeInput.Template(
6673
function(result_element) { /* Highlight function - with `pre code` code element */
6774
/* Highlight code in result_element - code is already escaped so it doesn't become HTML */
6875
},
@@ -105,8 +112,15 @@ Now that you have registered a template, you can use the custom `<code-input>` e
105112
```
106113
*or*
107114
```HTML
108-
<code-input lang="HTML" placeholder="Type code here" value="<a href='https://github.com/WebCoder49/code-input'>code-input</a>" template="syntax-highlighted" onchange="console.log('Your code is', this.value)"></code-input>
115+
<code-input lang="HTML" placeholder="Type code here" template="syntax-highlighted" onchange="console.log('Your code is', this.value)"><a href='https://github.com/WebCoder49/code-input'>code-input</a></code-input>
109116
```
110117

118+
### *Next:* What Else Can `code-input` do?
119+
*The two sides to the library:*
120+
121+
1. **Our aim is to make `code-input` work from the start like an ordinary `<textarea>` element, with `name` attribute support, form reset functions, and accessible `aria-` attribute support, etc. leading to HTML form compatibility.**
122+
123+
2. Thanks to many contributions, suggestions and bug identifications from the open-source community, `code-input`'s capabilities are constantly growing. With customisable plugins, you can also turn `code-input` into whatever you want.
124+
111125
## Contributing
112126
If you have any features you would like to add to `code-input`, or have found any bugs, please [open an issue](https://github.com/WebCoder49/code-input/issues) or [fork and submit a pull request](https://github.com/WebCoder49/code-input/fork)! All contributions to this open-source project would be greatly appreciated.

code-input.d.ts

Lines changed: 234 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,236 @@
1-
export as namespace codeInput; // TODO: Complete + Test + Add to repo+npm
2-
3-
export class Plugin {}
4-
5-
// Templates
6-
export class Template {}
7-
export namespace templates {
8-
function custom(highlight: (code: HTMLElement) => void, preElementStyled: boolean, isCode: boolean, includeCodeInputInHighlightFunc: false, plugins: Plugin[]): Template
9-
function prism(prism: Object, plugins: Plugin[]): Template
10-
function hljs(hljs: Object, plugins: Plugin[]): Template
11-
function characterLimit(plugins: Plugin[]): Template
12-
function rainbowText(rainbowColors: string[], delimiter: string, plugins: Plugin[]): Template
1+
export as namespace codeInput;
2+
3+
/**
4+
* Plugins are imported from the plugins folder. They will then
5+
* provide custom extra functionality to code-input elements.
6+
*/
7+
export abstract class Plugin {
8+
constructor()
9+
/**
10+
* Runs before code is highlighted.
11+
* @param {codeInput.CodeInput} codeInput - The codeInput element
12+
*/
13+
beforeHighlight(codeInput: CodeInput): void
14+
/**
15+
* Runs after code is highlighted.
16+
* @param {codeInput.CodeInput} codeInput - The codeInput element
17+
*/
18+
afterHighlight(codeInput: CodeInput): void
19+
/**
20+
* Runs before elements are added into a code-input element.
21+
* @param {codeInput.CodeInput} codeInput - The codeInput element
22+
*/
23+
beforeElementsAdded(codeInput: CodeInput): void
24+
/**
25+
* Runs after elements are added into a code-input element (useful for adding events to the textarea).
26+
* @param {codeInput.CodeInput} codeInput - The codeInput element
27+
*/
28+
afterElementsAdded(codeInput: CodeInput): void
29+
/**
30+
* Runs when an attribute of a code-input element is changed (you must add the attribute name to `codeInput.Plugin.observedAttributes` first).
31+
* @param {codeInput.CodeInput} codeInput - The codeInput element
32+
* @param {string} name - The name of the attribute
33+
* @param {string} oldValue - The value of the attribute before it was changed
34+
* @param {string} newValue - The value of the attribute after it is changed
35+
*/
36+
attributeChanged(codeInput: CodeInput, name: string, oldValue: string, newValue: string): void
37+
/**
38+
* The HTML attributes to watch for this plugin, and report any
39+
* modifications to the `codeInput.Plugin.attributeChanged` method.
40+
*/
41+
observedAttributes: Array<string>
42+
}
43+
44+
/**
45+
* Before using any plugin in this namespace, please ensure you import its JavaScript
46+
* files (in the plugins folder), or continue to get a more detailed error in the developer
47+
* console.
48+
*
49+
* Where plugins are stored, after they are imported. The plugin
50+
* file assigns them a space in this object.
51+
* For adding completely new syntax-highlighting algorithms, please see `codeInput.templates`.
52+
*
53+
* Key - plugin name
54+
*
55+
* Value - plugin object
56+
* @type {Object}
57+
*/
58+
export namespace plugins {
59+
/**
60+
* JavaScript example of a plugin, which brings extra,
61+
* non-central optional functionality to code-input.
62+
* Instances of plugins can be passed in in an array
63+
* to the `plugins` argument when registering a template,
64+
* for example like this:
65+
* ```javascript
66+
* codeInput.registerTemplate("syntax-highlighted", codeInput.templates.hljs(hljs, [new codeInput.plugins.Test()]));
67+
* ```
68+
*/
69+
class Test extends Plugin {
70+
constructor();
71+
}
72+
73+
/**
74+
* Display a popup under the caret using the text in the code-input element. This works well with autocomplete suggestions.
75+
* Files: autocomplete.js / autocomplete.css
76+
*/
77+
class Autocomplete extends Plugin {
78+
/**
79+
* Pass in a function to display the popup that takes in (popup element, textarea, textarea.selectionEnd).
80+
* @param {function} updatePopupCallback a function to display the popup that takes in (popup element, textarea, textarea.selectionEnd).
81+
*/
82+
constructor(updatePopupCallback: (popupElem: HTMLElement, textarea: HTMLTextAreaElement, selectionEnd: number) => void);
83+
}
84+
85+
/**
86+
* Autodetect the language live and change the `lang` attribute using the syntax highlighter's
87+
* autodetect capabilities. Works with highlight.js only.
88+
* Files: autodetect.js
89+
*/
90+
class Autodetect extends Plugin {
91+
constructor();
92+
}
93+
94+
/**
95+
* Debounce the update and highlighting function
96+
* https://medium.com/@jamischarles/what-is-debouncing-2505c0648ff1
97+
* Files: debounce-update.js
98+
*/
99+
class DebounceUpdate extends Plugin {
100+
/**
101+
* Create a debounced update plugin to pass into a template.
102+
* @param {Number} delayMs Delay, in ms, to wait until updating the syntax highlighting
103+
*/
104+
constructor(delayMs: number);
105+
}
106+
107+
/**
108+
* Adds indentation using the `Tab` key, and auto-indents after a newline, as well as making it
109+
* possible to indent/unindent multiple lines using Tab/Shift+Tab
110+
* Files: indent.js
111+
*/
112+
class Indent extends Plugin {
113+
constructor();
114+
}
115+
116+
/**
117+
* Render special characters and control characters as a symbol with their hex code.
118+
* Files: special-chars.js, special-chars.css
119+
*/
120+
class SpecialChars extends Plugin {
121+
/**
122+
* Create a special characters plugin instance.
123+
* Default = covers many non-renderable ASCII characters.
124+
* @param {Boolean} colorInSpecialChars Whether or not to give special characters custom background colors based on their hex code
125+
* @param {Boolean} inheritTextColor If `colorInSpecialChars` is false, forces the color of the hex code to inherit from syntax highlighting. Otherwise, the base color of the `pre code` element is used to give contrast to the small characters.
126+
* @param {RegExp} specialCharRegExp The regular expression which matches special characters
127+
*/
128+
constructor(colorInSpecialChars?: boolean, inheritTextColor?: boolean, specialCharRegExp?: RegExp);
129+
}
130+
}
131+
132+
/**
133+
* Register a plugin class under `codeInput.plugins`.
134+
* @param {string} pluginName The identifier of the plugin: if it is `"foo"`, `new codeInput.plugins.foo(`...`)` will instantiate it, etc.
135+
* @param {Object} pluginClass The class of the plugin, created with `class extends codeInput.plugin {`...`}`
136+
*/
137+
export function registerPluginClass(pluginName: string, pluginClass: Object): void;
138+
139+
/**
140+
* Please see `codeInput.templates.prism` or `codeInput.templates.hljs`.
141+
* Templates are used in `<code-input>` elements and once registered with
142+
* `codeInput.registerTemplate` will be in charge of the highlighting
143+
* algorithm and settings for all code-inputs with a `template` attribute
144+
* matching the registered name.
145+
*/
146+
export class Template {
147+
/**
148+
* **When `includeCodeInputInHighlightFunc` is `false`, `highlight` takes only the `<pre><code>` element as a parameter.**
149+
*
150+
* Constructor to create a custom template instance. Pass this into `codeInput.registerTemplate` to use it.
151+
* I would strongly recommend using the built-in simpler template `codeInput.templates.prism` or `codeInput.templates.hljs`.
152+
* @param {Function} highlight - a callback to highlight the code, that takes an HTML `<code>` element inside a `<pre>` element as a parameter
153+
* @param {boolean} preElementStyled - is the `<pre>` element CSS-styled as well as the `<code>` element? If true, `<pre>` element's scrolling is synchronised; if false, `<code>` element's scrolling is synchronised.
154+
* @param {boolean} isCode - is this for writing code? If true, the code-input's lang HTML attribute can be used, and the `<code>` element will be given the class name 'language-[lang attribute's value]'.
155+
* @param {false} includeCodeInputInHighlightFunc - Setting this to true passes the `<code-input>` element as a second argument to the highlight function.
156+
* @param {codeInput.Plugin[]} plugins - An array of plugin objects to add extra features - see `codeInput.Plugin`
157+
* @returns template object
158+
*/
159+
constructor(highlight?: (code: HTMLElement) => void, preElementStyled?: boolean, isCode?: boolean, includeCodeInputInHighlightFunc?: false, plugins?: Plugin[])
160+
/**
161+
* **When `includeCodeInputInHighlightFunc` is `true`, `highlight` takes two parameters: the `<pre><code>` element, and the `<code-input>` element.**
162+
*
163+
* Constructor to create a custom template instance. Pass this into `codeInput.registerTemplate` to use it.
164+
* I would strongly recommend using the built-in simpler template `codeInput.templates.prism` or `codeInput.templates.hljs`.
165+
* @param {Function} highlight - a callback to highlight the code, that takes an HTML `<code>` element inside a `<pre>` element as a parameter
166+
* @param {boolean} preElementStyled - is the `<pre>` element CSS-styled as well as the `<code>` element? If true, `<pre>` element's scrolling is synchronised; if false, `<code>` element's scrolling is synchronised.
167+
* @param {boolean} isCode - is this for writing code? If true, the code-input's lang HTML attribute can be used, and the `<code>` element will be given the class name 'language-[lang attribute's value]'.
168+
* @param {true} includeCodeInputInHighlightFunc - Setting this to true passes the `<code-input>` element as a second argument to the highlight function.
169+
* @param {codeInput.Plugin[]} plugins - An array of plugin objects to add extra features - see `codeInput.Plugin`
170+
* @returns template object
171+
*/
172+
constructor(highlight?: (code: HTMLElement, codeInput: CodeInput) => void, preElementStyled?: boolean, isCode?: boolean, includeCodeInputInHighlightFunc?: true, plugins?: Plugin[])
173+
highlight: Function
174+
preElementStyled: boolean
175+
isCode: boolean
176+
includeCodeInputInHighlightFunc: boolean
177+
plugins: Plugin[]
13178
}
14179

15-
// Main
16-
export class CodeInput {}
17-
export function registerTemplate(name: "syntax-highlighted", template: Template): void;
180+
/**
181+
* Shortcut functions for creating templates.
182+
* Each code-input element has a template attribute that
183+
* tells it which template to use.
184+
* Each template contains functions and preferences that
185+
* run the syntax-highlighting and let code-input control
186+
* the highlighting.
187+
*
188+
* For creating a custom template from scratch, please
189+
* use `new codeInput.Template(...)`.
190+
*
191+
* For adding small pieces of functionality, please see `codeInput.plugins`.
192+
*/
193+
export namespace templates {
194+
/**
195+
* Constructor to create a template that uses Prism.js syntax highlighting (https://prismjs.com/)
196+
* @param {Object} prism Import Prism.js, then after that import pass the `Prism` object as this parameter.
197+
* @param {codeInput.Plugin[]} plugins - An array of plugin objects to add extra features - see `codeInput.plugins`
198+
* @returns template object
199+
*/
200+
function prism(prism: Object, plugins?: Plugin[]): Template
201+
/**
202+
* Constructor to create a template that uses highlight.js syntax highlighting (https://highlightjs.org/)
203+
* @param {Object} hljs Import highlight.js, then after that import pass the `hljs` object as this parameter.
204+
* @param {codeInput.Plugin[]} plugins - An array of plugin objects to add extra features - see `codeInput.plugins`
205+
* @returns template object
206+
*/
207+
function hljs(hljs: Object, plugins?: Plugin[]): Template
208+
/**
209+
* Constructor to create a proof-of-concept template that gives a message if too many characters are typed.
210+
* @param {codeInput.Plugin[]} plugins - An array of plugin objects to add extra features - see `codeInput.plugins`
211+
* @returns template object
212+
*/
213+
function characterLimit(plugins?: Plugin[]): Template
214+
/**
215+
* Constructor to create a proof-of-concept template that shows text in a repeating series of colors.
216+
* @param {string[]} rainbowColors - An array of CSS colors, in the order each color will be shown
217+
* @param {string} delimiter - The character used to split up parts of text where each part is a different colour (e.g. "" = characters, " " = words)
218+
* @param {codeInput.Plugin[]} plugins - An array of plugin objects to add extra features - see `codeInput.plugins`
219+
* @returns template object
220+
*/
221+
function rainbowText(rainbowColors?: string[], delimiter?: string, plugins?: Plugin[]): Template
222+
}
223+
224+
/**
225+
* A `<code-input>` element, an instance of an `HTMLElement`, and the result
226+
* of `document.createElement("code-input")`.
227+
*/
228+
export class CodeInput extends HTMLElement { }
229+
230+
/**
231+
* Register a template so code-input elements with a template attribute that equals the templateName will use the template.
232+
* See `codeInput.templates` for constructors to create templates.
233+
* @param {string} templateName - the name to register the template under
234+
* @param {Object} template - a Template object instance - see `codeInput.templates`
235+
*/
236+
export function registerTemplate(templateName: string, template: Template): void;

0 commit comments

Comments
 (0)