@webcoder49/code-input 2.6.0 → 2.6.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/SECURITY.md ADDED
@@ -0,0 +1,7 @@
1
+ # Reporting Security Vulnerabilities
2
+ If you find a sensitive security vulnerability
3
+ in the code-input.js library, please
4
+ contact the maintainer Oliver Geer at
5
+ [security@webcoder49.dev](mailto:security@webcoder49.dev),
6
+ using [this optional PGP encryption key and advice](https://oliver.geer.im#email)
7
+ if you know how to do so.
package/code-input.js CHANGED
@@ -15,12 +15,14 @@
15
15
 
16
16
  var codeInput = {
17
17
  /**
18
- * A list of attributes that will trigger the
19
- * `codeInput.CodeInput.attributeChangedCallback`
18
+ * A list of attributes that will trigger functionality in the
19
+ * `codeInput.CodeInput.attributeChangedCallback`
20
20
  * when modified in a code-input element. This
21
21
  * does not include events, which are handled in
22
22
  * `codeInput.CodeInput.addEventListener` and
23
23
  * `codeInput.CodeInput.removeEventListener`.
24
+ *
25
+ * This does not include those listed in `codeInput.textareaSyncAttributes` that only synchronise with the textarea element.
24
26
  */
25
27
  observedAttributes: [
26
28
  "value",
@@ -133,9 +135,7 @@ var codeInput = {
133
135
  for (let i in codeInput.templateNotYetRegisteredQueue[templateName]) {
134
136
  const elem = codeInput.templateNotYetRegisteredQueue[templateName][i];
135
137
  elem.templateObject = template;
136
- elem.connectedCallback();
137
- // Bind sets elem as first parameter of function
138
- // So innerHTML can be read
138
+ elem.setup();
139
139
  }
140
140
  }
141
141
 
@@ -146,9 +146,7 @@ var codeInput = {
146
146
  for (let i in codeInput.templateNotYetRegisteredQueue[undefined]) {
147
147
  const elem = codeInput.templateNotYetRegisteredQueue[undefined][i];
148
148
  elem.templateObject = template;
149
- elem.connectedCallback();
150
- // Bind sets elem as first parameter of function
151
- // So innerHTML can be read
149
+ elem.setup();
152
150
  }
153
151
  }
154
152
  }
@@ -611,6 +609,8 @@ var codeInput = {
611
609
  setup() {
612
610
  if(this.textareaElement != null) return; // Already set up
613
611
 
612
+ this.classList.add("code-input_registered");
613
+
614
614
  this.mutationObserver = new MutationObserver(this.mutationObserverCallback.bind(this));
615
615
  this.mutationObserver.observe(this, {
616
616
  attributes: true,
@@ -630,6 +630,8 @@ var codeInput = {
630
630
  let textareaAttributeNames = fallbackTextarea.getAttributeNames();
631
631
  for(let i = 0; i < textareaAttributeNames.length; i++) {
632
632
  const attr = textareaAttributeNames[i];
633
+ if(attr == "data-code-input-fallback") continue;
634
+
633
635
  if(!this.hasAttribute(attr)) {
634
636
  this.setAttribute(attr, fallbackTextarea.getAttribute(attr));
635
637
  }
@@ -655,7 +657,10 @@ var codeInput = {
655
657
  textarea.value = value;
656
658
  }
657
659
  textarea.innerHTML = this.innerHTML;
658
- textarea.setAttribute("spellcheck", "false");
660
+ if(!this.hasAttribute("spellcheck")) {
661
+ // For backwards compatibility:
662
+ textarea.setAttribute("spellcheck", "false");
663
+ }
659
664
 
660
665
  // Disable focusing on the code-input element - only allow the textarea to be focusable
661
666
  textarea.setAttribute("tabindex", this.getAttribute("tabindex") || 0);
@@ -728,6 +733,8 @@ var codeInput = {
728
733
  this.syncSize();
729
734
  });
730
735
  resizeObserver.observe(this);
736
+
737
+ this.classList.add("code-input_loaded");
731
738
  }
732
739
 
733
740
  /**
@@ -775,9 +782,10 @@ var codeInput = {
775
782
  // template property with the string value of the attribute
776
783
  this.templateObject = this.getTemplate();
777
784
  if (this.templateObject != undefined) {
785
+ // Template registered before loading
778
786
  this.classList.add("code-input_registered");
779
- this.setup();
780
- this.classList.add("code-input_loaded");
787
+ // Children not yet present - wait until they are
788
+ window.addEventListener("DOMContentLoaded", this.setup.bind(this))
781
789
  }
782
790
  }
783
791
 
@@ -792,6 +800,11 @@ var codeInput = {
792
800
  return this.attributeChangedCallback(mutation.attributeName, mutation.oldValue, super.getAttribute(mutation.attributeName));
793
801
  }
794
802
  }
803
+ for(let i = 0; i < codeInput.textareaSyncAttributes.length; i++) {
804
+ if (mutation.attributeName == codeInput.textareaSyncAttributes[i]) {
805
+ return this.attributeChangedCallback(mutation.attributeName, mutation.oldValue, super.getAttribute(mutation.attributeName));
806
+ }
807
+ }
795
808
  if (mutation.attributeName.substring(0, 5) == "aria-") {
796
809
  return this.attributeChangedCallback(mutation.attributeName, mutation.oldValue, super.getAttribute(mutation.attributeName));
797
810
  }
@@ -962,117 +975,167 @@ var codeInput = {
962
975
  }
963
976
  }
964
977
 
978
+ //-------------------------------------------
979
+ //----------- Textarea interface ------------
980
+ //-------------------------------------------
981
+ // See https://developer.mozilla.org/en-US/docs/Web/API/HTMLTextAreaElement
982
+ // Attributes defined at codeInput.textareaSyncAttributes
983
+
965
984
  /**
966
- * Get the text contents of the code-input element.
985
+ * Get the JavaScript property from the internal textarea
986
+ * element, given its name and a defaultValue to return
987
+ * when no textarea is present (undefined to make it throw
988
+ * an error instead).
989
+ *
990
+ * For internal use - treat the code-input element as a
991
+ * textarea for the standard properties (e.g. document.
992
+ * querySelector("code-input").defaultValue).
967
993
  */
968
- get value() {
994
+ getTextareaProperty(name, defaultValue=undefined) {
969
995
  if(this.textareaElement) {
970
- // Get from editable textarea element
971
- return this.textareaElement.value;
996
+ return this.textareaElement[name];
972
997
  } else {
973
998
  // Unregistered
974
999
  const fallbackTextarea = this.querySelector("textarea[data-code-input-fallback]");
975
1000
  if(fallbackTextarea) {
976
- return fallbackTextarea.value;
1001
+ return fallbackTextarea[name];
977
1002
  } else {
978
- return this.innerHTML;
1003
+ if(defaultValue === undefined) {
1004
+ throw new Error("Cannot get "+name+" of an unregistered code-input element without a data-code-input-fallback textarea.");
1005
+ }
1006
+ return defaultValue;
979
1007
  }
980
1008
  }
981
1009
  }
982
1010
  /**
983
- * Set the text contents of the code-input element.
984
- * @param {string} val - New text contents
1011
+ * Set the JavaScript property of the internal textarea
1012
+ * element, given its name and value.
1013
+ *
1014
+ * If there is no registered or fallback textarea and errorIfCannot is
1015
+ * false, return false (otherwise true); If there is no registered or
1016
+ * fallback textarea and errorIfCannot is true, throw an error.
1017
+ *
1018
+ * For internal use - treat the code-input element as a
1019
+ * textarea for the standard properties (e.g. document.
1020
+ * querySelector("code-input").defaultValue).
985
1021
  */
986
- set value(val) {
987
- if (val === null || val === undefined) {
988
- val = "";
989
- }
1022
+ setTextareaProperty(name, value, errorIfCannot=true) {
990
1023
  if(this.textareaElement) {
991
- // Save in editable textarea element
992
- this.textareaElement.value = val;
993
- // Trigger highlight
994
- this.scheduleHighlight();
1024
+ this.textareaElement[name] = value;
995
1025
  } else {
996
1026
  // Unregistered
997
1027
  const fallbackTextarea = this.querySelector("textarea[data-code-input-fallback]");
998
1028
  if(fallbackTextarea) {
999
- fallbackTextarea.value = val;
1029
+ fallbackTextarea[name] = value;
1000
1030
  } else {
1001
- this.innerHTML = val;
1031
+ if(!errorIfCannot) return false;
1032
+ throw new Error("Cannot set "+name+" of an unregistered code-input element without a data-code-input-fallback textarea.");
1002
1033
  }
1003
1034
  }
1035
+ return true;
1004
1036
  }
1005
1037
 
1006
- // Synchronise blur and focus
1007
- focus(options={}) {
1008
- return this.textareaElement.focus(options);
1009
- }
1010
- blur(options={}) {
1011
- return this.textareaElement.blur(options);
1038
+ get autocomplete() { return this.getAttribute("autocomplete"); }
1039
+ set autocomplete(val) { return this.setAttribute("autocomplete", val); }
1040
+ get cols() { return this.getTextareaProperty("cols", Number(this.getAttribute("cols"))); }
1041
+ set cols(val) { this.setAttribute("cols", val); }
1042
+ get defaultValue() { return this.initialValue; }
1043
+ set defaultValue(val) { this.initialValue = val; }
1044
+ get textContent() { return this.initialValue; }
1045
+ set textContent(val) { this.initialValue = val; }
1046
+ get dirName() { return this.getAttribute("dirName") || ""; }
1047
+ set dirName(val) { this.setAttribute("dirname", val); }
1048
+ get disabled() { return this.hasAttribute("disabled"); }
1049
+ set disabled(val) {
1050
+ if(val) {
1051
+ this.setAttribute("disabled", true);
1052
+ } else {
1053
+ this.removeAttribute("disabled");
1054
+ }
1012
1055
  }
1013
-
1014
- /**
1015
- * Get the placeholder of the code-input element that appears
1016
- * when no code has been entered.
1017
- */
1018
- get placeholder() {
1019
- return this.getAttribute("placeholder");
1056
+ get form() { return this.getTextareaProperty("form"); }
1057
+ get labels() { return this.getTextareaProperty("labels"); }
1058
+ get maxLength() {
1059
+ const result = Number(this.getAttribute("maxlength"));
1060
+ if(isNaN(result)) {
1061
+ return -1;
1062
+ }
1063
+ return result;
1020
1064
  }
1021
- /**
1022
- * Set the placeholder of the code-input element that appears
1023
- * when no code has been entered.
1024
- * @param {string} val - New placeholder
1025
- */
1026
- set placeholder(val) {
1027
- return this.setAttribute("placeholder", val);
1065
+ set maxLength(val) {
1066
+ if(val == -1) {
1067
+ this.removeAttribute("maxlength");
1068
+ } else {
1069
+ this.setAttribute("maxlength", val);
1070
+ }
1028
1071
  }
1029
-
1030
- /**
1031
- * Returns a ValidityState object that represents the validity states of an element.
1032
- *
1033
- * See `HTMLTextAreaElement.validity`
1034
- */
1035
- get validity() {
1036
- return this.textareaElement.validity;
1072
+ get minLength() {
1073
+ const result = Number(this.getAttribute("minlength"));
1074
+ if(isNaN(result)) {
1075
+ return -1;
1076
+ }
1077
+ return result;
1037
1078
  }
1038
-
1039
- /**
1040
- * Returns the error message that would be displayed if the user submits the form, or an empty string if no error message.
1041
- * It also triggers the standard error message, such as "this is a required field". The result is that the user sees validation
1042
- * messages without actually submitting.
1043
- *
1044
- * See `HTMLTextAreaElement.validationMessage`
1045
- */
1046
- get validationMessage() {
1047
- return this.textareaElement.validationMessage;
1079
+ set minLength(val) {
1080
+ if(val == -1) {
1081
+ this.removeAttribute("minlength");
1082
+ } else {
1083
+ this.setAttribute("minlength", val);
1084
+ }
1048
1085
  }
1049
-
1050
- /**
1051
- * Sets a custom error message that is displayed when a form is submitted.
1052
- *
1053
- * See `HTMLTextAreaElement.setCustomValidity`
1054
- * @param error Sets a custom error message that is displayed when a form is submitted.
1055
- */
1056
- setCustomValidity(error) {
1057
- return this.textareaElement.setCustomValidity(error);
1086
+ get name() { return this.getAttribute("name") || ""; }
1087
+ set name(val) { this.setAttribute("name", val); }
1088
+ get placeholder() { return this.getAttribute("placeholder") || ""; }
1089
+ set placeholder(val) { this.setAttribute("placeholder", val); }
1090
+ get readOnly() { return this.hasAttribute("readonly"); }
1091
+ set readOnly(val) {
1092
+ if(val) {
1093
+ this.setAttribute("readonly", true);
1094
+ } else {
1095
+ this.removeAttribute("readonly");
1096
+ }
1058
1097
  }
1059
-
1060
- /**
1061
- * Returns whether a form will validate when it is submitted,
1062
- * without having to submit it.
1063
- *
1064
- * See `HTMLTextAreaElement.checkValidity`
1065
- */
1066
- checkValidity() {
1067
- return this.textareaElement.checkValidity();
1098
+ get required() { return this.hasAttribute("readonly"); }
1099
+ set required(val) {
1100
+ if(val) {
1101
+ this.setAttribute("readonly", true);
1102
+ } else {
1103
+ this.removeAttribute("readonly");
1104
+ }
1068
1105
  }
1069
-
1070
- /**
1071
- * See `HTMLTextAreaElement.reportValidity`
1072
- */
1073
- reportValidity() {
1074
- return this.textareaElement.reportValidity();
1106
+ get rows() { return this.getTextareaProperty("rows", Number(this.getAttribute("rows"))); }
1107
+ set rows(val) { this.setAttribute("rows", val); }
1108
+ get selectionDirection() { return this.getTextareaProperty("selectionDirection"); }
1109
+ set selectionDirection(val) { this.setTextareaProperty("selectionDirection", val); }
1110
+ get selectionEnd() { return this.getTextareaProperty("selectionEnd"); }
1111
+ set selectionEnd(val) { this.setTextareaProperty("selectionEnd", val); }
1112
+ get selectionStart() { return this.getTextareaProperty("selectionStart"); }
1113
+ set selectionStart(val) { this.setTextareaProperty("selectionStart", val); }
1114
+ get textLength() { return this.value.length; }
1115
+ get type() { return "textarea"; } // Mimics textarea
1116
+ get validationMessage() { return this.getTextareaProperty("validationMessage"); }
1117
+ get validity() { return this.getTextareaProperty("validationMessage"); }
1118
+ get value() { return this.getTextareaProperty("value", this.getAttribute("value") || this.innerHTML); }
1119
+ set value(val) {
1120
+ val = val || "";
1121
+ if(this.setTextareaProperty("value", val, false)) {
1122
+ if(this.textareaElement) this.scheduleHighlight();
1123
+ } else {
1124
+ this.innerHTML = val;
1125
+ }
1075
1126
  }
1127
+ get willValidate() { return this.getTextareaProperty("willValidate", this.disabled || this.readOnly); }
1128
+ get wrap() { return this.getAttribute("wrap") || ""; }
1129
+ set wrap(val) { this.setAttribute("wrap", val); }
1130
+
1131
+
1132
+ blur(options={}) { return this.textareaElement.blur(options); }
1133
+ checkValidity() { return this.textareaElement.checkValidity(); }
1134
+ focus(options={}) { return this.textareaElement.focus(options); }
1135
+ reportValidity() { return this.textareaElement.reportValidity(); }
1136
+ setCustomValidity(error) { this.textareaElement.setCustomValidity(error); }
1137
+ setRangeText(replacement, selectionStart=this.selectionStart, selectionEnd=this.selectionEnd, selectMode="preserve") { this.getTextareaProperty("setRangeText")(replacement, selectionStart, selectionEnd, selectMode); }
1138
+ setSelectionRange(selectionStart, selectionEnd, selectionDirection="none") { this.getTextareaProperty("setSelectionRange")(selectionStart, selectionEnd, selectionDirection); }
1076
1139
 
1077
1140
  /**
1078
1141
  * Allows plugins to store data in the scope of a single element.
package/code-input.min.js CHANGED
@@ -9,4 +9,4 @@
9
9
  * @license MIT
10
10
  *
11
11
  * **<https://code-input-js.org>**
12
- */"use strict";var codeInput={observedAttributes:["value","placeholder","language","lang","template"],textareaSyncAttributes:["value","min","max","type","pattern","autocomplete","autocorrect","autofocus","cols","dirname","disabled","form","maxlength","minlength","name","placeholder","readonly","required","rows","spellcheck","wrap"],textareaSyncEvents:["change","selectionchange","invalid","input","focus","blur","focusin","focusout"],usedTemplates:{},defaultTemplate:void 0,templateNotYetRegisteredQueue:{},registerTemplate:function(a,b){if(!("string"==typeof a||a instanceof String))throw TypeError(`code-input: Name of template "${a}" must be a string.`);if(!("function"==typeof b.highlight||b.highlight instanceof Function))throw TypeError(`code-input: Template for "${a}" invalid, because the highlight function provided is not a function; it is "${b.highlight}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.includeCodeInputInHighlightFunc||b.includeCodeInputInHighlightFunc instanceof Boolean))throw TypeError(`code-input: Template for "${a}" invalid, because the includeCodeInputInHighlightFunc value provided is not a true or false; it is "${b.includeCodeInputInHighlightFunc}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.preElementStyled||b.preElementStyled instanceof Boolean))throw TypeError(`code-input: Template for "${a}" invalid, because the preElementStyled value provided is not a true or false; it is "${b.preElementStyled}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.isCode||b.isCode instanceof Boolean))throw TypeError(`code-input: Template for "${a}" invalid, because the isCode value provided is not a true or false; it is "${b.isCode}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!Array.isArray(b.plugins))throw TypeError(`code-input: Template for "${a}" invalid, because the plugin array provided is not an array; it is "${b.plugins}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(b.plugins.forEach((c,d)=>{if(!(c instanceof codeInput.Plugin))throw TypeError(`code-input: Template for "${a}" invalid, because the plugin provided at index ${d} is not valid; it is "${b.plugins[d]}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`)}),codeInput.usedTemplates[a]=b,a in codeInput.templateNotYetRegisteredQueue)for(let c in codeInput.templateNotYetRegisteredQueue[a]){const d=codeInput.templateNotYetRegisteredQueue[a][c];d.templateObject=b,d.connectedCallback()}if(null==codeInput.defaultTemplate&&(codeInput.defaultTemplate=a,void 0 in codeInput.templateNotYetRegisteredQueue))for(let a in codeInput.templateNotYetRegisteredQueue[void 0]){const c=codeInput.templateNotYetRegisteredQueue[void 0][a];c.templateObject=b,c.connectedCallback()}},Template:class{constructor(a=function(){},b=!0,c=!0,d=!1,e=[]){this.highlight=a,this.preElementStyled=b,this.isCode=c,this.includeCodeInputInHighlightFunc=d,this.plugins=e}highlight=function(){};preElementStyled=!0;isCode=!0;includeCodeInputInHighlightFunc=!1;plugins=[]},templates:{prism(a,b=[]){return new codeInput.templates.Prism(a,b)},hljs(a,b=[]){return new codeInput.templates.Hljs(a,b)},characterLimit(a){return{highlight:function(a,b,c=[]){let d=+b.getAttribute("data-character-limit"),e=b.escapeHtml(b.value.slice(0,d)),f=b.escapeHtml(b.value.slice(d));a.innerHTML=`${e}<mark class="overflow">${f}</mark>`,0<f.length&&(a.innerHTML+=` <mark class="overflow-msg">${b.getAttribute("data-overflow-msg")||"(Character limit reached)"}</mark>`)},includeCodeInputInHighlightFunc:!0,preElementStyled:!0,isCode:!1,plugins:a}},rainbowText(a=["red","orangered","orange","goldenrod","gold","green","darkgreen","navy","blue","magenta"],b="",c=[]){return{highlight:function(a,b){let c=[],d=b.value.split(b.template.delimiter);for(let e=0;e<d.length;e++)c.push(`<span style="color: ${b.template.rainbowColors[e%b.template.rainbowColors.length]}">${b.escapeHtml(d[e])}</span>`);a.innerHTML=c.join(b.template.delimiter)},includeCodeInputInHighlightFunc:!0,preElementStyled:!0,isCode:!1,rainbowColors:a,delimiter:b,plugins:c}},character_limit(){return this.characterLimit([])},rainbow_text(a=["red","orangered","orange","goldenrod","gold","green","darkgreen","navy","blue","magenta"],b="",c=[]){return this.rainbowText(a,b,c)},custom(a=function(){},b=!0,c=!0,d=!1,e=[]){return{highlight:a,includeCodeInputInHighlightFunc:d,preElementStyled:b,isCode:c,plugins:e}}},plugins:new Proxy({},{get(a,b){if(a[b]==null)throw ReferenceError(`code-input: Plugin '${b}' is not defined. Please ensure you import the necessary files from the plugins folder in the WebCoder49/code-input repository, in the <head> of your HTML, before the plugin is instatiated.`);return a[b]}}),Plugin:class{constructor(a){a.forEach(a=>{codeInput.observedAttributes.push(a)})}addTranslations(a,b){for(const c in b)a[c]=b[c]}beforeHighlight(){}afterHighlight(){}beforeElementsAdded(){}afterElementsAdded(){}attributeChanged(){}},CodeInput:class extends HTMLElement{constructor(){super()}templateObject=null;textareaElement=null;preElement=null;codeElement=null;dialogContainerElement=null;static formAssociated=!0;boundEventCallbacks={};pluginEvt(a,b){for(let c in this.templateObject.plugins){let d=this.templateObject.plugins[c];a in d&&(b===void 0?d[a](this):d[a](this,...b))}}needsHighlight=!1;originalAriaDescription;scheduleHighlight(){this.needsHighlight=!0}animateFrame(){this.needsHighlight&&(this.update(),this.needsHighlight=!1),window.requestAnimationFrame(this.animateFrame.bind(this))}update(){let a=this.codeElement,b=this.value;b+="\n",a.innerHTML=this.escapeHtml(b),this.pluginEvt("beforeHighlight"),this.templateObject.includeCodeInputInHighlightFunc?this.templateObject.highlight(a,this):this.templateObject.highlight(a),this.syncSize(),this.pluginEvt("afterHighlight")}syncSize(){this.templateObject.preElementStyled?(this.style.backgroundColor=getComputedStyle(this.preElement).backgroundColor,this.textareaElement.style.height=getComputedStyle(this.preElement).height,this.textareaElement.style.width=getComputedStyle(this.preElement).width):(this.style.backgroundColor=getComputedStyle(this.codeElement).backgroundColor,this.textareaElement.style.height=getComputedStyle(this.codeElement).height,this.textareaElement.style.width=getComputedStyle(this.codeElement).width)}setKeyboardNavInstructions(a,b){this.dialogContainerElement.querySelector(".code-input_keyboard-navigation-instructions").innerText=a,b?this.textareaElement.setAttribute("aria-description",this.originalAriaDescription+". "+a):this.textareaElement.setAttribute("aria-description",a)}escapeHtml(a){return a.replace(/&/g,"&amp;").replace(/</g,"&lt;")}unescapeHtml(a){return a.replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">")}getTemplate(){let a;return a=null==this.getAttribute("template")?codeInput.defaultTemplate:this.getAttribute("template"),a in codeInput.usedTemplates?codeInput.usedTemplates[a]:(a in codeInput.templateNotYetRegisteredQueue||(codeInput.templateNotYetRegisteredQueue[a]=[]),void codeInput.templateNotYetRegisteredQueue[a].push(this))}setup(){if(null!=this.textareaElement)return;this.mutationObserver=new MutationObserver(this.mutationObserverCallback.bind(this)),this.mutationObserver.observe(this,{attributes:!0,attributeOldValue:!0}),this.classList.add("code-input_registered"),this.templateObject.preElementStyled&&this.classList.add("code-input_pre-element-styled"),this.pluginEvt("beforeElementsAdded");const a=this.querySelector("textarea[data-code-input-fallback]");let b;if(a){let c=a.getAttributeNames();for(let b=0;b<c.length;b++){const d=c[b];this.hasAttribute(d)||this.setAttribute(d,a.getAttribute(d))}b=a.value}else b=this.unescapeHtml(this.innerHTML);b=b||this.getAttribute("value")||"";const c=this.getAttribute("language")||this.getAttribute("lang"),d=this.getAttribute("placeholder")||c||"";this.initialValue=b;const e=document.createElement("textarea");e.placeholder=d,""!=b&&(e.value=b),e.innerHTML=this.innerHTML,e.setAttribute("spellcheck","false"),e.setAttribute("tabindex",this.getAttribute("tabindex")||0),this.setAttribute("tabindex",-1),this.originalAriaDescription=this.getAttribute("aria-description")||"Code input field",this.addEventListener("mousedown",()=>{this.classList.add("code-input_mouse-focused")}),e.addEventListener("blur",()=>{this.classList.remove("code-input_mouse-focused")}),this.innerHTML="";for(let a,b=0;b<this.attributes.length;b++)a=this.attributes[b].name,(codeInput.textareaSyncAttributes.includes(a)||"aria-"==a.substring(0,5))&&e.setAttribute(a,this.getAttribute(a));e.addEventListener("input",()=>{this.value=this.textareaElement.value}),this.textareaElement=e,this.append(e);let f=document.createElement("code"),g=document.createElement("pre");g.setAttribute("aria-hidden","true"),g.setAttribute("tabindex","-1"),g.setAttribute("inert",!0),this.preElement=g,this.codeElement=f,g.append(f),this.append(g),this.templateObject.isCode&&c!=null&&""!=c&&f.classList.add("language-"+c.toLowerCase());let h=document.createElement("div");h.classList.add("code-input_dialog-container"),this.append(h),this.dialogContainerElement=h;let i=document.createElement("div");i.classList.add("code-input_keyboard-navigation-instructions"),h.append(i),this.pluginEvt("afterElementsAdded"),this.dispatchEvent(new CustomEvent("code-input_load")),this.value=b,this.animateFrame();const j=new ResizeObserver(()=>{this.syncSize()});j.observe(this)}escape_html(a){return this.escapeHtml(a)}get_template(){return this.getTemplate()}get template(){return this.templateObject}set template(a){}connectedCallback(){this.templateObject=this.getTemplate(),this.templateObject!=null&&(this.classList.add("code-input_registered"),this.setup(),this.classList.add("code-input_loaded"))}mutationObserverCallback(a){for(const b of a)if("attributes"===b.type){for(let a=0;a<codeInput.observedAttributes.length;a++)if(b.attributeName==codeInput.observedAttributes[a])return this.attributeChangedCallback(b.attributeName,b.oldValue,super.getAttribute(b.attributeName));if("aria-"==b.attributeName.substring(0,5))return this.attributeChangedCallback(b.attributeName,b.oldValue,super.getAttribute(b.attributeName))}}disconnectedCallback(){this.mutationObserver.disconnect()}attributeChangedCallback(a,b,c){if(this.isConnected)switch(this.pluginEvt("attributeChanged",[a,b,c]),a){case"value":this.value=c;break;case"template":this.templateObject=codeInput.usedTemplates[c||codeInput.defaultTemplate],this.templateObject.preElementStyled?this.classList.add("code-input_pre-element-styled"):this.classList.remove("code-input_pre-element-styled"),this.scheduleHighlight();break;case"lang":case"language":let d=this.codeElement,e=this.textareaElement;if(null!=c&&(c=c.toLowerCase(),d.classList.contains(`language-${c}`)))break;null!==b&&(b=b.toLowerCase(),d.classList.remove("language-"+b),d.parentElement.classList.remove("language-"+b)),d.classList.remove("language-none"),d.parentElement.classList.remove("language-none"),null!=c&&""!=c&&d.classList.add("language-"+c),e.placeholder==b&&(e.placeholder=c),this.scheduleHighlight();break;default:codeInput.textareaSyncAttributes.includes(a)||"aria-"==a.substring(0,5)?null==c||null==c?this.textareaElement.removeAttribute(a):this.textareaElement.setAttribute(a,c):codeInput.textareaSyncAttributes.regexp.forEach(b=>{a.match(b)&&(null==c?this.textareaElement.removeAttribute(a):this.textareaElement.setAttribute(a,c))})}}addEventListener(a,b,c=void 0){let d=function(a){"function"==typeof b?b(a):b&&b.handleEvent&&b.handleEvent(a)}.bind(this);this.boundEventCallbacks[b]=d,codeInput.textareaSyncEvents.includes(a)?(this.boundEventCallbacks[b]=d,c===void 0?null==this.textareaElement?this.addEventListener("code-input_load",()=>{this.textareaElement.addEventListener(a,d)}):this.textareaElement.addEventListener(a,d):null==this.textareaElement?this.addEventListener("code-input_load",()=>{this.textareaElement.addEventListener(a,d,c)}):this.textareaElement.addEventListener(a,d,c)):c===void 0?super.addEventListener(a,d):super.addEventListener(a,d,c)}removeEventListener(a,b,c=void 0){let d=this.boundEventCallbacks[b];codeInput.textareaSyncEvents.includes(a)?c===void 0?null==this.textareaElement?this.addEventListener("code-input_load",()=>{this.textareaElement.removeEventListener(a,d)}):this.textareaElement.removeEventListener(a,d):null==this.textareaElement?this.addEventListener("code-input_load",()=>{this.textareaElement.removeEventListener(a,d,c)}):this.textareaElement.removeEventListener(a,d,c):c===void 0?super.removeEventListener(a,d):super.removeEventListener(a,d,c)}get value(){if(this.textareaElement)return this.textareaElement.value;else{const a=this.querySelector("textarea[data-code-input-fallback]");return a?a.value:this.innerHTML}}set value(a){if((null===a||void 0===a)&&(a=""),this.textareaElement)this.textareaElement.value=a,this.scheduleHighlight();else{const b=this.querySelector("textarea[data-code-input-fallback]");b?b.value=a:this.innerHTML=a}}focus(a={}){return this.textareaElement.focus(a)}blur(a={}){return this.textareaElement.blur(a)}get placeholder(){return this.getAttribute("placeholder")}set placeholder(a){return this.setAttribute("placeholder",a)}get validity(){return this.textareaElement.validity}get validationMessage(){return this.textareaElement.validationMessage}setCustomValidity(a){return this.textareaElement.setCustomValidity(a)}checkValidity(){return this.textareaElement.checkValidity()}reportValidity(){return this.textareaElement.reportValidity()}pluginData={};formResetCallback(){this.value=this.initialValue}}};{class a extends codeInput.Template{constructor(a,b=[],c=!0){super(a.highlightElement,c,!0,!1,b)}}codeInput.templates.Prism=a;class b extends codeInput.Template{constructor(a,b=[],c=!1){super(function(b){b.removeAttribute("data-highlighted"),a.highlightElement(b)},c,!0,!1,b)}}codeInput.templates.Hljs=b}customElements.define("code-input",codeInput.CodeInput);
12
+ */"use strict";var codeInput={observedAttributes:["value","placeholder","language","lang","template"],textareaSyncAttributes:["value","min","max","type","pattern","autocomplete","autocorrect","autofocus","cols","dirname","disabled","form","maxlength","minlength","name","placeholder","readonly","required","rows","spellcheck","wrap"],textareaSyncEvents:["change","selectionchange","invalid","input","focus","blur","focusin","focusout"],usedTemplates:{},defaultTemplate:void 0,templateNotYetRegisteredQueue:{},registerTemplate:function(a,b){if(!("string"==typeof a||a instanceof String))throw TypeError(`code-input: Name of template "${a}" must be a string.`);if(!("function"==typeof b.highlight||b.highlight instanceof Function))throw TypeError(`code-input: Template for "${a}" invalid, because the highlight function provided is not a function; it is "${b.highlight}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.includeCodeInputInHighlightFunc||b.includeCodeInputInHighlightFunc instanceof Boolean))throw TypeError(`code-input: Template for "${a}" invalid, because the includeCodeInputInHighlightFunc value provided is not a true or false; it is "${b.includeCodeInputInHighlightFunc}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.preElementStyled||b.preElementStyled instanceof Boolean))throw TypeError(`code-input: Template for "${a}" invalid, because the preElementStyled value provided is not a true or false; it is "${b.preElementStyled}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.isCode||b.isCode instanceof Boolean))throw TypeError(`code-input: Template for "${a}" invalid, because the isCode value provided is not a true or false; it is "${b.isCode}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!Array.isArray(b.plugins))throw TypeError(`code-input: Template for "${a}" invalid, because the plugin array provided is not an array; it is "${b.plugins}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(b.plugins.forEach((c,d)=>{if(!(c instanceof codeInput.Plugin))throw TypeError(`code-input: Template for "${a}" invalid, because the plugin provided at index ${d} is not valid; it is "${b.plugins[d]}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`)}),codeInput.usedTemplates[a]=b,a in codeInput.templateNotYetRegisteredQueue)for(let c in codeInput.templateNotYetRegisteredQueue[a]){const d=codeInput.templateNotYetRegisteredQueue[a][c];d.templateObject=b,d.setup()}if(null==codeInput.defaultTemplate&&(codeInput.defaultTemplate=a,void 0 in codeInput.templateNotYetRegisteredQueue))for(let a in codeInput.templateNotYetRegisteredQueue[void 0]){const c=codeInput.templateNotYetRegisteredQueue[void 0][a];c.templateObject=b,c.setup()}},Template:class{constructor(a=function(){},b=!0,c=!0,d=!1,e=[]){this.highlight=a,this.preElementStyled=b,this.isCode=c,this.includeCodeInputInHighlightFunc=d,this.plugins=e}highlight=function(){};preElementStyled=!0;isCode=!0;includeCodeInputInHighlightFunc=!1;plugins=[]},templates:{prism(a,b=[]){return new codeInput.templates.Prism(a,b)},hljs(a,b=[]){return new codeInput.templates.Hljs(a,b)},characterLimit(a){return{highlight:function(a,b,c=[]){let d=+b.getAttribute("data-character-limit"),e=b.escapeHtml(b.value.slice(0,d)),f=b.escapeHtml(b.value.slice(d));a.innerHTML=`${e}<mark class="overflow">${f}</mark>`,0<f.length&&(a.innerHTML+=` <mark class="overflow-msg">${b.getAttribute("data-overflow-msg")||"(Character limit reached)"}</mark>`)},includeCodeInputInHighlightFunc:!0,preElementStyled:!0,isCode:!1,plugins:a}},rainbowText(a=["red","orangered","orange","goldenrod","gold","green","darkgreen","navy","blue","magenta"],b="",c=[]){return{highlight:function(a,b){let c=[],d=b.value.split(b.template.delimiter);for(let e=0;e<d.length;e++)c.push(`<span style="color: ${b.template.rainbowColors[e%b.template.rainbowColors.length]}">${b.escapeHtml(d[e])}</span>`);a.innerHTML=c.join(b.template.delimiter)},includeCodeInputInHighlightFunc:!0,preElementStyled:!0,isCode:!1,rainbowColors:a,delimiter:b,plugins:c}},character_limit(){return this.characterLimit([])},rainbow_text(a=["red","orangered","orange","goldenrod","gold","green","darkgreen","navy","blue","magenta"],b="",c=[]){return this.rainbowText(a,b,c)},custom(a=function(){},b=!0,c=!0,d=!1,e=[]){return{highlight:a,includeCodeInputInHighlightFunc:d,preElementStyled:b,isCode:c,plugins:e}}},plugins:new Proxy({},{get(a,b){if(a[b]==null)throw ReferenceError(`code-input: Plugin '${b}' is not defined. Please ensure you import the necessary files from the plugins folder in the WebCoder49/code-input repository, in the <head> of your HTML, before the plugin is instatiated.`);return a[b]}}),Plugin:class{constructor(a){a.forEach(a=>{codeInput.observedAttributes.push(a)})}addTranslations(a,b){for(const c in b)a[c]=b[c]}beforeHighlight(){}afterHighlight(){}beforeElementsAdded(){}afterElementsAdded(){}attributeChanged(){}},CodeInput:class extends HTMLElement{constructor(){super()}templateObject=null;textareaElement=null;preElement=null;codeElement=null;dialogContainerElement=null;static formAssociated=!0;boundEventCallbacks={};pluginEvt(a,b){for(let c in this.templateObject.plugins){let d=this.templateObject.plugins[c];a in d&&(b===void 0?d[a](this):d[a](this,...b))}}needsHighlight=!1;originalAriaDescription;scheduleHighlight(){this.needsHighlight=!0}animateFrame(){this.needsHighlight&&(this.update(),this.needsHighlight=!1),window.requestAnimationFrame(this.animateFrame.bind(this))}update(){let a=this.codeElement,b=this.value;b+="\n",a.innerHTML=this.escapeHtml(b),this.pluginEvt("beforeHighlight"),this.templateObject.includeCodeInputInHighlightFunc?this.templateObject.highlight(a,this):this.templateObject.highlight(a),this.syncSize(),this.pluginEvt("afterHighlight")}syncSize(){this.templateObject.preElementStyled?(this.style.backgroundColor=getComputedStyle(this.preElement).backgroundColor,this.textareaElement.style.height=getComputedStyle(this.preElement).height,this.textareaElement.style.width=getComputedStyle(this.preElement).width):(this.style.backgroundColor=getComputedStyle(this.codeElement).backgroundColor,this.textareaElement.style.height=getComputedStyle(this.codeElement).height,this.textareaElement.style.width=getComputedStyle(this.codeElement).width)}setKeyboardNavInstructions(a,b){this.dialogContainerElement.querySelector(".code-input_keyboard-navigation-instructions").innerText=a,b?this.textareaElement.setAttribute("aria-description",this.originalAriaDescription+". "+a):this.textareaElement.setAttribute("aria-description",a)}escapeHtml(a){return a.replace(/&/g,"&amp;").replace(/</g,"&lt;")}unescapeHtml(a){return a.replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">")}getTemplate(){let a;return a=null==this.getAttribute("template")?codeInput.defaultTemplate:this.getAttribute("template"),a in codeInput.usedTemplates?codeInput.usedTemplates[a]:(a in codeInput.templateNotYetRegisteredQueue||(codeInput.templateNotYetRegisteredQueue[a]=[]),void codeInput.templateNotYetRegisteredQueue[a].push(this))}setup(){if(null!=this.textareaElement)return;this.classList.add("code-input_registered"),this.mutationObserver=new MutationObserver(this.mutationObserverCallback.bind(this)),this.mutationObserver.observe(this,{attributes:!0,attributeOldValue:!0}),this.classList.add("code-input_registered"),this.templateObject.preElementStyled&&this.classList.add("code-input_pre-element-styled"),this.pluginEvt("beforeElementsAdded");const a=this.querySelector("textarea[data-code-input-fallback]");let b;if(a){let c=a.getAttributeNames();for(let b=0;b<c.length;b++){const d=c[b];"data-code-input-fallback"!=d&&(this.hasAttribute(d)||this.setAttribute(d,a.getAttribute(d)))}b=a.value}else b=this.unescapeHtml(this.innerHTML);b=b||this.getAttribute("value")||"";const c=this.getAttribute("language")||this.getAttribute("lang"),d=this.getAttribute("placeholder")||c||"";this.initialValue=b;const e=document.createElement("textarea");e.placeholder=d,""!=b&&(e.value=b),e.innerHTML=this.innerHTML,this.hasAttribute("spellcheck")||e.setAttribute("spellcheck","false"),e.setAttribute("tabindex",this.getAttribute("tabindex")||0),this.setAttribute("tabindex",-1),this.originalAriaDescription=this.getAttribute("aria-description")||"Code input field",this.addEventListener("mousedown",()=>{this.classList.add("code-input_mouse-focused")}),e.addEventListener("blur",()=>{this.classList.remove("code-input_mouse-focused")}),this.innerHTML="";for(let a,b=0;b<this.attributes.length;b++)a=this.attributes[b].name,(codeInput.textareaSyncAttributes.includes(a)||"aria-"==a.substring(0,5))&&e.setAttribute(a,this.getAttribute(a));e.addEventListener("input",()=>{this.value=this.textareaElement.value}),this.textareaElement=e,this.append(e);let f=document.createElement("code"),g=document.createElement("pre");g.setAttribute("aria-hidden","true"),g.setAttribute("tabindex","-1"),g.setAttribute("inert",!0),this.preElement=g,this.codeElement=f,g.append(f),this.append(g),this.templateObject.isCode&&c!=null&&""!=c&&f.classList.add("language-"+c.toLowerCase());let h=document.createElement("div");h.classList.add("code-input_dialog-container"),this.append(h),this.dialogContainerElement=h;let i=document.createElement("div");i.classList.add("code-input_keyboard-navigation-instructions"),h.append(i),this.pluginEvt("afterElementsAdded"),this.dispatchEvent(new CustomEvent("code-input_load")),this.value=b,this.animateFrame();const j=new ResizeObserver(()=>{this.syncSize()});j.observe(this),this.classList.add("code-input_loaded")}escape_html(a){return this.escapeHtml(a)}get_template(){return this.getTemplate()}get template(){return this.templateObject}set template(a){}connectedCallback(){this.templateObject=this.getTemplate(),this.templateObject!=null&&(this.classList.add("code-input_registered"),window.addEventListener("DOMContentLoaded",this.setup.bind(this)))}mutationObserverCallback(a){for(const b of a)if("attributes"===b.type){for(let a=0;a<codeInput.observedAttributes.length;a++)if(b.attributeName==codeInput.observedAttributes[a])return this.attributeChangedCallback(b.attributeName,b.oldValue,super.getAttribute(b.attributeName));for(let a=0;a<codeInput.textareaSyncAttributes.length;a++)if(b.attributeName==codeInput.textareaSyncAttributes[a])return this.attributeChangedCallback(b.attributeName,b.oldValue,super.getAttribute(b.attributeName));if("aria-"==b.attributeName.substring(0,5))return this.attributeChangedCallback(b.attributeName,b.oldValue,super.getAttribute(b.attributeName))}}disconnectedCallback(){this.mutationObserver.disconnect()}attributeChangedCallback(a,b,c){if(this.isConnected)switch(this.pluginEvt("attributeChanged",[a,b,c]),a){case"value":this.value=c;break;case"template":this.templateObject=codeInput.usedTemplates[c||codeInput.defaultTemplate],this.templateObject.preElementStyled?this.classList.add("code-input_pre-element-styled"):this.classList.remove("code-input_pre-element-styled"),this.scheduleHighlight();break;case"lang":case"language":let d=this.codeElement,e=this.textareaElement;if(null!=c&&(c=c.toLowerCase(),d.classList.contains(`language-${c}`)))break;null!==b&&(b=b.toLowerCase(),d.classList.remove("language-"+b),d.parentElement.classList.remove("language-"+b)),d.classList.remove("language-none"),d.parentElement.classList.remove("language-none"),null!=c&&""!=c&&d.classList.add("language-"+c),e.placeholder==b&&(e.placeholder=c),this.scheduleHighlight();break;default:codeInput.textareaSyncAttributes.includes(a)||"aria-"==a.substring(0,5)?null==c||null==c?this.textareaElement.removeAttribute(a):this.textareaElement.setAttribute(a,c):codeInput.textareaSyncAttributes.regexp.forEach(b=>{a.match(b)&&(null==c?this.textareaElement.removeAttribute(a):this.textareaElement.setAttribute(a,c))})}}addEventListener(a,b,c=void 0){let d=function(a){"function"==typeof b?b(a):b&&b.handleEvent&&b.handleEvent(a)}.bind(this);this.boundEventCallbacks[b]=d,codeInput.textareaSyncEvents.includes(a)?(this.boundEventCallbacks[b]=d,c===void 0?null==this.textareaElement?this.addEventListener("code-input_load",()=>{this.textareaElement.addEventListener(a,d)}):this.textareaElement.addEventListener(a,d):null==this.textareaElement?this.addEventListener("code-input_load",()=>{this.textareaElement.addEventListener(a,d,c)}):this.textareaElement.addEventListener(a,d,c)):c===void 0?super.addEventListener(a,d):super.addEventListener(a,d,c)}removeEventListener(a,b,c=void 0){let d=this.boundEventCallbacks[b];codeInput.textareaSyncEvents.includes(a)?c===void 0?null==this.textareaElement?this.addEventListener("code-input_load",()=>{this.textareaElement.removeEventListener(a,d)}):this.textareaElement.removeEventListener(a,d):null==this.textareaElement?this.addEventListener("code-input_load",()=>{this.textareaElement.removeEventListener(a,d,c)}):this.textareaElement.removeEventListener(a,d,c):c===void 0?super.removeEventListener(a,d):super.removeEventListener(a,d,c)}getTextareaProperty(a,b=void 0){if(this.textareaElement)return this.textareaElement[a];else{const c=this.querySelector("textarea[data-code-input-fallback]");if(c)return c[a];if(void 0===b)throw new Error("Cannot get "+a+" of an unregistered code-input element without a data-code-input-fallback textarea.");return b}}setTextareaProperty(a,b,c=!0){if(this.textareaElement)this.textareaElement[a]=b;else{const d=this.querySelector("textarea[data-code-input-fallback]");if(d)d[a]=b;else{if(!c)return(!1);throw new Error("Cannot set "+a+" of an unregistered code-input element without a data-code-input-fallback textarea.")}}return(!0)}get autocomplete(){return this.getAttribute("autocomplete")}set autocomplete(a){return this.setAttribute("autocomplete",a)}get cols(){return this.getTextareaProperty("cols",+this.getAttribute("cols"))}set cols(a){this.setAttribute("cols",a)}get defaultValue(){return this.initialValue}set defaultValue(a){this.initialValue=a}get textContent(){return this.initialValue}set textContent(a){this.initialValue=a}get dirName(){return this.getAttribute("dirName")||""}set dirName(a){this.setAttribute("dirname",a)}get disabled(){return this.hasAttribute("disabled")}set disabled(a){a?this.setAttribute("disabled",!0):this.removeAttribute("disabled")}get form(){return this.getTextareaProperty("form")}get labels(){return this.getTextareaProperty("labels")}get maxLength(){const a=+this.getAttribute("maxlength");return isNaN(a)?-1:a}set maxLength(a){-1==a?this.removeAttribute("maxlength"):this.setAttribute("maxlength",a)}get minLength(){const a=+this.getAttribute("minlength");return isNaN(a)?-1:a}set minLength(a){-1==a?this.removeAttribute("minlength"):this.setAttribute("minlength",a)}get name(){return this.getAttribute("name")||""}set name(a){this.setAttribute("name",a)}get placeholder(){return this.getAttribute("placeholder")||""}set placeholder(a){this.setAttribute("placeholder",a)}get readOnly(){return this.hasAttribute("readonly")}set readOnly(a){a?this.setAttribute("readonly",!0):this.removeAttribute("readonly")}get required(){return this.hasAttribute("readonly")}set required(a){a?this.setAttribute("readonly",!0):this.removeAttribute("readonly")}get rows(){return this.getTextareaProperty("rows",+this.getAttribute("rows"))}set rows(a){this.setAttribute("rows",a)}get selectionDirection(){return this.getTextareaProperty("selectionDirection")}set selectionDirection(a){this.setTextareaProperty("selectionDirection",a)}get selectionEnd(){return this.getTextareaProperty("selectionEnd")}set selectionEnd(a){this.setTextareaProperty("selectionEnd",a)}get selectionStart(){return this.getTextareaProperty("selectionStart")}set selectionStart(a){this.setTextareaProperty("selectionStart",a)}get textLength(){return this.value.length}get type(){return"textarea"}get validationMessage(){return this.getTextareaProperty("validationMessage")}get validity(){return this.getTextareaProperty("validationMessage")}get value(){return this.getTextareaProperty("value",this.getAttribute("value")||this.innerHTML)}set value(a){a=a||"",this.setTextareaProperty("value",a,!1)?this.textareaElement&&this.scheduleHighlight():this.innerHTML=a}get willValidate(){return this.getTextareaProperty("willValidate",this.disabled||this.readOnly)}get wrap(){return this.getAttribute("wrap")||""}set wrap(a){this.setAttribute("wrap",a)}blur(a={}){return this.textareaElement.blur(a)}checkValidity(){return this.textareaElement.checkValidity()}focus(a={}){return this.textareaElement.focus(a)}reportValidity(){return this.textareaElement.reportValidity()}setCustomValidity(a){this.textareaElement.setCustomValidity(a)}setRangeText(a,b=this.selectionStart,c=this.selectionEnd,d="preserve"){this.getTextareaProperty("setRangeText")(a,b,c,d)}setSelectionRange(a,b,c="none"){this.getTextareaProperty("setSelectionRange")(a,b,c)}pluginData={};formResetCallback(){this.value=this.initialValue}}};{class a extends codeInput.Template{constructor(a,b=[],c=!0){super(a.highlightElement,c,!0,!1,b)}}codeInput.templates.Prism=a;class b extends codeInput.Template{constructor(a,b=[],c=!1){super(function(b){b.removeAttribute("data-highlighted"),a.highlightElement(b)},c,!0,!1,b)}}codeInput.templates.Hljs=b}customElements.define("code-input",codeInput.CodeInput);
package/docs/_index.md CHANGED
@@ -10,7 +10,7 @@ Aiming to be [more <mark>flexible</mark>, <mark>lightweight</mark>,
10
10
  [HTML forms](interface/forms), the [`<textarea>` JavaScript interface](interface/js), more languages and
11
11
  more use cases.
12
12
 
13
- *code-input.js is free, libre, open source software under the MIT (AKA Expat) license.* **Download it [from the Git repository](https://github.com/WebCoder49/code-input/tree/v2.6.0), [in a ZIP archive](/release/code-input-js-v2.6.0.zip), [in a TAR.GZ archive](/release/code-input-js-v2.6.0.tar.gz), or from `@webcoder49/code-input` on the NPM registry ([Yarn](https://yarnpkg.com/package?name=@webcoder49/code-input), [NPM](https://npmjs.com/package/@webcoder49/code-input), etc.).**
13
+ *code-input.js is free, libre, open source software under the MIT (AKA Expat) license.* **Download it [from the Git repository](https://github.com/WebCoder49/code-input/tree/v2.6.3), [in a ZIP archive](/release/code-input-js-v2.6.3.zip), [in a TAR.GZ archive](/release/code-input-js-v2.6.3.tar.gz), or from `@webcoder49/code-input` on the NPM registry ([Yarn](https://yarnpkg.com/package?name=@webcoder49/code-input), [NPM](https://npmjs.com/package/@webcoder49/code-input), etc.).**
14
14
 
15
15
  ## Get Started with a Demo
16
16
 
@@ -80,6 +80,9 @@ console.log("Hello, World!");</textarea></code-input>
80
80
  <script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.6/plugins/indent.min.js"></script>
81
81
 
82
82
  <!--Register code-input template-->
83
+ <!--This can be before the code-input element is created, in which case it will defer the registration of all code-input
84
+ elements until the page is loaded, or after it is created, in which case registration will occur immediately, but not inside
85
+ code-input elements.-->
83
86
  <script>
84
87
  codeInput.registerTemplate("syntax-highlighted",
85
88
  new codeInput.templates.Prism(
@@ -137,6 +140,9 @@ console.log("Hello, World!");</textarea></code-input>
137
140
  <script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.6/plugins/indent.min.js"></script>
138
141
 
139
142
  <!--Register code-input template-->
143
+ <!--This can be before the code-input element is created, in which case it will defer the registration of all code-input
144
+ elements until the page is loaded, or after it is created, in which case registration will occur immediately, but not inside
145
+ code-input elements.-->
140
146
  <script>
141
147
  codeInput.registerTemplate("syntax-highlighted",
142
148
  new codeInput.templates.Hljs(
@@ -182,6 +188,9 @@ console.log("Hello, World!");</textarea></code-input>
182
188
  <script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.6/plugins/indent.min.js"></script>
183
189
 
184
190
  <!--Register code-input template-->
191
+ <!--This can be before the code-input element is created, in which case it will defer the registration of all code-input
192
+ elements until the page is loaded, or after it is created, in which case registration will occur immediately, but not inside
193
+ code-input elements.-->
185
194
  <script>
186
195
  codeInput.registerTemplate("syntax-highlighted",
187
196
  new codeInput.Template(
@@ -303,6 +312,6 @@ something like [CodeMirror](https://codemirror.net/),
303
312
 
304
313
  ## Contribute Bug Reports / Code / Docs {#contributing}
305
314
 
306
- 🎉 code-input.js is collaboratively developed by many people, which is what keeps it going strong. By version 2.6.0, many have reported bugs and suggestions, and [9 people (see them on GitHub)](https://github.com/WebCoder49/code-input/graphs/contributors) have contributed code or documentation directly. If you have found a bug, would like to help with the code or documentation, or have additional suggestions, for plugins or core functionality, [please look at GitHub](https://github.com/WebCoder49/code-input/tree/main/CONTRIBUTING.md) or [get in touch via email so I can add it for you](mailto:code-input-js@webcoder49.dev)!
315
+ 🎉 code-input.js is collaboratively developed by many people, which is what keeps it going strong. By version 2.6.0, many have reported bugs and suggestions, and [9 people (see them on GitHub)](https://github.com/WebCoder49/code-input/graphs/contributors) have contributed code or documentation directly. If you have found a bug, would like to help with the code or documentation, or have additional suggestions, for plugins or core functionality, [please look at GitHub](https://github.com/WebCoder49/code-input/tree/main/CONTRIBUTING.md) or [get in touch via email so I can add it for you](mailto:code-input-js@webcoder49.dev) / [this address for security issues](mailto:security@webcoder49.dev) ([address owner, encryption and privacy info](https://oliver.geer.im/#email))!
307
316
 
308
- *We're looking into mirroring code-input.js onto Codeberg as well as GitHub for more flexibility and freedom - if you have ideas for this please get in touch!*
317
+ *I'm looking into mirroring code-input.js onto Codeberg as well as GitHub for more flexibility and freedom - if you have ideas for this please get in touch!*
@@ -6,6 +6,6 @@ title = '`code-input` vs the `textarea` in JavaScript'
6
6
 
7
7
  > Contributors: 2025 Oliver Geer
8
8
 
9
- Once registered, `code-input` elements support most of the JavaScript properties and events used with a `textarea` element, because they are built around them. Try swapping out your `textarea` element in your JavaScript application for a `code-input`! If it doesn't work, [submit a bug report](https://github.com/WebCoder49/code-input/issues).
9
+ Once registered, `code-input` elements support the JavaScript properties and events used with a `textarea` element, because they are built around them. Try swapping out your `textarea` element in your JavaScript application for a `code-input`! If it doesn't work, [submit a bug report](https://github.com/WebCoder49/code-input/issues).
10
10
 
11
11
  If you want to replace a `textarea` with a `code-input` in an application that doesn't need JavaScript, [look here](../forms). We support HTML5 forms, and progressive enhancement so JavaScript isn't needed!