@webcoder49/code-input 2.6.0 → 2.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SECURITY.md +7 -0
- package/code-input.js +154 -91
- package/code-input.min.js +1 -1
- package/docs/_index.md +12 -3
- package/docs/interface/js/_index.md +1 -1
- package/esm/code-input.d.mts +154 -0
- package/esm/code-input.mjs +1058 -0
- package/esm/plugins/auto-close-brackets.d.mts +15 -0
- package/esm/plugins/auto-close-brackets.mjs +84 -0
- package/esm/plugins/autocomplete.d.mts +14 -0
- package/esm/plugins/autocomplete.mjs +93 -0
- package/esm/plugins/autodetect.d.mts +11 -0
- package/esm/plugins/autodetect.mjs +35 -0
- package/esm/plugins/find-and-replace.d.mts +43 -0
- package/esm/plugins/find-and-replace.mjs +777 -0
- package/esm/plugins/go-to-line.d.mts +29 -0
- package/esm/plugins/go-to-line.mjs +217 -0
- package/esm/plugins/indent.d.mts +22 -0
- package/esm/plugins/indent.mjs +359 -0
- package/esm/plugins/select-token-callbacks.d.mts +51 -0
- package/esm/plugins/select-token-callbacks.mjs +296 -0
- package/esm/plugins/special-chars.d.mts +25 -0
- package/esm/plugins/special-chars.mjs +207 -0
- package/esm/plugins/test.d.mts +16 -0
- package/esm/plugins/test.mjs +56 -0
- package/esm/templates/hljs.d.mts +16 -0
- package/esm/templates/hljs.mjs +28 -0
- package/esm/templates/prism.d.mts +16 -0
- package/esm/templates/prism.mjs +25 -0
- package/package.json +1 -1
- package/esm/.code-input.mjs.kate-swp +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// NOTICE: This code is @generated from code outside the esm directory. Please do not edit it to contribute!
|
|
2
|
+
|
|
3
|
+
import { Plugin, CodeInput } from "../code-input.d.mts";
|
|
4
|
+
/**
|
|
5
|
+
* Automatically closes pairs of brackets/quotes/other syntaxes in code, but also lets you choose the brackets this
|
|
6
|
+
* is activated for.
|
|
7
|
+
* Files: auto-close-brackets.js
|
|
8
|
+
*/
|
|
9
|
+
export default class AutoCloseBrackets extends Plugin {
|
|
10
|
+
/**
|
|
11
|
+
* Create an auto-close brackets plugin to pass into a template
|
|
12
|
+
* @param {Object} bracketPairs Opening brackets mapped to closing brackets, default and example {"(": ")", "[": "]", "{": "}", '"': '"'}. All brackets must only be one character.
|
|
13
|
+
*/
|
|
14
|
+
constructor(bracketPairs?: Object);
|
|
15
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// NOTICE: This code is @generated from code outside the esm directory. Please do not edit it to contribute!
|
|
2
|
+
|
|
3
|
+
import { Plugin } from "../code-input.mjs";
|
|
4
|
+
const plugins = {};
|
|
5
|
+
/**
|
|
6
|
+
* Automatically close pairs of brackets/quotes/other syntaxes in code, but also optionally choose the brackets this
|
|
7
|
+
* is activated for.
|
|
8
|
+
* Files: auto-close-brackets.js
|
|
9
|
+
*/
|
|
10
|
+
"use strict";
|
|
11
|
+
|
|
12
|
+
plugins.AutoCloseBrackets = class extends Plugin {
|
|
13
|
+
bracketPairs = [];
|
|
14
|
+
bracketsOpenedStack = []; // Each item [closing bracket string, opening bracket location] Innermost at right so can know which brackets should be ignored when retyped
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Create an auto-close brackets plugin to pass into a template
|
|
18
|
+
* @param {Object} bracketPairs Opening brackets mapped to closing brackets, default and example {"(": ")", "[": "]", "{": "}", '"': '"'}. All brackets must only be one character.
|
|
19
|
+
*/
|
|
20
|
+
constructor(bracketPairs={"(": ")", "[": "]", "{": "}", '"': '"'}) {
|
|
21
|
+
super([]); // No observed attributes
|
|
22
|
+
|
|
23
|
+
this.bracketPairs = bracketPairs;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* Add keystroke events */
|
|
27
|
+
afterElementsAdded(codeInput) {
|
|
28
|
+
codeInput.pluginData.autoCloseBrackets = { automatedKeypresses: false};
|
|
29
|
+
codeInput.textareaElement.addEventListener('keydown', (event) => { this.checkBackspace(codeInput, event); });
|
|
30
|
+
codeInput.textareaElement.addEventListener('beforeinput', (event) => { this.checkClosingBracket(codeInput, event); });
|
|
31
|
+
codeInput.textareaElement.addEventListener('input', (event) => { this.checkOpeningBracket(codeInput, event); });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* Deal with the ability to "retype" a closing bracket where one has already
|
|
35
|
+
been placed. Runs before input so newly typing a closing bracket can be
|
|
36
|
+
prevented.*/
|
|
37
|
+
checkClosingBracket(codeInput, event) {
|
|
38
|
+
if(codeInput.pluginData.autoCloseBrackets.automatedKeypresses) return;
|
|
39
|
+
if(event.data == codeInput.textareaElement.value[codeInput.textareaElement.selectionStart]) {
|
|
40
|
+
// Check if a closing bracket is typed
|
|
41
|
+
for(let openingBracket in this.bracketPairs) {
|
|
42
|
+
let closingBracket = this.bracketPairs[openingBracket];
|
|
43
|
+
if(event.data == closingBracket) {
|
|
44
|
+
// "Retype" a closing bracket, i.e. just move caret
|
|
45
|
+
codeInput.textareaElement.selectionStart = codeInput.textareaElement.selectionEnd += 1;
|
|
46
|
+
event.preventDefault();
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* Deal with the automatic creation of closing bracket when opening brackets are typed. Runs after input for consistency between browsers. */
|
|
54
|
+
checkOpeningBracket(codeInput, event) {
|
|
55
|
+
if(codeInput.pluginData.autoCloseBrackets.automatedKeypresses) return;
|
|
56
|
+
if(event.data in this.bracketPairs) {
|
|
57
|
+
// Opening bracket typed; Create bracket pair
|
|
58
|
+
let closingBracket = this.bracketPairs[event.data];
|
|
59
|
+
// Insert the closing bracket
|
|
60
|
+
// automatedKeypresses property to prevent keypresses being captured
|
|
61
|
+
// by this plugin during automated input as some browsers
|
|
62
|
+
// (e.g. GNOME Web) do.
|
|
63
|
+
codeInput.pluginData.autoCloseBrackets.automatedKeypresses = true;
|
|
64
|
+
document.execCommand("insertText", false, closingBracket);
|
|
65
|
+
codeInput.pluginData.autoCloseBrackets.automatedKeypresses = false;
|
|
66
|
+
// Move caret before the inserted closing bracket
|
|
67
|
+
codeInput.textareaElement.selectionStart = codeInput.textareaElement.selectionEnd -= 1;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* Deal with cases where a backspace deleting an opening bracket deletes the closing bracket straight after it as well */
|
|
72
|
+
checkBackspace(codeInput, event) {
|
|
73
|
+
if(codeInput.pluginData.autoCloseBrackets.automatedKeypresses) return;
|
|
74
|
+
if(event.key == "Backspace" && codeInput.textareaElement.selectionStart == codeInput.textareaElement.selectionEnd) {
|
|
75
|
+
let closingBracket = this.bracketPairs[codeInput.textareaElement.value[codeInput.textareaElement.selectionStart-1]];
|
|
76
|
+
if(closingBracket != undefined && codeInput.textareaElement.value[codeInput.textareaElement.selectionStart] == closingBracket) {
|
|
77
|
+
// Opening bracket being deleted so delete closing bracket as well
|
|
78
|
+
codeInput.textareaElement.selectionEnd = codeInput.textareaElement.selectionStart + 1;
|
|
79
|
+
codeInput.textareaElement.selectionStart -= 1;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export default plugins.AutoCloseBrackets;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// NOTICE: This code is @generated from code outside the esm directory. Please do not edit it to contribute!
|
|
2
|
+
|
|
3
|
+
import { Plugin, CodeInput } from "../code-input.d.mts";
|
|
4
|
+
/**
|
|
5
|
+
* Display a popup under the caret using the text in the code-input element. This works well with autocomplete suggestions.
|
|
6
|
+
* Files: autocomplete.js / autocomplete.css
|
|
7
|
+
*/
|
|
8
|
+
export default class Autocomplete extends Plugin {
|
|
9
|
+
/**
|
|
10
|
+
* Pass in a function to create a plugin that displays the popup that takes in (popup element, textarea, textarea.selectionEnd).
|
|
11
|
+
* @param {(popupElement: HTMLElement, textarea: HTMLTextAreaElement, selectionEnd: number, selectionStart?: number) => void} updatePopupCallback a function to display the popup that takes in (popup element, textarea, textarea.selectionEnd).
|
|
12
|
+
*/
|
|
13
|
+
constructor(updatePopupCallback: (popupElem: HTMLElement, textarea: HTMLTextAreaElement, selectionEnd: number, selectionStart?: number) => void);
|
|
14
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// NOTICE: This code is @generated from code outside the esm directory. Please do not edit it to contribute!
|
|
2
|
+
|
|
3
|
+
import { Plugin } from "../code-input.mjs";
|
|
4
|
+
const plugins = {};
|
|
5
|
+
/**
|
|
6
|
+
* Display a popup under the caret using the text in the code-input element. This works well with autocomplete suggestions.
|
|
7
|
+
* Files: autocomplete.js / autocomplete.css
|
|
8
|
+
*/
|
|
9
|
+
"use strict";
|
|
10
|
+
|
|
11
|
+
plugins.Autocomplete = class extends Plugin {
|
|
12
|
+
/**
|
|
13
|
+
* Pass in a function to create a plugin that displays the popup that takes in (popup element, textarea, textarea.selectionEnd).
|
|
14
|
+
* @param {(popupElement: HTMLElement, textarea: HTMLTextAreaElement, selectionEnd: number) => void} updatePopupCallback a function to display the popup that takes in (popup element, textarea, textarea.selectionEnd).
|
|
15
|
+
*/
|
|
16
|
+
constructor(updatePopupCallback) {
|
|
17
|
+
super([]); // No observed attributes
|
|
18
|
+
this.updatePopupCallback = updatePopupCallback;
|
|
19
|
+
}
|
|
20
|
+
/* When a key is pressed, or scrolling occurs, update the popup position */
|
|
21
|
+
updatePopup(codeInput, onlyScrolled) {
|
|
22
|
+
let textarea = codeInput.textareaElement;
|
|
23
|
+
let caretCoords = this.getCaretCoordinates(codeInput, textarea, textarea.selectionEnd, onlyScrolled);
|
|
24
|
+
let popupElem = codeInput.querySelector(".code-input_autocomplete_popup");
|
|
25
|
+
popupElem.style.top = caretCoords.top + "px";
|
|
26
|
+
popupElem.style.left = caretCoords.left + "px";
|
|
27
|
+
|
|
28
|
+
if(!onlyScrolled) {
|
|
29
|
+
this.updatePopupCallback(popupElem, textarea, textarea.selectionEnd, textarea.selectionStart);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/* Create the popup element */
|
|
33
|
+
afterElementsAdded(codeInput) {
|
|
34
|
+
let popupElem = document.createElement("div");
|
|
35
|
+
popupElem.classList.add("code-input_autocomplete_popup");
|
|
36
|
+
codeInput.appendChild(popupElem);
|
|
37
|
+
|
|
38
|
+
let testPosPre = document.createElement("pre");
|
|
39
|
+
testPosPre.setAttribute("aria-hidden", true); // Hide for screen readers
|
|
40
|
+
if(codeInput.templateObject.preElementStyled) {
|
|
41
|
+
testPosPre.classList.add("code-input_autocomplete_testpos");
|
|
42
|
+
codeInput.appendChild(testPosPre); // Styled like first pre, but first pre found to update
|
|
43
|
+
} else {
|
|
44
|
+
let testPosCode = document.createElement("code");
|
|
45
|
+
testPosCode.classList.add("code-input_autocomplete_testpos");
|
|
46
|
+
testPosPre.appendChild(testPosCode);
|
|
47
|
+
codeInput.appendChild(testPosPre); // Styled like first pre, but first pre found to update
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let textarea = codeInput.textareaElement;
|
|
51
|
+
textarea.addEventListener("input", () => { this.updatePopup(codeInput, false)});
|
|
52
|
+
textarea.addEventListener("selectionchange", () => { this.updatePopup(codeInput, false)});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Return the coordinates of the caret in a code-input
|
|
56
|
+
* @param {codeInput.CodeInput} codeInput
|
|
57
|
+
* @param {HTMLElement} textarea
|
|
58
|
+
* @param {Number} charIndex
|
|
59
|
+
* @param {boolean} onlyScrolled True if no edits have been made to the text and the caret hasn't been repositioned
|
|
60
|
+
* @returns {Object} {"top": CSS top value in pixels, "left": CSS left value in pixels}
|
|
61
|
+
*/
|
|
62
|
+
getCaretCoordinates(codeInput, textarea, charIndex, onlyScrolled) {
|
|
63
|
+
let afterSpan;
|
|
64
|
+
if(onlyScrolled) {
|
|
65
|
+
// No edits to text; don't update element - span at index 1 is after span
|
|
66
|
+
let spans = codeInput.querySelector(".code-input_autocomplete_testpos").querySelectorAll("span");
|
|
67
|
+
if(spans.length < 2) {
|
|
68
|
+
// Hasn't saved text in test pre to find pos
|
|
69
|
+
// Need to regenerate text in test pre
|
|
70
|
+
return this.getCaretCoordinates(codeInput, textarea, charIndex, false);
|
|
71
|
+
}
|
|
72
|
+
afterSpan = spans[1];
|
|
73
|
+
} else {
|
|
74
|
+
/* Inspired by https://github.com/component/textarea-caret-position */
|
|
75
|
+
let testPosElem = codeInput.querySelector(".code-input_autocomplete_testpos");
|
|
76
|
+
|
|
77
|
+
let beforeSpan = document.createElement("span");
|
|
78
|
+
beforeSpan.textContent = textarea.value.substring(0, charIndex);
|
|
79
|
+
afterSpan = document.createElement("span");
|
|
80
|
+
afterSpan.textContent = "."; // Placeholder
|
|
81
|
+
|
|
82
|
+
// Clear test pre - https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild
|
|
83
|
+
while (testPosElem.firstChild) {
|
|
84
|
+
testPosElem.removeChild(testPosElem.firstChild);
|
|
85
|
+
}
|
|
86
|
+
testPosElem.appendChild(beforeSpan);
|
|
87
|
+
testPosElem.appendChild(afterSpan);
|
|
88
|
+
}
|
|
89
|
+
return {"top": afterSpan.offsetTop - textarea.scrollTop, "left": afterSpan.offsetLeft - textarea.scrollLeft};
|
|
90
|
+
}
|
|
91
|
+
updatePopupCallback = function() {};
|
|
92
|
+
}
|
|
93
|
+
export default plugins.Autocomplete;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// NOTICE: This code is @generated from code outside the esm directory. Please do not edit it to contribute!
|
|
2
|
+
|
|
3
|
+
import { Plugin, CodeInput } from "../code-input.d.mts";
|
|
4
|
+
/**
|
|
5
|
+
* Autodetect the language live and change the `lang` attribute using the syntax highlighter's
|
|
6
|
+
* autodetect capabilities. Works with highlight.js only.
|
|
7
|
+
* Files: autodetect.js
|
|
8
|
+
*/
|
|
9
|
+
export default class Autodetect extends Plugin {
|
|
10
|
+
constructor();
|
|
11
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// NOTICE: This code is @generated from code outside the esm directory. Please do not edit it to contribute!
|
|
2
|
+
|
|
3
|
+
import { Plugin } from "../code-input.mjs";
|
|
4
|
+
const plugins = {};
|
|
5
|
+
/**
|
|
6
|
+
* Autodetect the language live and change the `lang` attribute using the syntax highlighter's
|
|
7
|
+
* autodetect capabilities. Works with highlight.js only.
|
|
8
|
+
* Files: autodetect.js
|
|
9
|
+
*/
|
|
10
|
+
"use strict";
|
|
11
|
+
|
|
12
|
+
plugins.Autodetect = class extends Plugin {
|
|
13
|
+
constructor() {
|
|
14
|
+
super([]); // No observed attributes
|
|
15
|
+
}
|
|
16
|
+
/* Remove previous language class */
|
|
17
|
+
beforeHighlight(codeInput) {
|
|
18
|
+
let resultElement = codeInput.codeElement;
|
|
19
|
+
resultElement.className = ""; // CODE
|
|
20
|
+
resultElement.parentElement.className = ""; // PRE
|
|
21
|
+
}
|
|
22
|
+
/* Get new language class and set `language` attribute */
|
|
23
|
+
afterHighlight(codeInput) {
|
|
24
|
+
let langClass = codeInput.codeElement.className || codeInput.preElement.className;
|
|
25
|
+
let lang = langClass.match(/lang(\w|-)*/i)[0]; // Get word starting with lang...; Get outer bracket
|
|
26
|
+
lang = lang.match(/(?<=-)(\w|-)*/i)[0];
|
|
27
|
+
if(lang == "undefined") {
|
|
28
|
+
codeInput.removeAttribute("language");
|
|
29
|
+
codeInput.removeAttribute("lang");
|
|
30
|
+
} else {
|
|
31
|
+
codeInput.setAttribute("language", lang);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export default plugins.Autodetect;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// NOTICE: This code is @generated from code outside the esm directory. Please do not edit it to contribute!
|
|
2
|
+
|
|
3
|
+
import { Plugin, CodeInput } from "../code-input.d.mts";
|
|
4
|
+
/**
|
|
5
|
+
* Add Find-and-Replace (Ctrl+F for find, Ctrl+H for replace by default) functionality to the code editor.
|
|
6
|
+
* Files: find-and-replace.js / find-and-replace.css
|
|
7
|
+
*/
|
|
8
|
+
export default class FindAndReplace extends Plugin {
|
|
9
|
+
/**
|
|
10
|
+
* Create a find-and-replace command plugin to pass into a template
|
|
11
|
+
* @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)`.
|
|
12
|
+
* @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)`.
|
|
13
|
+
* @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.
|
|
14
|
+
*/
|
|
15
|
+
constructor(useCtrlF?: boolean, useCtrlH?: boolean,
|
|
16
|
+
instructionTranslations?: {
|
|
17
|
+
start?: string;
|
|
18
|
+
none?: string;
|
|
19
|
+
oneFound?: string;
|
|
20
|
+
matchIndex?: (index: Number, count: Number) => string;
|
|
21
|
+
error?: (message: string) => string;
|
|
22
|
+
infiniteLoopError?: string;
|
|
23
|
+
closeDialog?: string;
|
|
24
|
+
findPlaceholder?: string;
|
|
25
|
+
findCaseSensitive?: string;
|
|
26
|
+
findRegExp?: string;
|
|
27
|
+
replaceTitle?: string;
|
|
28
|
+
replacePlaceholder?: string;
|
|
29
|
+
findNext?: string;
|
|
30
|
+
findPrevious?: string;
|
|
31
|
+
replaceActionShort?: string;
|
|
32
|
+
replaceAction?: string;
|
|
33
|
+
replaceAllActionShort?: string;
|
|
34
|
+
replaceAllAction?: string
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
/**
|
|
38
|
+
* Show a find-and-replace dialog.
|
|
39
|
+
* @param {CodeInput} codeInputElement the `<code-input>` element.
|
|
40
|
+
* @param {boolean} replacePartExpanded whether the replace part of the find-and-replace dialog should be expanded
|
|
41
|
+
*/
|
|
42
|
+
showPrompt(codeInputElement: CodeInput, replacePartExpanded: boolean): void;
|
|
43
|
+
}
|