@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.
- package/LICENSE +1 -1
- package/README.md +9 -126
- package/code-input.css +70 -33
- package/code-input.d.ts +135 -59
- package/code-input.js +201 -110
- package/code-input.min.css +1 -1
- package/code-input.min.js +12 -1
- package/docs/LICENSE +3 -0
- package/docs/LICENSE.CC-BY-SA-4.0 +116 -0
- package/docs/LICENSE.CC0-1.0 +30 -0
- package/docs/README.md +5 -0
- package/docs/_index.md +308 -0
- package/docs/i18n/_index.md +52 -0
- package/docs/interface/_index.md +3 -0
- package/docs/interface/css/_index.md +12 -0
- package/docs/interface/forms/_index.md +17 -0
- package/docs/interface/js/_index.md +11 -0
- package/docs/modules-and-frameworks/_index.md +3 -0
- package/docs/modules-and-frameworks/custom/_index.md +9 -0
- package/docs/modules-and-frameworks/hljs/_index.md +13 -0
- package/docs/modules-and-frameworks/hljs/esm/_index.md +71 -0
- package/docs/modules-and-frameworks/hljs/nuxt/_index.md +250 -0
- package/docs/modules-and-frameworks/hljs/nuxt/nuxt-demo-screenshot.png +0 -0
- package/docs/modules-and-frameworks/hljs/vue/_index.md +233 -0
- package/docs/modules-and-frameworks/hljs/vue/vue-demo-screenshot.png +0 -0
- package/docs/modules-and-frameworks/prism/_index.md +14 -0
- package/docs/plugins/_index.md +676 -0
- package/docs/plugins/new/_index.md +52 -0
- package/docs/theory/_index.md +9 -0
- package/esm/.code-input.mjs.kate-swp +0 -0
- package/esm/README.md +23 -0
- package/esm/code-input.mjs +2 -0
- package/package.json +83 -7
- package/plugins/README.md +2 -0
- package/plugins/auto-close-brackets.js +2 -0
- package/plugins/auto-close-brackets.min.js +1 -1
- package/plugins/autocomplete.js +6 -6
- package/plugins/autocomplete.min.js +1 -1
- package/plugins/autodetect.js +4 -2
- package/plugins/autodetect.min.js +1 -1
- package/plugins/find-and-replace.css +0 -4
- package/plugins/find-and-replace.js +28 -8
- package/plugins/find-and-replace.min.css +1 -1
- package/plugins/find-and-replace.min.js +1 -1
- package/plugins/go-to-line.css +10 -5
- package/plugins/go-to-line.js +39 -6
- package/plugins/go-to-line.min.css +1 -1
- package/plugins/go-to-line.min.js +1 -1
- package/plugins/indent.js +4 -2
- package/plugins/indent.min.js +1 -1
- package/plugins/prism-line-numbers.css +14 -5
- package/plugins/prism-line-numbers.min.css +1 -1
- package/plugins/select-token-callbacks.js +3 -1
- package/plugins/select-token-callbacks.min.js +1 -1
- package/plugins/special-chars.css +13 -1
- package/plugins/special-chars.js +14 -4
- package/plugins/special-chars.min.css +1 -1
- package/plugins/special-chars.min.js +1 -1
- package/plugins/test.js +22 -7
- package/plugins/test.min.js +1 -1
- package/.github/workflows/minify.yml +0 -22
- package/.github/workflows/npm-publish.yml +0 -21
- package/CODE_OF_CONDUCT.md +0 -130
- package/CONTRIBUTING.md +0 -35
- package/tests/hljs.html +0 -55
- package/tests/i18n.html +0 -197
- package/tests/prism-match-braces-compatibility.js +0 -215
- package/tests/prism-match-braces-compatibility.min.js +0 -1
- package/tests/prism.html +0 -54
- package/tests/tester.js +0 -600
- 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.
|
package/package.json
CHANGED
|
@@ -1,10 +1,84 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webcoder49/code-input",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.6.0",
|
|
4
|
+
"description": "An editable <textarea> 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
|
|
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": "
|
|
98
|
+
"name": "Oliver Geer and contributors",
|
|
23
99
|
"email": "hi@webcoder49.dev",
|
|
24
|
-
"url": "https://
|
|
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://
|
|
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)}}};
|
package/plugins/autocomplete.js
CHANGED
|
@@ -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.
|
|
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("
|
|
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(
|
|
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(){}};
|
package/plugins/autodetect.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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)}};
|
|
@@ -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?
|
|
35
|
-
* @param {boolean} useCtrlH Should Ctrl+H be overriden for find-and-replace replace functionality?
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
|
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}}};
|
package/plugins/go-to-line.css
CHANGED
|
@@ -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
|
+
}
|