@webcoder49/code-input 2.5.1 → 2.6.0

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.
Files changed (71) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +9 -126
  3. package/code-input.css +70 -33
  4. package/code-input.d.ts +135 -59
  5. package/code-input.js +201 -110
  6. package/code-input.min.css +1 -1
  7. package/code-input.min.js +12 -1
  8. package/docs/LICENSE +3 -0
  9. package/docs/LICENSE.CC-BY-SA-4.0 +116 -0
  10. package/docs/LICENSE.CC0-1.0 +30 -0
  11. package/docs/README.md +5 -0
  12. package/docs/_index.md +308 -0
  13. package/docs/i18n/_index.md +52 -0
  14. package/docs/interface/_index.md +3 -0
  15. package/docs/interface/css/_index.md +12 -0
  16. package/docs/interface/forms/_index.md +17 -0
  17. package/docs/interface/js/_index.md +11 -0
  18. package/docs/modules-and-frameworks/_index.md +3 -0
  19. package/docs/modules-and-frameworks/custom/_index.md +9 -0
  20. package/docs/modules-and-frameworks/hljs/_index.md +13 -0
  21. package/docs/modules-and-frameworks/hljs/esm/_index.md +71 -0
  22. package/docs/modules-and-frameworks/hljs/nuxt/_index.md +250 -0
  23. package/docs/modules-and-frameworks/hljs/nuxt/nuxt-demo-screenshot.png +0 -0
  24. package/docs/modules-and-frameworks/hljs/vue/_index.md +233 -0
  25. package/docs/modules-and-frameworks/hljs/vue/vue-demo-screenshot.png +0 -0
  26. package/docs/modules-and-frameworks/prism/_index.md +14 -0
  27. package/docs/plugins/_index.md +676 -0
  28. package/docs/plugins/new/_index.md +52 -0
  29. package/docs/theory/_index.md +9 -0
  30. package/esm/.code-input.mjs.kate-swp +0 -0
  31. package/esm/README.md +23 -0
  32. package/esm/code-input.mjs +2 -0
  33. package/package.json +83 -7
  34. package/plugins/README.md +2 -0
  35. package/plugins/auto-close-brackets.js +2 -0
  36. package/plugins/auto-close-brackets.min.js +1 -1
  37. package/plugins/autocomplete.js +6 -6
  38. package/plugins/autocomplete.min.js +1 -1
  39. package/plugins/autodetect.js +4 -2
  40. package/plugins/autodetect.min.js +1 -1
  41. package/plugins/find-and-replace.css +0 -4
  42. package/plugins/find-and-replace.js +28 -8
  43. package/plugins/find-and-replace.min.css +1 -1
  44. package/plugins/find-and-replace.min.js +1 -1
  45. package/plugins/go-to-line.css +10 -5
  46. package/plugins/go-to-line.js +39 -6
  47. package/plugins/go-to-line.min.css +1 -1
  48. package/plugins/go-to-line.min.js +1 -1
  49. package/plugins/indent.js +4 -2
  50. package/plugins/indent.min.js +1 -1
  51. package/plugins/prism-line-numbers.css +14 -5
  52. package/plugins/prism-line-numbers.min.css +1 -1
  53. package/plugins/select-token-callbacks.js +3 -1
  54. package/plugins/select-token-callbacks.min.js +1 -1
  55. package/plugins/special-chars.css +13 -1
  56. package/plugins/special-chars.js +14 -4
  57. package/plugins/special-chars.min.css +1 -1
  58. package/plugins/special-chars.min.js +1 -1
  59. package/plugins/test.js +22 -7
  60. package/plugins/test.min.js +1 -1
  61. package/.github/workflows/minify.yml +0 -22
  62. package/.github/workflows/npm-publish.yml +0 -21
  63. package/CODE_OF_CONDUCT.md +0 -130
  64. package/CONTRIBUTING.md +0 -35
  65. package/tests/hljs.html +0 -55
  66. package/tests/i18n.html +0 -197
  67. package/tests/prism-match-braces-compatibility.js +0 -215
  68. package/tests/prism-match-braces-compatibility.min.js +0 -1
  69. package/tests/prism.html +0 -54
  70. package/tests/tester.js +0 -600
  71. package/tests/tester.min.js +0 -21
@@ -2,17 +2,24 @@
2
2
  * Add basic Go-To-Line (Ctrl+G by default) functionality to the code editor.
3
3
  * Files: go-to-line.js / go-to-line.css
4
4
  */
5
+ "use strict";
6
+
5
7
  codeInput.plugins.GoToLine = class extends codeInput.Plugin {
6
8
  useCtrlG = false;
7
9
 
8
10
  instructions = {
9
11
  closeDialog: "Close Dialog and Return to Editor",
10
12
  input: "Line:Column / Line no. then Enter",
13
+ guidanceFormat: "Wrong format. Enter a line number (e.g. 1) or a line number then colon then column number (e.g. 1:3).",
14
+ guidanceLineRange: (current, max) => `Line number (currently ${current}) should be between 1 and ${max} inclusive.`,
15
+ guidanceColumnRange: (line, current, max) => `On line ${line}, column number (currently ${current}) should be between 1 and ${max} inclusive.`,
16
+ guidanceValidLine: (line) => `Press Enter to go to line ${line}.`,
17
+ guidanceValidColumn: (line, column) => `Press Enter to go to line ${line}, column ${column}.`,
11
18
  };
12
19
 
13
20
  /**
14
21
  * Create a go-to-line command plugin to pass into a template
15
- * @param {boolean} useCtrlG Should Ctrl+G be overriden for go-to-line functionality? If not, you can trigger it yourself using (instance of this plugin)`.showPrompt(code-input element)`.
22
+ * @param {boolean} useCtrlG Should Ctrl+G be overriden for go-to-line functionality? Either way, you can trigger it yourself using (instance of this plugin)`.showPrompt(code-input element)`.
16
23
  * @param {Object} instructionTranslations: user interface string keys mapped to translated versions for localisation. Look at the go-to-line.js source code for the available keys and English text.
17
24
  */
18
25
  constructor(useCtrlG = true, instructionTranslations = {}) {
@@ -31,6 +38,8 @@ codeInput.plugins.GoToLine = class extends codeInput.Plugin {
31
38
 
32
39
  /* Called with a dialog box keyup event to check the validity of the line number entered and submit the dialog if Enter is pressed */
33
40
  checkPrompt(dialog, event) {
41
+ if (event.key == 'Escape') return this.cancelPrompt(dialog, event);
42
+
34
43
  // Line number(:column number)
35
44
  const lines = dialog.textarea.value.split('\n');
36
45
  const maxLineNo = lines.length;
@@ -38,25 +47,42 @@ codeInput.plugins.GoToLine = class extends codeInput.Plugin {
38
47
  let columnNo = 0; // Means go to start of indented line
39
48
  let maxColumnNo = 1;
40
49
  const querySplitByColons = dialog.input.value.split(':');
41
- if(querySplitByColons.length > 2) return dialog.input.classList.add('code-input_go-to-line_error');
42
50
 
43
- if (event.key == 'Escape') return this.cancelPrompt(dialog, event);
51
+ // Invalid format
52
+ if(querySplitByColons.length > 2 || !/^[0-9:]*$/.test(dialog.input.value)) {
53
+ dialog.guidance.textContent = this.instructions.guidanceFormat;
54
+ return dialog.input.classList.add('code-input_go-to-line_error');
55
+ }
44
56
 
57
+ // Number(s) present
45
58
  if (dialog.input.value) {
46
- if (!/^[0-9:]*$/.test(dialog.input.value) || lineNo < 1 || lineNo > maxLineNo) {
59
+ if (lineNo < 1 || lineNo > maxLineNo) {
60
+ // Out-of-range line number
61
+ dialog.guidance.textContent = this.instructions.guidanceLineRange(lineNo, maxLineNo);
47
62
  return dialog.input.classList.add('code-input_go-to-line_error');
48
63
  } else {
49
- // Check if line:column
64
+ // Check if line:column - if so calculate column number
50
65
  if(querySplitByColons.length >= 2) {
51
66
  columnNo = Number(querySplitByColons[1]);
52
- maxColumnNo = lines[lineNo-1].length;
67
+ maxColumnNo = lines[lineNo-1].length+1; // column 1 always works since at start of line
53
68
  }
54
69
  if(columnNo < 0 || columnNo > maxColumnNo) {
70
+ dialog.guidance.textContent = this.instructions.guidanceColumnRange(lineNo, columnNo, maxColumnNo);
55
71
  return dialog.input.classList.add('code-input_go-to-line_error');
56
72
  } else {
73
+ if(columnNo === 0) {
74
+ // No column specified, or 0 which for backwards compatibility acts
75
+ // like none selected
76
+ dialog.guidance.textContent = this.instructions.guidanceValidLine(lineNo);
77
+ } else {
78
+ dialog.guidance.textContent = this.instructions.guidanceValidColumn(lineNo, columnNo);
79
+ }
57
80
  dialog.input.classList.remove('code-input_go-to-line_error');
58
81
  }
59
82
  }
83
+ } else {
84
+ // No value
85
+ dialog.guidance.textContent = "";
60
86
  }
61
87
 
62
88
  if (event.key == 'Enter') {
@@ -89,6 +115,7 @@ codeInput.plugins.GoToLine = class extends codeInput.Plugin {
89
115
  const textarea = codeInput.textareaElement;
90
116
 
91
117
  const dialog = document.createElement('div');
118
+
92
119
  const input = document.createElement('input');
93
120
 
94
121
  // TODO: Make a button element (semantic HTML for accessibility) in next major version
@@ -98,8 +125,13 @@ codeInput.plugins.GoToLine = class extends codeInput.Plugin {
98
125
  cancel.setAttribute("tabindex", 0); // Visible to keyboard navigation
99
126
  cancel.setAttribute("title", this.instructions.closeDialog);
100
127
 
128
+ const guidance = document.createElement('p');
129
+ guidance.setAttribute("aria-live", "assertive"); // Screen reader must read the status message.
130
+ guidance.textContent = "";
131
+
101
132
  dialog.appendChild(input);
102
133
  dialog.appendChild(cancel);
134
+ dialog.appendChild(guidance);
103
135
 
104
136
  dialog.className = 'code-input_go-to-line_dialog';
105
137
  input.spellcheck = false;
@@ -107,6 +139,7 @@ codeInput.plugins.GoToLine = class extends codeInput.Plugin {
107
139
  dialog.codeInput = codeInput;
108
140
  dialog.textarea = textarea;
109
141
  dialog.input = input;
142
+ dialog.guidance = guidance;
110
143
 
111
144
  input.addEventListener('keypress', (event) => {
112
145
  /* Stop enter from submitting form */
@@ -1 +1 @@
1
- @keyframes code-input_go-to-line_roll-in{0%{opacity:0;transform:translateY(-34px)}100%{opacity:1;transform:translateY(0)}}@keyframes code-input_go-to-line_roll-out{0%{opacity:1;transform:translateY(0)}100%{opacity:0;transform:translateY(-34px)}}.code-input_go-to-line_dialog{position:absolute;top:0;right:14px;height:28px;padding:6px;padding-top:8px;border:solid 1px #00000044;background-color:#fff;border-radius:6px;box-shadow:0 .2em 1em .2em rgba(0,0,0,.16)}.code-input_go-to-line_dialog:not(.code-input_go-to-line_hidden-dialog){animation:code-input_go-to-line_roll-in .2s;opacity:1;pointer-events:all}.code-input_go-to-line_dialog.code-input_go-to-line_hidden-dialog{animation:code-input_go-to-line_roll-out .2s;opacity:0;pointer-events:none}.code-input_go-to-line_dialog input::placeholder{font-size:80%}.code-input_go-to-line_dialog input{position:relative;width:240px;height:32px;top:-3px;font-size:large;color:#000000aa;border:0}.code-input_go-to-line_dialog input.code-input_go-to-line_error{color:#ff0000aa}.code-input_go-to-line_dialog input:focus{outline:0}.code-input_go-to-line_dialog span{display:inline-block;width:24px;line-height:24px;font-family:system-ui;font-size:22px;font-weight:500;text-align:center;border-radius:50%;color:#000;opacity:.6;vertical-align:top}.code-input_go-to-line_dialog span:before{content:"\00d7"}.code-input_go-to-line_dialog span:hover{opacity:.8;background-color:#00000018}
1
+ @keyframes code-input_go-to-line_roll-in{0%{opacity:0;transform:translateY(-34px)}100%{opacity:1;transform:translateY(0)}}@keyframes code-input_go-to-line_roll-out{0%{opacity:1;transform:translateY(0)}100%{opacity:0;transform:translateY(-34px)}}.code-input_go-to-line_dialog{position:absolute;top:0;right:14px;padding:6px;padding-top:8px;border:solid 1px #00000044;background-color:#fff;border-radius:6px;box-shadow:0 .2em 1em .2em rgba(0,0,0,.16)}.code-input_go-to-line_dialog:not(.code-input_go-to-line_hidden-dialog){animation:code-input_go-to-line_roll-in .2s;opacity:1;pointer-events:all}.code-input_go-to-line_dialog.code-input_go-to-line_hidden-dialog{animation:code-input_go-to-line_roll-out .2s;opacity:0;pointer-events:none}.code-input_go-to-line_dialog input::placeholder{font-size:80%}.code-input_go-to-line_dialog input{position:relative;width:240px;height:32px;top:-3px;font-size:large;color:#000000aa;border:0}.code-input_go-to-line_dialog input.code-input_go-to-line_error{color:#ff0000aa}.code-input_go-to-line_dialog span{display:inline-block;width:24px;line-height:24px;font-family:system-ui;font-size:22px;font-weight:500;text-align:center;border-radius:50%;color:#000;opacity:.6;vertical-align:top}.code-input_go-to-line_dialog span:before{content:"\00d7"}.code-input_go-to-line_dialog span:hover{opacity:.8;background-color:#00000018}.code-input_go-to-line_dialog p{font-family:monospace;width:264px;margin:0;overflow:hidden;white-space:wrap}
@@ -1 +1 @@
1
- codeInput.plugins.GoToLine=class extends codeInput.Plugin{useCtrlG=!1;instructions={closeDialog:"Close Dialog and Return to Editor",input:"Line:Column / Line no. then Enter"};constructor(a=!0,b={}){super([]),this.useCtrlG=a,this.addTranslations(this.instructions,b)}afterElementsAdded(a){const b=a.textareaElement;this.useCtrlG&&b.addEventListener("keydown",b=>{this.checkCtrlG(a,b)})}checkPrompt(a,b){const c=a.textarea.value.split("\n"),d=c.length,e=+a.input.value.split(":")[0];let f=0,g=1;const h=a.input.value.split(":");if(2<h.length)return a.input.classList.add("code-input_go-to-line_error");if("Escape"==b.key)return this.cancelPrompt(a,b);if(a.input.value){if(!/^[0-9:]*$/.test(a.input.value)||1>e||e>d)return a.input.classList.add("code-input_go-to-line_error");if(2<=h.length&&(f=+h[1],g=c[e-1].length),0>f||f>g)return a.input.classList.add("code-input_go-to-line_error");a.input.classList.remove("code-input_go-to-line_error")}"Enter"==b.key&&(this.goTo(a.textarea,e,f),this.cancelPrompt(a,b))}cancelPrompt(a,b){b.preventDefault(),a.codeInput.handleEventsFromTextarea=!1,a.textarea.focus(),a.codeInput.handleEventsFromTextarea=!0,a.setAttribute("inert",!0),a.setAttribute("tabindex",-1),a.setAttribute("aria-hidden",!0),a.classList.add("code-input_go-to-line_hidden-dialog"),a.input.value=""}showPrompt(a){if(a.pluginData.goToLine==null||a.pluginData.goToLine.dialog==null){const b=a.textareaElement,c=document.createElement("div"),d=document.createElement("input"),e=document.createElement("span");e.setAttribute("role","button"),e.setAttribute("aria-label",this.instructions.closeDialog),e.setAttribute("tabindex",0),e.setAttribute("title",this.instructions.closeDialog),c.appendChild(d),c.appendChild(e),c.className="code-input_go-to-line_dialog",d.spellcheck=!1,d.placeholder=this.instructions.input,c.codeInput=a,c.textarea=b,c.input=d,d.addEventListener("keypress",a=>{"Enter"==a.key&&a.preventDefault()}),d.addEventListener("keyup",a=>this.checkPrompt(c,a)),e.addEventListener("click",a=>{this.cancelPrompt(c,a)}),e.addEventListener("keypress",a=>{("Space"==a.key||"Enter"==a.key)&&this.cancelPrompt(c,a)}),a.dialogContainerElement.appendChild(c),a.pluginData.goToLine={dialog:c},d.focus()}else a.pluginData.goToLine.dialog.classList.remove("code-input_go-to-line_hidden-dialog"),a.pluginData.goToLine.dialog.removeAttribute("inert"),a.pluginData.goToLine.dialog.setAttribute("tabindex",0),a.pluginData.goToLine.dialog.removeAttribute("aria-hidden"),a.pluginData.goToLine.dialog.input.focus()}goTo(a,b,c=0){let d,e,f,g,h=-1,i=a.value.split("\n");if(0<b&&b<=i.length){if(a.computedStyleMap?(d=a.computedStyleMap().get("font-size").value,e=d*a.computedStyleMap().get("line-height").value):(d=document.defaultView.getComputedStyle(a,null).getPropertyValue("font-size").split("px")[0],e=document.defaultView.getComputedStyle(a,null).getPropertyValue("line-height").split("px")[0]),f=(3<b?b-3:1)*e,g=(e-d)/2,1<b&&(h=i.slice(0,b-1).join("\n").length),0==c)do h++;while("\n"!=a.value[h]&&/\s/.test(a.value[h]));else h+=1+c-1;a.scrollTop=f-g,a.setSelectionRange(h,h),a.click()}}checkCtrlG(a,b){b.ctrlKey&&"g"==b.key&&(b.preventDefault(),this.showPrompt(a))}};
1
+ "use strict";codeInput.plugins.GoToLine=class extends codeInput.Plugin{useCtrlG=!1;instructions={closeDialog:"Close Dialog and Return to Editor",input:"Line:Column / Line no. then Enter",guidanceFormat:"Wrong format. Enter a line number (e.g. 1) or a line number then colon then column number (e.g. 1:3).",guidanceLineRange:(a,b)=>`Line number (currently ${a}) should be between 1 and ${b} inclusive.`,guidanceColumnRange:(a,b,c)=>`On line ${a}, column number (currently ${b}) should be between 1 and ${c} inclusive.`,guidanceValidLine:a=>`Press Enter to go to line ${a}.`,guidanceValidColumn:(a,b)=>`Press Enter to go to line ${a}, column ${b}.`};constructor(a=!0,b={}){super([]),this.useCtrlG=a,this.addTranslations(this.instructions,b)}afterElementsAdded(a){const b=a.textareaElement;this.useCtrlG&&b.addEventListener("keydown",b=>{this.checkCtrlG(a,b)})}checkPrompt(a,b){if("Escape"==b.key)return this.cancelPrompt(a,b);const c=a.textarea.value.split("\n"),d=c.length,e=+a.input.value.split(":")[0];let f=0,g=1;const h=a.input.value.split(":");if(2<h.length||!/^[0-9:]*$/.test(a.input.value))return a.guidance.textContent=this.instructions.guidanceFormat,a.input.classList.add("code-input_go-to-line_error");if(a.input.value){if(1>e||e>d)return a.guidance.textContent=this.instructions.guidanceLineRange(e,d),a.input.classList.add("code-input_go-to-line_error");if(2<=h.length&&(f=+h[1],g=c[e-1].length+1),0>f||f>g)return a.guidance.textContent=this.instructions.guidanceColumnRange(e,f,g),a.input.classList.add("code-input_go-to-line_error");a.guidance.textContent=0===f?this.instructions.guidanceValidLine(e):this.instructions.guidanceValidColumn(e,f),a.input.classList.remove("code-input_go-to-line_error")}else a.guidance.textContent="";"Enter"==b.key&&(this.goTo(a.textarea,e,f),this.cancelPrompt(a,b))}cancelPrompt(a,b){b.preventDefault(),a.codeInput.handleEventsFromTextarea=!1,a.textarea.focus(),a.codeInput.handleEventsFromTextarea=!0,a.setAttribute("inert",!0),a.setAttribute("tabindex",-1),a.setAttribute("aria-hidden",!0),a.classList.add("code-input_go-to-line_hidden-dialog"),a.input.value=""}showPrompt(a){if(a.pluginData.goToLine==null||a.pluginData.goToLine.dialog==null){const b=a.textareaElement,c=document.createElement("div"),d=document.createElement("input"),e=document.createElement("span");e.setAttribute("role","button"),e.setAttribute("aria-label",this.instructions.closeDialog),e.setAttribute("tabindex",0),e.setAttribute("title",this.instructions.closeDialog);const f=document.createElement("p");f.setAttribute("aria-live","assertive"),f.textContent="",c.appendChild(d),c.appendChild(e),c.appendChild(f),c.className="code-input_go-to-line_dialog",d.spellcheck=!1,d.placeholder=this.instructions.input,c.codeInput=a,c.textarea=b,c.input=d,c.guidance=f,d.addEventListener("keypress",a=>{"Enter"==a.key&&a.preventDefault()}),d.addEventListener("keyup",a=>this.checkPrompt(c,a)),e.addEventListener("click",a=>{this.cancelPrompt(c,a)}),e.addEventListener("keypress",a=>{("Space"==a.key||"Enter"==a.key)&&this.cancelPrompt(c,a)}),a.dialogContainerElement.appendChild(c),a.pluginData.goToLine={dialog:c},d.focus()}else a.pluginData.goToLine.dialog.classList.remove("code-input_go-to-line_hidden-dialog"),a.pluginData.goToLine.dialog.removeAttribute("inert"),a.pluginData.goToLine.dialog.setAttribute("tabindex",0),a.pluginData.goToLine.dialog.removeAttribute("aria-hidden"),a.pluginData.goToLine.dialog.input.focus()}goTo(a,b,c=0){let d,e,f,g,h=-1,i=a.value.split("\n");if(0<b&&b<=i.length){if(a.computedStyleMap?(d=a.computedStyleMap().get("font-size").value,e=d*a.computedStyleMap().get("line-height").value):(d=document.defaultView.getComputedStyle(a,null).getPropertyValue("font-size").split("px")[0],e=document.defaultView.getComputedStyle(a,null).getPropertyValue("line-height").split("px")[0]),f=(3<b?b-3:1)*e,g=(e-d)/2,1<b&&(h=i.slice(0,b-1).join("\n").length),0==c)do h++;while("\n"!=a.value[h]&&/\s/.test(a.value[h]));else h+=1+c-1;a.scrollTop=f-g,a.setSelectionRange(h,h),a.click()}}checkCtrlG(a,b){b.ctrlKey&&"g"==b.key&&(b.preventDefault(),this.showPrompt(a))}};
package/plugins/indent.js CHANGED
@@ -3,6 +3,8 @@
3
3
  * possible to indent/unindent multiple lines using Tab/Shift+Tab
4
4
  * Files: indent.js
5
5
  */
6
+ "use strict";
7
+
6
8
  codeInput.plugins.Indent = class extends codeInput.Plugin {
7
9
 
8
10
  bracketPairs = {}; // No bracket-auto-indentation used when {}
@@ -65,7 +67,7 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
65
67
  let testIndentationWidthPre = document.createElement("pre");
66
68
  testIndentationWidthPre.setAttribute("aria-hidden", "true"); // Hide for screen readers
67
69
  let testIndentationWidthSpan = document.createElement("span");
68
- if(codeInput.template.preElementStyled) {
70
+ if(codeInput.templateObject.preElementStyled) {
69
71
  testIndentationWidthPre.appendChild(testIndentationWidthSpan);
70
72
  testIndentationWidthPre.classList.add("code-input_autocomplete_test-indentation-width");
71
73
  codeInput.appendChild(testIndentationWidthPre); // Styled like first pre, but first pre found to update
@@ -218,7 +220,7 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
218
220
  // find the index of the line our cursor is currently on
219
221
  for (let i = 0; i < lines.length; i++) {
220
222
  letterI += lines[i].length + 1;
221
- if(inputElement.selectionEnd <= letterI) {
223
+ if(inputElement.selectionEnd < letterI) {
222
224
  currentLineI = i;
223
225
  break;
224
226
  }
@@ -1 +1 @@
1
- codeInput.plugins.Indent=class extends codeInput.Plugin{bracketPairs={};indentation="\t";indentationNumChars=1;tabIndentationEnabled=!0;escTabToChangeFocus=!0;escJustPressed=!1;instructions={tabForIndentation:"Tab and Shift-Tab currently for indentation. Press Esc to enable keyboard navigation.",tabForNavigation:"Tab and Shift-Tab currently for keyboard navigation. Type to return to indentation."};constructor(a=!1,b=4,c={"(":")","[":"]","{":"}"},d=!0,e={}){if(super([]),this.bracketPairs=c,a){this.indentation="";for(let a=0;a<b;a++)this.indentation+=" ";this.indentationNumChars=b}this.escTabToChangeFocus=!0,this.addTranslations(this.instructions,e)}disableTabIndentation(){this.tabIndentationEnabled=!1}enableTabIndentation(){this.tabIndentationEnabled=!0}afterElementsAdded(a){let b=a.textareaElement;b.addEventListener("focus",()=>{this.escTabToChangeFocus&&a.setKeyboardNavInstructions(this.instructions.tabForIndentation,!0)}),b.addEventListener("keydown",b=>{this.checkTab(a,b),this.checkEnter(a,b),this.checkBackspace(a,b)}),b.addEventListener("beforeinput",b=>{this.checkCloseBracket(a,b)});let c=document.createElement("pre");c.setAttribute("aria-hidden","true");let d=document.createElement("span");if(a.template.preElementStyled)c.appendChild(d),c.classList.add("code-input_autocomplete_test-indentation-width"),a.appendChild(c);else{let b=document.createElement("code");b.appendChild(d),b.classList.add("code-input_autocomplete_test-indentation-width"),c.appendChild(b),a.appendChild(c)}d.innerHTML=a.escapeHtml(this.indentation);let e=d.offsetWidth;a.removeChild(c),a.pluginData.indent={automatedKeypresses:!1,indentationWidthPx:e}}checkTab(a,b){var c=Math.max;if(!a.pluginData.indent.automatedKeypresses&&this.tabIndentationEnabled){if(this.escTabToChangeFocus){if("Escape"==b.key)return this.escJustPressed=!0,void a.setKeyboardNavInstructions(this.instructions.tabForNavigation,!1);if("Tab"!=b.key)return"Shift"==b.key?void 0:(a.setKeyboardNavInstructions(this.instructions.tabForIndentation,!1),void(this.escJustPressed=!1));if(!this.enableTabIndentation||this.escJustPressed)return a.setKeyboardNavInstructions("",!1),void(this.escJustPressed=!1)}else if("Tab"!=b.key)return;let d=a.textareaElement;if(b.preventDefault(),!b.shiftKey&&d.selectionStart==d.selectionEnd)a.pluginData.indent.automatedKeypresses=!0,document.execCommand("insertText",!1,this.indentation),a.pluginData.indent.automatedKeypresses=!1;else{let e=d.value.split("\n"),f=0,g=d.selectionStart,h=d.selectionEnd;for(let j=0;j<e.length;j++)(g<=f+e[j].length&&h>=f+1||g==h&&g<=f+e[j].length+1&&h>=f)&&(b.shiftKey?e[j].substring(0,this.indentationNumChars)==this.indentation&&(d.selectionStart=f,d.selectionEnd=f+this.indentationNumChars,document.execCommand("delete",!1,""),g>f&&(g=c(g-this.indentationNumChars,f)),h-=this.indentationNumChars,f-=this.indentationNumChars):(d.selectionStart=f,d.selectionEnd=f,a.pluginData.indent.f=!0,document.execCommand("insertText",!1,this.indentation),a.pluginData.indent.automatedKeypresses=!1,g>f&&(g+=this.indentationNumChars),h+=this.indentationNumChars,f+=this.indentationNumChars)),f+=e[j].length+1;d.selectionStart=g,d.selectionEnd=h;const i=getComputedStyle(a).direction;"rtl"==i?b.shiftKey?a.scrollBy(a.pluginData.indent.indentationWidthPx,0):a.scrollBy(-a.pluginData.indent.indentationWidthPx,0):b.shiftKey?a.scrollBy(-a.pluginData.indent.indentationWidthPx,0):a.scrollBy(a.pluginData.indent.indentationWidthPx,0)}a.value=d.value}}checkEnter(a,b){if(a.pluginData.indent.automatedKeypresses)return;if("Enter"!=b.key)return;b.preventDefault();let c=a.textareaElement,d=c.value.split("\n"),e=0,f=d.length-1,g="",h=0;for(let g=0;g<d.length;g++)if(e+=d[g].length+1,c.selectionEnd<=e){f=g;break}let j=d[f].length-(e-c.selectionEnd)+1;for(let c=0;c<j&&d[f].substring(c,c+this.indentationNumChars)==this.indentation;c+=this.indentationNumChars)h++;let k="";j!=d[f].length&&(k=d[f].substring(j),d[f]=d[f].substring(0,j));let l=!1,m="";if(null!=this.bracketPairs)for(let a in this.bracketPairs)if(d[f][d[f].length-1]==a){let b=this.bracketPairs[a];if(0<k.length&&k[0]==b){l=!0;for(let a=0;a<h+1;a++)m+=this.indentation}else h++;break}else{let b=this.bracketPairs[a];if(0<k.length&&k[0]==b){h--;break}}0>h&&(h=0);for(let c=0;c<h;c++)g+=this.indentation;let n=c.selectionStart;a.pluginData.indent.automatedKeypresses=!0,l&&(document.execCommand("insertText",!1,"\n"+m),h+=1),document.execCommand("insertText",!1,"\n"+g),a.pluginData.indent.automatedKeypresses=!1,c.selectionStart=n+h*this.indentationNumChars+1,c.selectionEnd=c.selectionStart;let o=+getComputedStyle(c).paddingTop.replace("px",""),p=+getComputedStyle(c).lineHeight.replace("px",""),q=+getComputedStyle(a).height.replace("px","");f*p+2*p+o>=c.scrollTop+q&&a.scrollBy(0,+getComputedStyle(c).lineHeight.replace("px","")),a.value=c.value}checkBackspace(a,b){if(!a.pluginData.indent.automatedKeypresses&&"Backspace"==b.key&&1!=this.indentationNumChars){let c=a.textareaElement;c.selectionStart==c.selectionEnd&&a.value.substring(c.selectionStart-this.indentationNumChars,c.selectionStart)==this.indentation&&(c.selectionStart-=this.indentationNumChars,b.preventDefault(),document.execCommand("delete",!1,""))}}checkCloseBracket(a,b){if(a.textareaElement.selectionStart==a.textareaElement.selectionEnd)for(let c in this.bracketPairs){let d=this.bracketPairs[c];b.data==d&&a.value.substring(a.textareaElement.selectionStart-this.indentationNumChars,a.textareaElement.selectionStart)==this.indentation&&(a.textareaElement.selectionStart-=this.indentationNumChars)}}};
1
+ "use strict";codeInput.plugins.Indent=class extends codeInput.Plugin{bracketPairs={};indentation="\t";indentationNumChars=1;tabIndentationEnabled=!0;escTabToChangeFocus=!0;escJustPressed=!1;instructions={tabForIndentation:"Tab and Shift-Tab currently for indentation. Press Esc to enable keyboard navigation.",tabForNavigation:"Tab and Shift-Tab currently for keyboard navigation. Type to return to indentation."};constructor(a=!1,b=4,c={"(":")","[":"]","{":"}"},d=!0,e={}){if(super([]),this.bracketPairs=c,a){this.indentation="";for(let a=0;a<b;a++)this.indentation+=" ";this.indentationNumChars=b}this.escTabToChangeFocus=!0,this.addTranslations(this.instructions,e)}disableTabIndentation(){this.tabIndentationEnabled=!1}enableTabIndentation(){this.tabIndentationEnabled=!0}afterElementsAdded(a){let b=a.textareaElement;b.addEventListener("focus",()=>{this.escTabToChangeFocus&&a.setKeyboardNavInstructions(this.instructions.tabForIndentation,!0)}),b.addEventListener("keydown",b=>{this.checkTab(a,b),this.checkEnter(a,b),this.checkBackspace(a,b)}),b.addEventListener("beforeinput",b=>{this.checkCloseBracket(a,b)});let c=document.createElement("pre");c.setAttribute("aria-hidden","true");let d=document.createElement("span");if(a.templateObject.preElementStyled)c.appendChild(d),c.classList.add("code-input_autocomplete_test-indentation-width"),a.appendChild(c);else{let b=document.createElement("code");b.appendChild(d),b.classList.add("code-input_autocomplete_test-indentation-width"),c.appendChild(b),a.appendChild(c)}d.innerHTML=a.escapeHtml(this.indentation);let e=d.offsetWidth;a.removeChild(c),a.pluginData.indent={automatedKeypresses:!1,indentationWidthPx:e}}checkTab(a,b){var c=Math.max;if(!a.pluginData.indent.automatedKeypresses&&this.tabIndentationEnabled){if(this.escTabToChangeFocus){if("Escape"==b.key)return this.escJustPressed=!0,void a.setKeyboardNavInstructions(this.instructions.tabForNavigation,!1);if("Tab"!=b.key)return"Shift"==b.key?void 0:(a.setKeyboardNavInstructions(this.instructions.tabForIndentation,!1),void(this.escJustPressed=!1));if(!this.enableTabIndentation||this.escJustPressed)return a.setKeyboardNavInstructions("",!1),void(this.escJustPressed=!1)}else if("Tab"!=b.key)return;let d=a.textareaElement;if(b.preventDefault(),!b.shiftKey&&d.selectionStart==d.selectionEnd)a.pluginData.indent.automatedKeypresses=!0,document.execCommand("insertText",!1,this.indentation),a.pluginData.indent.automatedKeypresses=!1;else{let e=d.value.split("\n"),f=0,g=d.selectionStart,h=d.selectionEnd;for(let j=0;j<e.length;j++)(g<=f+e[j].length&&h>=f+1||g==h&&g<=f+e[j].length+1&&h>=f)&&(b.shiftKey?e[j].substring(0,this.indentationNumChars)==this.indentation&&(d.selectionStart=f,d.selectionEnd=f+this.indentationNumChars,document.execCommand("delete",!1,""),g>f&&(g=c(g-this.indentationNumChars,f)),h-=this.indentationNumChars,f-=this.indentationNumChars):(d.selectionStart=f,d.selectionEnd=f,a.pluginData.indent.f=!0,document.execCommand("insertText",!1,this.indentation),a.pluginData.indent.automatedKeypresses=!1,g>f&&(g+=this.indentationNumChars),h+=this.indentationNumChars,f+=this.indentationNumChars)),f+=e[j].length+1;d.selectionStart=g,d.selectionEnd=h;const i=getComputedStyle(a).direction;"rtl"==i?b.shiftKey?a.scrollBy(a.pluginData.indent.indentationWidthPx,0):a.scrollBy(-a.pluginData.indent.indentationWidthPx,0):b.shiftKey?a.scrollBy(-a.pluginData.indent.indentationWidthPx,0):a.scrollBy(a.pluginData.indent.indentationWidthPx,0)}a.value=d.value}}checkEnter(a,b){if(a.pluginData.indent.automatedKeypresses)return;if("Enter"!=b.key)return;b.preventDefault();let c=a.textareaElement,d=c.value.split("\n"),e=0,f=d.length-1,g="",h=0;for(let g=0;g<d.length;g++)if(e+=d[g].length+1,c.selectionEnd<e){f=g;break}let j=d[f].length-(e-c.selectionEnd)+1;for(let c=0;c<j&&d[f].substring(c,c+this.indentationNumChars)==this.indentation;c+=this.indentationNumChars)h++;let k="";j!=d[f].length&&(k=d[f].substring(j),d[f]=d[f].substring(0,j));let l=!1,m="";if(null!=this.bracketPairs)for(let a in this.bracketPairs)if(d[f][d[f].length-1]==a){let b=this.bracketPairs[a];if(0<k.length&&k[0]==b){l=!0;for(let a=0;a<h+1;a++)m+=this.indentation}else h++;break}else{let b=this.bracketPairs[a];if(0<k.length&&k[0]==b){h--;break}}0>h&&(h=0);for(let c=0;c<h;c++)g+=this.indentation;let n=c.selectionStart;a.pluginData.indent.automatedKeypresses=!0,l&&(document.execCommand("insertText",!1,"\n"+m),h+=1),document.execCommand("insertText",!1,"\n"+g),a.pluginData.indent.automatedKeypresses=!1,c.selectionStart=n+h*this.indentationNumChars+1,c.selectionEnd=c.selectionStart;let o=+getComputedStyle(c).paddingTop.replace("px",""),p=+getComputedStyle(c).lineHeight.replace("px",""),q=+getComputedStyle(a).height.replace("px","");f*p+2*p+o>=c.scrollTop+q&&a.scrollBy(0,+getComputedStyle(c).lineHeight.replace("px","")),a.value=c.value}checkBackspace(a,b){if(!a.pluginData.indent.automatedKeypresses&&"Backspace"==b.key&&1!=this.indentationNumChars){let c=a.textareaElement;c.selectionStart==c.selectionEnd&&a.value.substring(c.selectionStart-this.indentationNumChars,c.selectionStart)==this.indentation&&(c.selectionStart-=this.indentationNumChars,b.preventDefault(),document.execCommand("delete",!1,""))}}checkCloseBracket(a,b){if(a.textareaElement.selectionStart==a.textareaElement.selectionEnd)for(let c in this.bracketPairs){let d=this.bracketPairs[c];b.data==d&&a.value.substring(a.textareaElement.selectionStart-this.indentationNumChars,a.textareaElement.selectionStart)==this.indentation&&(a.textareaElement.selectionStart-=this.indentationNumChars)}}};
@@ -5,8 +5,8 @@
5
5
  * Files: prism-line-numbers.css
6
6
  */
7
7
  /* Update padding to match line-numbers plugin */
8
- code-input.line-numbers textarea, code-input.line-numbers.code-input_pre-element-styled pre,
9
- .line-numbers code-input textarea, .line-numbers code-input.code-input_pre-element-styled pre {
8
+ code-input.line-numbers textarea, code-input.line-numbers.code-input_pre-element-styled pre, code-input.line-numbers:not(.code-input_pre-element-styled) pre code,
9
+ .line-numbers code-input textarea, .line-numbers code-input.code-input_pre-element-styled pre, .line-numbers code-input:not(.code-input_pre-element-styled) pre code {
10
10
  padding-left: max(3.8em, var(--padding, 16px))!important;
11
11
  }
12
12
 
@@ -15,7 +15,16 @@ code-input.line-numbers, .line-numbers code-input {
15
15
  grid-template-columns: calc(100% - max(0em, calc(3.8em - var(--padding, 16px))));
16
16
  }
17
17
 
18
- /* Make keyboard navigation still fill width */
19
- code-input .code-input_dialog-container .code-input_keyboard-navigation-instructions {
20
- width: calc(100% + max(3.8em, var(--padding, 16px)))!important;
18
+ /* Override Prism styles so there's no display:inline, relatively-positioned code element which breaks offsetTop, used in FindAndReplace, in Firefox. */
19
+ code-input pre[class*=language-].line-numbers>code {
20
+ position: static;
21
+ }
22
+ /* Line numbers now positioned relative to the pre element not the code element. */
23
+ code-input .line-numbers .line-numbers-rows {
24
+ left: 0;
25
+ top: var(--padding);
26
+ }
27
+ /* Things with padding when instructions are present */
28
+ code-input:not(:has(.code-input_keyboard-navigation-instructions:empty)):has(textarea:not([data-code-input-fallback]):focus):not(.code-input_mouse-focused) .line-numbers .line-numbers-rows {
29
+ top: calc(var(--padding) + 3em);
21
30
  }
@@ -1 +1 @@
1
- .line-numbers code-input textarea,.line-numbers code-input.code-input_pre-element-styled pre,code-input.line-numbers textarea,code-input.line-numbers.code-input_pre-element-styled pre{padding-left:max(3.8em,var(--padding,16px))!important}.line-numbers code-input,code-input.line-numbers{grid-template-columns:calc(100% - max(0em,calc(3.8em - var(--padding,16px))))}code-input .code-input_dialog-container .code-input_keyboard-navigation-instructions{width:calc(100% + max(3.8em,var(--padding,16px)))!important}
1
+ .line-numbers code-input textarea,.line-numbers code-input.code-input_pre-element-styled pre,.line-numbers code-input:not(.code-input_pre-element-styled) pre code,code-input.line-numbers textarea,code-input.line-numbers.code-input_pre-element-styled pre,code-input.line-numbers:not(.code-input_pre-element-styled) pre code{padding-left:max(3.8em,var(--padding,16px))!important}.line-numbers code-input,code-input.line-numbers{grid-template-columns:calc(100% - max(0em,calc(3.8em - var(--padding,16px))))}code-input pre[class*=language-].line-numbers>code{position:static}code-input .line-numbers .line-numbers-rows{left:0;top:var(--padding)}code-input:not(:has(.code-input_keyboard-navigation-instructions:empty)):has(textarea:not([data-code-input-fallback]):focus):not(.code-input_mouse-focused) .line-numbers .line-numbers-rows{top:calc(var(--padding) + 3em)}
@@ -3,6 +3,8 @@
3
3
  * gain a CSS class while selected, or trigger JavaScript callbacks.
4
4
  * Files: select-token-callbacks.js
5
5
  */
6
+ "use strict";
7
+
6
8
  codeInput.plugins.SelectTokenCallbacks = class extends codeInput.Plugin {
7
9
  /**
8
10
  * Set up the behaviour of tokens text-selected in the `<code-input>` element, and the exact definition of a token being text-selected.
@@ -286,4 +288,4 @@ codeInput.plugins.SelectTokenCallbacks.SelectedTokenState = class {
286
288
  endIndex -= childText.length;
287
289
  }
288
290
  }
289
- }
291
+ }
@@ -1 +1 @@
1
- codeInput.plugins.SelectTokenCallbacks=class extends codeInput.Plugin{constructor(a=codeInput.plugins.SelectTokenCallbacks.TokenSelectorCallbacks.createClassSynchronisation(),b=!1,c=!0,d=!0,e=!1,f=!0,g=!0){super([]),this.tokenSelectorCallbacks=a,this.onlyCaretNotSelection=b,this.caretAtStartIsSelected=c,this.caretAtEndIsSelected=d,this.createSubTokens=e,this.partiallySelectedTokensAreSelected=f,this.parentTokensAreSelected=g}afterHighlight(a){this.syncSelection(a)}afterElementsAdded(a){a.pluginData.selectTokenCallbacks={},a.pluginData.selectTokenCallbacks.lastSelectionStart=a.textareaElement.selectionStart,a.pluginData.selectTokenCallbacks.lastSelectionEnd=a.textareaElement.selectionEnd,a.pluginData.selectTokenCallbacks.selectedTokenState=new codeInput.plugins.SelectTokenCallbacks.SelectedTokenState(a.codeElement,this.tokenSelectorCallbacks,this.onlyCaretNotSelection,this.caretAtStartIsSelected,this.caretAtEndIsSelected,this.createSubTokens,this.partiallySelectedTokensAreSelected,this.parentTokensAreSelected),this.syncSelection(a),a.textareaElement.addEventListener("selectionchange",()=>{this.checkSelectionChanged(a)}),a.textareaElement.addEventListener("select",()=>{this.checkSelectionChanged(a)}),a.textareaElement.addEventListener("keypress",()=>{this.checkSelectionChanged(a)}),a.textareaElement.addEventListener("mousedown",()=>{this.checkSelectionChanged(a)})}checkSelectionChanged(a){(a.textareaElement.selectionStart!=a.pluginData.selectTokenCallbacks.lastSelectionStart||a.textareaElement.selectionEnd!=a.pluginData.selectTokenCallbacks.lastSelectionEnd)&&(this.syncSelection(a),a.pluginData.selectTokenCallbacks.lastSelectionStart=a.textareaElement.selectionStart,a.pluginData.selectTokenCallbacks.lastSelectionEnd=a.textareaElement.selectionEnd)}syncSelection(a){a.pluginData.selectTokenCallbacks.selectedTokenState.updateSelection(a.textareaElement.selectionStart,a.textareaElement.selectionEnd)}},codeInput.plugins.SelectTokenCallbacks.TokenSelectorCallbacks=class{constructor(a,b){this.tokenSelectedCallback=a,this.selectChangedCallback=b}static createClassSynchronisation(a="code-input_select-token-callbacks_selected"){return new codeInput.plugins.SelectTokenCallbacks.TokenSelectorCallbacks(b=>{b.classList.add(a)},b=>{for(let c=b.getElementsByClassName(a);0<c.length;)c[0].classList.remove(a)})}},codeInput.plugins.SelectTokenCallbacks.SelectedTokenState=class{constructor(a,b,c,d,e,f,g,h){this.tokenContainer=a,this.tokenSelectorCallbacks=b,this.onlyCaretNotSelection=c,this.caretAtStartIsSelected=d,this.caretAtEndIsSelected=e,this.createSubTokens=f,this.partiallySelectedTokensAreSelected=g,this.parentTokensAreSelected=h}updateSelection(a,b){this.selectChanged(),this.onlyCaretNotSelection&&a!=b||this.updateSelectedTokens(this.tokenContainer,a,b)}selectChanged(){if(this.createSubTokens)for(let a=this.tokenContainer.getElementsByClassName("code-input_select-token-callbacks_temporary-span");0<a.length;)a[0].parentElement.replaceChild(new Text(a[0].textContent),a[0]);this.tokenSelectorCallbacks.selectChangedCallback(this.tokenContainer)}updateSelectedTokens(a,b,c){if(!(0>c)&&(0!=c||this.caretAtStartIsSelected)){this.parentTokensAreSelected&&a!==this.tokenContainer&&this.tokenSelectorCallbacks.tokenSelectedCallback(a);for(let d=0;d<a.childNodes.length;d++){let e=a.childNodes[d],f=e.textContent,g=!1;if(3==e.nodeType)if(this.createSubTokens){if(d+1<a.childNodes.length&&3==a.childNodes[d+1].nodeType){a.childNodes[d+1].textContent=e.textContent+a.childNodes[d+1].textContent,a.removeChild(e),d--;continue}g=!0;let b=document.createElement("span");b.textContent=f,b.classList.add("code-input_select-token-callbacks_temporary-span"),a.replaceChild(b,e),e=b}else{b-=f.length,c-=f.length;continue}if(0>=b){if(f.length>c){if(this.partiallySelectedTokensAreSelected)if(g){if(this.createSubTokens&&b!=c){let a=document.createElement("span");this.tokenSelectorCallbacks.tokenSelectedCallback(a),a.classList.add("code-input_select-token-callbacks_temporary-span"),a.textContent=f.substring(0,c);let b=f.substring(c);e.textContent=b,e.insertAdjacentElement("beforebegin",a),d++}(this.parentTokensAreSelected||!this.createSubTokens)&&this.tokenSelectorCallbacks.tokenSelectedCallback(e)}else this.updateSelectedTokens(e,0,c);return}this.tokenSelectorCallbacks.tokenSelectedCallback(e)}else if(this.caretAtEndIsSelected&&f.length>=b||f.length>b){if(this.partiallySelectedTokensAreSelected)if(g){if(this.createSubTokens&&b!=c)if(f.length>c){let a=document.createElement("span");a.classList.add("code-input_select-token-callbacks_temporary-span"),a.textContent=f.substring(0,b);let g=f.substring(b,c);e.textContent=g,this.tokenSelectorCallbacks.tokenSelectedCallback(e);let h=document.createElement("span");h.classList.add("code-input_select-token-callbacks_temporary-span"),h.textContent=f.substring(c),e.insertAdjacentElement("beforebegin",a),e.insertAdjacentElement("afterend",h),d++}else{let a=f.substring(0,b);e.textContent=a;let c=document.createElement("span");this.tokenSelectorCallbacks.tokenSelectedCallback(c),c.classList.add("code-input_select-token-callbacks_temporary-span"),c.textContent=f.substring(b),e.insertAdjacentElement("afterend",c),d++}(this.parentTokensAreSelected||!this.createSubTokens)&&this.tokenSelectorCallbacks.tokenSelectedCallback(e)}else this.updateSelectedTokens(e,b,c);if(this.caretAtStartIsSelected){if(f.length>c)return;}else if(f.length>=c)return}b-=f.length,c-=f.length}}}};
1
+ "use strict";codeInput.plugins.SelectTokenCallbacks=class extends codeInput.Plugin{constructor(a=codeInput.plugins.SelectTokenCallbacks.TokenSelectorCallbacks.createClassSynchronisation(),b=!1,c=!0,d=!0,e=!1,f=!0,g=!0){super([]),this.tokenSelectorCallbacks=a,this.onlyCaretNotSelection=b,this.caretAtStartIsSelected=c,this.caretAtEndIsSelected=d,this.createSubTokens=e,this.partiallySelectedTokensAreSelected=f,this.parentTokensAreSelected=g}afterHighlight(a){this.syncSelection(a)}afterElementsAdded(a){a.pluginData.selectTokenCallbacks={},a.pluginData.selectTokenCallbacks.lastSelectionStart=a.textareaElement.selectionStart,a.pluginData.selectTokenCallbacks.lastSelectionEnd=a.textareaElement.selectionEnd,a.pluginData.selectTokenCallbacks.selectedTokenState=new codeInput.plugins.SelectTokenCallbacks.SelectedTokenState(a.codeElement,this.tokenSelectorCallbacks,this.onlyCaretNotSelection,this.caretAtStartIsSelected,this.caretAtEndIsSelected,this.createSubTokens,this.partiallySelectedTokensAreSelected,this.parentTokensAreSelected),this.syncSelection(a),a.textareaElement.addEventListener("selectionchange",()=>{this.checkSelectionChanged(a)}),a.textareaElement.addEventListener("select",()=>{this.checkSelectionChanged(a)}),a.textareaElement.addEventListener("keypress",()=>{this.checkSelectionChanged(a)}),a.textareaElement.addEventListener("mousedown",()=>{this.checkSelectionChanged(a)})}checkSelectionChanged(a){(a.textareaElement.selectionStart!=a.pluginData.selectTokenCallbacks.lastSelectionStart||a.textareaElement.selectionEnd!=a.pluginData.selectTokenCallbacks.lastSelectionEnd)&&(this.syncSelection(a),a.pluginData.selectTokenCallbacks.lastSelectionStart=a.textareaElement.selectionStart,a.pluginData.selectTokenCallbacks.lastSelectionEnd=a.textareaElement.selectionEnd)}syncSelection(a){a.pluginData.selectTokenCallbacks.selectedTokenState.updateSelection(a.textareaElement.selectionStart,a.textareaElement.selectionEnd)}},codeInput.plugins.SelectTokenCallbacks.TokenSelectorCallbacks=class{constructor(a,b){this.tokenSelectedCallback=a,this.selectChangedCallback=b}static createClassSynchronisation(a="code-input_select-token-callbacks_selected"){return new codeInput.plugins.SelectTokenCallbacks.TokenSelectorCallbacks(b=>{b.classList.add(a)},b=>{for(let c=b.getElementsByClassName(a);0<c.length;)c[0].classList.remove(a)})}},codeInput.plugins.SelectTokenCallbacks.SelectedTokenState=class{constructor(a,b,c,d,e,f,g,h){this.tokenContainer=a,this.tokenSelectorCallbacks=b,this.onlyCaretNotSelection=c,this.caretAtStartIsSelected=d,this.caretAtEndIsSelected=e,this.createSubTokens=f,this.partiallySelectedTokensAreSelected=g,this.parentTokensAreSelected=h}updateSelection(a,b){this.selectChanged(),this.onlyCaretNotSelection&&a!=b||this.updateSelectedTokens(this.tokenContainer,a,b)}selectChanged(){if(this.createSubTokens)for(let a=this.tokenContainer.getElementsByClassName("code-input_select-token-callbacks_temporary-span");0<a.length;)a[0].parentElement.replaceChild(new Text(a[0].textContent),a[0]);this.tokenSelectorCallbacks.selectChangedCallback(this.tokenContainer)}updateSelectedTokens(a,b,c){if(!(0>c)&&(0!=c||this.caretAtStartIsSelected)){this.parentTokensAreSelected&&a!==this.tokenContainer&&this.tokenSelectorCallbacks.tokenSelectedCallback(a);for(let d=0;d<a.childNodes.length;d++){let e=a.childNodes[d],f=e.textContent,g=!1;if(3==e.nodeType)if(this.createSubTokens){if(d+1<a.childNodes.length&&3==a.childNodes[d+1].nodeType){a.childNodes[d+1].textContent=e.textContent+a.childNodes[d+1].textContent,a.removeChild(e),d--;continue}g=!0;let b=document.createElement("span");b.textContent=f,b.classList.add("code-input_select-token-callbacks_temporary-span"),a.replaceChild(b,e),e=b}else{b-=f.length,c-=f.length;continue}if(0>=b){if(f.length>c){if(this.partiallySelectedTokensAreSelected)if(g){if(this.createSubTokens&&b!=c){let a=document.createElement("span");this.tokenSelectorCallbacks.tokenSelectedCallback(a),a.classList.add("code-input_select-token-callbacks_temporary-span"),a.textContent=f.substring(0,c);let b=f.substring(c);e.textContent=b,e.insertAdjacentElement("beforebegin",a),d++}(this.parentTokensAreSelected||!this.createSubTokens)&&this.tokenSelectorCallbacks.tokenSelectedCallback(e)}else this.updateSelectedTokens(e,0,c);return}this.tokenSelectorCallbacks.tokenSelectedCallback(e)}else if(this.caretAtEndIsSelected&&f.length>=b||f.length>b){if(this.partiallySelectedTokensAreSelected)if(g){if(this.createSubTokens&&b!=c)if(f.length>c){let a=document.createElement("span");a.classList.add("code-input_select-token-callbacks_temporary-span"),a.textContent=f.substring(0,b);let g=f.substring(b,c);e.textContent=g,this.tokenSelectorCallbacks.tokenSelectedCallback(e);let h=document.createElement("span");h.classList.add("code-input_select-token-callbacks_temporary-span"),h.textContent=f.substring(c),e.insertAdjacentElement("beforebegin",a),e.insertAdjacentElement("afterend",h),d++}else{let a=f.substring(0,b);e.textContent=a;let c=document.createElement("span");this.tokenSelectorCallbacks.tokenSelectedCallback(c),c.classList.add("code-input_select-token-callbacks_temporary-span"),c.textContent=f.substring(b),e.insertAdjacentElement("afterend",c),d++}(this.parentTokensAreSelected||!this.createSubTokens)&&this.tokenSelectorCallbacks.tokenSelectedCallback(e)}else this.updateSelectedTokens(e,b,c);if(this.caretAtStartIsSelected){if(f.length>c)return;}else if(f.length>=c)return}b-=f.length,c-=f.length}}}};
@@ -1,6 +1,14 @@
1
1
  /**
2
2
  * Render special characters and control characters as a symbol with their hex code.
3
3
  * Files: special-chars.js, special-chars.css
4
+ *
5
+ * WARNING:
6
+ *
7
+ * This plugin is currently unstable when used with other plugins,
8
+ * Unicode characters, or highlight.js. I hope to fix much of this by
9
+ * major version 3, and if you could help that would be amazing!
10
+ *
11
+ * See https://github.com/WebCoder49/code-input/issues?q=is%3Aissue%20state%3Aopen%20specialchars
4
12
  */
5
13
 
6
14
  /* Main styling */
@@ -37,6 +45,10 @@
37
45
  vertical-align: middle;
38
46
  outline: 0.1px solid currentColor;
39
47
 
48
+ /* Contain character for use by other plugins, but hide it */
49
+ color: transparent;
50
+ font-size: 0;
51
+
40
52
  --hex-0: var(
41
53
  --code-input_special-chars_0);
42
54
  --hex-1: var(
@@ -91,4 +103,4 @@
91
103
  height: 1.5em;
92
104
  bottom: -1em;
93
105
  content: attr(data-hex3);
94
- }
106
+ }
@@ -1,7 +1,16 @@
1
1
  /**
2
2
  * Render special characters and control characters as a symbol with their hex code.
3
3
  * Files: special-chars.js, special-chars.css
4
+ *
5
+ * WARNING:
6
+ *
7
+ * This plugin is currently unstable when used with other plugins,
8
+ * Unicode characters, or highlight.js. I hope to fix much of this by
9
+ * major version 3, and if you could help that would be amazing!
10
+ *
11
+ * See https://github.com/WebCoder49/code-input/issues?q=is%3Aissue%20state%3Aopen%20specialchars
4
12
  */
13
+ "use strict";
5
14
 
6
15
  codeInput.plugins.SpecialChars = class extends codeInput.Plugin {
7
16
  specialCharRegExp;
@@ -13,9 +22,9 @@ codeInput.plugins.SpecialChars = class extends codeInput.Plugin {
13
22
  /**
14
23
  * Create a special characters plugin instance.
15
24
  * Default = covers many non-renderable ASCII characters.
16
- * @param {Boolean} colorInSpecialChars Whether or not to give special characters custom background colors based on their hex code
17
- * @param {Boolean} inheritTextColor If `inheritTextColor` 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.
18
- * @param {RegExp} specialCharRegExp The regular expression which matches special characters
25
+ * @param {Boolean} colorInSpecialChars Whether or not to give special characters custom background colors based on their hex code. Defaults to false.
26
+ * @param {Boolean} inheritTextColor If true, forces the color of the hex code to inherit from syntax highlighting. If false, the base color of the `pre code` element is used to give contrast to the small characters. Defaults to false.
27
+ * @param {RegExp} specialCharRegExp The regular expression which matches special characters. Defaults to many non-renderable ASCII characters (which characters are renderable depends on the browser and OS).
19
28
  */
20
29
  constructor(colorInSpecialChars = false, inheritTextColor = false, specialCharRegExp = /(?!\n)(?!\t)[\u{0000}-\u{001F}]|[\u{007F}-\u{009F}]|[\u{0200}-\u{FFFF}]/ug) { // By default, covers many non-renderable ASCII characters
21
30
  super([]); // No observed attributes
@@ -100,6 +109,7 @@ codeInput.plugins.SpecialChars = class extends codeInput.Plugin {
100
109
 
101
110
  // Create element with hex code
102
111
  let result = document.createElement("span");
112
+ result.textContent = matchChar;
103
113
  result.classList.add("code-input_special-char");
104
114
  result.style.setProperty("--hex-0", "var(--code-input_special-chars_" + hexCode[0] + ")");
105
115
  result.style.setProperty("--hex-1", "var(--code-input_special-chars_" + hexCode[1] + ")");
@@ -189,4 +199,4 @@ codeInput.plugins.SpecialChars = class extends codeInput.Plugin {
189
199
 
190
200
  return width;
191
201
  }
192
- }
202
+ }
@@ -1,4 +1,4 @@
1
- :root,body{--code-input_special-chars_0:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABtJREFUGFdjZGBgYPj///9/RhCAMcA0bg6yHgAPmh/6BoxTcQAAAABJRU5ErkJgggAA');--code-input_special-chars_1:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABZJREFUGFdjZGBgYPj///9/RhAggwMAitIUBr9U6sYAAAAASUVORK5CYII=');--code-input_special-chars_2:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB9JREFUGFdj/P///38GKGCEMUCCjCgyYBFGRrAKFBkAuLYT9kYcIu0AAAAASUVORK5CYII=');--code-input_special-chars_3:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABhJREFUGFdj/P///38GKGCEMUCCjMTJAACYiBPyG8sfAgAAAABJRU5ErkJggg==');--code-input_special-chars_4:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB5JREFUGFdj/P///39GRkZGMI3BYYACRhgDrAKZAwAYxhvyz0DRIQAAAABJRU5ErkJggg==');--code-input_special-chars_5:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAACJJREFUGFdj/P///38GKGAEcRgZGRlBfDAHLgNjgFUgywAAuR4T9hxJl2YAAAAASUVORK5CYII=');--code-input_special-chars_6:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAACBJREFUGFdj/P///38GKGAEcRgZGRlBfDAHQwasAlkGABcdF/Y4yco2AAAAAElFTkSuQmCC');--code-input_special-chars_7:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABZJREFUGFdj/P///38GKGCEMUCCRHIAWMgT8kue3bQAAAAASUVORK5CYII=');--code-input_special-chars_8:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABlJREFUGFdj/P///38GKGAEcRgZGSE0cTIAvHcb8v+mIfAAAAAASUVORK5CYII=');--code-input_special-chars_9:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB9JREFUGFdj/P///38GKGAEcRgZGSE0igxMCVgGmQMAPqcX8hWL1K0AAAAASUVORK5CYII=');--code-input_special-chars_A:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAACBJREFUGFdjZGBgYPj///9/RhCAMcA0iADJggCmDEw5ALdxH/aGuYHqAAAAAElFTkSuQmCC');--code-input_special-chars_B:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABlJREFUGFdj/P///38GBgYGRhAAceA0cTIAvc0b/vRDnVoAAAAASUVORK5CYII=');--code-input_special-chars_C:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB5JREFUGFdjZGBgYPj///9/EM0IYjAyMjIS4CDrAQC57hP+uLwvFQAAAABJRU5ErkJggg==');--code-input_special-chars_D:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABtJREFUGFdj/P///38GBgYGRhAAceA0fg5MDwAveh/6ToN9VwAAAABJRU5ErkJggg==');--code-input_special-chars_E:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABxJREFUGFdj/P///38GKGAEcRgZGRlBfDCHsAwA2UwT+mVIH1MAAAAASUVORK5CYII=');--code-input_special-chars_F:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB5JREFUGFdj/P///38GKGAEcRgZGRlBfDAHtwxMGQDZZhP+BnB1kwAAAABJRU5ErkJggg==')}.code-input_special-char{display:inline-block;position:relative;top:0;left:0;height:1em;overflow:hidden;text-decoration:none;text-shadow:none;vertical-align:middle;outline:.1px solid currentColor;--hex-0:var(
1
+ :root,body{--code-input_special-chars_0:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABtJREFUGFdjZGBgYPj///9/RhCAMcA0bg6yHgAPmh/6BoxTcQAAAABJRU5ErkJgggAA');--code-input_special-chars_1:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABZJREFUGFdjZGBgYPj///9/RhAggwMAitIUBr9U6sYAAAAASUVORK5CYII=');--code-input_special-chars_2:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB9JREFUGFdj/P///38GKGCEMUCCjCgyYBFGRrAKFBkAuLYT9kYcIu0AAAAASUVORK5CYII=');--code-input_special-chars_3:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABhJREFUGFdj/P///38GKGCEMUCCjMTJAACYiBPyG8sfAgAAAABJRU5ErkJggg==');--code-input_special-chars_4:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB5JREFUGFdj/P///39GRkZGMI3BYYACRhgDrAKZAwAYxhvyz0DRIQAAAABJRU5ErkJggg==');--code-input_special-chars_5:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAACJJREFUGFdj/P///38GKGAEcRgZGRlBfDAHLgNjgFUgywAAuR4T9hxJl2YAAAAASUVORK5CYII=');--code-input_special-chars_6:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAACBJREFUGFdj/P///38GKGAEcRgZGRlBfDAHQwasAlkGABcdF/Y4yco2AAAAAElFTkSuQmCC');--code-input_special-chars_7:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABZJREFUGFdj/P///38GKGCEMUCCRHIAWMgT8kue3bQAAAAASUVORK5CYII=');--code-input_special-chars_8:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABlJREFUGFdj/P///38GKGAEcRgZGSE0cTIAvHcb8v+mIfAAAAAASUVORK5CYII=');--code-input_special-chars_9:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB9JREFUGFdj/P///38GKGAEcRgZGSE0igxMCVgGmQMAPqcX8hWL1K0AAAAASUVORK5CYII=');--code-input_special-chars_A:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAACBJREFUGFdjZGBgYPj///9/RhCAMcA0iADJggCmDEw5ALdxH/aGuYHqAAAAAElFTkSuQmCC');--code-input_special-chars_B:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABlJREFUGFdj/P///38GBgYGRhAAceA0cTIAvc0b/vRDnVoAAAAASUVORK5CYII=');--code-input_special-chars_C:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB5JREFUGFdjZGBgYPj///9/EM0IYjAyMjIS4CDrAQC57hP+uLwvFQAAAABJRU5ErkJggg==');--code-input_special-chars_D:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABtJREFUGFdj/P///38GBgYGRhAAceA0fg5MDwAveh/6ToN9VwAAAABJRU5ErkJggg==');--code-input_special-chars_E:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABxJREFUGFdj/P///38GKGAEcRgZGRlBfDCHsAwA2UwT+mVIH1MAAAAASUVORK5CYII=');--code-input_special-chars_F:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB5JREFUGFdj/P///38GKGAEcRgZGRlBfDAHtwxMGQDZZhP+BnB1kwAAAABJRU5ErkJggg==')}.code-input_special-char{display:inline-block;position:relative;top:0;left:0;height:1em;overflow:hidden;text-decoration:none;text-shadow:none;vertical-align:middle;outline:.1px solid currentColor;color:transparent;font-size:0;--hex-0:var(
2
2
  --code-input_special-chars_0);--hex-1:var(
3
3
  --code-input_special-chars_0);--hex-2:var(
4
4
  --code-input_special-chars_0);--hex-3:var(
@@ -1 +1 @@
1
- codeInput.plugins.SpecialChars=class extends codeInput.Plugin{specialCharRegExp;cachedColors;cachedWidths;canvasContext;constructor(a=!1,b=!1,c=/(?!\n)(?!\t)[\u{0000}-\u{001F}]|[\u{007F}-\u{009F}]|[\u{0200}-\u{FFFF}]/ug){super([]),this.specialCharRegExp=c,this.colorInSpecialChars=a,this.inheritTextColor=b,this.cachedColors={},this.cachedWidths={};let d=document.createElement("canvas");this.canvasContext=d.getContext("2d")}afterElementsAdded(a){setTimeout(()=>{a.value=a.value},100)}afterHighlight(a){let b=a.codeElement;a.pluginData.specialChars={},a.pluginData.specialChars.contrastColor=window.getComputedStyle(b).color,this.recursivelyReplaceText(a,b),this.lastFont=window.getComputedStyle(a.textareaElement).font}recursivelyReplaceText(a,b){for(let c,d=0;d<b.childNodes.length;d++)if(c=b.childNodes[d],3==c.nodeType){let b=c.nodeValue;this.specialCharRegExp.lastIndex=0;let d=this.specialCharRegExp.exec(b);if(null!=d){let b=d.index;if(c=c.splitText(b+1).previousSibling,0<b&&(c=c.splitText(b)),""!=c.textContent){let b=this.getStylisedSpecialChar(a,c.textContent);c.parentNode.insertBefore(b,c),c.textContent=""}}}else 1==c.nodeType&&"code-input_special-char"!=c.className&&""!=c.nodeValue&&this.recursivelyReplaceText(a,c)}getStylisedSpecialChar(a,b){let c,d=b.codePointAt(0);this.colorInSpecialChars&&(c=this.getCharacterColors(d)),d=d.toString(16),d=("0000"+d).substring(d.length),d=d.toUpperCase();let e=this.getCharacterWidthEm(a,b),f=document.createElement("span");return f.classList.add("code-input_special-char"),f.style.setProperty("--hex-0","var(--code-input_special-chars_"+d[0]+")"),f.style.setProperty("--hex-1","var(--code-input_special-chars_"+d[1]+")"),f.style.setProperty("--hex-2","var(--code-input_special-chars_"+d[2]+")"),f.style.setProperty("--hex-3","var(--code-input_special-chars_"+d[3]+")"),0==e?f.classList.add("code-input_special-char_zero-width"):f.style.width=e+"em",this.colorInSpecialChars?(f.style.backgroundColor="#"+c[0],f.style.setProperty("--code-input_special-char_color",c[1])):!this.inheritTextColor&&f.style.setProperty("--code-input_special-char_color",a.pluginData.specialChars.contrastColor),f}getCharacterColors(a){let b;if(!(a in this.cachedColors)){let c=a.toString(16),d="";for(let a=0;a<c.length;a++)d+=c[a]+c[a];d=("000000"+d).substring(d.length);let e=0;const f=[.299,.587,.114];for(let a=0;6>a;a+=2)e+=parseInt(d.substring(a,a+2),16)*f[a/2];return b=128>e?"white":"black",this.cachedColors[a]=[d,b],[d,b]}return this.cachedColors[a]}getCharacterWidthEm(a,b){if(/­|˞|[̀-ͯ]|[҃-҉]|[​-‍]|/.test(b))return 0;if("\x96"!=b&&/[\0-]|[-Ÿ]/g.test(b)){let b=this.getCharacterWidthEm(a,"\x96");return b}let c=getComputedStyle(a.textareaElement).fontFamily+" "+getComputedStyle(a.textareaElement).fontStretch+" "+getComputedStyle(a.textareaElement).fontStyle+" "+getComputedStyle(a.textareaElement).fontVariant+" "+getComputedStyle(a.textareaElement).fontWeight+" "+getComputedStyle(a.textareaElement).lineHeight;if(null==this.cachedWidths[c]&&(this.cachedWidths[c]={}),null!=this.cachedWidths[c][b])return this.cachedWidths[c][b];this.canvasContext.font=getComputedStyle(a.textareaElement).font.replace(getComputedStyle(a.textareaElement).fontSize,"20px");let d=this.canvasContext.measureText(b).width/20;if(1<d)d/=2;else if(0==d&&"\x96"!=b){let b=this.getCharacterWidthEm(a,"\x96");return b}if(navigator.userAgent.includes("Mozilla")&&!navigator.userAgent.includes("Chrome")&&!navigator.userAgent.includes("Safari")){let b=+getComputedStyle(a.textareaElement).fontSize.substring(0,getComputedStyle(a.textareaElement).fontSize.length-2);20>b&&(d*=20/b)}return this.cachedWidths[c][b]=d,d}};
1
+ "use strict";codeInput.plugins.SpecialChars=class extends codeInput.Plugin{specialCharRegExp;cachedColors;cachedWidths;canvasContext;constructor(a=!1,b=!1,c=/(?!\n)(?!\t)[\u{0000}-\u{001F}]|[\u{007F}-\u{009F}]|[\u{0200}-\u{FFFF}]/ug){super([]),this.specialCharRegExp=c,this.colorInSpecialChars=a,this.inheritTextColor=b,this.cachedColors={},this.cachedWidths={};let d=document.createElement("canvas");this.canvasContext=d.getContext("2d")}afterElementsAdded(a){setTimeout(()=>{a.value=a.value},100)}afterHighlight(a){let b=a.codeElement;a.pluginData.specialChars={},a.pluginData.specialChars.contrastColor=window.getComputedStyle(b).color,this.recursivelyReplaceText(a,b),this.lastFont=window.getComputedStyle(a.textareaElement).font}recursivelyReplaceText(a,b){for(let c,d=0;d<b.childNodes.length;d++)if(c=b.childNodes[d],3==c.nodeType){let b=c.nodeValue;this.specialCharRegExp.lastIndex=0;let d=this.specialCharRegExp.exec(b);if(null!=d){let b=d.index;if(c=c.splitText(b+1).previousSibling,0<b&&(c=c.splitText(b)),""!=c.textContent){let b=this.getStylisedSpecialChar(a,c.textContent);c.parentNode.insertBefore(b,c),c.textContent=""}}}else 1==c.nodeType&&"code-input_special-char"!=c.className&&""!=c.nodeValue&&this.recursivelyReplaceText(a,c)}getStylisedSpecialChar(a,b){let c,d=b.codePointAt(0);this.colorInSpecialChars&&(c=this.getCharacterColors(d)),d=d.toString(16),d=("0000"+d).substring(d.length),d=d.toUpperCase();let e=this.getCharacterWidthEm(a,b),f=document.createElement("span");return f.textContent=b,f.classList.add("code-input_special-char"),f.style.setProperty("--hex-0","var(--code-input_special-chars_"+d[0]+")"),f.style.setProperty("--hex-1","var(--code-input_special-chars_"+d[1]+")"),f.style.setProperty("--hex-2","var(--code-input_special-chars_"+d[2]+")"),f.style.setProperty("--hex-3","var(--code-input_special-chars_"+d[3]+")"),0==e?f.classList.add("code-input_special-char_zero-width"):f.style.width=e+"em",this.colorInSpecialChars?(f.style.backgroundColor="#"+c[0],f.style.setProperty("--code-input_special-char_color",c[1])):!this.inheritTextColor&&f.style.setProperty("--code-input_special-char_color",a.pluginData.specialChars.contrastColor),f}getCharacterColors(a){let b;if(!(a in this.cachedColors)){let c=a.toString(16),d="";for(let a=0;a<c.length;a++)d+=c[a]+c[a];d=("000000"+d).substring(d.length);let e=0;const f=[.299,.587,.114];for(let a=0;6>a;a+=2)e+=parseInt(d.substring(a,a+2),16)*f[a/2];return b=128>e?"white":"black",this.cachedColors[a]=[d,b],[d,b]}return this.cachedColors[a]}getCharacterWidthEm(a,b){if(/­|˞|[̀-ͯ]|[҃-҉]|[​-‍]|/.test(b))return 0;if("\x96"!=b&&/[\0-]|[-Ÿ]/g.test(b)){let b=this.getCharacterWidthEm(a,"\x96");return b}let c=getComputedStyle(a.textareaElement).fontFamily+" "+getComputedStyle(a.textareaElement).fontStretch+" "+getComputedStyle(a.textareaElement).fontStyle+" "+getComputedStyle(a.textareaElement).fontVariant+" "+getComputedStyle(a.textareaElement).fontWeight+" "+getComputedStyle(a.textareaElement).lineHeight;if(null==this.cachedWidths[c]&&(this.cachedWidths[c]={}),null!=this.cachedWidths[c][b])return this.cachedWidths[c][b];this.canvasContext.font=getComputedStyle(a.textareaElement).font.replace(getComputedStyle(a.textareaElement).fontSize,"20px");let d=this.canvasContext.measureText(b).width/20;if(1<d)d/=2;else if(0==d&&"\x96"!=b){let b=this.getCharacterWidthEm(a,"\x96");return b}if(navigator.userAgent.includes("Mozilla")&&!navigator.userAgent.includes("Chrome")&&!navigator.userAgent.includes("Safari")){let b=+getComputedStyle(a.textareaElement).fontSize.substring(0,getComputedStyle(a.textareaElement).fontSize.length-2);20>b&&(d*=20/b)}return this.cachedWidths[c][b]=d,d}};
package/plugins/test.js CHANGED
@@ -8,29 +8,44 @@
8
8
  * codeInput.registerTemplate("syntax-highlighted", codeInput.templates.hljs(hljs, [new codeInput.plugins.Test()]));
9
9
  * ```
10
10
  */
11
+ "use strict";
12
+
11
13
  codeInput.plugins.Test = class extends codeInput.Plugin {
12
- constructor() {
14
+ instructions = {
15
+ beforeHighlight: "before highlight",
16
+ afterHighlight: "after highlight",
17
+ beforeElementsAdded: "before elements added",
18
+ afterElementsAdded: "after elements added",
19
+ attributeChanged: (name, oldValue, newValue) => `${name}: '${oldValue}'>'${newValue}'`
20
+ };
21
+
22
+ constructor(instructionTranslations = {}) {
13
23
  super(["testattr"]);
14
24
  // Array of observed attributes as parameter
25
+
26
+ // instructionTranslations, instructions, and the addTranslations
27
+ // call need not be present if this plugin uses no localisable
28
+ // text.
29
+ this.addTranslations(this.instructions, instructionTranslations);
15
30
  }
16
31
  /* Runs before code is highlighted; Params: codeInput element) */
17
32
  beforeHighlight(codeInput) {
18
- console.log(codeInput, "before highlight");
33
+ console.log(codeInput, this.instructions.beforeHighlight);
19
34
  }
20
35
  /* Runs after code is highlighted; Params: codeInput element) */
21
36
  afterHighlight(codeInput) {
22
- console.log(codeInput, "after highlight");
37
+ console.log(codeInput, this.instructions.afterHighlight);
23
38
  }
24
39
  /* Runs before elements are added into a `code-input`; Params: codeInput element) */
25
40
  beforeElementsAdded(codeInput) {
26
- console.log(codeInput, "before elements added");
41
+ console.log(codeInput, this.instructions.beforeElementsAdded);
27
42
  }
28
43
  /* Runs after elements are added into a `code-input` (useful for adding events to the textarea); Params: codeInput element) */
29
44
  afterElementsAdded(codeInput) {
30
- console.log(codeInput, "after elements added");
45
+ console.log(codeInput, this.instructions.afterElementsAdded);
31
46
  }
32
47
  /* Runs when an observed attribute of a `code-input` is changed (you must add the attribute name in the constructor); Params: codeInput element, name attribute name, oldValue previous value of attribute, newValue changed value of attribute) */
33
48
  attributeChanged(codeInput, name, oldValue, newValue) {
34
- console.log(codeInput, name, ":", oldValue, ">", newValue);
49
+ console.log(codeInput, this.instructions.attriibuteChanged(name, oldValue, newValue));
35
50
  }
36
- }
51
+ }
@@ -1 +1 @@
1
- codeInput.plugins.Test=class extends codeInput.Plugin{constructor(){super(["testattr"])}beforeHighlight(a){console.log(a,"before highlight")}afterHighlight(a){console.log(a,"after highlight")}beforeElementsAdded(a){console.log(a,"before elements added")}afterElementsAdded(a){console.log(a,"after elements added")}attributeChanged(a,b,c,d){console.log(a,b,":",c,">",d)}};
1
+ "use strict";codeInput.plugins.Test=class extends codeInput.Plugin{instructions={beforeHighlight:"before highlight",afterHighlight:"after highlight",beforeElementsAdded:"before elements added",afterElementsAdded:"after elements added",attributeChanged:(a,b,c)=>`${a}: '${b}'>'${c}'`};constructor(a={}){super(["testattr"]),this.addTranslations(this.instructions,a)}beforeHighlight(a){console.log(a,this.instructions.beforeHighlight)}afterHighlight(a){console.log(a,this.instructions.afterHighlight)}beforeElementsAdded(a){console.log(a,this.instructions.beforeElementsAdded)}afterElementsAdded(a){console.log(a,this.instructions.afterElementsAdded)}attributeChanged(a,b,c,d){console.log(a,this.instructions.attriibuteChanged(b,c,d))}};
@@ -1,22 +0,0 @@
1
- name: Auto-minify
2
- on:
3
- push:
4
- branches:
5
- - main
6
- jobs:
7
- Minify:
8
- runs-on: ubuntu-latest
9
- steps:
10
- # Checks-out your repository under $GITHUB_WORKSPACE, so auto-minify job can access it
11
- - uses: actions/checkout@v2
12
-
13
- - name: Auto Minify
14
- uses: nizarmah/auto-minify@v2.1
15
-
16
- # Auto commits minified files to the repository
17
- # Ignore it if you don't want to commit the files to the repository
18
- - name: Auto committing minified files
19
- uses: stefanzweifel/git-auto-commit-action@v4
20
- with:
21
- commit_message: "Auto Minified JS and CSS files"
22
- branch: ${{ github.ref }}
@@ -1,21 +0,0 @@
1
- # This workflow will publish a package to GitHub Packages when a release is created
2
- # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
3
-
4
- name: Node.js Package
5
-
6
- on:
7
- release:
8
- types: [created]
9
-
10
- jobs:
11
- publish-npm:
12
- runs-on: ubuntu-latest
13
- steps:
14
- - uses: actions/checkout@v3
15
- - uses: actions/setup-node@v3
16
- with:
17
- node-version: 16
18
- registry-url: https://registry.npmjs.org/
19
- - run: npm publish
20
- env:
21
- NODE_AUTH_TOKEN: ${{secrets.npm_token}}