@webcoder49/code-input 2.5.0 → 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 +71 -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 +25 -7
  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 +34 -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 +43 -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 +29 -4
  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 -593
  71. package/tests/tester.min.js +0 -21
@@ -11,7 +11,6 @@
11
11
  .code-input_go-to-line_dialog {
12
12
  position: absolute;
13
13
  top: 0; right: 14px;
14
- height: 28px;
15
14
  padding: 6px;
16
15
  padding-top: 8px;
17
16
  border: solid 1px #00000044;
@@ -48,10 +47,6 @@
48
47
  color: #ff0000aa;
49
48
  }
50
49
 
51
- .code-input_go-to-line_dialog input:focus {
52
- outline: none;
53
- }
54
-
55
50
  /* Cancel icon */
56
51
  .code-input_go-to-line_dialog span {
57
52
  display: inline-block;
@@ -75,3 +70,13 @@
75
70
  opacity: .8;
76
71
  background-color: #00000018;
77
72
  }
73
+
74
+ /* For backwards compatibility, p element on the same level as buttons rather than
75
+ buttons being nested inside other element like in FindAndReplace. */
76
+ .code-input_go-to-line_dialog p {
77
+ font-family: monospace;
78
+ width: 264px;
79
+ margin: 0;
80
+ overflow: hidden;
81
+ white-space: wrap;
82
+ }
@@ -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,13 +115,23 @@ 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');
120
+
121
+ // TODO: Make a button element (semantic HTML for accessibility) in next major version
93
122
  const cancel = document.createElement('span');
123
+ cancel.setAttribute("role", "button");
124
+ cancel.setAttribute("aria-label", this.instructions.closeDialog);
94
125
  cancel.setAttribute("tabindex", 0); // Visible to keyboard navigation
95
126
  cancel.setAttribute("title", this.instructions.closeDialog);
96
127
 
128
+ const guidance = document.createElement('p');
129
+ guidance.setAttribute("aria-live", "assertive"); // Screen reader must read the status message.
130
+ guidance.textContent = "";
131
+
97
132
  dialog.appendChild(input);
98
133
  dialog.appendChild(cancel);
134
+ dialog.appendChild(guidance);
99
135
 
100
136
  dialog.className = 'code-input_go-to-line_dialog';
101
137
  input.spellcheck = false;
@@ -103,6 +139,7 @@ codeInput.plugins.GoToLine = class extends codeInput.Plugin {
103
139
  dialog.codeInput = codeInput;
104
140
  dialog.textarea = textarea;
105
141
  dialog.input = input;
142
+ dialog.guidance = guidance;
106
143
 
107
144
  input.addEventListener('keypress', (event) => {
108
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("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
@@ -81,11 +83,12 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
81
83
  let indentationWidthPx = testIndentationWidthSpan.offsetWidth;
82
84
  codeInput.removeChild(testIndentationWidthPre);
83
85
 
84
- codeInput.pluginData.indent = {indentationWidthPx: indentationWidthPx};
86
+ codeInput.pluginData.indent = {automatedKeypresses: false, indentationWidthPx: indentationWidthPx};
85
87
  }
86
88
 
87
89
  /* Deal with the Tab key causing indentation, and Tab+Selection indenting / Shift+Tab+Selection unindenting lines, and the mechanism through which Tab can be used to switch focus instead (accessibility). */
88
90
  checkTab(codeInput, event) {
91
+ if(codeInput.pluginData.indent.automatedKeypresses) return;
89
92
  if(!this.tabIndentationEnabled) return;
90
93
  if(this.escTabToChangeFocus) {
91
94
  // Accessibility - allow Tab for keyboard navigation when Esc pressed right before it.
@@ -116,7 +119,12 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
116
119
 
117
120
  if(!event.shiftKey && inputElement.selectionStart == inputElement.selectionEnd) {
118
121
  // Just place a tab/spaces here.
122
+ // automatedKeypresses property to prevent keypresses being captured
123
+ // by this plugin during automated input as some browsers
124
+ // (e.g. GNOME Web) do.
125
+ codeInput.pluginData.indent.automatedKeypresses = true;
119
126
  document.execCommand("insertText", false, this.indentation);
127
+ codeInput.pluginData.indent.automatedKeypresses = false;
120
128
 
121
129
  } else {
122
130
  let lines = inputElement.value.split("\n");
@@ -147,7 +155,12 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
147
155
  // Add tab at start
148
156
  inputElement.selectionStart = letterI;
149
157
  inputElement.selectionEnd = letterI;
158
+ // automatedKeypresses property to prevent keypresses being captured
159
+ // by this plugin during automated input as some browsers
160
+ // (e.g. GNOME Web) do.
161
+ codeInput.pluginData.indent.f = true;
150
162
  document.execCommand("insertText", false, this.indentation);
163
+ codeInput.pluginData.indent.automatedKeypresses = false;
151
164
 
152
165
  // Change selection
153
166
  if(selectionStartI > letterI) { // Indented outside selection
@@ -191,6 +204,7 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
191
204
 
192
205
  /* Deal with new lines retaining indentation */
193
206
  checkEnter(codeInput, event) {
207
+ if(codeInput.pluginData.indent.automatedKeypresses) return;
194
208
  if(event.key != "Enter") {
195
209
  return;
196
210
  }
@@ -206,7 +220,7 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
206
220
  // find the index of the line our cursor is currently on
207
221
  for (let i = 0; i < lines.length; i++) {
208
222
  letterI += lines[i].length + 1;
209
- if(inputElement.selectionEnd <= letterI) {
223
+ if(inputElement.selectionEnd < letterI) {
210
224
  currentLineI = i;
211
225
  break;
212
226
  }
@@ -263,6 +277,10 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
263
277
  }
264
278
 
265
279
  // insert our indents and any text from the previous line that might have been after the line break
280
+ // negative indents shouldn't exist and would only break future calculations.
281
+ if(numberIndents < 0) {
282
+ numberIndents = 0;
283
+ }
266
284
  for (let i = 0; i < numberIndents; i++) {
267
285
  newLine += this.indentation;
268
286
  }
@@ -270,11 +288,16 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
270
288
  // save the current cursor position
271
289
  let selectionStartI = inputElement.selectionStart;
272
290
 
291
+ // automatedKeypresses property to prevent keypresses being captured
292
+ // by this plugin during automated input as some browsers
293
+ // (e.g. GNOME Web) do.
294
+ codeInput.pluginData.indent.automatedKeypresses = true;
273
295
  if(bracketThreeLinesTriggered) {
274
296
  document.execCommand("insertText", false, "\n" + furtherIndentation); // Write indented line
275
297
  numberIndents += 1; // Reflects the new indent
276
298
  }
277
299
  document.execCommand("insertText", false, "\n" + newLine); // Write new line, including auto-indentation
300
+ codeInput.pluginData.indent.automatedKeypresses = false;
278
301
 
279
302
  // move cursor to new position
280
303
  inputElement.selectionStart = selectionStartI + numberIndents*this.indentationNumChars + 1; // count the indent level and the newline character
@@ -294,6 +317,7 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
294
317
 
295
318
  /* Deal with one 'tab' of spaces-based-indentation being deleted by each backspace, rather than one space */
296
319
  checkBackspace(codeInput, event) {
320
+ if(codeInput.pluginData.indent.automatedKeypresses) return;
297
321
  if(event.key != "Backspace" || this.indentationNumChars == 1) {
298
322
  return; // Normal backspace when indentation of 1
299
323
  }
@@ -321,7 +345,8 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
321
345
  if(codeInput.value.substring(codeInput.textareaElement.selectionStart - this.indentationNumChars, codeInput.textareaElement.selectionStart) == this.indentation) {
322
346
  // Indentation before cursor = delete it
323
347
  codeInput.textareaElement.selectionStart -= this.indentationNumChars;
324
- document.execCommand("delete", false, "");
348
+ // document.execCommand("delete", false, "");
349
+ // event.preventDefault();
325
350
  }
326
351
  }
327
352
  }
@@ -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={indentationWidthPx:e}}checkTab(a,b){var c=Math.max;if(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)document.execCommand("insertText",!1,this.indentation);else{let e=d.value.split("\n"),f=0,g=d.selectionStart,h=d.selectionEnd;for(let a=0;a<e.length;a++)(g<=f+e[a].length&&h>=f+1||g==h&&g<=f+e[a].length+1&&h>=f)&&(b.shiftKey?e[a].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,document.execCommand("insertText",!1,this.indentation),g>f&&(g+=this.indentationNumChars),h+=this.indentationNumChars,f+=this.indentationNumChars)),f+=e[a].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("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}}for(let c=0;c<h;c++)g+=this.indentation;let n=c.selectionStart;l&&(document.execCommand("insertText",!1,"\n"+m),h+=1),document.execCommand("insertText",!1,"\n"+g),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("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,document.execCommand("delete",!1,""))}}};
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 }}