@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
@@ -0,0 +1,52 @@
1
+ +++
2
+ title = 'Creating your own code-input Plugin to add functionality'
3
+ +++
4
+
5
+ # Creating your own code-input Plugin to add functionality
6
+
7
+ If you're writing some code that depends on the code-input editor and isn't very useful independent of it, or integrates other code with code-input, writing a plugin's often the way to go. You can even choose to contribute it back to the code-input library!
8
+
9
+ A very useful source of reference is the code-input.d.ts file in code-input.js' source code, which defines the public JavaScript interface of the code-input.js library including code-input elements.
10
+
11
+ Start with this code, which is also available as the `test` plugin. Afterwards, construct and pass a `new TestPlugin()` into the array when you register a code-input.js template, like any other code-input plugin:
12
+ ```javascript
13
+ const TestPlugin = class extends codeInput.Plugin {
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 = {}) {
23
+ super(["testattr"]);
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);
30
+ }
31
+ /* Runs before code is highlighted; Params: codeInput element) */
32
+ beforeHighlight(codeInput) {
33
+ console.log(codeInput, this.instructions.beforeHighlight);
34
+ }
35
+ /* Runs after code is highlighted; Params: codeInput element) */
36
+ afterHighlight(codeInput) {
37
+ console.log(codeInput, this.instructions.afterHighlight);
38
+ }
39
+ /* Runs before elements are added into a `code-input`; Params: codeInput element) */
40
+ beforeElementsAdded(codeInput) {
41
+ console.log(codeInput, this.instructions.beforeElementsAdded);
42
+ }
43
+ /* Runs after elements are added into a `code-input` (useful for adding events to the textarea); Params: codeInput element) */
44
+ afterElementsAdded(codeInput) {
45
+ console.log(codeInput, this.instructions.afterElementsAdded);
46
+ }
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) */
48
+ attributeChanged(codeInput, name, oldValue, newValue) {
49
+ console.log(codeInput, this.instructions.attriibuteChanged(name, oldValue, newValue));
50
+ }
51
+ };
52
+ ```
@@ -0,0 +1,9 @@
1
+ +++
2
+ title = 'How code-input.js works Behind The Scenes'
3
+ +++
4
+
5
+ # How `code-input.js` works Behind The Scenes
6
+
7
+ > Contributors: 2021 Oliver Geer
8
+
9
+ Bearing in mind that it will teach you to make your own version of the core of <code>code-input.js</code> but you should use the library itself if you want more stability, please see [this CSS-Tricks article](https://css-tricks.com/creating-an-editable-textarea-that-supports-syntax-highlighted-code). It was written by the founder of the library just before development started, so doesn't contain all bugfixes but does contain the core theory and how to create a minimal `code-input` yourself.
Binary file
package/esm/README.md ADDED
@@ -0,0 +1,23 @@
1
+ # Autogenerated ECMAScript Modules
2
+
3
+ ## Using
4
+
5
+ If you are using Yarn, NPM, or a similar package manager, the files should have been generated before being uploaded to the package repository, or on `pack` if the package manager is fetching from Git.
6
+
7
+ Otherwise, after changing directory to the one containing this file:
8
+
9
+ - If you have Node.js installed, run `node generate.mjs`.
10
+ - If you don't have Node.js installed but are on a POSIX-like system with `bash`/`zsh`, run `sh ./generate.sh`.
11
+ - If neither of the above are true, install Node.js or (slightly harder; look online) a POSIX/"Linux" compatible shell.
12
+
13
+ ## Extra Information
14
+
15
+ When code-input was started, it was written and tested only to be imported directly via a `<script>` tag, and it assigned an object to a global `codeInput` variable containing all its functionality. As plugins were added, they were implemented as similar but separate `<script>` tags. However, this limits where `codeInput` can be used, making it difficult to integrate with many larger JavaScript projects and frameworks, and causes code duplication when multiple plugins use the same code.
16
+
17
+ To fix these, code-input is gaining support for ECMAScript Modules (ESM), a standard way to import modules and export from them with JavaScript. ESM can be used directly in NPM/Yarn-led environments, bundled for inclusion in a `<script>` tag in a backwards-compatible way, or imported as a module into a web browser which supports it natively.
18
+
19
+ To ensure backwards compatibility, in the first stage of the transition a process to auto-generate ESM-compatible files from the existing JavaScript files will be created, so existing `<script>` tag users are unaffected.
20
+
21
+ Later in the second stage, `code-input`'s daily-edited source code may be relocated to ESM, using these generated files, and the direct importable files would be produced by a bundler.
22
+
23
+ However, refactoring the core would need quite a lot of work and testing, and the first stage suffices for compatibility with all the examples. This directory will exist from the first stage until the second stage, containing the tools to generate ESM files. After the second stage, it would likely be repurposed as the main source code directory, containing the same files which would become the main developed ones.
@@ -0,0 +1,2 @@
1
+ // NOTICE: This code is @generated from code outside the esm directory. Please do not edit it to contribute!
2
+
package/package.json CHANGED
@@ -1,10 +1,84 @@
1
1
  {
2
2
  "name": "@webcoder49/code-input",
3
- "version": "2.5.1",
4
- "description": "Fully customisable, editable syntax-highlighted textareas.",
3
+ "version": "2.6.0",
4
+ "description": "An editable &lt;textarea&gt; that supports *any* syntax highlighting algorithm, for code or something else. Also, added plugins.",
5
5
  "browser": "code-input.js",
6
+ "exports": {
7
+ ".": {
8
+ "import": "./esm/code-input.mjs"
9
+ },
10
+ "./code-input.mjs": {
11
+ "import": "./esm/code-input.mjs"
12
+ },
13
+ "./templates/hljs.mjs": {
14
+ "import": "./esm/templates/hljs.mjs"
15
+ },
16
+ "./templates/prism.mjs": {
17
+ "import": "./esm/templates/prism.mjs"
18
+ },
19
+ "./plugins/auto-close-brackets.mjs": {
20
+ "import": "./esm/plugins/auto-close-brackets.mjs"
21
+ },
22
+ "./plugins/autocomplete.mjs": {
23
+ "import": "./esm/plugins/autocomplete.mjs"
24
+ },
25
+ "./plugins/autodetect.mjs": {
26
+ "import": "./esm/plugins/autodetect.mjs"
27
+ },
28
+ "./plugins/find-and-replace.mjs": {
29
+ "import": "./esm/plugins/find-and-replace.mjs"
30
+ },
31
+ "./plugins/go-to-line.mjs": {
32
+ "import": "./esm/plugins/go-to-line.mjs"
33
+ },
34
+ "./plugins/indent.mjs": {
35
+ "import": "./esm/plugins/indent.mjs"
36
+ },
37
+ "./plugins/select-token-callbacks.mjs": {
38
+ "import": "./esm/plugins/select-token-callbacks.mjs"
39
+ },
40
+ "./plugins/special-chars.mjs": {
41
+ "import": "./esm/plugins/special-chars.mjs"
42
+ },
43
+ "./plugins/test.mjs": {
44
+ "import": "./esm/plugins/test.mjs"
45
+ },
46
+ "./code-input.js": "./code-input.js",
47
+ "./plugins/auto-close-brackets.js": "./plugins/auto-close-brackets.js",
48
+ "./plugins/autocomplete.js": "./plugins/autocomplete.js",
49
+ "./plugins/autodetect.js": "./plugins/autodetect.js",
50
+ "./plugins/find-and-replace.js": "./plugins/find-and-replace.js",
51
+ "./plugins/go-to-line.js": "./plugins/go-to-line.js",
52
+ "./plugins/indent.js": "./plugins/indent.js",
53
+ "./plugins/select-token-callbacks.js": "./plugins/select-token-callbacks.js",
54
+ "./plugins/special-chars.js": "./plugins/special-chars.js",
55
+ "./plugins/test.js": "./plugins/test.js",
56
+ "./code-input.min.js": "./code-input.min.js",
57
+ "./plugins/auto-close-brackets.min.js": "./plugins/auto-close-brackets.min.js",
58
+ "./plugins/autocomplete.min.js": "./plugins/autocomplete.min.js",
59
+ "./plugins/autodetect.min.js": "./plugins/autodetect.min.js",
60
+ "./plugins/find-and-replace.min.js": "./plugins/find-and-replace.min.js",
61
+ "./plugins/go-to-line.min.js": "./plugins/go-to-line.min.js",
62
+ "./plugins/indent.min.js": "./plugins/indent.min.js",
63
+ "./plugins/select-token-callbacks.min.js": "./plugins/select-token-callbacks.min.js",
64
+ "./plugins/special-chars.min.js": "./plugins/special-chars.min.js",
65
+ "./plugins/test.min.js": "./plugins/test.min.js",
66
+ "./code-input.css": "./code-input.css",
67
+ "./plugins/autocomplete.css": "./plugins/autocomplete.css",
68
+ "./plugins/find-and-replace.css": "./plugins/find-and-replace.css",
69
+ "./plugins/go-to-line.css": "./plugins/go-to-line.css",
70
+ "./plugins/prism-line-numbers.css": "./plugins/prism-line-numbers.css",
71
+ "./plugins/special-chars.css": "./plugins/special-chars.css",
72
+ "./code-input.min.css": "./code-input.min.css",
73
+ "./plugins/autocomplete.min.css": "./plugins/autocomplete.min.css",
74
+ "./plugins/find-and-replace.min.css": "./plugins/find-and-replace.min.css",
75
+ "./plugins/go-to-line.min.css": "./plugins/go-to-line.min.css",
76
+ "./plugins/prism-line-numbers.min.css": "./plugins/prism-line-numbers.min.css",
77
+ "./plugins/special-chars.min.css": "./plugins/special-chars.min.css"
78
+ },
6
79
  "scripts": {
7
- "test": "echo \"This is a front-end library, not a Node library. Please see the README for how to use.\" && exit 1"
80
+ "test": "echo \"This is a front-end library, not a Node library. Please see https://code-input-js.org for how to use.\" && exit 1",
81
+ "prepack": "cd esm ; node generate.mjs ; cd .."
8
82
  },
9
83
  "repository": {
10
84
  "type": "git",
@@ -16,16 +90,18 @@
16
90
  "highlight",
17
91
  "textarea",
18
92
  "editable",
19
- "web-components"
93
+ "web-components",
94
+ "code-editor",
95
+ "text-editor"
20
96
  ],
21
97
  "author": {
22
- "name": "WebCoder49",
98
+ "name": "Oliver Geer and contributors",
23
99
  "email": "hi@webcoder49.dev",
24
- "url": "https://webcoder49.dev/"
100
+ "url": "https://oliver.geer.im/"
25
101
  },
26
102
  "license": "MIT",
27
103
  "bugs": {
28
104
  "url": "https://github.com/WebCoder49/code-input/issues"
29
105
  },
30
- "homepage": "https://github.com/WebCoder49/code-input#readme"
106
+ "homepage": "https://code-input-js.org/"
31
107
  }
package/plugins/README.md CHANGED
@@ -61,6 +61,8 @@ Files: [prism-line-numbers.css](./prism-line-numbers.css) (NO JS FILE)
61
61
  Render special characters and control characters as a symbol
62
62
  with their hex code.
63
63
 
64
+ **Please note: This plugin is known to contain bugs, especially when used with highlight.js and/or other plugins. Please bear this in mind and look at the Issues if you want more details; fixes for the bugs are planned but not prioritised as much as those used in more common plugins or the core library.**
65
+
64
66
  Files: [special-chars.js](./special-chars.js) / [special-chars.css](./special-chars.css)
65
67
 
66
68
  [🚀 *CodePen Demo*](https://codepen.io/WebCoder49/pen/jOeYJbm)
@@ -3,6 +3,8 @@
3
3
  * is activated for.
4
4
  * Files: auto-close-brackets.js
5
5
  */
6
+ "use strict";
7
+
6
8
  codeInput.plugins.AutoCloseBrackets = class extends codeInput.Plugin {
7
9
  bracketPairs = [];
8
10
  bracketsOpenedStack = []; // Each item [closing bracket string, opening bracket location] Innermost at right so can know which brackets should be ignored when retyped
@@ -1 +1 @@
1
- codeInput.plugins.AutoCloseBrackets=class extends codeInput.Plugin{bracketPairs=[];bracketsOpenedStack=[];constructor(a={"(":")","[":"]","{":"}",'"':"\""}){super([]),this.bracketPairs=a}afterElementsAdded(a){a.pluginData.autoCloseBrackets={automatedKeypresses:!1},a.textareaElement.addEventListener("keydown",b=>{this.checkBackspace(a,b)}),a.textareaElement.addEventListener("beforeinput",b=>{this.checkClosingBracket(a,b)}),a.textareaElement.addEventListener("input",b=>{this.checkOpeningBracket(a,b)})}checkClosingBracket(a,b){if(!a.pluginData.autoCloseBrackets.automatedKeypresses&&b.data==a.textareaElement.value[a.textareaElement.selectionStart])for(let c in this.bracketPairs){let d=this.bracketPairs[c];if(b.data==d){a.textareaElement.selectionStart=a.textareaElement.selectionEnd+=1,b.preventDefault();break}}}checkOpeningBracket(a,b){if(!a.pluginData.autoCloseBrackets.automatedKeypresses&&b.data in this.bracketPairs){let c=this.bracketPairs[b.data];a.pluginData.autoCloseBrackets.automatedKeypresses=!0,document.execCommand("insertText",!1,c),a.pluginData.autoCloseBrackets.automatedKeypresses=!1,a.textareaElement.selectionStart=a.textareaElement.selectionEnd-=1}}checkBackspace(a,b){if(!a.pluginData.autoCloseBrackets.automatedKeypresses&&"Backspace"==b.key&&a.textareaElement.selectionStart==a.textareaElement.selectionEnd){let b=this.bracketPairs[a.textareaElement.value[a.textareaElement.selectionStart-1]];null!=b&&a.textareaElement.value[a.textareaElement.selectionStart]==b&&(a.textareaElement.selectionEnd=a.textareaElement.selectionStart+1,a.textareaElement.selectionStart-=1)}}};
1
+ "use strict";codeInput.plugins.AutoCloseBrackets=class extends codeInput.Plugin{bracketPairs=[];bracketsOpenedStack=[];constructor(a={"(":")","[":"]","{":"}",'"':"\""}){super([]),this.bracketPairs=a}afterElementsAdded(a){a.pluginData.autoCloseBrackets={automatedKeypresses:!1},a.textareaElement.addEventListener("keydown",b=>{this.checkBackspace(a,b)}),a.textareaElement.addEventListener("beforeinput",b=>{this.checkClosingBracket(a,b)}),a.textareaElement.addEventListener("input",b=>{this.checkOpeningBracket(a,b)})}checkClosingBracket(a,b){if(!a.pluginData.autoCloseBrackets.automatedKeypresses&&b.data==a.textareaElement.value[a.textareaElement.selectionStart])for(let c in this.bracketPairs){let d=this.bracketPairs[c];if(b.data==d){a.textareaElement.selectionStart=a.textareaElement.selectionEnd+=1,b.preventDefault();break}}}checkOpeningBracket(a,b){if(!a.pluginData.autoCloseBrackets.automatedKeypresses&&b.data in this.bracketPairs){let c=this.bracketPairs[b.data];a.pluginData.autoCloseBrackets.automatedKeypresses=!0,document.execCommand("insertText",!1,c),a.pluginData.autoCloseBrackets.automatedKeypresses=!1,a.textareaElement.selectionStart=a.textareaElement.selectionEnd-=1}}checkBackspace(a,b){if(!a.pluginData.autoCloseBrackets.automatedKeypresses&&"Backspace"==b.key&&a.textareaElement.selectionStart==a.textareaElement.selectionEnd){let b=this.bracketPairs[a.textareaElement.value[a.textareaElement.selectionStart-1]];null!=b&&a.textareaElement.value[a.textareaElement.selectionStart]==b&&(a.textareaElement.selectionEnd=a.textareaElement.selectionStart+1,a.textareaElement.selectionStart-=1)}}};
@@ -2,6 +2,8 @@
2
2
  * Display a popup under the caret using the text in the code-input element. This works well with autocomplete suggestions.
3
3
  * Files: autocomplete.js / autocomplete.css
4
4
  */
5
+ "use strict";
6
+
5
7
  codeInput.plugins.Autocomplete = class extends codeInput.Plugin {
6
8
  /**
7
9
  * Pass in a function to create a plugin that displays the popup that takes in (popup element, textarea, textarea.selectionEnd).
@@ -20,7 +22,7 @@ codeInput.plugins.Autocomplete = class extends codeInput.Plugin {
20
22
  popupElem.style.left = caretCoords.left + "px";
21
23
 
22
24
  if(!onlyScrolled) {
23
- this.updatePopupCallback(popupElem, textarea, textarea.selectionEnd);
25
+ this.updatePopupCallback(popupElem, textarea, textarea.selectionEnd, textarea.selectionStart);
24
26
  }
25
27
  }
26
28
  /* Create the popup element */
@@ -30,10 +32,8 @@ codeInput.plugins.Autocomplete = class extends codeInput.Plugin {
30
32
  codeInput.appendChild(popupElem);
31
33
 
32
34
  let testPosPre = document.createElement("pre");
33
- popupElem.setAttribute("inert", true); // Invisible to keyboard navigation
34
- popupElem.setAttribute("tabindex", -1); // Invisible to keyboard navigation
35
35
  testPosPre.setAttribute("aria-hidden", true); // Hide for screen readers
36
- if(codeInput.template.preElementStyled) {
36
+ if(codeInput.templateObject.preElementStyled) {
37
37
  testPosPre.classList.add("code-input_autocomplete_testpos");
38
38
  codeInput.appendChild(testPosPre); // Styled like first pre, but first pre found to update
39
39
  } else {
@@ -45,7 +45,7 @@ codeInput.plugins.Autocomplete = class extends codeInput.Plugin {
45
45
 
46
46
  let textarea = codeInput.textareaElement;
47
47
  textarea.addEventListener("input", () => { this.updatePopup(codeInput, false)});
48
- textarea.addEventListener("click", () => { this.updatePopup(codeInput, false)});
48
+ textarea.addEventListener("selectionchange", () => { this.updatePopup(codeInput, false)});
49
49
  }
50
50
  /**
51
51
  * Return the coordinates of the caret in a code-input
@@ -85,4 +85,4 @@ codeInput.plugins.Autocomplete = class extends codeInput.Plugin {
85
85
  return {"top": afterSpan.offsetTop - textarea.scrollTop, "left": afterSpan.offsetLeft - textarea.scrollLeft};
86
86
  }
87
87
  updatePopupCallback = function() {};
88
- }
88
+ }
@@ -1 +1 @@
1
- codeInput.plugins.Autocomplete=class extends codeInput.Plugin{constructor(a){super([]),this.updatePopupCallback=a}updatePopup(a,b){let c=a.textareaElement,d=this.getCaretCoordinates(a,c,c.selectionEnd,b),e=a.querySelector(".code-input_autocomplete_popup");e.style.top=d.top+"px",e.style.left=d.left+"px",b||this.updatePopupCallback(e,c,c.selectionEnd)}afterElementsAdded(a){let b=document.createElement("div");b.classList.add("code-input_autocomplete_popup"),a.appendChild(b);let c=document.createElement("pre");if(b.setAttribute("inert",!0),b.setAttribute("tabindex",-1),c.setAttribute("aria-hidden",!0),a.template.preElementStyled)c.classList.add("code-input_autocomplete_testpos"),a.appendChild(c);else{let b=document.createElement("code");b.classList.add("code-input_autocomplete_testpos"),c.appendChild(b),a.appendChild(c)}let d=a.textareaElement;d.addEventListener("input",()=>{this.updatePopup(a,!1)}),d.addEventListener("click",()=>{this.updatePopup(a,!1)})}getCaretCoordinates(a,b,c,d){let e;if(d){let d=a.querySelector(".code-input_autocomplete_testpos").querySelectorAll("span");if(2>d.length)return this.getCaretCoordinates(a,b,c,!1);e=d[1]}else{let d=a.querySelector(".code-input_autocomplete_testpos"),f=document.createElement("span");for(f.textContent=b.value.substring(0,c),e=document.createElement("span"),e.textContent=".";d.firstChild;)d.removeChild(d.firstChild);d.appendChild(f),d.appendChild(e)}return{top:e.offsetTop-b.scrollTop,left:e.offsetLeft-b.scrollLeft}}updatePopupCallback=function(){}};
1
+ "use strict";codeInput.plugins.Autocomplete=class extends codeInput.Plugin{constructor(a){super([]),this.updatePopupCallback=a}updatePopup(a,b){let c=a.textareaElement,d=this.getCaretCoordinates(a,c,c.selectionEnd,b),e=a.querySelector(".code-input_autocomplete_popup");e.style.top=d.top+"px",e.style.left=d.left+"px",b||this.updatePopupCallback(e,c,c.selectionEnd,c.selectionStart)}afterElementsAdded(a){let b=document.createElement("div");b.classList.add("code-input_autocomplete_popup"),a.appendChild(b);let c=document.createElement("pre");if(c.setAttribute("aria-hidden",!0),a.templateObject.preElementStyled)c.classList.add("code-input_autocomplete_testpos"),a.appendChild(c);else{let b=document.createElement("code");b.classList.add("code-input_autocomplete_testpos"),c.appendChild(b),a.appendChild(c)}let d=a.textareaElement;d.addEventListener("input",()=>{this.updatePopup(a,!1)}),d.addEventListener("selectionchange",()=>{this.updatePopup(a,!1)})}getCaretCoordinates(a,b,c,d){let e;if(d){let d=a.querySelector(".code-input_autocomplete_testpos").querySelectorAll("span");if(2>d.length)return this.getCaretCoordinates(a,b,c,!1);e=d[1]}else{let d=a.querySelector(".code-input_autocomplete_testpos"),f=document.createElement("span");for(f.textContent=b.value.substring(0,c),e=document.createElement("span"),e.textContent=".";d.firstChild;)d.removeChild(d.firstChild);d.appendChild(f),d.appendChild(e)}return{top:e.offsetTop-b.scrollTop,left:e.offsetLeft-b.scrollLeft}}updatePopupCallback=function(){}};
@@ -3,6 +3,8 @@
3
3
  * autodetect capabilities. Works with highlight.js only.
4
4
  * Files: autodetect.js
5
5
  */
6
+ "use strict";
7
+
6
8
  codeInput.plugins.Autodetect = class extends codeInput.Plugin {
7
9
  constructor() {
8
10
  super([]); // No observed attributes
@@ -17,7 +19,7 @@ codeInput.plugins.Autodetect = class extends codeInput.Plugin {
17
19
  afterHighlight(codeInput) {
18
20
  let langClass = codeInput.codeElement.className || codeInput.preElement.className;
19
21
  let lang = langClass.match(/lang(\w|-)*/i)[0]; // Get word starting with lang...; Get outer bracket
20
- lang = lang.split("-")[1];
22
+ lang = lang.match(/(?<=-)(\w|-)*/i)[0];
21
23
  if(lang == "undefined") {
22
24
  codeInput.removeAttribute("language");
23
25
  codeInput.removeAttribute("lang");
@@ -25,4 +27,4 @@ codeInput.plugins.Autodetect = class extends codeInput.Plugin {
25
27
  codeInput.setAttribute("language", lang);
26
28
  }
27
29
  }
28
- }
30
+ }
@@ -1 +1 @@
1
- codeInput.plugins.Autodetect=class extends codeInput.Plugin{constructor(){super([])}beforeHighlight(a){let b=a.codeElement;b.className="",b.parentElement.className=""}afterHighlight(a){let b=a.codeElement.className||a.preElement.className,c=b.match(/lang(\w|-)*/i)[0];c=c.split("-")[1],"undefined"==c?(a.removeAttribute("language"),a.removeAttribute("lang")):a.setAttribute("language",c)}};
1
+ "use strict";codeInput.plugins.Autodetect=class extends codeInput.Plugin{constructor(){super([])}beforeHighlight(a){let b=a.codeElement;b.className="",b.parentElement.className=""}afterHighlight(a){let b=a.codeElement.className||a.preElement.className,c=b.match(/lang(\w|-)*/i)[0];c=c.match(/(?<=-)(\w|-)*/i)[0],"undefined"==c?(a.removeAttribute("language"),a.removeAttribute("lang")):a.setAttribute("language",c)}};
@@ -60,10 +60,6 @@
60
60
  border: 0;
61
61
  }
62
62
 
63
- .code-input_find-and-replace_dialog input:hover {
64
- outline: none;
65
- }
66
-
67
63
  .code-input_find-and-replace_dialog input.code-input_find-and-replace_error {
68
64
  color: #ff0000aa;
69
65
  }
@@ -2,6 +2,8 @@
2
2
  * Add Find-and-Replace (Ctrl+F for find, Ctrl+H for replace by default) functionality to the code editor.
3
3
  * Files: find-and-replace.js / find-and-replace.css
4
4
  */
5
+ "use strict";
6
+
5
7
  codeInput.plugins.FindAndReplace = class extends codeInput.Plugin {
6
8
  useCtrlF = false;
7
9
  useCtrlH = false;
@@ -31,8 +33,8 @@ codeInput.plugins.FindAndReplace = class extends codeInput.Plugin {
31
33
 
32
34
  /**
33
35
  * Create a find-and-replace command plugin to pass into a template
34
- * @param {boolean} useCtrlF Should Ctrl+F be overriden for find-and-replace find functionality? If not, you can trigger it yourself using (instance of this plugin)`.showPrompt(code-input element, false)`.
35
- * @param {boolean} useCtrlH Should Ctrl+H be overriden for find-and-replace replace functionality? If not, you can trigger it yourself using (instance of this plugin)`.showPrompt(code-input element, true)`.
36
+ * @param {boolean} useCtrlF Should Ctrl+F be overriden for find-and-replace find functionality? Either way, you can also trigger it yourself using (instance of this plugin)`.showPrompt(code-input element, false)`.
37
+ * @param {boolean} useCtrlH Should Ctrl+H be overriden for find-and-replace replace functionality? Either way, you can also trigger it yourself using (instance of this plugin)`.showPrompt(code-input element, true)`.
36
38
  * @param {Object} instructionTranslations: user interface string keys mapped to translated versions for localisation. Look at the find-and-replace.js source code for the English text and available keys.
37
39
  */
38
40
  constructor(useCtrlF = true, useCtrlH = true, instructionTranslations = {}) {
@@ -192,6 +194,7 @@ codeInput.plugins.FindAndReplace = class extends codeInput.Plugin {
192
194
  const findInput = document.createElement('input');
193
195
  const findCaseSensitiveCheckbox = document.createElement('input');
194
196
  const findRegExpCheckbox = document.createElement('input');
197
+ // TODO in next major version: use more semantic HTML element than code
195
198
  const matchDescription = document.createElement('code');
196
199
  matchDescription.setAttribute("aria-live", "assertive"); // Screen reader must read the number of matches found.
197
200
 
@@ -238,7 +241,7 @@ codeInput.plugins.FindAndReplace = class extends codeInput.Plugin {
238
241
  findRegExpCheckbox.title = this.instructions.findRegExp;
239
242
  findRegExpCheckbox.classList.add("code-input_find-and-replace_reg-exp-checkbox");
240
243
 
241
- matchDescription.textContent = "Search for matches in your code.";
244
+ matchDescription.textContent = this.instructions.start;
242
245
  matchDescription.classList.add("code-input_find-and-replace_match-description");
243
246
 
244
247
 
@@ -623,11 +626,28 @@ codeInput.plugins.FindAndReplace.FindMatchState = class {
623
626
  }
624
627
  }
625
628
 
626
- /* Highlight a match from the find functionality given its start and end indexes in the text.
627
- Start from the currentElement as this function is recursive. Use the matchID in the class name
629
+ /* Highlight a match from the find functionality given its start and end indexes in the text.
630
+ Start from the currentElement. Use the matchID in the class name
628
631
  of the match so different matches can be identified.
629
- This code is similar to codeInput.plugins.SelectTokenCallbacks.SelectedTokenState.updateSelectedTokens*/
632
+ */
630
633
  highlightMatch(matchID, currentElement, startIndex, endIndex) {
634
+ const lines = currentElement.textContent.substring(startIndex, endIndex).split("\n");
635
+ let lineStartIndex = startIndex;
636
+ for(let i = 0; i < lines.length; i++) {
637
+ if(i == 0) {
638
+ this.highlightMatchNewlineOnlyAtStart(matchID, currentElement, lineStartIndex, lineStartIndex+lines[i].length);
639
+ } else {
640
+ // Include previous newline character too
641
+ this.highlightMatchNewlineOnlyAtStart(matchID, currentElement, lineStartIndex-1, lineStartIndex+lines[i].length);
642
+ }
643
+
644
+ lineStartIndex += lines[i].length + 1; // +1 for newline character
645
+ }
646
+ }
647
+
648
+ /* Same as highlightMatch, but assumes any newlines in the
649
+ match are at the startIndex (for simpler code). */
650
+ highlightMatchNewlineOnlyAtStart(matchID, currentElement, startIndex, endIndex) {
631
651
  for(let i = 0; i < currentElement.childNodes.length; i++) {
632
652
  let childElement = currentElement.childNodes[i];
633
653
  let childText = childElement.textContent;
@@ -676,7 +696,7 @@ codeInput.plugins.FindAndReplace.FindMatchState = class {
676
696
  i++; // An extra element has been added
677
697
  return;
678
698
  } else {
679
- this.highlightMatch(matchID, childElement, 0, endIndex);
699
+ this.highlightMatchNewlineOnlyAtStart(matchID, childElement, 0, endIndex);
680
700
  }
681
701
 
682
702
  // Match ended - nothing to do after backtracking
@@ -735,7 +755,7 @@ codeInput.plugins.FindAndReplace.FindMatchState = class {
735
755
  i++; // An extra element has been added
736
756
  }
737
757
  } else {
738
- this.highlightMatch(matchID, childElement, startIndex, endIndex);
758
+ this.highlightMatchNewlineOnlyAtStart(matchID, childElement, startIndex, endIndex);
739
759
  }
740
760
 
741
761
  if(childText.length > endIndex) {
@@ -1 +1 @@
1
- .code-input_find-and-replace_find-match{color:inherit;text-shadow:none!important;background-color:#ff0!important}.code-input_find-and-replace_find-match-focused,.code-input_find-and-replace_find-match-focused *{background-color:#f80!important;color:#000!important}.code-input_find-and-replace_start-newline::before{content:"⤶"}@keyframes code-input_find-and-replace_roll-in{0%{opacity:0;transform:translateY(-34px)}100%{opacity:1;transform:translateY(0)}}@keyframes code-input_find-and-replace_roll-out{0%{opacity:1;top:0}100%{opacity:0;top:-34px}}.code-input_find-and-replace_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_find-and-replace_dialog:not(.code-input_find-and-replace_hidden-dialog){animation:code-input_find-and-replace_roll-in .2s;opacity:1;pointer-events:all}.code-input_find-and-replace_dialog.code-input_find-and-replace_hidden-dialog{animation:code-input_find-and-replace_roll-out .2s;opacity:0;pointer-events:none}.code-input_find-and-replace_dialog input::placeholder{font-size:80%}.code-input_find-and-replace_dialog input{position:relative;width:240px;height:32px;top:-3px;font-size:large;color:#000000aa;border:0}.code-input_find-and-replace_dialog input:hover{outline:0}.code-input_find-and-replace_dialog input.code-input_find-and-replace_error{color:#ff0000aa}.code-input_find-and-replace_dialog button,.code-input_find-and-replace_dialog input[type=checkbox]{display:inline-block;line-height:24px;font-size:22px;cursor:pointer;appearance:none;width:min-content;margin:5px;padding:5px;border:0;background-color:#ddd;text-align:center;color:#000;vertical-align:top}.code-input_find-and-replace_dialog input[type=checkbox].code-input_find-and-replace_case-sensitive-checkbox::before{content:"Aa"}.code-input_find-and-replace_dialog input[type=checkbox].code-input_find-and-replace_reg-exp-checkbox::before{content:".*"}.code-input_find-and-replace_dialog button:hover,.code-input_find-and-replace_dialog input[type=checkbox]:hover{background-color:#bbb}.code-input_find-and-replace_dialog input[type=checkbox]:checked{background-color:#222;color:#fff}.code-input_find-and-replace_match-description{display:block;color:#444}.code-input_find-and-replace_dialog button,.code-input_find-and-replace_dialog details summary{cursor:pointer}.code-input_find-and-replace_dialog button.code-input_find-and-replace_button-hidden{opacity:0;pointer-events:none}.code-input_find-and-replace_dialog span{display:block;float:right;margin:5px;padding:5px;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}.code-input_find-and-replace_dialog span:before{content:"\00d7"}.code-input_find-and-replace_dialog span:hover{opacity:.8;background-color:#00000018}
1
+ .code-input_find-and-replace_find-match{color:inherit;text-shadow:none!important;background-color:#ff0!important}.code-input_find-and-replace_find-match-focused,.code-input_find-and-replace_find-match-focused *{background-color:#f80!important;color:#000!important}.code-input_find-and-replace_start-newline::before{content:"⤶"}@keyframes code-input_find-and-replace_roll-in{0%{opacity:0;transform:translateY(-34px)}100%{opacity:1;transform:translateY(0)}}@keyframes code-input_find-and-replace_roll-out{0%{opacity:1;top:0}100%{opacity:0;top:-34px}}.code-input_find-and-replace_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_find-and-replace_dialog:not(.code-input_find-and-replace_hidden-dialog){animation:code-input_find-and-replace_roll-in .2s;opacity:1;pointer-events:all}.code-input_find-and-replace_dialog.code-input_find-and-replace_hidden-dialog{animation:code-input_find-and-replace_roll-out .2s;opacity:0;pointer-events:none}.code-input_find-and-replace_dialog input::placeholder{font-size:80%}.code-input_find-and-replace_dialog input{position:relative;width:240px;height:32px;top:-3px;font-size:large;color:#000000aa;border:0}.code-input_find-and-replace_dialog input.code-input_find-and-replace_error{color:#ff0000aa}.code-input_find-and-replace_dialog button,.code-input_find-and-replace_dialog input[type=checkbox]{display:inline-block;line-height:24px;font-size:22px;cursor:pointer;appearance:none;width:min-content;margin:5px;padding:5px;border:0;background-color:#ddd;text-align:center;color:#000;vertical-align:top}.code-input_find-and-replace_dialog input[type=checkbox].code-input_find-and-replace_case-sensitive-checkbox::before{content:"Aa"}.code-input_find-and-replace_dialog input[type=checkbox].code-input_find-and-replace_reg-exp-checkbox::before{content:".*"}.code-input_find-and-replace_dialog button:hover,.code-input_find-and-replace_dialog input[type=checkbox]:hover{background-color:#bbb}.code-input_find-and-replace_dialog input[type=checkbox]:checked{background-color:#222;color:#fff}.code-input_find-and-replace_match-description{display:block;color:#444}.code-input_find-and-replace_dialog button,.code-input_find-and-replace_dialog details summary{cursor:pointer}.code-input_find-and-replace_dialog button.code-input_find-and-replace_button-hidden{opacity:0;pointer-events:none}.code-input_find-and-replace_dialog span{display:block;float:right;margin:5px;padding:5px;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}.code-input_find-and-replace_dialog span:before{content:"\00d7"}.code-input_find-and-replace_dialog span:hover{opacity:.8;background-color:#00000018}
@@ -1 +1 @@
1
- codeInput.plugins.FindAndReplace=class extends codeInput.Plugin{useCtrlF=!1;useCtrlH=!1;findMatchesOnValueChange=!0;instructions={start:"Search for matches in your code.",none:"No matches",oneFound:"1 match found.",matchIndex:(a,b)=>`${a} of ${b} matches.`,error:a=>`Error: ${a}`,infiniteLoopError:"Causes an infinite loop",closeDialog:"Close Dialog and Return to Editor",findPlaceholder:"Find",findCaseSensitive:"Match Case Sensitive",findRegExp:"Use JavaScript Regular Expression",replaceTitle:"Replace",replacePlaceholder:"Replace with",findNext:"Find Next Occurrence",findPrevious:"Find Previous Occurrence",replaceActionShort:"Replace",replaceAction:"Replace This Occurrence",replaceAllActionShort:"Replace All",replaceAllAction:"Replace All Occurrences"};constructor(a=!0,b=!0,c={}){super([]),this.useCtrlF=a,this.useCtrlH=b,this.addTranslations(this.instructions,c)}afterElementsAdded(a){const b=a.textareaElement;this.useCtrlF&&b.addEventListener("keydown",b=>{this.checkCtrlF(a,b)}),this.useCtrlH&&b.addEventListener("keydown",b=>{this.checkCtrlH(a,b)})}afterHighlight(a){a.pluginData.findAndReplace==null||a.pluginData.findAndReplace.dialog==null||a.pluginData.findAndReplace.dialog.classList.contains("code-input_find-and-replace_hidden-dialog")||(a.pluginData.findAndReplace.dialog.findMatchState.rehighlightMatches(),this.updateMatchDescription(a.pluginData.findAndReplace.dialog),0==a.pluginData.findAndReplace.dialog.findMatchState.numMatches&&a.pluginData.findAndReplace.dialog.findInput.classList.add("code-input_find-and-replace_error"))}text2RegExp(a,b,c){return new RegExp(c?a:a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),b?"g":"gi")}updateMatchDescription(a){a.matchDescription.textContent=0==a.findInput.value.length?this.instructions.start:0>=a.findMatchState.numMatches?this.instructions.none:1==a.findMatchState.numMatches?this.instructions.oneFound:this.instructions.matchIndex(a.findMatchState.focusedMatchID+1,a.findMatchState.numMatches)}updateFindMatches(a){let b=a.findInput.value;setTimeout(()=>{if(b==a.findInput.value){if(a.findMatchState.clearMatches(),0<b.length){try{a.findMatchState.updateMatches(this.text2RegExp(a.findInput.value,a.findCaseSensitiveCheckbox.checked,a.findRegExpCheckbox.checked))}catch(b){if(b instanceof SyntaxError){a.findInput.classList.add("code-input_find-and-replace_error");let c=b.message.split(": ");return void(a.matchDescription.textContent=this.instructions.error(c[c.length-1]))}throw b}0<a.findMatchState.numMatches?a.findInput.classList.remove("code-input_find-and-replace_error"):a.findInput.classList.add("code-input_find-and-replace_error")}this.updateMatchDescription(a)}},100)}checkFindPrompt(a,b,c){"Enter"==c.key&&(a.findMatchState.nextMatch(),this.updateMatchDescription(a))}checkReplacePrompt(a,b,c){"Enter"==c.key&&(a.findMatchState.replaceOnce(a.replaceInput.value),a.replaceInput.focus(),this.updateMatchDescription(a))}cancelPrompt(a,b,c){c.preventDefault(),this.findMatchesOnValueChange=!1,a.findInput.focus(),a.findInput.selectionStart=0,a.findInput.selectionEnd=a.findInput.value.length,document.execCommand("insertText",!1,a.findInput.value),this.findMatchesOnValueChange=!0,a.textarea.focus(),a.setAttribute("inert",!0),a.setAttribute("tabindex",-1),a.setAttribute("aria-hidden",!0),0<a.findMatchState.numMatches?(b.textareaElement.selectionStart=a.findMatchState.matchStartIndexes[a.findMatchState.focusedMatchID],b.textareaElement.selectionEnd=a.findMatchState.matchEndIndexes[a.findMatchState.focusedMatchID]):(b.textareaElement.selectionStart=a.selectionStart,b.textareaElement.selectionEnd=a.selectionEnd),a.findMatchState.clearMatches(),a.classList.add("code-input_find-and-replace_hidden-dialog")}showPrompt(a,b){let c;if(null==a.pluginData.findAndReplace||null==a.pluginData.findAndReplace.dialog){const d=a.textareaElement;c=document.createElement("div");const e=document.createElement("input"),f=document.createElement("input"),g=document.createElement("input"),h=document.createElement("code");h.setAttribute("aria-live","assertive");const i=document.createElement("input"),j=document.createElement("details"),k=document.createElement("summary"),l=document.createElement("div"),m=document.createElement("button"),n=document.createElement("button"),o=document.createElement("button"),p=document.createElement("button"),q=document.createElement("span");if(q.setAttribute("role","button"),q.setAttribute("aria-label",this.instructions.closeDialog),q.setAttribute("tabindex",0),q.setAttribute("title",this.instructions.closeDialog),l.appendChild(m),l.appendChild(n),l.appendChild(o),l.appendChild(p),l.appendChild(q),c.appendChild(l),c.appendChild(e),c.appendChild(g),c.appendChild(f),c.appendChild(h),j.appendChild(k),j.appendChild(i),c.appendChild(j),c.className="code-input_find-and-replace_dialog",e.spellcheck=!1,e.placeholder=this.instructions.findPlaceholder,f.setAttribute("type","checkbox"),f.title=this.instructions.findCaseSensitive,f.classList.add("code-input_find-and-replace_case-sensitive-checkbox"),g.setAttribute("type","checkbox"),g.title=this.instructions.findRegExp,g.classList.add("code-input_find-and-replace_reg-exp-checkbox"),h.textContent="Search for matches in your code.",h.classList.add("code-input_find-and-replace_match-description"),k.innerText=this.instructions.replaceTitle,i.spellcheck=!1,i.placeholder=this.instructions.replacePlaceholder,m.innerText="\u2193",m.title=this.instructions.findNext,m.setAttribute("aria-label",this.instructions.findNext),n.innerText="\u2191",n.title=this.instructions.findPrevious,m.setAttribute("aria-label",this.instructions.findPrevious),o.className="code-input_find-and-replace_button-hidden",o.innerText=this.instructions.replaceActionShort,o.title=this.instructions.replaceAction,o.addEventListener("focus",()=>{j.setAttribute("open",!0)}),p.className="code-input_find-and-replace_button-hidden",p.innerText=this.instructions.replaceAllActionShort,p.title=this.instructions.replaceAllAction,p.addEventListener("focus",()=>{j.setAttribute("open",!0)}),m.addEventListener("click",a=>{a.preventDefault(),c.findMatchState.nextMatch(),this.updateMatchDescription(c)}),n.addEventListener("click",()=>{event.preventDefault(),c.findMatchState.previousMatch(),this.updateMatchDescription(c)}),o.addEventListener("click",a=>{a.preventDefault(),c.findMatchState.replaceOnce(i.value),c.focus()}),p.addEventListener("click",a=>{a.preventDefault(),c.findMatchState.replaceAll(i.value),p.focus()}),j.addEventListener("toggle",()=>{o.classList.toggle("code-input_find-and-replace_button-hidden"),p.classList.toggle("code-input_find-and-replace_button-hidden")}),c.findMatchState=new codeInput.plugins.FindAndReplace.FindMatchState(a),c.codeInput=a,c.textarea=d,c.findInput=e,c.findCaseSensitiveCheckbox=f,c.findRegExpCheckbox=g,c.matchDescription=h,c.replaceInput=i,c.replaceDropdown=j,this.checkCtrlH&&e.addEventListener("keydown",a=>{a.ctrlKey&&"h"==a.key&&(a.preventDefault(),j.setAttribute("open",!0))}),e.addEventListener("keypress",a=>{"Enter"==a.key&&a.preventDefault()}),i.addEventListener("keypress",a=>{"Enter"==a.key&&a.preventDefault()}),i.addEventListener("input",()=>{c.classList.contains("code-input_find-and-replace_hidden-dialog")?this.showPrompt(c.codeInput,!0):!c.replaceDropdown.hasAttribute("open")&&c.replaceDropdown.setAttribute("open",!0)}),c.addEventListener("keyup",b=>{"Escape"==b.key&&this.cancelPrompt(c,a,b)}),e.addEventListener("keyup",b=>{this.checkFindPrompt(c,a,b)}),e.addEventListener("input",()=>{this.findMatchesOnValueChange&&this.updateFindMatches(c),c.classList.contains("code-input_find-and-replace_hidden-dialog")&&this.showPrompt(c.codeInput,!1)}),f.addEventListener("click",()=>{this.updateFindMatches(c)}),g.addEventListener("click",()=>{this.updateFindMatches(c)}),i.addEventListener("keyup",b=>{this.checkReplacePrompt(c,a,b),i.focus()}),q.addEventListener("click",b=>{this.cancelPrompt(c,a,b)}),q.addEventListener("keypress",b=>{("Space"==b.key||"Enter"==b.key)&&this.cancelPrompt(c,a,b)}),a.dialogContainerElement.appendChild(c),a.pluginData.findAndReplace={dialog:c},e.focus(),b&&j.setAttribute("open",!0),c.selectionStart=a.textareaElement.selectionStart,c.selectionEnd=a.textareaElement.selectionEnd,c.selectionStart<c.selectionEnd){let b=a.textareaElement.value.substring(c.selectionStart,c.selectionEnd);c.findInput.focus(),c.findInput.selectionStart=0,c.findInput.selectionEnd=c.findInput.value.length,document.execCommand("insertText",!1,b)}}else c=a.pluginData.findAndReplace.dialog,c.classList.remove("code-input_find-and-replace_hidden-dialog"),c.removeAttribute("inert"),c.setAttribute("tabindex",0),c.removeAttribute("aria-hidden"),c.findInput.focus(),b?c.replaceDropdown.setAttribute("open",!0):c.replaceDropdown.removeAttribute("open");if(c.selectionStart=a.textareaElement.selectionStart,c.selectionEnd=a.textareaElement.selectionEnd,c.selectionStart<c.selectionEnd){let b=a.textareaElement.value.substring(c.selectionStart,c.selectionEnd);c.findInput.focus(),c.findInput.selectionStart=0,c.findInput.selectionEnd=c.findInput.value.length,document.execCommand("insertText",!1,b)}this.updateFindMatches(c)}checkCtrlF(a,b){b.ctrlKey&&"f"==b.key&&(b.preventDefault(),this.showPrompt(a,!1))}checkCtrlH(a,b){b.ctrlKey&&"h"==b.key&&(b.preventDefault(),this.showPrompt(a,!0))}};const CODE_INPUT_FIND_AND_REPLACE_MATCH_BLOCK_SIZE=500;codeInput.plugins.FindAndReplace.FindMatchState=class{codeInput=null;lastValue=null;lastSearchRegexp=null;numMatches=0;focusedMatchID=0;matchStartIndexes=[];matchEndIndexes=[];focusedMatchStartIndex=0;matchBlocksHighlighted=[];constructor(a){this.focusedMatchStartIndex=a.textareaElement.selectionStart,this.codeInput=a}clearMatches(){this.numMatches=0,this.matchStartIndexes=[],this.matchEndIndexes=[];let a=this.codeInput.codeElement.querySelectorAll(".code-input_find-and-replace_temporary-span");for(let b=0;b<a.length;b++)a[b].parentElement.replaceChild(new Text(a[b].textContent),a[b]);let b=this.codeInput.codeElement.querySelectorAll(".code-input_find-and-replace_find-match");for(let a=0;a<b.length;a++)b[a].removeAttribute("data-code-input_find-and-replace_match-id"),b[a].classList.remove("code-input_find-and-replace_find-match"),b[a].classList.remove("code-input_find-and-replace_find-match-focused")}updateMatches(a){var b=Math.floor;this.lastSearchRegexp=a,this.lastValue=this.codeInput.value;let c,d=0;this.matchStartIndexes=[],this.matchEndIndexes=[],this.matchBlocksHighlighted=[];let e=b(this.focusedMatchID/CODE_INPUT_FIND_AND_REPLACE_MATCH_BLOCK_SIZE);for(let b=0;b<e;b++)this.matchBlocksHighlighted.push(!1);for(this.matchBlocksHighlighted.push(!0);null!==(c=a.exec(this.codeInput.value));){let a=c[0];if(0==a.length)throw SyntaxError(this.instructions.infiniteLoopError);let e=b(d/CODE_INPUT_FIND_AND_REPLACE_MATCH_BLOCK_SIZE);this.matchBlocksHighlighted.length<e&&this.matchBlocksHighlighted.push(!1),this.matchBlocksHighlighted[e]&&this.highlightMatch(d,this.codeInput.codeElement,c.index,c.index+a.length),this.matchStartIndexes.push(c.index),this.matchEndIndexes.push(c.index+a.length),d++}this.numMatches=d,0<this.numMatches&&this.focusMatch()}rehighlightMatches(){this.updateMatches(this.lastSearchRegexp),this.focusMatch()}replaceOnce(a){0<this.numMatches&&a!=this.codeInput.value.substring(0,this.matchStartIndexes[this.focusedMatchID],this.matchEndIndexes[this.focusedMatchID])&&(this.focusedMatchStartIndex+=a.length,this.codeInput.handleEventsFromTextarea=!1,this.codeInput.textareaElement.focus(),this.codeInput.textareaElement.selectionStart=this.matchStartIndexes[this.focusedMatchID],this.codeInput.textareaElement.selectionEnd=this.matchEndIndexes[this.focusedMatchID],document.execCommand("insertText",!1,a),this.codeInput.handleEventsFromTextarea=!0)}replaceAll(a){const b=a.length;let c=0;for(let d=0;d<this.numMatches;d++)this.codeInput.handleEventsFromTextarea=!1,this.codeInput.textareaElement.focus(),this.codeInput.textareaElement.selectionStart=this.matchStartIndexes[d]+c,this.codeInput.textareaElement.selectionEnd=this.matchEndIndexes[d]+c,c+=b-(this.matchEndIndexes[d]-this.matchStartIndexes[d]),document.execCommand("insertText",!1,a),this.codeInput.handleEventsFromTextarea=!0}nextMatch(){this.focusMatch((this.focusedMatchID+1)%this.numMatches)}previousMatch(){this.focusMatch((this.focusedMatchID+this.numMatches-1)%this.numMatches)}focusMatch(a=void 0){if(a===void 0){for(a=0;a<this.matchStartIndexes.length&&this.matchStartIndexes[a]<this.focusedMatchStartIndex;)a++;a>=this.matchStartIndexes.length&&(a=0)}this.focusedMatchStartIndex=this.matchStartIndexes[a],this.focusedMatchID=a;let b=this.codeInput.codeElement.querySelectorAll(".code-input_find-and-replace_find-match-focused");for(let c=0;c<b.length;c++)b[c].classList.remove("code-input_find-and-replace_find-match-focused");let c=Math.floor(a/CODE_INPUT_FIND_AND_REPLACE_MATCH_BLOCK_SIZE);if(!this.matchBlocksHighlighted[c]){this.matchBlocksHighlighted[c]=!0;for(let a=CODE_INPUT_FIND_AND_REPLACE_MATCH_BLOCK_SIZE*c;a<CODE_INPUT_FIND_AND_REPLACE_MATCH_BLOCK_SIZE*(c+1);a++)this.highlightMatch(a,this.codeInput.codeElement,this.matchStartIndexes[a],this.matchEndIndexes[a])}let d=this.codeInput.codeElement.querySelectorAll(`.code-input_find-and-replace_find-match[data-code-input_find-and-replace_match-id="${a}"]`);for(let b=0;b<d.length;b++)d[b].classList.add("code-input_find-and-replace_find-match-focused");0<d.length&&this.codeInput.scrollTo(d[0].offsetLeft-this.codeInput.offsetWidth/2,d[0].offsetTop-this.codeInput.offsetHeight/2)}highlightMatch(a,b,c,d){for(let e=0;e<b.childNodes.length;e++){let f=b.childNodes[e],g=f.textContent,h=!1;if(3==f.nodeType){if(e+1<b.childNodes.length&&3==b.childNodes[e+1].nodeType){b.childNodes[e+1].textContent=f.textContent+b.childNodes[e+1].textContent,b.removeChild(f),e--;continue}h=!0;let a=document.createElement("span");a.textContent=g,a.classList.add("code-input_find-and-replace_temporary-span"),b.replaceChild(a,f),f=a}if(0>=c){if(g.length>=d){if(h){let b=document.createElement("span");b.classList.add("code-input_find-and-replace_find-match"),b.setAttribute("data-code-input_find-and-replace_match-id",a),b.classList.add("code-input_find-and-replace_temporary-span"),b.textContent=g.substring(0,d),"\n"==b.textContent[0]&&b.classList.add("code-input_find-and-replace_start-newline");let c=g.substring(d);return f.textContent=c,f.insertAdjacentElement("beforebegin",b),void e++}return void this.highlightMatch(a,f,0,d)}f.classList.add("code-input_find-and-replace_find-match"),f.setAttribute("data-code-input_find-and-replace_match-id",a),"\n"==f.textContent[0]&&f.classList.add("code-input_find-and-replace_start-newline")}else if(g.length>c){if(!h)this.highlightMatch(a,f,c,d);else if(g.length>d){let b=document.createElement("span");b.classList.add("code-input_find-and-replace_temporary-span"),b.textContent=g.substring(0,c);let h=g.substring(c,d);f.textContent=h,f.classList.add("code-input_find-and-replace_find-match"),f.setAttribute("data-code-input_find-and-replace_match-id",a),"\n"==f.textContent[0]&&f.classList.add("code-input_find-and-replace_start-newline");let i=document.createElement("span");i.classList.add("code-input_find-and-replace_temporary-span"),i.textContent=g.substring(d),f.insertAdjacentElement("beforebegin",b),f.insertAdjacentElement("afterend",i),e++}else{let b=g.substring(0,c);f.textContent=b;let d=document.createElement("span");d.classList.add("code-input_find-and-replace_find-match"),d.setAttribute("data-code-input_find-and-replace_match-id",a),d.classList.add("code-input_find-and-replace_temporary-span"),d.textContent=g.substring(c),"\n"==d.textContent[0]&&d.classList.add("code-input_find-and-replace_start-newline"),f.insertAdjacentElement("afterend",d),e++}if(g.length>d)return}c-=g.length,d-=g.length}}};
1
+ "use strict";codeInput.plugins.FindAndReplace=class extends codeInput.Plugin{useCtrlF=!1;useCtrlH=!1;findMatchesOnValueChange=!0;instructions={start:"Search for matches in your code.",none:"No matches",oneFound:"1 match found.",matchIndex:(a,b)=>`${a} of ${b} matches.`,error:a=>`Error: ${a}`,infiniteLoopError:"Causes an infinite loop",closeDialog:"Close Dialog and Return to Editor",findPlaceholder:"Find",findCaseSensitive:"Match Case Sensitive",findRegExp:"Use JavaScript Regular Expression",replaceTitle:"Replace",replacePlaceholder:"Replace with",findNext:"Find Next Occurrence",findPrevious:"Find Previous Occurrence",replaceActionShort:"Replace",replaceAction:"Replace This Occurrence",replaceAllActionShort:"Replace All",replaceAllAction:"Replace All Occurrences"};constructor(a=!0,b=!0,c={}){super([]),this.useCtrlF=a,this.useCtrlH=b,this.addTranslations(this.instructions,c)}afterElementsAdded(a){const b=a.textareaElement;this.useCtrlF&&b.addEventListener("keydown",b=>{this.checkCtrlF(a,b)}),this.useCtrlH&&b.addEventListener("keydown",b=>{this.checkCtrlH(a,b)})}afterHighlight(a){a.pluginData.findAndReplace==null||a.pluginData.findAndReplace.dialog==null||a.pluginData.findAndReplace.dialog.classList.contains("code-input_find-and-replace_hidden-dialog")||(a.pluginData.findAndReplace.dialog.findMatchState.rehighlightMatches(),this.updateMatchDescription(a.pluginData.findAndReplace.dialog),0==a.pluginData.findAndReplace.dialog.findMatchState.numMatches&&a.pluginData.findAndReplace.dialog.findInput.classList.add("code-input_find-and-replace_error"))}text2RegExp(a,b,c){return new RegExp(c?a:a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),b?"g":"gi")}updateMatchDescription(a){a.matchDescription.textContent=0==a.findInput.value.length?this.instructions.start:0>=a.findMatchState.numMatches?this.instructions.none:1==a.findMatchState.numMatches?this.instructions.oneFound:this.instructions.matchIndex(a.findMatchState.focusedMatchID+1,a.findMatchState.numMatches)}updateFindMatches(a){let b=a.findInput.value;setTimeout(()=>{if(b==a.findInput.value){if(a.findMatchState.clearMatches(),0<b.length){try{a.findMatchState.updateMatches(this.text2RegExp(a.findInput.value,a.findCaseSensitiveCheckbox.checked,a.findRegExpCheckbox.checked))}catch(b){if(b instanceof SyntaxError){a.findInput.classList.add("code-input_find-and-replace_error");let c=b.message.split(": ");return void(a.matchDescription.textContent=this.instructions.error(c[c.length-1]))}throw b}0<a.findMatchState.numMatches?a.findInput.classList.remove("code-input_find-and-replace_error"):a.findInput.classList.add("code-input_find-and-replace_error")}this.updateMatchDescription(a)}},100)}checkFindPrompt(a,b,c){"Enter"==c.key&&(a.findMatchState.nextMatch(),this.updateMatchDescription(a))}checkReplacePrompt(a,b,c){"Enter"==c.key&&(a.findMatchState.replaceOnce(a.replaceInput.value),a.replaceInput.focus(),this.updateMatchDescription(a))}cancelPrompt(a,b,c){c.preventDefault(),this.findMatchesOnValueChange=!1,a.findInput.focus(),a.findInput.selectionStart=0,a.findInput.selectionEnd=a.findInput.value.length,document.execCommand("insertText",!1,a.findInput.value),this.findMatchesOnValueChange=!0,a.textarea.focus(),a.setAttribute("inert",!0),a.setAttribute("tabindex",-1),a.setAttribute("aria-hidden",!0),0<a.findMatchState.numMatches?(b.textareaElement.selectionStart=a.findMatchState.matchStartIndexes[a.findMatchState.focusedMatchID],b.textareaElement.selectionEnd=a.findMatchState.matchEndIndexes[a.findMatchState.focusedMatchID]):(b.textareaElement.selectionStart=a.selectionStart,b.textareaElement.selectionEnd=a.selectionEnd),a.findMatchState.clearMatches(),a.classList.add("code-input_find-and-replace_hidden-dialog")}showPrompt(a,b){let c;if(null==a.pluginData.findAndReplace||null==a.pluginData.findAndReplace.dialog){const d=a.textareaElement;c=document.createElement("div");const e=document.createElement("input"),f=document.createElement("input"),g=document.createElement("input"),h=document.createElement("code");h.setAttribute("aria-live","assertive");const i=document.createElement("input"),j=document.createElement("details"),k=document.createElement("summary"),l=document.createElement("div"),m=document.createElement("button"),n=document.createElement("button"),o=document.createElement("button"),p=document.createElement("button"),q=document.createElement("span");if(q.setAttribute("role","button"),q.setAttribute("aria-label",this.instructions.closeDialog),q.setAttribute("tabindex",0),q.setAttribute("title",this.instructions.closeDialog),l.appendChild(m),l.appendChild(n),l.appendChild(o),l.appendChild(p),l.appendChild(q),c.appendChild(l),c.appendChild(e),c.appendChild(g),c.appendChild(f),c.appendChild(h),j.appendChild(k),j.appendChild(i),c.appendChild(j),c.className="code-input_find-and-replace_dialog",e.spellcheck=!1,e.placeholder=this.instructions.findPlaceholder,f.setAttribute("type","checkbox"),f.title=this.instructions.findCaseSensitive,f.classList.add("code-input_find-and-replace_case-sensitive-checkbox"),g.setAttribute("type","checkbox"),g.title=this.instructions.findRegExp,g.classList.add("code-input_find-and-replace_reg-exp-checkbox"),h.textContent=this.instructions.start,h.classList.add("code-input_find-and-replace_match-description"),k.innerText=this.instructions.replaceTitle,i.spellcheck=!1,i.placeholder=this.instructions.replacePlaceholder,m.innerText="\u2193",m.title=this.instructions.findNext,m.setAttribute("aria-label",this.instructions.findNext),n.innerText="\u2191",n.title=this.instructions.findPrevious,m.setAttribute("aria-label",this.instructions.findPrevious),o.className="code-input_find-and-replace_button-hidden",o.innerText=this.instructions.replaceActionShort,o.title=this.instructions.replaceAction,o.addEventListener("focus",()=>{j.setAttribute("open",!0)}),p.className="code-input_find-and-replace_button-hidden",p.innerText=this.instructions.replaceAllActionShort,p.title=this.instructions.replaceAllAction,p.addEventListener("focus",()=>{j.setAttribute("open",!0)}),m.addEventListener("click",a=>{a.preventDefault(),c.findMatchState.nextMatch(),this.updateMatchDescription(c)}),n.addEventListener("click",()=>{event.preventDefault(),c.findMatchState.previousMatch(),this.updateMatchDescription(c)}),o.addEventListener("click",a=>{a.preventDefault(),c.findMatchState.replaceOnce(i.value),c.focus()}),p.addEventListener("click",a=>{a.preventDefault(),c.findMatchState.replaceAll(i.value),p.focus()}),j.addEventListener("toggle",()=>{o.classList.toggle("code-input_find-and-replace_button-hidden"),p.classList.toggle("code-input_find-and-replace_button-hidden")}),c.findMatchState=new codeInput.plugins.FindAndReplace.FindMatchState(a),c.codeInput=a,c.textarea=d,c.findInput=e,c.findCaseSensitiveCheckbox=f,c.findRegExpCheckbox=g,c.matchDescription=h,c.replaceInput=i,c.replaceDropdown=j,this.checkCtrlH&&e.addEventListener("keydown",a=>{a.ctrlKey&&"h"==a.key&&(a.preventDefault(),j.setAttribute("open",!0))}),e.addEventListener("keypress",a=>{"Enter"==a.key&&a.preventDefault()}),i.addEventListener("keypress",a=>{"Enter"==a.key&&a.preventDefault()}),i.addEventListener("input",()=>{c.classList.contains("code-input_find-and-replace_hidden-dialog")?this.showPrompt(c.codeInput,!0):!c.replaceDropdown.hasAttribute("open")&&c.replaceDropdown.setAttribute("open",!0)}),c.addEventListener("keyup",b=>{"Escape"==b.key&&this.cancelPrompt(c,a,b)}),e.addEventListener("keyup",b=>{this.checkFindPrompt(c,a,b)}),e.addEventListener("input",()=>{this.findMatchesOnValueChange&&this.updateFindMatches(c),c.classList.contains("code-input_find-and-replace_hidden-dialog")&&this.showPrompt(c.codeInput,!1)}),f.addEventListener("click",()=>{this.updateFindMatches(c)}),g.addEventListener("click",()=>{this.updateFindMatches(c)}),i.addEventListener("keyup",b=>{this.checkReplacePrompt(c,a,b),i.focus()}),q.addEventListener("click",b=>{this.cancelPrompt(c,a,b)}),q.addEventListener("keypress",b=>{("Space"==b.key||"Enter"==b.key)&&this.cancelPrompt(c,a,b)}),a.dialogContainerElement.appendChild(c),a.pluginData.findAndReplace={dialog:c},e.focus(),b&&j.setAttribute("open",!0),c.selectionStart=a.textareaElement.selectionStart,c.selectionEnd=a.textareaElement.selectionEnd,c.selectionStart<c.selectionEnd){let b=a.textareaElement.value.substring(c.selectionStart,c.selectionEnd);c.findInput.focus(),c.findInput.selectionStart=0,c.findInput.selectionEnd=c.findInput.value.length,document.execCommand("insertText",!1,b)}}else c=a.pluginData.findAndReplace.dialog,c.classList.remove("code-input_find-and-replace_hidden-dialog"),c.removeAttribute("inert"),c.setAttribute("tabindex",0),c.removeAttribute("aria-hidden"),c.findInput.focus(),b?c.replaceDropdown.setAttribute("open",!0):c.replaceDropdown.removeAttribute("open");if(c.selectionStart=a.textareaElement.selectionStart,c.selectionEnd=a.textareaElement.selectionEnd,c.selectionStart<c.selectionEnd){let b=a.textareaElement.value.substring(c.selectionStart,c.selectionEnd);c.findInput.focus(),c.findInput.selectionStart=0,c.findInput.selectionEnd=c.findInput.value.length,document.execCommand("insertText",!1,b)}this.updateFindMatches(c)}checkCtrlF(a,b){b.ctrlKey&&"f"==b.key&&(b.preventDefault(),this.showPrompt(a,!1))}checkCtrlH(a,b){b.ctrlKey&&"h"==b.key&&(b.preventDefault(),this.showPrompt(a,!0))}};const CODE_INPUT_FIND_AND_REPLACE_MATCH_BLOCK_SIZE=500;codeInput.plugins.FindAndReplace.FindMatchState=class{codeInput=null;lastValue=null;lastSearchRegexp=null;numMatches=0;focusedMatchID=0;matchStartIndexes=[];matchEndIndexes=[];focusedMatchStartIndex=0;matchBlocksHighlighted=[];constructor(a){this.focusedMatchStartIndex=a.textareaElement.selectionStart,this.codeInput=a}clearMatches(){this.numMatches=0,this.matchStartIndexes=[],this.matchEndIndexes=[];let a=this.codeInput.codeElement.querySelectorAll(".code-input_find-and-replace_temporary-span");for(let b=0;b<a.length;b++)a[b].parentElement.replaceChild(new Text(a[b].textContent),a[b]);let b=this.codeInput.codeElement.querySelectorAll(".code-input_find-and-replace_find-match");for(let a=0;a<b.length;a++)b[a].removeAttribute("data-code-input_find-and-replace_match-id"),b[a].classList.remove("code-input_find-and-replace_find-match"),b[a].classList.remove("code-input_find-and-replace_find-match-focused")}updateMatches(a){var b=Math.floor;this.lastSearchRegexp=a,this.lastValue=this.codeInput.value;let c,d=0;this.matchStartIndexes=[],this.matchEndIndexes=[],this.matchBlocksHighlighted=[];let e=b(this.focusedMatchID/CODE_INPUT_FIND_AND_REPLACE_MATCH_BLOCK_SIZE);for(let b=0;b<e;b++)this.matchBlocksHighlighted.push(!1);for(this.matchBlocksHighlighted.push(!0);null!==(c=a.exec(this.codeInput.value));){let a=c[0];if(0==a.length)throw SyntaxError(this.instructions.infiniteLoopError);let e=b(d/CODE_INPUT_FIND_AND_REPLACE_MATCH_BLOCK_SIZE);this.matchBlocksHighlighted.length<e&&this.matchBlocksHighlighted.push(!1),this.matchBlocksHighlighted[e]&&this.highlightMatch(d,this.codeInput.codeElement,c.index,c.index+a.length),this.matchStartIndexes.push(c.index),this.matchEndIndexes.push(c.index+a.length),d++}this.numMatches=d,0<this.numMatches&&this.focusMatch()}rehighlightMatches(){this.updateMatches(this.lastSearchRegexp),this.focusMatch()}replaceOnce(a){0<this.numMatches&&a!=this.codeInput.value.substring(0,this.matchStartIndexes[this.focusedMatchID],this.matchEndIndexes[this.focusedMatchID])&&(this.focusedMatchStartIndex+=a.length,this.codeInput.handleEventsFromTextarea=!1,this.codeInput.textareaElement.focus(),this.codeInput.textareaElement.selectionStart=this.matchStartIndexes[this.focusedMatchID],this.codeInput.textareaElement.selectionEnd=this.matchEndIndexes[this.focusedMatchID],document.execCommand("insertText",!1,a),this.codeInput.handleEventsFromTextarea=!0)}replaceAll(a){const b=a.length;let c=0;for(let d=0;d<this.numMatches;d++)this.codeInput.handleEventsFromTextarea=!1,this.codeInput.textareaElement.focus(),this.codeInput.textareaElement.selectionStart=this.matchStartIndexes[d]+c,this.codeInput.textareaElement.selectionEnd=this.matchEndIndexes[d]+c,c+=b-(this.matchEndIndexes[d]-this.matchStartIndexes[d]),document.execCommand("insertText",!1,a),this.codeInput.handleEventsFromTextarea=!0}nextMatch(){this.focusMatch((this.focusedMatchID+1)%this.numMatches)}previousMatch(){this.focusMatch((this.focusedMatchID+this.numMatches-1)%this.numMatches)}focusMatch(a=void 0){if(a===void 0){for(a=0;a<this.matchStartIndexes.length&&this.matchStartIndexes[a]<this.focusedMatchStartIndex;)a++;a>=this.matchStartIndexes.length&&(a=0)}this.focusedMatchStartIndex=this.matchStartIndexes[a],this.focusedMatchID=a;let b=this.codeInput.codeElement.querySelectorAll(".code-input_find-and-replace_find-match-focused");for(let c=0;c<b.length;c++)b[c].classList.remove("code-input_find-and-replace_find-match-focused");let c=Math.floor(a/CODE_INPUT_FIND_AND_REPLACE_MATCH_BLOCK_SIZE);if(!this.matchBlocksHighlighted[c]){this.matchBlocksHighlighted[c]=!0;for(let a=CODE_INPUT_FIND_AND_REPLACE_MATCH_BLOCK_SIZE*c;a<CODE_INPUT_FIND_AND_REPLACE_MATCH_BLOCK_SIZE*(c+1);a++)this.highlightMatch(a,this.codeInput.codeElement,this.matchStartIndexes[a],this.matchEndIndexes[a])}let d=this.codeInput.codeElement.querySelectorAll(`.code-input_find-and-replace_find-match[data-code-input_find-and-replace_match-id="${a}"]`);for(let b=0;b<d.length;b++)d[b].classList.add("code-input_find-and-replace_find-match-focused");0<d.length&&this.codeInput.scrollTo(d[0].offsetLeft-this.codeInput.offsetWidth/2,d[0].offsetTop-this.codeInput.offsetHeight/2)}highlightMatch(a,b,c,d){const e=b.textContent.substring(c,d).split("\n");let f=c;for(let g=0;g<e.length;g++)0==g?this.highlightMatchNewlineOnlyAtStart(a,b,f,f+e[g].length):this.highlightMatchNewlineOnlyAtStart(a,b,f-1,f+e[g].length),f+=e[g].length+1}highlightMatchNewlineOnlyAtStart(a,b,c,d){for(let e=0;e<b.childNodes.length;e++){let f=b.childNodes[e],g=f.textContent,h=!1;if(3==f.nodeType){if(e+1<b.childNodes.length&&3==b.childNodes[e+1].nodeType){b.childNodes[e+1].textContent=f.textContent+b.childNodes[e+1].textContent,b.removeChild(f),e--;continue}h=!0;let a=document.createElement("span");a.textContent=g,a.classList.add("code-input_find-and-replace_temporary-span"),b.replaceChild(a,f),f=a}if(0>=c){if(g.length>=d){if(h){let b=document.createElement("span");b.classList.add("code-input_find-and-replace_find-match"),b.setAttribute("data-code-input_find-and-replace_match-id",a),b.classList.add("code-input_find-and-replace_temporary-span"),b.textContent=g.substring(0,d),"\n"==b.textContent[0]&&b.classList.add("code-input_find-and-replace_start-newline");let c=g.substring(d);return f.textContent=c,f.insertAdjacentElement("beforebegin",b),void e++}return void this.highlightMatchNewlineOnlyAtStart(a,f,0,d)}f.classList.add("code-input_find-and-replace_find-match"),f.setAttribute("data-code-input_find-and-replace_match-id",a),"\n"==f.textContent[0]&&f.classList.add("code-input_find-and-replace_start-newline")}else if(g.length>c){if(!h)this.highlightMatchNewlineOnlyAtStart(a,f,c,d);else if(g.length>d){let b=document.createElement("span");b.classList.add("code-input_find-and-replace_temporary-span"),b.textContent=g.substring(0,c);let h=g.substring(c,d);f.textContent=h,f.classList.add("code-input_find-and-replace_find-match"),f.setAttribute("data-code-input_find-and-replace_match-id",a),"\n"==f.textContent[0]&&f.classList.add("code-input_find-and-replace_start-newline");let i=document.createElement("span");i.classList.add("code-input_find-and-replace_temporary-span"),i.textContent=g.substring(d),f.insertAdjacentElement("beforebegin",b),f.insertAdjacentElement("afterend",i),e++}else{let b=g.substring(0,c);f.textContent=b;let d=document.createElement("span");d.classList.add("code-input_find-and-replace_find-match"),d.setAttribute("data-code-input_find-and-replace_match-id",a),d.classList.add("code-input_find-and-replace_temporary-span"),d.textContent=g.substring(c),"\n"==d.textContent[0]&&d.classList.add("code-input_find-and-replace_start-newline"),f.insertAdjacentElement("afterend",d),e++}if(g.length>d)return}c-=g.length,d-=g.length}}};
@@ -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
+ }