@webcoder49/code-input 2.6.8 → 2.7.1
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/code-input.css +36 -10
- package/code-input.js +114 -11
- package/code-input.min.css +1 -1
- package/code-input.min.js +1 -1
- package/docs/_index.md +19 -13
- package/docs/interface/css/_index.md +5 -1
- package/docs/interface/js/_index.md +14 -1
- package/docs/plugins/_index.md +41 -40
- package/esm/code-input.mjs +114 -11
- package/esm/plugins/autocomplete.mjs +1 -0
- package/package.json +1 -1
- package/plugins/autocomplete.css +3 -4
- package/plugins/autocomplete.js +1 -0
- package/plugins/autocomplete.min.css +1 -1
- package/plugins/autocomplete.min.js +1 -1
- package/plugins/find-and-replace.min.css +1 -1
- package/plugins/go-to-line.min.css +1 -1
- package/plugins/prism-line-numbers.min.css +1 -1
- package/plugins/special-chars.min.css +1 -5
package/code-input.css
CHANGED
|
@@ -20,7 +20,14 @@ code-input {
|
|
|
20
20
|
top: 0;
|
|
21
21
|
left: 0;
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
/* CSS variables rather than inline styles used for values synced from JavaScript
|
|
24
|
+
to keep low precedence and thus overridability
|
|
25
|
+
The variable names may change and are for internal use. */
|
|
26
|
+
/* --code-input_highlight-text-color: Set by JS to be base text color of pre code element */
|
|
27
|
+
/* --code-input_no-override-color: Set by JS for very short time to get whether color has been overriden */
|
|
28
|
+
color: var(--code-input_no-override-color, black);
|
|
29
|
+
/* --code-input_default-caret-color: Set by JS to be same as color property - currentColor won't work because it's lazily evaluated so gives transparent for the textarea */
|
|
30
|
+
caret-color: var(--code-input_default-caret-color, inherit);
|
|
24
31
|
background-color: white;
|
|
25
32
|
|
|
26
33
|
/* Normal inline styles */
|
|
@@ -30,13 +37,13 @@ code-input {
|
|
|
30
37
|
--padding-right: var(--padding, 16px);
|
|
31
38
|
--padding-top: var(--padding, 16px);
|
|
32
39
|
--padding-bottom: var(--padding, 16px);
|
|
40
|
+
|
|
33
41
|
height: 250px;
|
|
34
42
|
font-size: inherit;
|
|
35
43
|
font-family: monospace;
|
|
36
44
|
text-align: start;
|
|
37
45
|
line-height: 1.5; /* Inherited to child elements */
|
|
38
46
|
tab-size: 2;
|
|
39
|
-
caret-color: darkgrey;
|
|
40
47
|
white-space: pre;
|
|
41
48
|
padding: 0!important; /* Use --padding to set the code-input element's padding */
|
|
42
49
|
display: grid;
|
|
@@ -44,7 +51,7 @@ code-input {
|
|
|
44
51
|
grid-template-rows: 100%;
|
|
45
52
|
}
|
|
46
53
|
|
|
47
|
-
code-input * {
|
|
54
|
+
code-input :not(.code-input_dialog-container *) {
|
|
48
55
|
box-sizing: content-box; /* Make height, width work consistently no matter the box-sizing of ancestors; dialogs can be styled as wanted so are excluded. */
|
|
49
56
|
}
|
|
50
57
|
|
|
@@ -56,18 +63,23 @@ code-input textarea, code-input:not(.code-input_pre-element-styled) pre code, co
|
|
|
56
63
|
padding-top: var(--padding-top, 16px)!important;
|
|
57
64
|
padding-bottom: var(--padding-bottom, 16px)!important;
|
|
58
65
|
border: 0;
|
|
66
|
+
|
|
59
67
|
min-width: calc(100% - var(--padding-left, 16px) - var(--padding-right, 16px));
|
|
60
68
|
min-height: calc(100% - var(--padding-top, 16px) - var(--padding-bottom, 16px));
|
|
61
|
-
overflow: hidden;
|
|
62
69
|
resize: none;
|
|
70
|
+
overflow: hidden;
|
|
63
71
|
grid-row: 1;
|
|
64
72
|
grid-column: 1;
|
|
65
73
|
display: block;
|
|
66
74
|
}
|
|
67
|
-
|
|
68
75
|
code-input:not(.code-input_pre-element-styled) pre code, code-input.code-input_pre-element-styled pre {
|
|
69
76
|
height: max-content;
|
|
70
77
|
width: max-content;
|
|
78
|
+
|
|
79
|
+
/* Allow colour change to reflect properly;
|
|
80
|
+
transition-behavior: allow-discrete could be used but this is better supported and
|
|
81
|
+
works with the color property. */
|
|
82
|
+
transition: color 0.001s;
|
|
71
83
|
}
|
|
72
84
|
|
|
73
85
|
code-input:not(.code-input_pre-element-styled) pre, code-input.code-input_pre-element-styled pre code {
|
|
@@ -75,6 +87,9 @@ code-input:not(.code-input_pre-element-styled) pre, code-input.code-input_pre-el
|
|
|
75
87
|
margin: 0!important;
|
|
76
88
|
padding: 0!important;
|
|
77
89
|
border: 0!important;
|
|
90
|
+
|
|
91
|
+
min-width: 100%;
|
|
92
|
+
min-height: 100%;
|
|
78
93
|
}
|
|
79
94
|
|
|
80
95
|
code-input textarea, code-input pre, code-input pre * {
|
|
@@ -85,6 +100,9 @@ code-input textarea, code-input pre, code-input pre * {
|
|
|
85
100
|
tab-size: inherit!important;
|
|
86
101
|
text-align: inherit!important;
|
|
87
102
|
}
|
|
103
|
+
code-input textarea, code-input pre, code-input pre code {
|
|
104
|
+
overflow: visible!important;
|
|
105
|
+
}
|
|
88
106
|
|
|
89
107
|
/* Make changing the text direction propogate */
|
|
90
108
|
code-input textarea[dir=auto] + pre {
|
|
@@ -118,12 +136,13 @@ code-input pre {
|
|
|
118
136
|
/* Make textarea almost completely transparent, except for caret and placeholder */
|
|
119
137
|
|
|
120
138
|
code-input textarea:not([data-code-input-fallback]) {
|
|
121
|
-
color: transparent;
|
|
122
139
|
background: transparent;
|
|
123
|
-
|
|
140
|
+
color: transparent;
|
|
141
|
+
caret-color: inherit;
|
|
124
142
|
}
|
|
125
|
-
code-input textarea
|
|
126
|
-
|
|
143
|
+
code-input textarea:not([data-code-input-fallback]):placeholder-shown {
|
|
144
|
+
/* Show placeholder */
|
|
145
|
+
color: var(--code-input_highlight-text-color, inherit);
|
|
127
146
|
}
|
|
128
147
|
|
|
129
148
|
/* Can be scrolled */
|
|
@@ -163,6 +182,11 @@ code-input .code-input_dialog-container {
|
|
|
163
182
|
|
|
164
183
|
/* Dialog boxes' text is based on text-direction */
|
|
165
184
|
text-align: inherit;
|
|
185
|
+
|
|
186
|
+
/* Allow colour change to reflect properly;
|
|
187
|
+
* transition-behavior: allow-discrete could be used but this is * better supported and works with the color property. */
|
|
188
|
+
color: inherit;
|
|
189
|
+
transition: color 0.001s;
|
|
166
190
|
}
|
|
167
191
|
|
|
168
192
|
[dir=rtl] code-input .code-input_dialog-container, code-input[dir=rtl] .code-input_dialog-container {
|
|
@@ -252,11 +276,13 @@ code-input:not(.code-input_loaded) pre, code-input:not(.code-input_loaded) texta
|
|
|
252
276
|
code-input:has(textarea[data-code-input-fallback]) {
|
|
253
277
|
padding: 0!important; /* Padding now in the textarea */
|
|
254
278
|
box-sizing: content-box;
|
|
279
|
+
|
|
280
|
+
caret-color: revert; /* JS not setting the colour since no highlighting */
|
|
255
281
|
}
|
|
256
282
|
code-input textarea[data-code-input-fallback] {
|
|
257
283
|
overflow: auto;
|
|
258
284
|
background-color: inherit;
|
|
259
|
-
color: inherit;
|
|
285
|
+
color: var(--code-input_highlight-text-color, inherit);
|
|
260
286
|
|
|
261
287
|
/* Don't overlap with message */
|
|
262
288
|
min-height: calc(100% - var(--padding-top, 16px) - 2em - var(--padding-bottom, 16px));
|
package/code-input.js
CHANGED
|
@@ -152,6 +152,8 @@ var codeInput = {
|
|
|
152
152
|
}
|
|
153
153
|
},
|
|
154
154
|
|
|
155
|
+
stylesheetI: 0, // Increments to give different classes to each code-input element so they can have custom styles synchronised internally without affecting the inline style
|
|
156
|
+
|
|
155
157
|
/**
|
|
156
158
|
* Please see `codeInput.templates.prism` or `codeInput.templates.hljs`.
|
|
157
159
|
* Templates are used in `<code-input>` elements and once registered with
|
|
@@ -445,6 +447,16 @@ var codeInput = {
|
|
|
445
447
|
*/
|
|
446
448
|
dialogContainerElement = null;
|
|
447
449
|
|
|
450
|
+
/**
|
|
451
|
+
* Like style attribute, but with a specificity of 1
|
|
452
|
+
* element, 1 class. Present so styles can be set on only
|
|
453
|
+
* this element while giving other code freedom of use of
|
|
454
|
+
* the style attribute.
|
|
455
|
+
*
|
|
456
|
+
* For internal use only.
|
|
457
|
+
*/
|
|
458
|
+
internalStyle = null;
|
|
459
|
+
|
|
448
460
|
/**
|
|
449
461
|
* Form-Associated Custom Element Callbacks
|
|
450
462
|
* https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-face-example
|
|
@@ -530,22 +542,75 @@ var codeInput = {
|
|
|
530
542
|
this.pluginEvt("afterHighlight");
|
|
531
543
|
}
|
|
532
544
|
|
|
545
|
+
getStyledHighlightingElement() {
|
|
546
|
+
if(this.templateObject.preElementStyled) {
|
|
547
|
+
return this.preElement;
|
|
548
|
+
} else {
|
|
549
|
+
return this.codeElement;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
533
553
|
/**
|
|
534
554
|
* Set the size of the textarea element to the size of the pre/code element.
|
|
535
555
|
*/
|
|
536
556
|
syncSize() {
|
|
537
557
|
// Synchronise the size of the pre/code and textarea elements
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
558
|
+
this.textareaElement.style.height = getComputedStyle(this.getStyledHighlightingElement()).height;
|
|
559
|
+
this.textareaElement.style.width = getComputedStyle(this.getStyledHighlightingElement()).width;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* If the color attribute has been defined on the
|
|
564
|
+
* code-input element by external code, return true.
|
|
565
|
+
* Otherwise, make the aspects the color affects
|
|
566
|
+
* (placeholder and caret colour) be the base colour
|
|
567
|
+
* of the highlighted text, for best contrast, and
|
|
568
|
+
* return false.
|
|
569
|
+
*/
|
|
570
|
+
isColorOverridenSyncIfNot() {
|
|
571
|
+
const oldTransition = this.style.transition;
|
|
572
|
+
this.style.transition = "unset";
|
|
573
|
+
window.requestAnimationFrame(() => {
|
|
574
|
+
this.internalStyle.setProperty("--code-input_no-override-color", "rgb(0, 0, 0)");
|
|
575
|
+
if(getComputedStyle(this).color == "rgb(0, 0, 0)") {
|
|
576
|
+
// May not be overriden
|
|
577
|
+
this.internalStyle.setProperty("--code-input_no-override-color", "rgb(255, 255, 255)");
|
|
578
|
+
if(getComputedStyle(this).color == "rgb(255, 255, 255)") {
|
|
579
|
+
// Definitely not overriden
|
|
580
|
+
this.internalStyle.removeProperty("--code-input_no-override-color");
|
|
581
|
+
this.style.transition = oldTransition;
|
|
582
|
+
|
|
583
|
+
const highlightedTextColor = getComputedStyle(this.getStyledHighlightingElement()).color;
|
|
584
|
+
|
|
585
|
+
this.internalStyle.setProperty("--code-input_highlight-text-color", highlightedTextColor);
|
|
586
|
+
this.internalStyle.setProperty("--code-input_default-caret-color", highlightedTextColor);
|
|
587
|
+
return false;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
this.internalStyle.removeProperty("--code-input_no-override-color");
|
|
591
|
+
this.style.transition = oldTransition;
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
return true;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Update the aspects the color affects
|
|
599
|
+
* (placeholder and caret colour) to the correct
|
|
600
|
+
* colour: either that defined on the code-input
|
|
601
|
+
* element, or if none is defined externally the
|
|
602
|
+
* base colour of the highlighted text.
|
|
603
|
+
*/
|
|
604
|
+
syncColorCompletely() {
|
|
605
|
+
// color of code-input element
|
|
606
|
+
if(this.isColorOverridenSyncIfNot()) {
|
|
607
|
+
// color overriden
|
|
608
|
+
this.internalStyle.removeProperty("--code-input_highlight-text-color");
|
|
609
|
+
this.internalStyle.setProperty("--code-input_default-caret-color", getComputedStyle(this).color);
|
|
546
610
|
}
|
|
547
611
|
}
|
|
548
612
|
|
|
613
|
+
|
|
549
614
|
/**
|
|
550
615
|
* Show some instructions to the user only if they are using keyboard navigation - for example, a prompt on how to navigate with the keyboard if Tab is repurposed.
|
|
551
616
|
* @param {string} instructions The instructions to display only if keyboard navigation is being used. If it's blank, no instructions will be shown.
|
|
@@ -741,7 +806,6 @@ var codeInput = {
|
|
|
741
806
|
this.codeElement = code;
|
|
742
807
|
pre.append(code);
|
|
743
808
|
this.append(pre);
|
|
744
|
-
|
|
745
809
|
if (this.templateObject.isCode) {
|
|
746
810
|
if (lang != undefined && lang != "") {
|
|
747
811
|
code.classList.add("language-" + lang.toLowerCase());
|
|
@@ -780,7 +844,44 @@ var codeInput = {
|
|
|
780
844
|
// The only element that could be resized is this code-input element.
|
|
781
845
|
this.syncSize();
|
|
782
846
|
});
|
|
783
|
-
resizeObserver.observe(this
|
|
847
|
+
resizeObserver.observe(this);
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
// Add internal style as non-externally-overridable alternative to style attribute for e.g. syncing color
|
|
851
|
+
this.classList.add("code-input_styles_" + codeInput.stylesheetI);
|
|
852
|
+
const stylesheet = document.createElement("style");
|
|
853
|
+
stylesheet.innerHTML = "code-input.code-input_styles_" + codeInput.stylesheetI + " {}";
|
|
854
|
+
this.appendChild(stylesheet);
|
|
855
|
+
this.internalStyle = stylesheet.sheet.cssRules[0].style;
|
|
856
|
+
codeInput.stylesheetI++;
|
|
857
|
+
|
|
858
|
+
// Synchronise colors
|
|
859
|
+
const preColorChangeCallback = (evt) => {
|
|
860
|
+
if(evt.propertyName == "color") {
|
|
861
|
+
this.isColorOverridenSyncIfNot();
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
this.preElement.addEventListener("transitionend", preColorChangeCallback);
|
|
865
|
+
this.preElement.addEventListener("-webkit-transitionend", preColorChangeCallback);
|
|
866
|
+
const thisColorChangeCallback = (evt) => {
|
|
867
|
+
if(evt.propertyName == "color") {
|
|
868
|
+
this.syncColorCompletely();
|
|
869
|
+
}
|
|
870
|
+
if(evt.target == this.dialogContainerElement) {
|
|
871
|
+
evt.stopPropagation();
|
|
872
|
+
// Prevent bubbling because code-input
|
|
873
|
+
// transitionend is separate
|
|
874
|
+
}
|
|
875
|
+
};
|
|
876
|
+
// Not on this element so CSS transition property does not override publicly-visible one
|
|
877
|
+
this.dialogContainerElement.addEventListener("transitionend", thisColorChangeCallback);
|
|
878
|
+
this.dialogContainerElement.addEventListener("-webkit-transitionend", thisColorChangeCallback);
|
|
879
|
+
|
|
880
|
+
// For when this code-input element has an externally-defined, different-duration transition
|
|
881
|
+
this.addEventListener("transitionend", thisColorChangeCallback);
|
|
882
|
+
this.addEventListener("-webkit-transitionend", thisColorChangeCallback);
|
|
883
|
+
|
|
884
|
+
this.syncColorCompletely();
|
|
784
885
|
|
|
785
886
|
this.classList.add("code-input_loaded");
|
|
786
887
|
}
|
|
@@ -938,7 +1039,9 @@ var codeInput = {
|
|
|
938
1039
|
code.classList.add("language-" + newValue);
|
|
939
1040
|
}
|
|
940
1041
|
|
|
941
|
-
if (mainTextarea.placeholder == oldValue
|
|
1042
|
+
if (mainTextarea.placeholder == oldValue || oldValue == null && mainTextarea.placeholder == "") {
|
|
1043
|
+
mainTextarea.placeholder = newValue;
|
|
1044
|
+
}
|
|
942
1045
|
|
|
943
1046
|
this.scheduleHighlight();
|
|
944
1047
|
|
package/code-input.min.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
code-input{
|
|
1
|
+
code-input{color:var(--code-input_no-override-color,black);caret-color:var(--code-input_default-caret-color,inherit);--padding:16px;--padding-left:var(--padding,16px);--padding-right:var(--padding,16px);--padding-top:var(--padding,16px);--padding-bottom:var(--padding,16px);height:250px;font-size:inherit;text-align:start;tab-size:2;white-space:pre;background-color:#fff;grid-template-rows:100%;grid-template-columns:100%;margin:8px;font-family:monospace;line-height:1.5;display:grid;position:relative;top:0;left:0;overflow:auto;padding:0!important}code-input :not(.code-input_dialog-container *){box-sizing:content-box}code-input textarea,code-input:not(.code-input_pre-element-styled) pre code,code-input.code-input_pre-element-styled pre{min-width:calc(100% - var(--padding-left,16px) - var(--padding-right,16px));min-height:calc(100% - var(--padding-top,16px) - var(--padding-bottom,16px));resize:none;border:0;grid-area:1/1;display:block;overflow:hidden;padding-left:var(--padding-left,16px)!important;padding-right:var(--padding-right,16px)!important;padding-top:var(--padding-top,16px)!important;padding-bottom:var(--padding-bottom,16px)!important;margin:0!important}code-input:not(.code-input_pre-element-styled) pre code,code-input.code-input_pre-element-styled pre{width:max-content;height:max-content;transition:color 1ms}code-input:not(.code-input_pre-element-styled) pre,code-input.code-input_pre-element-styled pre code{min-width:100%;min-height:100%;border:0!important;margin:0!important;padding:0!important}code-input textarea,code-input pre,code-input pre *{font-size:inherit!important;font-family:inherit!important;line-height:inherit!important;tab-size:inherit!important;text-align:inherit!important}code-input textarea,code-input pre,code-input pre code{overflow:visible!important}code-input textarea[dir=auto]+pre{unicode-bidi:plaintext}code-input textarea[dir=ltr]+pre{direction:ltr}code-input textarea[dir=rtl]+pre{direction:rtl}code-input textarea,code-input pre{grid-area:1/1}code-input textarea:not([data-code-input-fallback]){z-index:1}code-input pre{z-index:0}code-input textarea:not([data-code-input-fallback]){color:#0000;caret-color:inherit;background:0 0}code-input textarea:not([data-code-input-fallback]):placeholder-shown{color:var(--code-input_highlight-text-color,inherit)}code-input textarea,code-input pre{white-space:inherit;word-spacing:normal;word-break:normal;word-wrap:normal}code-input textarea{resize:none;outline:none!important}code-input:has(textarea:focus):not(.code-input_mouse-focused){outline:2px solid}code-input .code-input_dialog-container{z-index:2;width:100%;height:0;text-align:inherit;color:inherit;grid-area:1/1;margin:0;padding:0;transition:color 1ms;position:sticky;top:0;left:0}[dir=rtl] code-input .code-input_dialog-container,code-input[dir=rtl] .code-input_dialog-container{left:unset;right:0}code-input .code-input_dialog-container .code-input_keyboard-navigation-instructions{color:#fff;padding:2px;padding-left:var(--padding-left,16px);padding-right:var(--padding-right,16px);text-wrap:balance;box-sizing:border-box;background-color:#000;width:100%;height:3em;margin:0;display:block;position:absolute;top:0;left:0;overflow:hidden auto}code-input:not(:has(textarea:not([data-code-input-fallback]):focus)) .code-input_dialog-container .code-input_keyboard-navigation-instructions,code-input.code-input_mouse-focused .code-input_dialog-container .code-input_keyboard-navigation-instructions,code-input .code-input_dialog-container .code-input_keyboard-navigation-instructions:empty{display:none}code-input:not(:has(.code-input_keyboard-navigation-instructions:empty)):has(textarea:not([data-code-input-fallback]):focus):not(.code-input_mouse-focused) textarea,code-input:not(:has(.code-input_keyboard-navigation-instructions:empty)):has(textarea:not([data-code-input-fallback]):focus):not(.code-input_mouse-focused):not(.code-input_pre-element-styled) pre code,code-input:not(:has(.code-input_keyboard-navigation-instructions:empty)):has(textarea:not([data-code-input-fallback]):focus):not(.code-input_mouse-focused).code-input_pre-element-styled pre{min-height:calc(100% - var(--padding-top,16px) - 3em - var(--padding-bottom,16px));padding-top:calc(var(--padding-top,16px) + 3em)!important}code-input:not(.code-input_loaded){box-sizing:border-box;display:block;overflow:hidden;padding-left:var(--padding-left,16px)!important;padding-right:var(--padding-right,16px)!important;padding:var(--padding-top,16px)!important;padding:var(--padding-bottom,16px)!important}code-input:not(.code-input_loaded):after{content:"No highlighting. JavaScript support is disabled or insufficient, or codeInput.registerTemplate has not been called.";bottom:0;left:var(--padding-left,16px);width:calc(100% - var(--padding-left,1.6px) - var(--padding-right,1.6px));outline-top:0;background-color:inherit;color:inherit;border-top:1px solid;height:2em;margin:0;padding:0;display:block;position:absolute;overflow-x:auto}code-input:not(.code-input_loaded) pre,code-input:not(.code-input_loaded) textarea:not([data-code-input-fallback]){opacity:0}code-input:has(textarea[data-code-input-fallback]){box-sizing:content-box;caret-color:revert;padding:0!important}code-input textarea[data-code-input-fallback]{background-color:inherit;color:var(--code-input_highlight-text-color,inherit);min-height:calc(100% - var(--padding-top,16px) - 2em - var(--padding-bottom,16px));overflow:auto}
|
package/code-input.min.js
CHANGED
|
@@ -9,4 +9,4 @@
|
|
|
9
9
|
* @license MIT
|
|
10
10
|
*
|
|
11
11
|
* **<https://code-input-js.org>**
|
|
12
|
-
*/"use strict";var codeInput={observedAttributes:["value","placeholder","language","lang","template"],textareaSyncAttributes:["value","min","max","type","pattern","autocomplete","autocorrect","autofocus","cols","dirname","disabled","form","maxlength","minlength","name","placeholder","readonly","required","rows","spellcheck","wrap"],textareaSyncEvents:["change","selectionchange","invalid","input","focus","blur","focusin","focusout"],usedTemplates:{},defaultTemplate:void 0,templateNotYetRegisteredQueue:{},registerTemplate:function(a,b){if(!("string"==typeof a||a instanceof String))throw TypeError(`code-input: Name of template "${a}" must be a string.`);if(!("function"==typeof b.highlight||b.highlight instanceof Function))throw TypeError(`code-input: Template for "${a}" invalid, because the highlight function provided is not a function; it is "${b.highlight}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.includeCodeInputInHighlightFunc||b.includeCodeInputInHighlightFunc instanceof Boolean))throw TypeError(`code-input: Template for "${a}" invalid, because the includeCodeInputInHighlightFunc value provided is not a true or false; it is "${b.includeCodeInputInHighlightFunc}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.preElementStyled||b.preElementStyled instanceof Boolean))throw TypeError(`code-input: Template for "${a}" invalid, because the preElementStyled value provided is not a true or false; it is "${b.preElementStyled}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.isCode||b.isCode instanceof Boolean))throw TypeError(`code-input: Template for "${a}" invalid, because the isCode value provided is not a true or false; it is "${b.isCode}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!Array.isArray(b.plugins))throw TypeError(`code-input: Template for "${a}" invalid, because the plugin array provided is not an array; it is "${b.plugins}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(b.plugins.forEach((c,d)=>{if(!(c instanceof codeInput.Plugin))throw TypeError(`code-input: Template for "${a}" invalid, because the plugin provided at index ${d} is not valid; it is "${b.plugins[d]}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`)}),codeInput.usedTemplates[a]=b,a in codeInput.templateNotYetRegisteredQueue)for(let c in codeInput.templateNotYetRegisteredQueue[a]){const d=codeInput.templateNotYetRegisteredQueue[a][c];d.templateObject=b,d.setup()}if(null==codeInput.defaultTemplate&&(codeInput.defaultTemplate=a,void 0 in codeInput.templateNotYetRegisteredQueue))for(let a in codeInput.templateNotYetRegisteredQueue[void 0]){const c=codeInput.templateNotYetRegisteredQueue[void 0][a];c.templateObject=b,c.setup()}},Template:class{constructor(a=function(){},b=!0,c=!0,d=!1,e=[]){this.highlight=a,this.preElementStyled=b,this.isCode=c,this.includeCodeInputInHighlightFunc=d,this.plugins=e}highlight=function(){};preElementStyled=!0;isCode=!0;includeCodeInputInHighlightFunc=!1;plugins=[]},templates:{prism(a,b=[]){return new codeInput.templates.Prism(a,b)},hljs(a,b=[]){return new codeInput.templates.Hljs(a,b)},characterLimit(a){return{highlight:function(a,b,c=[]){let d=+b.getAttribute("data-character-limit"),e=b.escapeHtml(b.value.slice(0,d)),f=b.escapeHtml(b.value.slice(d));a.innerHTML=`${e}<mark class="overflow">${f}</mark>`,0<f.length&&(a.innerHTML+=` <mark class="overflow-msg">${b.getAttribute("data-overflow-msg")||"(Character limit reached)"}</mark>`)},includeCodeInputInHighlightFunc:!0,preElementStyled:!0,isCode:!1,plugins:a}},rainbowText(a=["red","orangered","orange","goldenrod","gold","green","darkgreen","navy","blue","magenta"],b="",c=[]){return{highlight:function(a,b){let c=[],d=b.value.split(b.template.delimiter);for(let e=0;e<d.length;e++)c.push(`<span style="color: ${b.template.rainbowColors[e%b.template.rainbowColors.length]}">${b.escapeHtml(d[e])}</span>`);a.innerHTML=c.join(b.template.delimiter)},includeCodeInputInHighlightFunc:!0,preElementStyled:!0,isCode:!1,rainbowColors:a,delimiter:b,plugins:c}},character_limit(){return this.characterLimit([])},rainbow_text(a=["red","orangered","orange","goldenrod","gold","green","darkgreen","navy","blue","magenta"],b="",c=[]){return this.rainbowText(a,b,c)},custom(a=function(){},b=!0,c=!0,d=!1,e=[]){return{highlight:a,includeCodeInputInHighlightFunc:d,preElementStyled:b,isCode:c,plugins:e}}},plugins:new Proxy({},{get(a,b){if(a[b]==null)throw ReferenceError(`code-input: Plugin '${b}' is not defined. Please ensure you import the necessary files from the plugins folder in the WebCoder49/code-input repository, in the <head> of your HTML, before the plugin is instatiated.`);return a[b]}}),Plugin:class{constructor(a){a.forEach(a=>{codeInput.observedAttributes.push(a)})}addTranslations(a,b){for(const c in b)a[c]=b[c]}beforeHighlight(){}afterHighlight(){}beforeElementsAdded(){}afterElementsAdded(){}attributeChanged(){}},CodeInput:class extends HTMLElement{constructor(){super()}templateObject=null;textareaElement=null;preElement=null;codeElement=null;dialogContainerElement=null;static formAssociated=!0;boundEventCallbacks={};pluginEvt(a,b){for(let c in this.templateObject.plugins){let d=this.templateObject.plugins[c];a in d&&(b===void 0?d[a](this):d[a](this,...b))}}needsHighlight=!1;originalAriaDescription;scheduleHighlight(){this.needsHighlight=!0}animateFrame(){this.needsHighlight&&(this.update(),this.needsHighlight=!1),window.requestAnimationFrame(this.animateFrame.bind(this))}update(){let a=this.codeElement,b=this.value;b+="\n",a.innerHTML=this.escapeHtml(b),this.pluginEvt("beforeHighlight"),this.templateObject.includeCodeInputInHighlightFunc?this.templateObject.highlight(a,this):this.templateObject.highlight(a),this.syncSize(),this.pluginEvt("afterHighlight")}syncSize(){this.templateObject.preElementStyled?(this.style.backgroundColor=getComputedStyle(this.preElement).backgroundColor,this.textareaElement.style.height=getComputedStyle(this.preElement).height,this.textareaElement.style.width=getComputedStyle(this.preElement).width):(this.style.backgroundColor=getComputedStyle(this.codeElement).backgroundColor,this.textareaElement.style.height=getComputedStyle(this.codeElement).height,this.textareaElement.style.width=getComputedStyle(this.codeElement).width)}setKeyboardNavInstructions(a,b){this.dialogContainerElement.querySelector(".code-input_keyboard-navigation-instructions").innerText=a,b?this.textareaElement.setAttribute("aria-description",this.originalAriaDescription+". "+a):this.textareaElement.setAttribute("aria-description",a)}escapeHtml(a){return a.replace(/&/g,"&").replace(/</g,"<")}unescapeHtml(a){return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}getTemplate(){let a;return a=null==this.getAttribute("template")?codeInput.defaultTemplate:this.getAttribute("template"),a in codeInput.usedTemplates?codeInput.usedTemplates[a]:(a in codeInput.templateNotYetRegisteredQueue||(codeInput.templateNotYetRegisteredQueue[a]=[]),void codeInput.templateNotYetRegisteredQueue[a].push(this))}setup(){if(null!=this.textareaElement)return;this.classList.add("code-input_registered"),this.mutationObserver=new MutationObserver(this.mutationObserverCallback.bind(this)),this.mutationObserver.observe(this,{attributes:!0,attributeOldValue:!0}),this.classList.add("code-input_registered"),this.templateObject.preElementStyled&&this.classList.add("code-input_pre-element-styled");const a=this.querySelector("textarea[data-code-input-fallback]");let b,c,d,e,f,g=!1;a&&(a===document.activeElement&&(g=!0),b=a.selectionStart,c=a.selectionEnd,d=a.selectionDirection,e=a.scrollLeft,f=a.scrollTop);let h;if(a){let b=a.getAttributeNames();for(let c=0;c<b.length;c++){const d=b[c];"data-code-input-fallback"!=d&&(this.hasAttribute(d)||this.setAttribute(d,a.getAttribute(d)))}h=a.value,this.innerHTML=this.escapeHtml(h)}else h=this.unescapeHtml(this.innerHTML);h=h||this.getAttribute("value")||"",this.pluginEvt("beforeElementsAdded");const i=this.getAttribute("language")||this.getAttribute("lang"),j=this.getAttribute("placeholder")||i||"";this.initialValue=h;const k=document.createElement("textarea");k.placeholder=j,""!=h&&(k.value=h),k.innerHTML=this.innerHTML,this.hasAttribute("spellcheck")||k.setAttribute("spellcheck","false"),k.setAttribute("tabindex",this.getAttribute("tabindex")||0),this.setAttribute("tabindex",-1),this.originalAriaDescription=this.getAttribute("aria-description")||"Code input field",this.addEventListener("mousedown",()=>{this.classList.add("code-input_mouse-focused"),window.setTimeout(()=>{this.syncSize()},0)}),k.addEventListener("blur",()=>{this.classList.remove("code-input_mouse-focused"),window.setTimeout(()=>{this.syncSize()},0)}),k.addEventListener("focus",()=>{window.setTimeout(()=>{this.syncSize()},0)}),this.innerHTML="";for(let a,b=0;b<this.attributes.length;b++)a=this.attributes[b].name,(codeInput.textareaSyncAttributes.includes(a)||"aria-"==a.substring(0,5))&&k.setAttribute(a,this.getAttribute(a));k.addEventListener("input",()=>{this.value=this.textareaElement.value}),this.textareaElement=k,this.append(k),this.setupTextareaSyncEvents(this.textareaElement);let l=document.createElement("code"),m=document.createElement("pre");m.setAttribute("aria-hidden","true"),m.setAttribute("tabindex","-1"),m.setAttribute("inert",!0),this.preElement=m,this.codeElement=l,m.append(l),this.append(m),this.templateObject.isCode&&i!=null&&""!=i&&l.classList.add("language-"+i.toLowerCase());let n=document.createElement("div");n.classList.add("code-input_dialog-container"),this.append(n),this.dialogContainerElement=n;let o=document.createElement("div");o.classList.add("code-input_keyboard-navigation-instructions"),n.append(o),this.pluginEvt("afterElementsAdded"),this.dispatchEvent(new CustomEvent("code-input_load")),this.value=h,b!==void 0&&(k.setSelectionRange(b,c,d),k.scrollTo(f,e)),g&&k.focus(),this.animateFrame();const p=new ResizeObserver(()=>{this.syncSize()});p.observe(this.textareaElement),this.classList.add("code-input_loaded")}escape_html(a){return this.escapeHtml(a)}get_template(){return this.getTemplate()}get template(){return this.templateObject}set template(a){}connectedCallback(){if(this.templateObject=this.getTemplate(),null!=this.templateObject&&(this.classList.add("code-input_registered"),"loading"===document.readyState?window.addEventListener("DOMContentLoaded",this.setup.bind(this)):this.setup()),"loading"===document.readyState)window.addEventListener("DOMContentLoaded",()=>{const a=this.querySelector("textarea[data-code-input-fallback]");a&&this.setupTextareaSyncEvents(a)});else{const a=this.querySelector("textarea[data-code-input-fallback]");a&&this.setupTextareaSyncEvents(a)}}mutationObserverCallback(a){for(const b of a)if("attributes"===b.type){for(let a=0;a<codeInput.observedAttributes.length;a++)if(b.attributeName==codeInput.observedAttributes[a])return this.attributeChangedCallback(b.attributeName,b.oldValue,super.getAttribute(b.attributeName));for(let a=0;a<codeInput.textareaSyncAttributes.length;a++)if(b.attributeName==codeInput.textareaSyncAttributes[a])return this.attributeChangedCallback(b.attributeName,b.oldValue,super.getAttribute(b.attributeName));if("aria-"==b.attributeName.substring(0,5))return this.attributeChangedCallback(b.attributeName,b.oldValue,super.getAttribute(b.attributeName))}}disconnectedCallback(){this.mutationObserver&&this.mutationObserver.disconnect()}attributeChangedCallback(a,b,c){if(this.isConnected)switch(this.pluginEvt("attributeChanged",[a,b,c]),a){case"value":this.value=c;break;case"template":this.templateObject=codeInput.usedTemplates[c||codeInput.defaultTemplate],this.templateObject.preElementStyled?this.classList.add("code-input_pre-element-styled"):this.classList.remove("code-input_pre-element-styled"),this.scheduleHighlight();break;case"lang":case"language":let d=this.codeElement,e=this.textareaElement;if(null!=c&&(c=c.toLowerCase(),d.classList.contains(`language-${c}`)))break;null!==b&&(b=b.toLowerCase(),d.classList.remove("language-"+b),d.parentElement.classList.remove("language-"+b)),d.classList.remove("language-none"),d.parentElement.classList.remove("language-none"),null!=c&&""!=c&&d.classList.add("language-"+c),e.placeholder==b&&(e.placeholder=c),this.scheduleHighlight();break;default:codeInput.textareaSyncAttributes.includes(a)||"aria-"==a.substring(0,5)?null==c||null==c?this.textareaElement.removeAttribute(a):this.textareaElement.setAttribute(a,c):codeInput.textareaSyncAttributes.regexp.forEach(b=>{a.match(b)&&(null==c?this.textareaElement.removeAttribute(a):this.textareaElement.setAttribute(a,c))})}}setupTextareaSyncEvents(a){for(let b=0;b<codeInput.textareaSyncEvents.length;b++){const c=codeInput.textareaSyncEvents[b];a.addEventListener(c,a=>{a.bubbles||this.dispatchEvent(new a.constructor(a.type,a))})}}addEventListener(a,b,c=void 0){let d=function(a){"function"==typeof b?b(a):b&&b.handleEvent&&b.handleEvent(a)}.bind(this);if(this.boundEventCallbacks[b]=d,!codeInput.textareaSyncEvents.includes(a))void 0===c?super.addEventListener(a,d):super.addEventListener(a,d,c);else if(this.boundEventCallbacks[b]=d,void 0===c){if(null==this.textareaElement){const b=this.querySelector("textarea[data-code-input-fallback]");b&&b.addEventListener(a,d),this.addEventListener("code-input_load",()=>{this.textareaElement.addEventListener(a,d)})}else this.textareaElement.addEventListener(a,d);}else if(null==this.textareaElement){const b=this.querySelector("textarea[data-code-input-fallback]");b&&b.addEventListener(a,d,c),this.addEventListener("code-input_load",()=>{this.textareaElement.addEventListener(a,d,c)})}else this.textareaElement.addEventListener(a,d,c)}removeEventListener(a,b,c=void 0){let d=this.boundEventCallbacks[b];if(!codeInput.textareaSyncEvents.includes(a))void 0===c?super.removeEventListener(a,d):super.removeEventListener(a,d,c);else if(void 0===c){if(null==this.textareaElement){const b=this.querySelector("textarea[data-code-input-fallback]");b&&b.removeEventListener(a,d),this.addEventListener("code-input_load",()=>{this.textareaElement.removeEventListener(a,d)})}else this.textareaElement.removeEventListener(a,d);}else if(null==this.textareaElement){const b=this.querySelector("textarea[data-code-input-fallback]");b&&b.removeEventListener(a,d,c),this.addEventListener("code-input_load",()=>{this.textareaElement.removeEventListener(a,d,c)})}else this.textareaElement.removeEventListener(a,d,c)}getTextareaProperty(a,b=void 0){if(this.textareaElement)return this.textareaElement[a];else{const c=this.querySelector("textarea[data-code-input-fallback]");if(c)return c[a];if(void 0===b)throw new Error("Cannot get "+a+" of an unregistered code-input element without a data-code-input-fallback textarea.");return b}}setTextareaProperty(a,b,c=!0){if(this.textareaElement)this.textareaElement[a]=b;else{const d=this.querySelector("textarea[data-code-input-fallback]");if(d)d[a]=b;else{if(!c)return(!1);throw new Error("Cannot set "+a+" of an unregistered code-input element without a data-code-input-fallback textarea.")}}return(!0)}get autocomplete(){return this.getAttribute("autocomplete")}set autocomplete(a){return this.setAttribute("autocomplete",a)}get cols(){return this.getTextareaProperty("cols",+this.getAttribute("cols"))}set cols(a){this.setAttribute("cols",a)}get defaultValue(){return this.initialValue}set defaultValue(a){this.initialValue=a}get textContent(){return this.initialValue}set textContent(a){this.initialValue=a}get dirName(){return this.getAttribute("dirName")||""}set dirName(a){this.setAttribute("dirname",a)}get disabled(){return this.hasAttribute("disabled")}set disabled(a){a?this.setAttribute("disabled",!0):this.removeAttribute("disabled")}get form(){return this.getTextareaProperty("form")}get labels(){return this.getTextareaProperty("labels")}get maxLength(){const a=+this.getAttribute("maxlength");return isNaN(a)?-1:a}set maxLength(a){-1==a?this.removeAttribute("maxlength"):this.setAttribute("maxlength",a)}get minLength(){const a=+this.getAttribute("minlength");return isNaN(a)?-1:a}set minLength(a){-1==a?this.removeAttribute("minlength"):this.setAttribute("minlength",a)}get name(){return this.getAttribute("name")||""}set name(a){this.setAttribute("name",a)}get placeholder(){return this.getAttribute("placeholder")||""}set placeholder(a){this.setAttribute("placeholder",a)}get readOnly(){return this.hasAttribute("readonly")}set readOnly(a){a?this.setAttribute("readonly",!0):this.removeAttribute("readonly")}get required(){return this.hasAttribute("readonly")}set required(a){a?this.setAttribute("readonly",!0):this.removeAttribute("readonly")}get rows(){return this.getTextareaProperty("rows",+this.getAttribute("rows"))}set rows(a){this.setAttribute("rows",a)}get selectionDirection(){return this.getTextareaProperty("selectionDirection")}set selectionDirection(a){this.setTextareaProperty("selectionDirection",a)}get selectionEnd(){return this.getTextareaProperty("selectionEnd")}set selectionEnd(a){this.setTextareaProperty("selectionEnd",a)}get selectionStart(){return this.getTextareaProperty("selectionStart")}set selectionStart(a){this.setTextareaProperty("selectionStart",a)}get textLength(){return this.value.length}get type(){return"textarea"}get validationMessage(){return this.getTextareaProperty("validationMessage")}get validity(){return this.getTextareaProperty("validationMessage")}get value(){return this.getTextareaProperty("value",this.getAttribute("value")||this.innerHTML)}set value(a){a=a||"",this.setTextareaProperty("value",a,!1)?this.textareaElement&&this.scheduleHighlight():this.innerHTML=a}get willValidate(){return this.getTextareaProperty("willValidate",this.disabled||this.readOnly)}get wrap(){return this.getAttribute("wrap")||""}set wrap(a){this.setAttribute("wrap",a)}getTextareaMethod(a){if(this.textareaElement)return this.textareaElement[a].bind(this.textareaElement);else{const b=this.querySelector("textarea[data-code-input-fallback]");if(b)return b[a].bind(b);throw new Error("Cannot call "+a+" on an unregistered code-input element without a data-code-input-fallback textarea.")}}blur(a={}){this.getTextareaMethod("blur")(a)}checkValidity(){return this.getTextareaMethod("checkValidity")()}focus(a={}){this.getTextareaMethod("focus")(a)}reportValidity(){return this.getTextareaMethod("reportValidity")()}setCustomValidity(a){this.getTextareaMethod("setCustomValidity")(a)}setRangeText(a,b=this.selectionStart,c=this.selectionEnd,d="preserve"){this.getTextareaMethod("setRangeText")(a,b,c,d),this.textareaElement&&this.scheduleHighlight()}setSelectionRange(a,b,c="none"){this.getTextareaMethod("setSelectionRange")(a,b,c)}pluginData={};formResetCallback(){this.value=this.initialValue}}};{class a extends codeInput.Template{constructor(a,b=[],c=!0){super(a.highlightElement,c,!0,!1,b)}}codeInput.templates.Prism=a;class b extends codeInput.Template{constructor(a,b=[],c=!1){super(function(b){b.removeAttribute("data-highlighted"),a.highlightElement(b)},c,!0,!1,b)}}codeInput.templates.Hljs=b}customElements.define("code-input",codeInput.CodeInput);
|
|
12
|
+
*/"use strict";var codeInput={observedAttributes:["value","placeholder","language","lang","template"],textareaSyncAttributes:["value","min","max","type","pattern","autocomplete","autocorrect","autofocus","cols","dirname","disabled","form","maxlength","minlength","name","placeholder","readonly","required","rows","spellcheck","wrap"],textareaSyncEvents:["change","selectionchange","invalid","input","focus","blur","focusin","focusout"],usedTemplates:{},defaultTemplate:void 0,templateNotYetRegisteredQueue:{},registerTemplate:function(a,b){if(!("string"==typeof a||a instanceof String))throw TypeError(`code-input: Name of template "${a}" must be a string.`);if(!("function"==typeof b.highlight||b.highlight instanceof Function))throw TypeError(`code-input: Template for "${a}" invalid, because the highlight function provided is not a function; it is "${b.highlight}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.includeCodeInputInHighlightFunc||b.includeCodeInputInHighlightFunc instanceof Boolean))throw TypeError(`code-input: Template for "${a}" invalid, because the includeCodeInputInHighlightFunc value provided is not a true or false; it is "${b.includeCodeInputInHighlightFunc}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.preElementStyled||b.preElementStyled instanceof Boolean))throw TypeError(`code-input: Template for "${a}" invalid, because the preElementStyled value provided is not a true or false; it is "${b.preElementStyled}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!("boolean"==typeof b.isCode||b.isCode instanceof Boolean))throw TypeError(`code-input: Template for "${a}" invalid, because the isCode value provided is not a true or false; it is "${b.isCode}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(!Array.isArray(b.plugins))throw TypeError(`code-input: Template for "${a}" invalid, because the plugin array provided is not an array; it is "${b.plugins}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`);if(b.plugins.forEach((c,d)=>{if(!(c instanceof codeInput.Plugin))throw TypeError(`code-input: Template for "${a}" invalid, because the plugin provided at index ${d} is not valid; it is "${b.plugins[d]}". Please make sure you use one of the constructors in codeInput.templates, and that you provide the correct arguments.`)}),codeInput.usedTemplates[a]=b,a in codeInput.templateNotYetRegisteredQueue)for(let c in codeInput.templateNotYetRegisteredQueue[a]){const d=codeInput.templateNotYetRegisteredQueue[a][c];d.templateObject=b,d.setup()}if(null==codeInput.defaultTemplate&&(codeInput.defaultTemplate=a,void 0 in codeInput.templateNotYetRegisteredQueue))for(let a in codeInput.templateNotYetRegisteredQueue[void 0]){const c=codeInput.templateNotYetRegisteredQueue[void 0][a];c.templateObject=b,c.setup()}},stylesheetI:0,Template:class{constructor(a=function(){},b=!0,c=!0,d=!1,e=[]){this.highlight=a,this.preElementStyled=b,this.isCode=c,this.includeCodeInputInHighlightFunc=d,this.plugins=e}highlight=function(){};preElementStyled=!0;isCode=!0;includeCodeInputInHighlightFunc=!1;plugins=[]},templates:{prism(a,b=[]){return new codeInput.templates.Prism(a,b)},hljs(a,b=[]){return new codeInput.templates.Hljs(a,b)},characterLimit(a){return{highlight:function(a,b,c=[]){let d=+b.getAttribute("data-character-limit"),e=b.escapeHtml(b.value.slice(0,d)),f=b.escapeHtml(b.value.slice(d));a.innerHTML=`${e}<mark class="overflow">${f}</mark>`,0<f.length&&(a.innerHTML+=` <mark class="overflow-msg">${b.getAttribute("data-overflow-msg")||"(Character limit reached)"}</mark>`)},includeCodeInputInHighlightFunc:!0,preElementStyled:!0,isCode:!1,plugins:a}},rainbowText(a=["red","orangered","orange","goldenrod","gold","green","darkgreen","navy","blue","magenta"],b="",c=[]){return{highlight:function(a,b){let c=[],d=b.value.split(b.template.delimiter);for(let e=0;e<d.length;e++)c.push(`<span style="color: ${b.template.rainbowColors[e%b.template.rainbowColors.length]}">${b.escapeHtml(d[e])}</span>`);a.innerHTML=c.join(b.template.delimiter)},includeCodeInputInHighlightFunc:!0,preElementStyled:!0,isCode:!1,rainbowColors:a,delimiter:b,plugins:c}},character_limit(){return this.characterLimit([])},rainbow_text(a=["red","orangered","orange","goldenrod","gold","green","darkgreen","navy","blue","magenta"],b="",c=[]){return this.rainbowText(a,b,c)},custom(a=function(){},b=!0,c=!0,d=!1,e=[]){return{highlight:a,includeCodeInputInHighlightFunc:d,preElementStyled:b,isCode:c,plugins:e}}},plugins:new Proxy({},{get(a,b){if(a[b]==null)throw ReferenceError(`code-input: Plugin '${b}' is not defined. Please ensure you import the necessary files from the plugins folder in the WebCoder49/code-input repository, in the <head> of your HTML, before the plugin is instatiated.`);return a[b]}}),Plugin:class{constructor(a){a.forEach(a=>{codeInput.observedAttributes.push(a)})}addTranslations(a,b){for(const c in b)a[c]=b[c]}beforeHighlight(){}afterHighlight(){}beforeElementsAdded(){}afterElementsAdded(){}attributeChanged(){}},CodeInput:class extends HTMLElement{constructor(){super()}templateObject=null;textareaElement=null;preElement=null;codeElement=null;dialogContainerElement=null;internalStyle=null;static formAssociated=!0;boundEventCallbacks={};pluginEvt(a,b){for(let c in this.templateObject.plugins){let d=this.templateObject.plugins[c];a in d&&(b===void 0?d[a](this):d[a](this,...b))}}needsHighlight=!1;originalAriaDescription;scheduleHighlight(){this.needsHighlight=!0}animateFrame(){this.needsHighlight&&(this.update(),this.needsHighlight=!1),window.requestAnimationFrame(this.animateFrame.bind(this))}update(){let a=this.codeElement,b=this.value;b+="\n",a.innerHTML=this.escapeHtml(b),this.pluginEvt("beforeHighlight"),this.templateObject.includeCodeInputInHighlightFunc?this.templateObject.highlight(a,this):this.templateObject.highlight(a),this.syncSize(),this.pluginEvt("afterHighlight")}getStyledHighlightingElement(){return this.templateObject.preElementStyled?this.preElement:this.codeElement}syncSize(){this.textareaElement.style.height=getComputedStyle(this.getStyledHighlightingElement()).height,this.textareaElement.style.width=getComputedStyle(this.getStyledHighlightingElement()).width}isColorOverridenSyncIfNot(){const a=this.style.transition;return this.style.transition="unset",window.requestAnimationFrame(()=>{if(this.internalStyle.setProperty("--code-input_no-override-color","rgb(0, 0, 0)"),"rgb(0, 0, 0)"==getComputedStyle(this).color&&(this.internalStyle.setProperty("--code-input_no-override-color","rgb(255, 255, 255)"),"rgb(255, 255, 255)"==getComputedStyle(this).color)){this.internalStyle.removeProperty("--code-input_no-override-color"),this.style.transition=a;const b=getComputedStyle(this.getStyledHighlightingElement()).color;return this.internalStyle.setProperty("--code-input_highlight-text-color",b),this.internalStyle.setProperty("--code-input_default-caret-color",b),!1}this.internalStyle.removeProperty("--code-input_no-override-color"),this.style.transition=a}),!0}syncColorCompletely(){this.isColorOverridenSyncIfNot()&&(this.internalStyle.removeProperty("--code-input_highlight-text-color"),this.internalStyle.setProperty("--code-input_default-caret-color",getComputedStyle(this).color))}setKeyboardNavInstructions(a,b){this.dialogContainerElement.querySelector(".code-input_keyboard-navigation-instructions").innerText=a,b?this.textareaElement.setAttribute("aria-description",this.originalAriaDescription+". "+a):this.textareaElement.setAttribute("aria-description",a)}escapeHtml(a){return a.replace(/&/g,"&").replace(/</g,"<")}unescapeHtml(a){return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}getTemplate(){let a;return a=null==this.getAttribute("template")?codeInput.defaultTemplate:this.getAttribute("template"),a in codeInput.usedTemplates?codeInput.usedTemplates[a]:(a in codeInput.templateNotYetRegisteredQueue||(codeInput.templateNotYetRegisteredQueue[a]=[]),void codeInput.templateNotYetRegisteredQueue[a].push(this))}setup(){if(null!=this.textareaElement)return;this.classList.add("code-input_registered"),this.mutationObserver=new MutationObserver(this.mutationObserverCallback.bind(this)),this.mutationObserver.observe(this,{attributes:!0,attributeOldValue:!0}),this.classList.add("code-input_registered"),this.templateObject.preElementStyled&&this.classList.add("code-input_pre-element-styled");const a=this.querySelector("textarea[data-code-input-fallback]");let b,c,d,e,f,g=!1;a&&(a===document.activeElement&&(g=!0),b=a.selectionStart,c=a.selectionEnd,d=a.selectionDirection,e=a.scrollLeft,f=a.scrollTop);let h;if(a){let b=a.getAttributeNames();for(let c=0;c<b.length;c++){const d=b[c];"data-code-input-fallback"!=d&&(this.hasAttribute(d)||this.setAttribute(d,a.getAttribute(d)))}h=a.value,this.innerHTML=this.escapeHtml(h)}else h=this.unescapeHtml(this.innerHTML);h=h||this.getAttribute("value")||"",this.pluginEvt("beforeElementsAdded");const i=this.getAttribute("language")||this.getAttribute("lang"),j=this.getAttribute("placeholder")||i||"";this.initialValue=h;const k=document.createElement("textarea");k.placeholder=j,""!=h&&(k.value=h),k.innerHTML=this.innerHTML,this.hasAttribute("spellcheck")||k.setAttribute("spellcheck","false"),k.setAttribute("tabindex",this.getAttribute("tabindex")||0),this.setAttribute("tabindex",-1),this.originalAriaDescription=this.getAttribute("aria-description")||"Code input field",this.addEventListener("mousedown",()=>{this.classList.add("code-input_mouse-focused"),window.setTimeout(()=>{this.syncSize()},0)}),k.addEventListener("blur",()=>{this.classList.remove("code-input_mouse-focused"),window.setTimeout(()=>{this.syncSize()},0)}),k.addEventListener("focus",()=>{window.setTimeout(()=>{this.syncSize()},0)}),this.innerHTML="";for(let a,b=0;b<this.attributes.length;b++)a=this.attributes[b].name,(codeInput.textareaSyncAttributes.includes(a)||"aria-"==a.substring(0,5))&&k.setAttribute(a,this.getAttribute(a));k.addEventListener("input",()=>{this.value=this.textareaElement.value}),this.textareaElement=k,this.append(k),this.setupTextareaSyncEvents(this.textareaElement);let l=document.createElement("code"),m=document.createElement("pre");m.setAttribute("aria-hidden","true"),m.setAttribute("tabindex","-1"),m.setAttribute("inert",!0),this.preElement=m,this.codeElement=l,m.append(l),this.append(m),this.templateObject.isCode&&i!=null&&""!=i&&l.classList.add("language-"+i.toLowerCase());let n=document.createElement("div");n.classList.add("code-input_dialog-container"),this.append(n),this.dialogContainerElement=n;let o=document.createElement("div");o.classList.add("code-input_keyboard-navigation-instructions"),n.append(o),this.pluginEvt("afterElementsAdded"),this.dispatchEvent(new CustomEvent("code-input_load")),this.value=h,b!==void 0&&(k.setSelectionRange(b,c,d),k.scrollTo(f,e)),g&&k.focus(),this.animateFrame();const p=new ResizeObserver(()=>{this.syncSize()});p.observe(this),this.classList.add("code-input_styles_"+codeInput.stylesheetI);const q=document.createElement("style");q.innerHTML="code-input.code-input_styles_"+codeInput.stylesheetI+" {}",this.appendChild(q),this.internalStyle=q.sheet.cssRules[0].style,codeInput.stylesheetI++;const r=a=>{"color"==a.propertyName&&this.isColorOverridenSyncIfNot()};this.preElement.addEventListener("transitionend",r),this.preElement.addEventListener("-webkit-transitionend",r);const s=a=>{"color"==a.propertyName&&this.syncColorCompletely(),a.target==this.dialogContainerElement&&a.stopPropagation()};this.dialogContainerElement.addEventListener("transitionend",s),this.dialogContainerElement.addEventListener("-webkit-transitionend",s),this.addEventListener("transitionend",s),this.addEventListener("-webkit-transitionend",s),this.syncColorCompletely(),this.classList.add("code-input_loaded")}escape_html(a){return this.escapeHtml(a)}get_template(){return this.getTemplate()}get template(){return this.templateObject}set template(a){}connectedCallback(){if(this.templateObject=this.getTemplate(),null!=this.templateObject&&(this.classList.add("code-input_registered"),"loading"===document.readyState?window.addEventListener("DOMContentLoaded",this.setup.bind(this)):this.setup()),"loading"===document.readyState)window.addEventListener("DOMContentLoaded",()=>{const a=this.querySelector("textarea[data-code-input-fallback]");a&&this.setupTextareaSyncEvents(a)});else{const a=this.querySelector("textarea[data-code-input-fallback]");a&&this.setupTextareaSyncEvents(a)}}mutationObserverCallback(a){for(const b of a)if("attributes"===b.type){for(let a=0;a<codeInput.observedAttributes.length;a++)if(b.attributeName==codeInput.observedAttributes[a])return this.attributeChangedCallback(b.attributeName,b.oldValue,super.getAttribute(b.attributeName));for(let a=0;a<codeInput.textareaSyncAttributes.length;a++)if(b.attributeName==codeInput.textareaSyncAttributes[a])return this.attributeChangedCallback(b.attributeName,b.oldValue,super.getAttribute(b.attributeName));if("aria-"==b.attributeName.substring(0,5))return this.attributeChangedCallback(b.attributeName,b.oldValue,super.getAttribute(b.attributeName))}}disconnectedCallback(){this.mutationObserver&&this.mutationObserver.disconnect()}attributeChangedCallback(a,b,c){if(this.isConnected)switch(this.pluginEvt("attributeChanged",[a,b,c]),a){case"value":this.value=c;break;case"template":this.templateObject=codeInput.usedTemplates[c||codeInput.defaultTemplate],this.templateObject.preElementStyled?this.classList.add("code-input_pre-element-styled"):this.classList.remove("code-input_pre-element-styled"),this.scheduleHighlight();break;case"lang":case"language":let d=this.codeElement,e=this.textareaElement;if(null!=c&&(c=c.toLowerCase(),d.classList.contains(`language-${c}`)))break;null!==b&&(b=b.toLowerCase(),d.classList.remove("language-"+b),d.parentElement.classList.remove("language-"+b)),d.classList.remove("language-none"),d.parentElement.classList.remove("language-none"),null!=c&&""!=c&&d.classList.add("language-"+c),(e.placeholder==b||null==b&&""==e.placeholder)&&(e.placeholder=c),this.scheduleHighlight();break;default:codeInput.textareaSyncAttributes.includes(a)||"aria-"==a.substring(0,5)?null==c||null==c?this.textareaElement.removeAttribute(a):this.textareaElement.setAttribute(a,c):codeInput.textareaSyncAttributes.regexp.forEach(b=>{a.match(b)&&(null==c?this.textareaElement.removeAttribute(a):this.textareaElement.setAttribute(a,c))})}}setupTextareaSyncEvents(a){for(let b=0;b<codeInput.textareaSyncEvents.length;b++){const c=codeInput.textareaSyncEvents[b];a.addEventListener(c,a=>{a.bubbles||this.dispatchEvent(new a.constructor(a.type,a))})}}addEventListener(a,b,c=void 0){let d=function(a){"function"==typeof b?b(a):b&&b.handleEvent&&b.handleEvent(a)}.bind(this);if(this.boundEventCallbacks[b]=d,!codeInput.textareaSyncEvents.includes(a))void 0===c?super.addEventListener(a,d):super.addEventListener(a,d,c);else if(this.boundEventCallbacks[b]=d,void 0===c){if(null==this.textareaElement){const b=this.querySelector("textarea[data-code-input-fallback]");b&&b.addEventListener(a,d),this.addEventListener("code-input_load",()=>{this.textareaElement.addEventListener(a,d)})}else this.textareaElement.addEventListener(a,d);}else if(null==this.textareaElement){const b=this.querySelector("textarea[data-code-input-fallback]");b&&b.addEventListener(a,d,c),this.addEventListener("code-input_load",()=>{this.textareaElement.addEventListener(a,d,c)})}else this.textareaElement.addEventListener(a,d,c)}removeEventListener(a,b,c=void 0){let d=this.boundEventCallbacks[b];if(!codeInput.textareaSyncEvents.includes(a))void 0===c?super.removeEventListener(a,d):super.removeEventListener(a,d,c);else if(void 0===c){if(null==this.textareaElement){const b=this.querySelector("textarea[data-code-input-fallback]");b&&b.removeEventListener(a,d),this.addEventListener("code-input_load",()=>{this.textareaElement.removeEventListener(a,d)})}else this.textareaElement.removeEventListener(a,d);}else if(null==this.textareaElement){const b=this.querySelector("textarea[data-code-input-fallback]");b&&b.removeEventListener(a,d,c),this.addEventListener("code-input_load",()=>{this.textareaElement.removeEventListener(a,d,c)})}else this.textareaElement.removeEventListener(a,d,c)}getTextareaProperty(a,b=void 0){if(this.textareaElement)return this.textareaElement[a];else{const c=this.querySelector("textarea[data-code-input-fallback]");if(c)return c[a];if(void 0===b)throw new Error("Cannot get "+a+" of an unregistered code-input element without a data-code-input-fallback textarea.");return b}}setTextareaProperty(a,b,c=!0){if(this.textareaElement)this.textareaElement[a]=b;else{const d=this.querySelector("textarea[data-code-input-fallback]");if(d)d[a]=b;else{if(!c)return(!1);throw new Error("Cannot set "+a+" of an unregistered code-input element without a data-code-input-fallback textarea.")}}return(!0)}get autocomplete(){return this.getAttribute("autocomplete")}set autocomplete(a){return this.setAttribute("autocomplete",a)}get cols(){return this.getTextareaProperty("cols",+this.getAttribute("cols"))}set cols(a){this.setAttribute("cols",a)}get defaultValue(){return this.initialValue}set defaultValue(a){this.initialValue=a}get textContent(){return this.initialValue}set textContent(a){this.initialValue=a}get dirName(){return this.getAttribute("dirName")||""}set dirName(a){this.setAttribute("dirname",a)}get disabled(){return this.hasAttribute("disabled")}set disabled(a){a?this.setAttribute("disabled",!0):this.removeAttribute("disabled")}get form(){return this.getTextareaProperty("form")}get labels(){return this.getTextareaProperty("labels")}get maxLength(){const a=+this.getAttribute("maxlength");return isNaN(a)?-1:a}set maxLength(a){-1==a?this.removeAttribute("maxlength"):this.setAttribute("maxlength",a)}get minLength(){const a=+this.getAttribute("minlength");return isNaN(a)?-1:a}set minLength(a){-1==a?this.removeAttribute("minlength"):this.setAttribute("minlength",a)}get name(){return this.getAttribute("name")||""}set name(a){this.setAttribute("name",a)}get placeholder(){return this.getAttribute("placeholder")||""}set placeholder(a){this.setAttribute("placeholder",a)}get readOnly(){return this.hasAttribute("readonly")}set readOnly(a){a?this.setAttribute("readonly",!0):this.removeAttribute("readonly")}get required(){return this.hasAttribute("readonly")}set required(a){a?this.setAttribute("readonly",!0):this.removeAttribute("readonly")}get rows(){return this.getTextareaProperty("rows",+this.getAttribute("rows"))}set rows(a){this.setAttribute("rows",a)}get selectionDirection(){return this.getTextareaProperty("selectionDirection")}set selectionDirection(a){this.setTextareaProperty("selectionDirection",a)}get selectionEnd(){return this.getTextareaProperty("selectionEnd")}set selectionEnd(a){this.setTextareaProperty("selectionEnd",a)}get selectionStart(){return this.getTextareaProperty("selectionStart")}set selectionStart(a){this.setTextareaProperty("selectionStart",a)}get textLength(){return this.value.length}get type(){return"textarea"}get validationMessage(){return this.getTextareaProperty("validationMessage")}get validity(){return this.getTextareaProperty("validationMessage")}get value(){return this.getTextareaProperty("value",this.getAttribute("value")||this.innerHTML)}set value(a){a=a||"",this.setTextareaProperty("value",a,!1)?this.textareaElement&&this.scheduleHighlight():this.innerHTML=a}get willValidate(){return this.getTextareaProperty("willValidate",this.disabled||this.readOnly)}get wrap(){return this.getAttribute("wrap")||""}set wrap(a){this.setAttribute("wrap",a)}getTextareaMethod(a){if(this.textareaElement)return this.textareaElement[a].bind(this.textareaElement);else{const b=this.querySelector("textarea[data-code-input-fallback]");if(b)return b[a].bind(b);throw new Error("Cannot call "+a+" on an unregistered code-input element without a data-code-input-fallback textarea.")}}blur(a={}){this.getTextareaMethod("blur")(a)}checkValidity(){return this.getTextareaMethod("checkValidity")()}focus(a={}){this.getTextareaMethod("focus")(a)}reportValidity(){return this.getTextareaMethod("reportValidity")()}setCustomValidity(a){this.getTextareaMethod("setCustomValidity")(a)}setRangeText(a,b=this.selectionStart,c=this.selectionEnd,d="preserve"){this.getTextareaMethod("setRangeText")(a,b,c,d),this.textareaElement&&this.scheduleHighlight()}setSelectionRange(a,b,c="none"){this.getTextareaMethod("setSelectionRange")(a,b,c)}pluginData={};formResetCallback(){this.value=this.initialValue}}};{class a extends codeInput.Template{constructor(a,b=[],c=!0){super(a.highlightElement,c,!0,!1,b)}}codeInput.templates.Prism=a;class b extends codeInput.Template{constructor(a,b=[],c=!1){super(function(b){b.removeAttribute("data-highlighted"),a.highlightElement(b)},c,!0,!1,b)}}codeInput.templates.Hljs=b}customElements.define("code-input",codeInput.CodeInput);
|
package/docs/_index.md
CHANGED
|
@@ -11,7 +11,11 @@ Aiming to be [more <mark>flexible</mark>, <mark>lightweight</mark>,
|
|
|
11
11
|
[HTML forms](interface/forms), the [`<textarea>` JavaScript interface](interface/js), more languages and
|
|
12
12
|
more use cases.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
## Download
|
|
15
|
+
|
|
16
|
+
*code-input.js is free, libre, open source software under the MIT (AKA Expat) license.* **Download it [from the Git repository](https://github.com/WebCoder49/code-input/tree/v2.7.1), [in a ZIP archive](/release/code-input-js-v2.7.1.zip), [in a TAR.GZ archive](/release/code-input-js-v2.7.1.tar.gz), or from `@webcoder49/code-input` on the NPM registry ([Yarn](https://yarnpkg.com/package?name=@webcoder49/code-input), [NPM](https://npmjs.com/package/@webcoder49/code-input), etc.).**
|
|
17
|
+
|
|
18
|
+
[Want to contribute to the code? You're very welcome to! See here.](#contributing)
|
|
15
19
|
|
|
16
20
|
## Get Started with a Demo
|
|
17
21
|
|
|
@@ -33,9 +37,9 @@ more use cases.
|
|
|
33
37
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.30/components/prism-core.min.js" data-manual></script><!--Remove data-manual if also using Prism normally-->
|
|
34
38
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.30/plugins/autoloader/prism-autoloader.min.js"></script>
|
|
35
39
|
<!--2. Import code-input-js-->
|
|
36
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
37
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
38
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
40
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.js"></script>
|
|
41
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.css">
|
|
42
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/indent.min.js"></script>
|
|
39
43
|
<!--3. Join code-input-js to highlighter-->
|
|
40
44
|
<script>codeInput.registerTemplate("syntax-highlighted", new codeInput.templates.Prism(Prism, [new codeInput.plugins.Indent()]));</script>
|
|
41
45
|
</head>
|
|
@@ -72,13 +76,13 @@ console.log("Hello, World!");</textarea></code-input>
|
|
|
72
76
|
|
|
73
77
|
<!--Import code-input-->
|
|
74
78
|
<!--The same goes for downloaded versions.-->
|
|
75
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
76
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
79
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.js"></script>
|
|
80
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.css">
|
|
77
81
|
|
|
78
82
|
<!--Import some code-input plugins-->
|
|
79
83
|
<!--The same goes for downloaded versions.-->
|
|
80
84
|
<!--Plugin files are here: https://code-input-js.org/plugins.-->
|
|
81
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
85
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/indent.min.js"></script>
|
|
82
86
|
|
|
83
87
|
<!--Register code-input template-->
|
|
84
88
|
<!--This can be before the code-input element is created, in which case it will defer the registration of all code-input
|
|
@@ -132,13 +136,13 @@ console.log("Hello, World!");</textarea></code-input>
|
|
|
132
136
|
|
|
133
137
|
<!--Import code-input-->
|
|
134
138
|
<!--The same goes for downloaded versions.-->
|
|
135
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
136
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
139
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.js"></script>
|
|
140
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.css">
|
|
137
141
|
|
|
138
142
|
<!--Import some code-input plugins-->
|
|
139
143
|
<!--The same goes for downloaded versions.-->
|
|
140
144
|
<!--Plugin files are here: https://code-input-js.org/plugins.-->
|
|
141
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
145
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/indent.min.js"></script>
|
|
142
146
|
|
|
143
147
|
<!--Register code-input template-->
|
|
144
148
|
<!--This can be before the code-input element is created, in which case it will defer the registration of all code-input
|
|
@@ -180,13 +184,13 @@ console.log("Hello, World!");</textarea></code-input>
|
|
|
180
184
|
|
|
181
185
|
<!--Import code-input-->
|
|
182
186
|
<!--The same goes for downloaded versions.-->
|
|
183
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
184
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
187
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.js"></script>
|
|
188
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.css">
|
|
185
189
|
|
|
186
190
|
<!--Import some code-input plugins-->
|
|
187
191
|
<!--The same goes for downloaded versions.-->
|
|
188
192
|
<!--Plugin files are here: https://code-input-js.org/plugins.-->
|
|
189
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
193
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/indent.min.js"></script>
|
|
190
194
|
|
|
191
195
|
<!--Register code-input template-->
|
|
192
196
|
<!--This can be before the code-input element is created, in which case it will defer the registration of all code-input
|
|
@@ -313,6 +317,8 @@ something like [CodeMirror](https://codemirror.net/),
|
|
|
313
317
|
|
|
314
318
|
## Contribute Bug Reports / Code / Docs {#contributing}
|
|
315
319
|
|
|
320
|
+
**An even more lightweight, flexible and clean major version 3 is being planned. Please come and participate with your feedback/ideas [on GitHub](https://github.com/WebCoder49/code-input/issues/190) or [via email to code-input-js+v3@webcoder49.dev](mailto:code-input-js+v3@webcoder49.dev)!**
|
|
321
|
+
|
|
316
322
|
🎉 code-input.js is collaboratively developed by many people, which is what keeps it going strong. Many have reported bugs and suggestions, and [10 people (see them on GitHub)](https://github.com/WebCoder49/code-input/graphs/contributors) have contributed code or documentation directly. If you have found a bug, would like to help with the code or documentation, or have additional suggestions, for plugins or core functionality, [please look at GitHub](https://github.com/WebCoder49/code-input/tree/main/CONTRIBUTING.md) or [get in touch via email so I can add it for you](mailto:code-input-js@webcoder49.dev). **Found a security vulnerability? [Please use this email address](mailto:security@webcoder49.dev), after reading ([this page with an encryption key](https://oliver.geer.im/#email)).**
|
|
317
323
|
|
|
318
324
|
*I'm looking into mirroring code-input.js onto Codeberg as well as GitHub for more flexibility and freedom - if you have ideas for this please get in touch!*
|
|
@@ -7,6 +7,10 @@ title = 'Styling `code-input` elements with CSS'
|
|
|
7
7
|
> Contributors: 2025 Oliver Geer
|
|
8
8
|
|
|
9
9
|
`code-input` elements can be styled like `textarea` elements in most cases; however, there are some exceptions:
|
|
10
|
-
* The CSS variable `--padding` should be used rather than the property `padding` (e.g. `<code-input style="--padding: 10px;">...`), or `--padding-left`, `--padding-right`, `--padding-top` and `--padding-bottom` instead of the CSS properties of the same names. For technical reasons, the value must have a unit (i.e. `0px`, not `0`).
|
|
10
|
+
* The CSS variable `--padding` should be used rather than the property `padding` (e.g. `<code-input style="--padding: 10px;">...`), or `--padding-left`, `--padding-right`, `--padding-top` and `--padding-bottom` instead of the CSS properties of the same names. For technical reasons, the value must have a unit (i.e. `0px`, not `0`). To avoid overcomplicating the code, this padding is always *included in* any width/heights of `code-input` elements, so if you want to style `textarea`s and `code-input` elements with best consistency set `box-sizing: border-box` on them.
|
|
11
11
|
* Background colours set on `code-input` elements will not work with highlighters that set background colours themselves - use `(code-input's selector) pre[class*="language-"]` for Prism.js or `.hljs` for highlight.js to target the highlighted element with higher specificity than the highlighter's theme. You may also set the `background-color` of the code-input element for its appearance when its template is unregistered / there is no JavaScript.
|
|
12
|
+
* The caret and placeholder colour by default follow and give good contrast with the highlighted theme. Setting a CSS rule for `color` and/or `caret-color` properties on the code-input element will override this behaviour.
|
|
13
|
+
* For technical reasons, `code-input:focus` won't match anything. Use `code-input:has(textarea:focus)` instead.
|
|
12
14
|
* For now, elements on top of `code-input` elements should have a CSS `z-index` at least 3 greater than the `code-input` element.
|
|
15
|
+
|
|
16
|
+
Please do **not** use `className` in JavaScript referring to code-input elements, because the code-input library needs to add its own classes to code-input elements for easier progressive enhancement. You can, however, use `classList` and `style` as much as you want - it will make your code cleaner anyway.
|
|
@@ -6,6 +6,19 @@ title = '`code-input` vs the `textarea` in JavaScript'
|
|
|
6
6
|
|
|
7
7
|
> Contributors: 2025 Oliver Geer
|
|
8
8
|
|
|
9
|
-
Once registered, `code-input` elements support the JavaScript properties and events used with a `textarea` element, because they are built around them. Try swapping out your `textarea` element in your JavaScript application for a `code-input`! If it doesn't work, [submit a bug report](https://github.com/WebCoder49/code-input/issues).
|
|
9
|
+
[Once registered](#code-input_load), `code-input` elements support the JavaScript properties and events used with a `textarea` element, because they are built around them. Try swapping out your `textarea` element in your JavaScript application for a `code-input`! If it doesn't work, [submit a bug report](https://github.com/WebCoder49/code-input/issues).
|
|
10
10
|
|
|
11
11
|
If you want to replace a `textarea` with a `code-input` in an application that doesn't need JavaScript, [look here](../forms). We support HTML5 forms, and progressive enhancement so JavaScript isn't needed!
|
|
12
|
+
|
|
13
|
+
## The `code-input_load` event {code-input_load}
|
|
14
|
+
|
|
15
|
+
Each `code-input` element fires a `code-input_load` event when it, its template and its plugins have been fully registered. You should carry out initialisation code for `code-input` elements in a handler for this event:
|
|
16
|
+
```javascript
|
|
17
|
+
// TODO: Get code-input element as codeInputElement
|
|
18
|
+
codeInputElement.addEventListener("code-input_load", () => {
|
|
19
|
+
// TODO: Initialisation code
|
|
20
|
+
// TODO: Add event handlers to the element here.
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
For backwards compatibility, you should also implement the subset of the functionality that doesn't require `code-input.js` on the `<textarea data-code-input-fallback>` element before load, if you have one. For backwards compatibility and technical reasons, event handlers registered in HTML attributes like `onchange` of the textarea will be passed to the code-input element when it is registered, but event listeners registered like that above will not - this should be cleaned up in major version 3.
|
package/docs/plugins/_index.md
CHANGED
|
@@ -23,13 +23,13 @@ Right now, you can only add one plugin of each type (e.g. one SelectTokenCallbac
|
|
|
23
23
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js" data-manual></script><!--Remove data-manual if also using Prism normally-->
|
|
24
24
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
|
25
25
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css"></link>
|
|
26
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
27
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
26
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.js"></script>
|
|
27
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.css">
|
|
28
28
|
|
|
29
29
|
<!--Import-->
|
|
30
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
30
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/auto-close-brackets.min.js"></script>
|
|
31
31
|
<!--Not necessary, but works very well with the Indent plugin-->
|
|
32
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
32
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/indent.min.js"></script>
|
|
33
33
|
|
|
34
34
|
<script>
|
|
35
35
|
codeInput.registerTemplate("syntax-highlighted", new codeInput.templates.Prism(Prism, [
|
|
@@ -60,12 +60,12 @@ Right now, you can only add one plugin of each type (e.g. one SelectTokenCallbac
|
|
|
60
60
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js" data-manual></script><!--Remove data-manual if also using Prism normally-->
|
|
61
61
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
|
62
62
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css"></link>
|
|
63
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
64
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
63
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.js"></script>
|
|
64
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.css">
|
|
65
65
|
|
|
66
66
|
<!--Import-->
|
|
67
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
68
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
67
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/autocomplete.min.js"></script>
|
|
68
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/autocomplete.min.css">
|
|
69
69
|
|
|
70
70
|
|
|
71
71
|
<script>
|
|
@@ -95,6 +95,7 @@ Right now, you can only add one plugin of each type (e.g. one SelectTokenCallbac
|
|
|
95
95
|
let autocompleteButton = document.createElement("button");
|
|
96
96
|
autocompleteButton.innerHTML = "<i>" + tag.substring(0, start_tag.length) + "</i>" + tag.substring(start_tag.length, tag.length);
|
|
97
97
|
autocompleteButton.addEventListener("click", () => {
|
|
98
|
+
textarea.parentElement.focus();
|
|
98
99
|
document.execCommand("insertText", false, tag.substring(start_tag.length, tag.length));
|
|
99
100
|
popupElem.innerHTML = ""; // On popup
|
|
100
101
|
});
|
|
@@ -103,18 +104,18 @@ Right now, you can only add one plugin of each type (e.g. one SelectTokenCallbac
|
|
|
103
104
|
});
|
|
104
105
|
|
|
105
106
|
if(popupElem.firstElementChild != null) {
|
|
106
|
-
|
|
107
|
+
popupElem.firstElementChild.innerHTML += "[Tab]";
|
|
107
108
|
}
|
|
108
109
|
textarea.addEventListener("keydown", (event) => {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
if(event.key == "Tab" && popupElem.firstElementChild != null) {
|
|
111
|
+
popupElem.firstElementChild.click();
|
|
112
|
+
event.preventDefault();
|
|
113
|
+
}
|
|
113
114
|
})
|
|
114
115
|
}
|
|
115
116
|
// Pass at register
|
|
116
117
|
codeInput.registerTemplate("syntax-highlighted", new codeInput.templates.Prism(Prism, [
|
|
117
|
-
|
|
118
|
+
new codeInput.plugins.Autocomplete(updatePopup) // See above
|
|
118
119
|
]));
|
|
119
120
|
</script>
|
|
120
121
|
<p>Start typing some HTML tags to see the autocomplete in action. You can click an autocomplete suggestion, or press the Tab key to select the first.</p>
|
|
@@ -134,12 +135,12 @@ Right now, you can only add one plugin of each type (e.g. one SelectTokenCallbac
|
|
|
134
135
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js" data-manual></script><!--Remove data-manual if also using Prism normally-->
|
|
135
136
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
|
136
137
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css"></link>
|
|
137
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
138
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
138
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.js"></script>
|
|
139
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.css">
|
|
139
140
|
|
|
140
141
|
<!--Import-->
|
|
141
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
142
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
142
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/find-and-replace.min.js"></script>
|
|
143
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/find-and-replace.min.css"/>
|
|
143
144
|
|
|
144
145
|
<script>
|
|
145
146
|
let findAndReplacePlugin = new codeInput.plugins.FindAndReplace(
|
|
@@ -183,14 +184,14 @@ Hickory dickory dock.</code-input>
|
|
|
183
184
|
<!--Not necessary, but works very well with the Prism line-numbers plugin-->
|
|
184
185
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/line-numbers/prism-line-numbers.min.js"></script>
|
|
185
186
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/line-numbers/prism-line-numbers.min.css">
|
|
186
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
187
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
187
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.js"></script>
|
|
188
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.css">
|
|
188
189
|
|
|
189
190
|
<!--Import-->
|
|
190
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
191
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
191
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/go-to-line.min.js"></script>
|
|
192
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/go-to-line.min.css"/>
|
|
192
193
|
<!--Not necessary, but works very well with the Prism line-numbers plugin-->
|
|
193
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
194
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/prism-line-numbers.min.css"/>
|
|
194
195
|
|
|
195
196
|
<script>
|
|
196
197
|
let goToLinePlugin = new codeInput.plugins.GoToLine(
|
|
@@ -227,11 +228,11 @@ Hickory dickory dock.</code-input>
|
|
|
227
228
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js" data-manual></script><!--Remove data-manual if also using Prism normally-->
|
|
228
229
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
|
229
230
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css"></link>
|
|
230
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
231
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
231
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.js"></script>
|
|
232
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.css">
|
|
232
233
|
|
|
233
234
|
<!--Import-->
|
|
234
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
235
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/indent.min.js"></script>
|
|
235
236
|
|
|
236
237
|
<script>
|
|
237
238
|
// Programatically opening the dialogs, to integrate with your user interface
|
|
@@ -500,11 +501,11 @@ Hickory dickory dock.</code-input>
|
|
|
500
501
|
</script>
|
|
501
502
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/match-braces/prism-match-braces.min.css"/>
|
|
502
503
|
|
|
503
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
504
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
504
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.js"></script>
|
|
505
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.css">
|
|
505
506
|
|
|
506
507
|
<!--Import-->
|
|
507
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
508
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/select-token-callbacks.min.js"></script>
|
|
508
509
|
</head>
|
|
509
510
|
<body>
|
|
510
511
|
<!--For convenience, this demo uses files from JSDelivr CDN; for more privacy and security download and host them yourself.-->
|
|
@@ -567,12 +568,12 @@ See https://github.com/WebCoder49/code-input/issues?q=is%3Aissue%20state%3Aopen%
|
|
|
567
568
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js" data-manual></script><!--Remove data-manual if also using Prism normally-->
|
|
568
569
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
|
569
570
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css"></link>
|
|
570
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
571
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
571
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.js"></script>
|
|
572
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.css">
|
|
572
573
|
|
|
573
574
|
<!--Import-->
|
|
574
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
575
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
575
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/special-chars.min.js"></script>
|
|
576
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/special-chars.min.css"></script>
|
|
576
577
|
|
|
577
578
|
<script>
|
|
578
579
|
codeInput.registerTemplate("syntax-highlighted", new codeInput.templates.Prism(Prism, [
|
|
@@ -612,12 +613,12 @@ See https://github.com/WebCoder49/code-input/issues?q=is%3Aissue%20state%3Aopen%
|
|
|
612
613
|
<!--highlight.js+code-input-->
|
|
613
614
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css">
|
|
614
615
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
|
|
615
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
616
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
616
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.js"></script>
|
|
617
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.css">
|
|
617
618
|
|
|
618
619
|
|
|
619
620
|
<!--Import-->
|
|
620
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
621
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/autodetect.min.js"></script>
|
|
621
622
|
|
|
622
623
|
<script>
|
|
623
624
|
codeInput.registerTemplate("syntax-highlighted", new codeInput.templates.Hljs(hljs, [
|
|
@@ -625,7 +626,7 @@ See https://github.com/WebCoder49/code-input/issues?q=is%3Aissue%20state%3Aopen%
|
|
|
625
626
|
new codeInput.plugins.Autodetect()
|
|
626
627
|
]));
|
|
627
628
|
</script>
|
|
628
|
-
<p>Start typing code of any language. <
|
|
629
|
+
<p>Start typing code of any language. <strong>Detected language: <span id="language"></span></strong>. Inaccurate language detection should be reported to <a target="_blank" href="https://highlightjs.org">highlight.js</a>, not code-input-js.</p>
|
|
629
630
|
<code-input oninput="document.getElementById('language').textContent = this.getAttribute('language');"></code-input>
|
|
630
631
|
<p></p>
|
|
631
632
|
</body>
|
|
@@ -645,14 +646,14 @@ See https://github.com/WebCoder49/code-input/issues?q=is%3Aissue%20state%3Aopen%
|
|
|
645
646
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js" data-manual></script><!--Remove data-manual if also using Prism normally-->
|
|
646
647
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
|
647
648
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css"></link>
|
|
648
|
-
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
649
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
649
|
+
<script src="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.js"></script>
|
|
650
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/code-input.min.css">
|
|
650
651
|
|
|
651
652
|
|
|
652
653
|
<!--Import-->
|
|
653
654
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/line-numbers/prism-line-numbers.min.js"></script>
|
|
654
655
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/line-numbers/prism-line-numbers.min.css">
|
|
655
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.
|
|
656
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/code-input@2.7/plugins/prism-line-numbers.min.css"/>
|
|
656
657
|
|
|
657
658
|
<script>
|
|
658
659
|
codeInput.registerTemplate("syntax-highlighted", new codeInput.templates.Prism(Prism, [
|
package/esm/code-input.mjs
CHANGED
|
@@ -154,6 +154,8 @@ var codeInput = {
|
|
|
154
154
|
}
|
|
155
155
|
},
|
|
156
156
|
|
|
157
|
+
stylesheetI: 0, // Increments to give different classes to each code-input element so they can have custom styles synchronised internally without affecting the inline style
|
|
158
|
+
|
|
157
159
|
/**
|
|
158
160
|
* Please see `codeInput.templates.prism` or `codeInput.templates.hljs`.
|
|
159
161
|
* Templates are used in `<code-input>` elements and once registered with
|
|
@@ -343,6 +345,16 @@ var codeInput = {
|
|
|
343
345
|
*/
|
|
344
346
|
dialogContainerElement = null;
|
|
345
347
|
|
|
348
|
+
/**
|
|
349
|
+
* Like style attribute, but with a specificity of 1
|
|
350
|
+
* element, 1 class. Present so styles can be set on only
|
|
351
|
+
* this element while giving other code freedom of use of
|
|
352
|
+
* the style attribute.
|
|
353
|
+
*
|
|
354
|
+
* For internal use only.
|
|
355
|
+
*/
|
|
356
|
+
internalStyle = null;
|
|
357
|
+
|
|
346
358
|
/**
|
|
347
359
|
* Form-Associated Custom Element Callbacks
|
|
348
360
|
* https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-face-example
|
|
@@ -428,22 +440,75 @@ var codeInput = {
|
|
|
428
440
|
this.pluginEvt("afterHighlight");
|
|
429
441
|
}
|
|
430
442
|
|
|
443
|
+
getStyledHighlightingElement() {
|
|
444
|
+
if(this.templateObject.preElementStyled) {
|
|
445
|
+
return this.preElement;
|
|
446
|
+
} else {
|
|
447
|
+
return this.codeElement;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
431
451
|
/**
|
|
432
452
|
* Set the size of the textarea element to the size of the pre/code element.
|
|
433
453
|
*/
|
|
434
454
|
syncSize() {
|
|
435
455
|
// Synchronise the size of the pre/code and textarea elements
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
456
|
+
this.textareaElement.style.height = getComputedStyle(this.getStyledHighlightingElement()).height;
|
|
457
|
+
this.textareaElement.style.width = getComputedStyle(this.getStyledHighlightingElement()).width;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* If the color attribute has been defined on the
|
|
462
|
+
* code-input element by external code, return true.
|
|
463
|
+
* Otherwise, make the aspects the color affects
|
|
464
|
+
* (placeholder and caret colour) be the base colour
|
|
465
|
+
* of the highlighted text, for best contrast, and
|
|
466
|
+
* return false.
|
|
467
|
+
*/
|
|
468
|
+
isColorOverridenSyncIfNot() {
|
|
469
|
+
const oldTransition = this.style.transition;
|
|
470
|
+
this.style.transition = "unset";
|
|
471
|
+
window.requestAnimationFrame(() => {
|
|
472
|
+
this.internalStyle.setProperty("--code-input_no-override-color", "rgb(0, 0, 0)");
|
|
473
|
+
if(getComputedStyle(this).color == "rgb(0, 0, 0)") {
|
|
474
|
+
// May not be overriden
|
|
475
|
+
this.internalStyle.setProperty("--code-input_no-override-color", "rgb(255, 255, 255)");
|
|
476
|
+
if(getComputedStyle(this).color == "rgb(255, 255, 255)") {
|
|
477
|
+
// Definitely not overriden
|
|
478
|
+
this.internalStyle.removeProperty("--code-input_no-override-color");
|
|
479
|
+
this.style.transition = oldTransition;
|
|
480
|
+
|
|
481
|
+
const highlightedTextColor = getComputedStyle(this.getStyledHighlightingElement()).color;
|
|
482
|
+
|
|
483
|
+
this.internalStyle.setProperty("--code-input_highlight-text-color", highlightedTextColor);
|
|
484
|
+
this.internalStyle.setProperty("--code-input_default-caret-color", highlightedTextColor);
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
this.internalStyle.removeProperty("--code-input_no-override-color");
|
|
489
|
+
this.style.transition = oldTransition;
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
return true;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Update the aspects the color affects
|
|
497
|
+
* (placeholder and caret colour) to the correct
|
|
498
|
+
* colour: either that defined on the code-input
|
|
499
|
+
* element, or if none is defined externally the
|
|
500
|
+
* base colour of the highlighted text.
|
|
501
|
+
*/
|
|
502
|
+
syncColorCompletely() {
|
|
503
|
+
// color of code-input element
|
|
504
|
+
if(this.isColorOverridenSyncIfNot()) {
|
|
505
|
+
// color overriden
|
|
506
|
+
this.internalStyle.removeProperty("--code-input_highlight-text-color");
|
|
507
|
+
this.internalStyle.setProperty("--code-input_default-caret-color", getComputedStyle(this).color);
|
|
444
508
|
}
|
|
445
509
|
}
|
|
446
510
|
|
|
511
|
+
|
|
447
512
|
/**
|
|
448
513
|
* Show some instructions to the user only if they are using keyboard navigation - for example, a prompt on how to navigate with the keyboard if Tab is repurposed.
|
|
449
514
|
* @param {string} instructions The instructions to display only if keyboard navigation is being used. If it's blank, no instructions will be shown.
|
|
@@ -639,7 +704,6 @@ var codeInput = {
|
|
|
639
704
|
this.codeElement = code;
|
|
640
705
|
pre.append(code);
|
|
641
706
|
this.append(pre);
|
|
642
|
-
|
|
643
707
|
if (this.templateObject.isCode) {
|
|
644
708
|
if (lang != undefined && lang != "") {
|
|
645
709
|
code.classList.add("language-" + lang.toLowerCase());
|
|
@@ -678,7 +742,44 @@ var codeInput = {
|
|
|
678
742
|
// The only element that could be resized is this code-input element.
|
|
679
743
|
this.syncSize();
|
|
680
744
|
});
|
|
681
|
-
resizeObserver.observe(this
|
|
745
|
+
resizeObserver.observe(this);
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
// Add internal style as non-externally-overridable alternative to style attribute for e.g. syncing color
|
|
749
|
+
this.classList.add("code-input_styles_" + codeInput.stylesheetI);
|
|
750
|
+
const stylesheet = document.createElement("style");
|
|
751
|
+
stylesheet.innerHTML = "code-input.code-input_styles_" + codeInput.stylesheetI + " {}";
|
|
752
|
+
this.appendChild(stylesheet);
|
|
753
|
+
this.internalStyle = stylesheet.sheet.cssRules[0].style;
|
|
754
|
+
codeInput.stylesheetI++;
|
|
755
|
+
|
|
756
|
+
// Synchronise colors
|
|
757
|
+
const preColorChangeCallback = (evt) => {
|
|
758
|
+
if(evt.propertyName == "color") {
|
|
759
|
+
this.isColorOverridenSyncIfNot();
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
this.preElement.addEventListener("transitionend", preColorChangeCallback);
|
|
763
|
+
this.preElement.addEventListener("-webkit-transitionend", preColorChangeCallback);
|
|
764
|
+
const thisColorChangeCallback = (evt) => {
|
|
765
|
+
if(evt.propertyName == "color") {
|
|
766
|
+
this.syncColorCompletely();
|
|
767
|
+
}
|
|
768
|
+
if(evt.target == this.dialogContainerElement) {
|
|
769
|
+
evt.stopPropagation();
|
|
770
|
+
// Prevent bubbling because code-input
|
|
771
|
+
// transitionend is separate
|
|
772
|
+
}
|
|
773
|
+
};
|
|
774
|
+
// Not on this element so CSS transition property does not override publicly-visible one
|
|
775
|
+
this.dialogContainerElement.addEventListener("transitionend", thisColorChangeCallback);
|
|
776
|
+
this.dialogContainerElement.addEventListener("-webkit-transitionend", thisColorChangeCallback);
|
|
777
|
+
|
|
778
|
+
// For when this code-input element has an externally-defined, different-duration transition
|
|
779
|
+
this.addEventListener("transitionend", thisColorChangeCallback);
|
|
780
|
+
this.addEventListener("-webkit-transitionend", thisColorChangeCallback);
|
|
781
|
+
|
|
782
|
+
this.syncColorCompletely();
|
|
682
783
|
|
|
683
784
|
this.classList.add("code-input_loaded");
|
|
684
785
|
}
|
|
@@ -836,7 +937,9 @@ var codeInput = {
|
|
|
836
937
|
code.classList.add("language-" + newValue);
|
|
837
938
|
}
|
|
838
939
|
|
|
839
|
-
if (mainTextarea.placeholder == oldValue
|
|
940
|
+
if (mainTextarea.placeholder == oldValue || oldValue == null && mainTextarea.placeholder == "") {
|
|
941
|
+
mainTextarea.placeholder = newValue;
|
|
942
|
+
}
|
|
840
943
|
|
|
841
944
|
this.scheduleHighlight();
|
|
842
945
|
|
|
@@ -36,6 +36,7 @@ plugins.Autocomplete = class extends Plugin {
|
|
|
36
36
|
codeInput.appendChild(popupElem);
|
|
37
37
|
|
|
38
38
|
let testPosPre = document.createElement("pre");
|
|
39
|
+
testPosPre.classList.add("code-input_autocomplete_invisiblepre"); // Hide visually
|
|
39
40
|
testPosPre.setAttribute("aria-hidden", true); // Hide for screen readers
|
|
40
41
|
if(codeInput.templateObject.preElementStyled) {
|
|
41
42
|
testPosPre.classList.add("code-input_autocomplete_testpos");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webcoder49/code-input",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.1",
|
|
4
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
6
|
"exports": {
|
package/plugins/autocomplete.css
CHANGED
package/plugins/autocomplete.js
CHANGED
|
@@ -32,6 +32,7 @@ codeInput.plugins.Autocomplete = class extends codeInput.Plugin {
|
|
|
32
32
|
codeInput.appendChild(popupElem);
|
|
33
33
|
|
|
34
34
|
let testPosPre = document.createElement("pre");
|
|
35
|
+
testPosPre.classList.add("code-input_autocomplete_invisiblepre"); // Hide visually
|
|
35
36
|
testPosPre.setAttribute("aria-hidden", true); // Hide for screen readers
|
|
36
37
|
if(codeInput.templateObject.preElementStyled) {
|
|
37
38
|
testPosPre.classList.add("code-input_autocomplete_testpos");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
code-input .code-input_autocomplete_popup{
|
|
1
|
+
code-input .code-input_autocomplete_popup{z-index:100;margin-top:1em;display:block;position:absolute}code-input pre.code-input_autocomplete_invisiblepre{opacity:0!important}
|
|
@@ -1 +1 @@
|
|
|
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(){}};
|
|
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.classList.add("code-input_autocomplete_invisiblepre"),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(){}};
|
|
@@ -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 *{
|
|
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 *{color:#000!important;background-color:#f80!important}.code-input_find-and-replace_start-newline:before{content:"⤶"}@keyframes code-input_find-and-replace_roll-in{0%{opacity:0;transform:translateY(-34px)}to{opacity:1;transform:translateY(0)}}@keyframes code-input_find-and-replace_roll-out{0%{opacity:1;top:0}to{opacity:0;top:-34px}}.code-input_find-and-replace_dialog{background-color:#fff;border:1px solid #0004;border-radius:6px;padding:8px 6px 6px;position:absolute;top:0;right:14px;box-shadow:0 .2em 1em .2em #00000029}.code-input_find-and-replace_dialog:not(.code-input_find-and-replace_hidden-dialog){opacity:1;pointer-events:all;animation:.2s code-input_find-and-replace_roll-in}.code-input_find-and-replace_dialog.code-input_find-and-replace_hidden-dialog{opacity:0;pointer-events:none;animation:.2s code-input_find-and-replace_roll-out}.code-input_find-and-replace_dialog input::placeholder{font-size:80%}.code-input_find-and-replace_dialog input{color:#000a;border:0;width:240px;height:32px;font-size:large;position:relative;top:-3px}.code-input_find-and-replace_dialog input.code-input_find-and-replace_error{color:#f00a}.code-input_find-and-replace_dialog button,.code-input_find-and-replace_dialog input[type=checkbox]{cursor:pointer;appearance:none;text-align:center;color:#000;vertical-align:top;background-color:#ddd;border:0;width:min-content;margin:5px;padding:5px;font-size:22px;line-height:24px;display:inline-block}.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{color:#fff;background-color:#222}.code-input_find-and-replace_match-description{color:#444;display:block}.code-input_find-and-replace_dialog details summary,.code-input_find-and-replace_dialog button{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{float:right;text-align:center;color:#000;opacity:.6;border-radius:50%;width:24px;margin:5px;padding:5px;font-family:system-ui;font-size:22px;font-weight:500;line-height:24px;display:block}.code-input_find-and-replace_dialog span:before{content:"×"}.code-input_find-and-replace_dialog span:hover{opacity:.8;background-color:#00000018}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@keyframes code-input_go-to-line_roll-in{0%{opacity:0;transform:translateY(-34px)}
|
|
1
|
+
@keyframes code-input_go-to-line_roll-in{0%{opacity:0;transform:translateY(-34px)}to{opacity:1;transform:translateY(0)}}@keyframes code-input_go-to-line_roll-out{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-34px)}}.code-input_go-to-line_dialog{background-color:#fff;border:1px solid #0004;border-radius:6px;padding:8px 6px 6px;position:absolute;top:0;right:14px;box-shadow:0 .2em 1em .2em #00000029}.code-input_go-to-line_dialog:not(.code-input_go-to-line_hidden-dialog){opacity:1;pointer-events:all;animation:.2s code-input_go-to-line_roll-in}.code-input_go-to-line_dialog.code-input_go-to-line_hidden-dialog{opacity:0;pointer-events:none;animation:.2s code-input_go-to-line_roll-out}.code-input_go-to-line_dialog input::placeholder{font-size:80%}.code-input_go-to-line_dialog input{color:#000a;border:0;width:240px;height:32px;font-size:large;position:relative;top:-3px}.code-input_go-to-line_dialog input.code-input_go-to-line_error{color:#f00a}.code-input_go-to-line_dialog span{text-align:center;color:#000;opacity:.6;vertical-align:top;border-radius:50%;width:24px;font-family:system-ui;font-size:22px;font-weight:500;line-height:24px;display:inline-block}.code-input_go-to-line_dialog span:before{content:"×"}.code-input_go-to-line_dialog span:hover{opacity:.8;background-color:#00000018}.code-input_go-to-line_dialog p{width:264px;white-space:wrap;margin:0;font-family:monospace;overflow:hidden}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.line-numbers code-input
|
|
1
|
+
code-input.line-numbers textarea,code-input.line-numbers.code-input_pre-element-styled pre,code-input.line-numbers:not(.code-input_pre-element-styled) pre code,.line-numbers code-input textarea,.line-numbers code-input.code-input_pre-element-styled pre,.line-numbers code-input:not(.code-input_pre-element-styled) pre code{padding-left:max(3.8em,var(--padding-left,16px))!important}code-input.line-numbers,.line-numbers code-input{grid-template-columns:calc(100% - max(0em,calc(3.8em - var(--padding-left,16px))))}code-input.line-numbers .code-input_dialog-container,.line-numbers code-input .code-input_dialog-container{width:calc(100% + max(0em,calc(3.8em - var(--padding-left,16px))))}code-input pre[class*=language-].line-numbers>code{position:static}code-input .line-numbers .line-numbers-rows{left:max(0em,calc(var(--padding-left,16px) - 3.8em));top:var(--padding-top)}code-input:not(:has(.code-input_keyboard-navigation-instructions:empty)):has(textarea:not([data-code-input-fallback]):focus):not(.code-input_mouse-focused) .line-numbers .line-numbers-rows{top:calc(var(--padding-top) + 3em)}
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
:root,body{--code-input_special-chars_0:url(
|
|
2
|
-
--code-input_special-chars_0);--hex-1:var(
|
|
3
|
-
--code-input_special-chars_0);--hex-2:var(
|
|
4
|
-
--code-input_special-chars_0);--hex-3:var(
|
|
5
|
-
--code-input_special-chars_0)}.code-input_special-char::before{margin-left:50%;transform:translate(-50%,0);content:" ";background-color:var(--code-input_special-char_color,currentColor);image-rendering:pixelated;display:inline-block;width:calc(100%-2px);height:100%;mask-image:var(--hex-0),var(--hex-1),var(--hex-2),var(--hex-3);mask-repeat:no-repeat,no-repeat,no-repeat,no-repeat;mask-size:min(40%,.25em),min(40%,.25em),min(40%,.25em),min(40%,.25em);mask-position:10% 10%,90% 10%,10% 90%,90% 90%;-webkit-mask-image:var(--hex-0),var(--hex-1),var(--hex-2),var(--hex-3);-webkit-mask-repeat:no-repeat,no-repeat,no-repeat,no-repeat;-webkit-mask-size:min(40%,.25em),min(40%,.25em),min(40%,.25em),min(40%,.25em);-webkit-mask-position:10% 10%,min(90%,.5em) 10%,10% 90%,min(90%,.5em) 90%}.code-input_special-char_zero-width{z-index:1;width:1em;margin-left:-.5em;margin-right:-.5em;position:relative;opacity:.75}.code-input_special-char_one-byte::before{height:1.5em;top:-1em;content:attr(data-hex2)}.code-input_special-char_one-byte::after{height:1.5em;bottom:-1em;content:attr(data-hex3)}
|
|
1
|
+
:root,body{--code-input_special-chars_0:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABtJREFUGFdjZGBgYPj///9/RhCAMcA0bg6yHgAPmh/6BoxTcQAAAABJRU5ErkJgggAA);--code-input_special-chars_1:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABZJREFUGFdjZGBgYPj///9/RhAggwMAitIUBr9U6sYAAAAASUVORK5CYII=);--code-input_special-chars_2:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB9JREFUGFdj/P///38GKGCEMUCCjCgyYBFGRrAKFBkAuLYT9kYcIu0AAAAASUVORK5CYII=);--code-input_special-chars_3:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABhJREFUGFdj/P///38GKGCEMUCCjMTJAACYiBPyG8sfAgAAAABJRU5ErkJggg==);--code-input_special-chars_4:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB5JREFUGFdj/P///39GRkZGMI3BYYACRhgDrAKZAwAYxhvyz0DRIQAAAABJRU5ErkJggg==);--code-input_special-chars_5:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAACJJREFUGFdj/P///38GKGAEcRgZGRlBfDAHLgNjgFUgywAAuR4T9hxJl2YAAAAASUVORK5CYII=);--code-input_special-chars_6:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAACBJREFUGFdj/P///38GKGAEcRgZGRlBfDAHQwasAlkGABcdF/Y4yco2AAAAAElFTkSuQmCC);--code-input_special-chars_7:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABZJREFUGFdj/P///38GKGCEMUCCRHIAWMgT8kue3bQAAAAASUVORK5CYII=);--code-input_special-chars_8:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABlJREFUGFdj/P///38GKGAEcRgZGSE0cTIAvHcb8v+mIfAAAAAASUVORK5CYII=);--code-input_special-chars_9:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB9JREFUGFdj/P///38GKGAEcRgZGSE0igxMCVgGmQMAPqcX8hWL1K0AAAAASUVORK5CYII=);--code-input_special-chars_A:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAACBJREFUGFdjZGBgYPj///9/RhCAMcA0iADJggCmDEw5ALdxH/aGuYHqAAAAAElFTkSuQmCC);--code-input_special-chars_B:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABlJREFUGFdj/P///38GBgYGRhAAceA0cTIAvc0b/vRDnVoAAAAASUVORK5CYII=);--code-input_special-chars_C:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB5JREFUGFdjZGBgYPj///9/EM0IYjAyMjIS4CDrAQC57hP+uLwvFQAAAABJRU5ErkJggg==);--code-input_special-chars_D:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABtJREFUGFdj/P///38GBgYGRhAAceA0fg5MDwAveh/6ToN9VwAAAABJRU5ErkJggg==);--code-input_special-chars_E:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABxJREFUGFdj/P///38GKGAEcRgZGRlBfDCHsAwA2UwT+mVIH1MAAAAASUVORK5CYII=);--code-input_special-chars_F:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB5JREFUGFdj/P///38GKGAEcRgZGRlBfDAHtwxMGQDZZhP+BnB1kwAAAABJRU5ErkJggg==)}.code-input_special-char{height:1em;text-shadow:none;vertical-align:middle;color:#0000;--hex-0:var(--code-input_special-chars_0);--hex-1:var(--code-input_special-chars_0);--hex-2:var(--code-input_special-chars_0);--hex-3:var(--code-input_special-chars_0);outline:.1px solid;font-size:0;text-decoration:none;display:inline-block;position:relative;top:0;left:0;overflow:hidden}.code-input_special-char:before{content:" ";background-color:var(--code-input_special-char_color,currentColor);image-rendering:pixelated;width:calc(100%-2px);height:100%;mask-image:var(--hex-0),var(--hex-1),var(--hex-2),var(--hex-3);mask-position:10% 10%,90% 10%,10% 90%,90% 90%;mask-size:min(40%,.25em),min(40%,.25em),min(40%,.25em),min(40%,.25em);mask-repeat:no-repeat,no-repeat,no-repeat,no-repeat;-webkit-mask-image:var(--hex-0),var(--hex-1),var(--hex-2),var(--hex-3);margin-left:50%;display:inline-block;transform:translate(-50%);-webkit-mask-position:10% 10%,min(90%,.5em) 10%,10% 90%,min(90%,.5em) 90%;-webkit-mask-size:min(40%,.25em),min(40%,.25em),min(40%,.25em),min(40%,.25em);-webkit-mask-repeat:no-repeat,no-repeat,no-repeat,no-repeat}.code-input_special-char_zero-width{z-index:1;opacity:.75;width:1em;margin-left:-.5em;margin-right:-.5em;position:relative}.code-input_special-char_one-byte:before{content:attr(data-hex2);height:1.5em;top:-1em}.code-input_special-char_one-byte:after{content:attr(data-hex3);height:1.5em;bottom:-1em}
|