Skip to content

Commit adeccc3

Browse files
committed
Add plugin structure
1 parent e236b9a commit adeccc3

File tree

1 file changed

+58
-14
lines changed

1 file changed

+58
-14
lines changed

code-input.js

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,44 @@ var codeInput = {
66
usedTemplates: {
77
},
88
defaultTemplate: undefined,
9+
plugins: { // Import a plugin from the plugins folder and it will be saved here.
10+
},
11+
Plugin: class {
12+
/* Runs before code is highlighted; Params: codeInput element) */
13+
beforeHighlight(codeInput) {}
14+
/* Runs after code is highlighted; Params: codeInput element) */
15+
afterHighlight(codeInput) {}
16+
/* Runs before elements are added into a `code-input`; Params: codeInput element) */
17+
beforeElementsAdded(codeInput) {}
18+
/* Runs after elements are added into a `code-input` (useful for adding events to the textarea); Params: codeInput element) */
19+
afterElementsAdded(codeInput) {}
20+
/* Runs when an attribute of a `code-input` is changed (you must add the attribute name to observedAttributes); Params: codeInput element, name attribute name, oldValue previous value of attribute, newValue changed value of attribute) */
21+
attributeChanged(codeInput, name, oldValue, newValue) {}
22+
observedAttributes = []
23+
},
924
CodeInput: class extends HTMLElement { // Create code input element
1025
constructor() {
1126
super(); // Element
1227
}
1328

29+
30+
/* Run this event in all plugins with a optional list of arguments */
31+
plugin_evt(id, args) {
32+
// Run the event `id` in each plugin
33+
for (let i in this.template.plugins) {
34+
let plugin = this.template.plugins[i];
35+
if (id in plugin) {
36+
if(args === undefined) {
37+
plugin[id](this);
38+
} else {
39+
plugin[id](this, ...args);
40+
}
41+
}
42+
}
43+
}
44+
1445
/* Syntax-highlighting functions */
1546
update(text) {
16-
1747
if(this.value != text) this.value = text; // Change value attribute if necessary.
1848
if(this.querySelector("textarea").value != text) this.querySelector("textarea").value = text;
1949

@@ -26,13 +56,17 @@ var codeInput = {
2656
}
2757
// Update code
2858
result_element.innerHTML = this.escape_html(text);
59+
this.plugin_evt("beforeHighlight");
60+
2961
if(this.autodetect) { // Autodetection
3062
result_element.className = ""; // CODE
3163
result_element.parentElement.className = ""; // PRE
3264
}
3365
// Syntax Highlight
3466
if(this.template.includeCodeInputInHighlightFunc) this.template.highlight(result_element, this);
3567
else this.template.highlight(result_element);
68+
69+
this.plugin_evt("afterHighlight");
3670
}
3771

3872
sync_scroll() {
@@ -175,6 +209,8 @@ var codeInput = {
175209
this.template = codeInput.usedTemplates[this.getAttribute("template") || codeInput.defaultTemplate];
176210
if(this.template.preElementStyled) this.classList.add("code-input_pre-element-styled");
177211

212+
this.plugin_evt("beforeElementsAdded");
213+
178214
/* Defaults */
179215
let lang = this.getAttribute("lang");
180216
let placeholder = this.getAttribute("placeholder") || this.getAttribute("lang") || "";
@@ -196,9 +232,8 @@ var codeInput = {
196232
textarea.setAttribute("oninput", "this.parentElement.update(this.value); this.parentElement.sync_scroll();");
197233
textarea.setAttribute("onscroll", "this.parentElement.sync_scroll();");
198234
textarea.setAttribute("onkeydown", "this.parentElement.check_tab(event); this.parentElement.check_enter(event);");
199-
200235
this.append(textarea);
201-
236+
202237
/* Create pre code */
203238
let code = document.createElement("code");
204239
let pre = document.createElement("pre");
@@ -210,14 +245,21 @@ var codeInput = {
210245
if(lang != undefined && lang != "") {
211246
code.classList.add("language-" + lang);
212247
}
213-
else this.autodetect = true // No lang attribute
214248
}
215249

250+
this.plugin_evt("afterElementsAdded");
251+
216252
/* Add code from value attribute - useful for loading from backend */
217253
this.update(value, this);
218254
}
219-
static get observedAttributes() {
220-
return ["value", "placeholder", "lang", "template"]; // Attributes to monitor
255+
get observedAttributes() {
256+
let attrs = ["value", "placeholder", "lang", "template"]; // Attributes to monitor
257+
258+
/* Add from plugins */
259+
for (let plugin in this.template.plugins) {
260+
attrs = attrs.concat(plugin.observedAttributes);
261+
}
262+
return attrs;
221263
}
222264
attributeChangedCallback(name, oldValue, newValue) {
223265
if(this.isConnected) {
@@ -260,14 +302,14 @@ var codeInput = {
260302
if(newValue != undefined && newValue != "") {
261303
code.classList.add("language-" + newValue);
262304
console.log("ADD", "language-" + newValue);
263-
} else {
264-
// Autodetect - works with HLJS
265-
this.autodetect = true;
266305
}
267306

268307
if(textarea.placeholder == oldValue) textarea.placeholder = newValue;
269308

270309
this.update(this.value);
310+
311+
default:
312+
this.plugin_evt("attributeChanged", [name, oldValue, newValue]); // Plugin event
271313
}
272314
}
273315

@@ -294,28 +336,30 @@ var codeInput = {
294336
codeInput.defaultTemplate = template_name;
295337
},
296338
templates: {
297-
custom(highlight=function() {}, preElementStyled=true, isCode=true, includeCodeInputInHighlightFunc=false) {
339+
custom(highlight=function() {}, preElementStyled=true, isCode=true, includeCodeInputInHighlightFunc=false, plugins=[]) {
298340
return {
299341
highlight: highlight,
300342
includeCodeInputInHighlightFunc: includeCodeInputInHighlightFunc,
301343
preElementStyled: preElementStyled,
302344
isCode: isCode,
303345
};
304346
},
305-
prism(prism) { // Dependency: Prism.js (https://prismjs.com/)
347+
prism(prism, plugins=[]) { // Dependency: Prism.js (https://prismjs.com/)
306348
return {
307349
includeCodeInputInHighlightFunc: false,
308350
highlight: prism.highlightElement,
309351
preElementStyled: true,
310-
isCode: true
352+
isCode: true,
353+
plugins: plugins,
311354
};
312355
},
313-
hljs(hljs) { // Dependency: Highlight.js (https://highlightjs.org/)
356+
hljs(hljs, plugins=[]) { // Dependency: Highlight.js (https://highlightjs.org/)
314357
return {
315358
includeCodeInputInHighlightFunc: false,
316359
highlight: hljs.highlightElement,
317360
preElementStyled: false,
318-
isCode: true
361+
isCode: true,
362+
plugins: plugins,
319363
};
320364
},
321365
characterLimit() {

0 commit comments

Comments
 (0)