Skip to content

Commit 0b7a5a4

Browse files
committed
Start working on event handling
1 parent 3bec1d4 commit 0b7a5a4

File tree

3 files changed

+86
-16
lines changed

3 files changed

+86
-16
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,10 @@ Now that you have registered a template, you can use the custom `<code-input>` e
105105
```
106106
*or*
107107
```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>
108+
<code-input lang="HTML" placeholder="Type code here" value="<a href='https://github.com/WebCoder49/code-input'>code-input</a>" template="syntax-highlighted" oninput="console.log('Your code is', this.value)"></code-input>
109109
```
110110
</details>
111+
> ❕To use the event when text is changed in a `coed-input` element, use `oninput` rather than `onchange`.
111112
112113
## Contributing
113114
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.js

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,34 @@
33
// Based on a CSS-Tricks Post
44

55
var codeInput = {
6+
observedAttributes: [
7+
"value",
8+
"placeholder",
9+
"lang",
10+
"template",
11+
"onchange",
12+
"onselectionchange"
13+
],
14+
// Attributes to monitor - needs to be global and static
15+
16+
last_events: {}, // Last events applied; removed when changed so can be added to textarea, etc.
17+
/* Templates */
618
usedTemplates: {
719
},
820
defaultTemplate: undefined,
921
templateQueue: {}, // lists of elements for each unrecognised template
22+
23+
/* Plugins */
1024
plugins: { // Import a plugin from the plugins folder and it will be saved here.
1125
},
1226
Plugin: class {
27+
constructor() {
28+
console.log("code-input: plugin: Created plugin!");
29+
30+
// Add attributes
31+
codeInput.observedAttributes = codeInput.observedAttributes.concat(self.observedAttributes);
32+
}
33+
1334
/* Runs before code is highlighted; Params: codeInput element) */
1435
beforeHighlight(codeInput) {}
1536
/* Runs after code is highlighted; Params: codeInput element) */
@@ -22,6 +43,8 @@ var codeInput = {
2243
attributeChanged(codeInput, name, oldValue, newValue) {}
2344
observedAttributes = []
2445
},
46+
47+
/* Main */
2548
CodeInput: class extends HTMLElement { // Create code input element
2649
constructor() {
2750
super(); // Element
@@ -146,6 +169,18 @@ var codeInput = {
146169

147170
this.plugin_evt("afterElementsAdded");
148171

172+
// Events
173+
textarea = this.querySelector("textarea");
174+
// Add event listeners, bound so `this` can be referenced
175+
if(this.onchange) {
176+
textarea.addEventListener("change", this.onchange.bind(this));
177+
this.onchange = undefined; // Prevent duplicate
178+
}
179+
if(this.onselectionchange) {
180+
textarea.addEventListener("selectionchange", this.onselectionchange.bind(this));
181+
this.onselectionchange = undefined; // Prevent duplicate
182+
}
183+
149184
/* Add code from value attribute - useful for loading from backend */
150185
this.update(value, this);
151186
}
@@ -156,14 +191,8 @@ var codeInput = {
156191
this.template = this.get_template();
157192
if(this.template != undefined) this.setup();
158193
}
159-
get observedAttributes() {
160-
let attrs = ["value", "placeholder", "lang", "template"]; // Attributes to monitor
161-
162-
/* Add from plugins */
163-
for (let plugin in this.template.plugins) {
164-
attrs = attrs.concat(plugin.observedAttributes);
165-
}
166-
return attrs;
194+
static get observedAttributes() {
195+
return codeInput.observedAttributes;
167196
}
168197

169198
attributeChangedCallback(name, oldValue, newValue) {
@@ -188,33 +217,66 @@ var codeInput = {
188217
else this.classList.remove("code-input_pre-element-styled");
189218
// Syntax Highlight
190219
this.update(this.value);
220+
221+
break;
191222

192223
case "lang":
193224
let code = this.querySelector("pre code");
194-
let textarea = this.querySelector("textarea");
225+
let main_textarea = this.querySelector("textarea");
195226

196227
// Case insensitive
197228
oldValue = oldValue.toLowerCase();
198229
newValue = newValue.toLowerCase();
199230

200231
// Remove old language class and add new
201-
console.log("REMOVE", "language-" + oldValue);
232+
console.log("code-input: Language: REMOVE", "language-" + oldValue);
202233
code.classList.remove("language-" + oldValue); // From CODE
203234
code.parentElement.classList.remove("language-" + oldValue); // From PRE
204235
code.classList.remove("language-none"); // Prism
205236
code.parentElement.classList.remove("language-none"); // Prism
206237

207238
if(newValue != undefined && newValue != "") {
208239
code.classList.add("language-" + newValue);
209-
console.log("ADD", "language-" + newValue);
240+
console.log("code-input: Language:ADD", "language-" + newValue);
210241
}
211242

212-
if(textarea.placeholder == oldValue) textarea.placeholder = newValue;
243+
if(main_textarea.placeholder == oldValue) main_textarea.placeholder = newValue;
213244

214245
this.update(this.value);
215-
216-
default:
217-
this.plugin_evt("attributeChanged", [name, oldValue, newValue]); // Plugin event
246+
247+
break;
248+
249+
// Events
250+
case "onchange":
251+
{
252+
// Doesn't exist
253+
let textarea = this.querySelector("textarea")
254+
if(oldValue) {
255+
textarea.removeEventListener("change", this.last_events["change"]);
256+
}
257+
if(newValue) {
258+
this.last_events["change"] = newValue.bind(this);
259+
textarea.addEventListener("change", this.last_events["change"]);
260+
this.onchange = undefined; // Prevent duplicate
261+
}
262+
}
263+
break;
264+
case "onselectionchange":
265+
{
266+
// Doesn't exist
267+
let textarea = this.querySelector("textarea")
268+
if(oldValue) {
269+
textarea.removeEventListener("selectionchange", this.last_events["selectionchange"]);
270+
}
271+
if(newValue) {
272+
this.last_events["selectionchange"] = newValue.bind(this);
273+
textarea.addEventListener("selectionchange", this.last_events["selectionchange"]);
274+
this.onselectionchange = undefined; // Prevent duplicate
275+
}
276+
}
277+
break;
278+
279+
this.plugin_evt("attributeChanged", [name, oldValue, newValue]); // Plugin event
218280
}
219281
}
220282

@@ -235,6 +297,7 @@ var codeInput = {
235297
return this.setAttribute("placeholder", val);
236298
}
237299
},
300+
238301
registerTemplate: function(template_name, template) {
239302
// Set default class
240303
codeInput.usedTemplates[template_name] = template;
@@ -245,6 +308,7 @@ var codeInput = {
245308
elem.template = template;
246309
elem.setup();
247310
}
311+
console.log(`code-input: template: Added existing elements with template ${template_name}`);
248312
}
249313
if(codeInput.defaultTemplate == undefined) {
250314
codeInput.defaultTemplate = template_name;
@@ -256,7 +320,9 @@ var codeInput = {
256320
elem.setup();
257321
}
258322
}
323+
console.log(`code-input: template: Set template ${template_name} as default`);
259324
}
325+
console.log(`code-input: template: Created template ${template_name}`);
260326
},
261327
templates: {
262328
custom(highlight=function() {}, preElementStyled=true, isCode=true, includeCodeInputInHighlightFunc=false, plugins=[]) {

plugins/autodetect.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
* autodetect capabilities. Works with highlight.js.
44
*/
55
codeInput.plugins.Autodetect = class extends codeInput.Plugin {
6+
constructor() {
7+
super();
8+
}
69
/* Remove previous language class */
710
beforeHighlight(codeInput) {
811
let result_element = codeInput.querySelector("pre code");

0 commit comments

Comments
 (0)