Skip to content

Commit 92ff274

Browse files
authored
Merge pull request #199 from WebCoder49/main
Update code in breaking key events
2 parents 5799bb1 + 5fcaac5 commit 92ff274

27 files changed

+518
-258
lines changed

.github/workflows/minify.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@ jobs:
88
runs-on: ubuntu-latest
99
steps:
1010
# Checks-out your repository under $GITHUB_WORKSPACE, so auto-minify job can access it
11-
- uses: actions/checkout@v2
11+
- uses: actions/checkout@v5
1212

1313
- name: Auto Minify
14-
uses: nizarmah/auto-minify@v2.1
14+
uses: nizarmah/auto-minify@v3
1515

1616
# Auto commits minified files to the repository
1717
# Ignore it if you don't want to commit the files to the repository
1818
- name: Auto committing minified files
19-
uses: stefanzweifel/git-auto-commit-action@v4
19+
uses: stefanzweifel/git-auto-commit-action@v6
2020
with:
21-
commit_message: "Auto Minified JS and CSS files"
22-
branch: ${{ github.ref }}
21+
commit_message: "Auto Minify JS and CSS files"

code-input.css

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,14 @@ code-input {
2020
top: 0;
2121
left: 0;
2222

23-
color: black;
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);
2431
background-color: white;
2532

2633
/* Normal inline styles */
@@ -30,21 +37,21 @@ code-input {
3037
--padding-right: var(--padding, 16px);
3138
--padding-top: var(--padding, 16px);
3239
--padding-bottom: var(--padding, 16px);
40+
3341
height: 250px;
3442
font-size: inherit;
3543
font-family: monospace;
3644
text-align: start;
3745
line-height: 1.5; /* Inherited to child elements */
3846
tab-size: 2;
39-
caret-color: darkgrey;
4047
white-space: pre;
4148
padding: 0!important; /* Use --padding to set the code-input element's padding */
4249
display: grid;
4350
grid-template-columns: 100%;
4451
grid-template-rows: 100%;
4552
}
4653

47-
code-input * {
54+
code-input :not(.code-input_dialog-container *) {
4855
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. */
4956
}
5057

@@ -56,25 +63,33 @@ code-input textarea, code-input:not(.code-input_pre-element-styled) pre code, co
5663
padding-top: var(--padding-top, 16px)!important;
5764
padding-bottom: var(--padding-bottom, 16px)!important;
5865
border: 0;
66+
5967
min-width: calc(100% - var(--padding-left, 16px) - var(--padding-right, 16px));
6068
min-height: calc(100% - var(--padding-top, 16px) - var(--padding-bottom, 16px));
61-
overflow: hidden;
6269
resize: none;
70+
overflow: hidden;
6371
grid-row: 1;
6472
grid-column: 1;
6573
display: block;
6674
}
67-
6875
code-input:not(.code-input_pre-element-styled) pre code, code-input.code-input_pre-element-styled pre {
6976
height: max-content;
7077
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;
7183
}
7284

7385
code-input:not(.code-input_pre-element-styled) pre, code-input.code-input_pre-element-styled pre code {
7486
/* Remove all margin and padding from others */
7587
margin: 0!important;
7688
padding: 0!important;
7789
border: 0!important;
90+
91+
min-width: 100%;
92+
min-height: 100%;
7893
}
7994

8095
code-input textarea, code-input pre, code-input pre * {
@@ -85,6 +100,9 @@ code-input textarea, code-input pre, code-input pre * {
85100
tab-size: inherit!important;
86101
text-align: inherit!important;
87102
}
103+
code-input textarea, code-input pre, code-input pre code {
104+
overflow: visible!important;
105+
}
88106

89107
/* Make changing the text direction propogate */
90108
code-input textarea[dir=auto] + pre {
@@ -118,12 +136,13 @@ code-input pre {
118136
/* Make textarea almost completely transparent, except for caret and placeholder */
119137

120138
code-input textarea:not([data-code-input-fallback]) {
121-
color: transparent;
122139
background: transparent;
123-
caret-color: inherit!important; /* Or choose your favourite color */
140+
color: transparent;
141+
caret-color: inherit;
124142
}
125-
code-input textarea::placeholder {
126-
color: lightgrey;
143+
code-input textarea:not([data-code-input-fallback]):placeholder-shown {
144+
/* Show placeholder */
145+
color: var(--code-input_highlight-text-color, inherit);
127146
}
128147

129148
/* Can be scrolled */
@@ -163,6 +182,11 @@ code-input .code-input_dialog-container {
163182

164183
/* Dialog boxes' text is based on text-direction */
165184
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;
166190
}
167191

168192
[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
252276
code-input:has(textarea[data-code-input-fallback]) {
253277
padding: 0!important; /* Padding now in the textarea */
254278
box-sizing: content-box;
279+
280+
caret-color: revert; /* JS not setting the colour since no highlighting */
255281
}
256282
code-input textarea[data-code-input-fallback] {
257283
overflow: auto;
258284
background-color: inherit;
259-
color: inherit;
285+
color: var(--code-input_highlight-text-color, inherit);
260286

261287
/* Don't overlap with message */
262288
min-height: calc(100% - var(--padding-top, 16px) - 2em - var(--padding-bottom, 16px));

code-input.js

Lines changed: 114 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ var codeInput = {
152152
}
153153
},
154154

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+
155157
/**
156158
* Please see `codeInput.templates.prism` or `codeInput.templates.hljs`.
157159
* Templates are used in `<code-input>` elements and once registered with
@@ -445,6 +447,16 @@ var codeInput = {
445447
*/
446448
dialogContainerElement = null;
447449

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+
448460
/**
449461
* Form-Associated Custom Element Callbacks
450462
* https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-face-example
@@ -530,22 +542,75 @@ var codeInput = {
530542
this.pluginEvt("afterHighlight");
531543
}
532544

545+
getStyledHighlightingElement() {
546+
if(this.templateObject.preElementStyled) {
547+
return this.preElement;
548+
} else {
549+
return this.codeElement;
550+
}
551+
}
552+
533553
/**
534554
* Set the size of the textarea element to the size of the pre/code element.
535555
*/
536556
syncSize() {
537557
// Synchronise the size of the pre/code and textarea elements
538-
if(this.templateObject.preElementStyled) {
539-
this.style.backgroundColor = getComputedStyle(this.preElement).backgroundColor;
540-
this.textareaElement.style.height = getComputedStyle(this.preElement).height;
541-
this.textareaElement.style.width = getComputedStyle(this.preElement).width;
542-
} else {
543-
this.style.backgroundColor = getComputedStyle(this.codeElement).backgroundColor;
544-
this.textareaElement.style.height = getComputedStyle(this.codeElement).height;
545-
this.textareaElement.style.width = getComputedStyle(this.codeElement).width;
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);
546610
}
547611
}
548612

613+
549614
/**
550615
* 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.
551616
* @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 = {
741806
this.codeElement = code;
742807
pre.append(code);
743808
this.append(pre);
744-
745809
if (this.templateObject.isCode) {
746810
if (lang != undefined && lang != "") {
747811
code.classList.add("language-" + lang.toLowerCase());
@@ -780,7 +844,44 @@ var codeInput = {
780844
// The only element that could be resized is this code-input element.
781845
this.syncSize();
782846
});
783-
resizeObserver.observe(this.textareaElement);
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();
784885

785886
this.classList.add("code-input_loaded");
786887
}
@@ -938,7 +1039,9 @@ var codeInput = {
9381039
code.classList.add("language-" + newValue);
9391040
}
9401041

941-
if (mainTextarea.placeholder == oldValue) mainTextarea.placeholder = newValue;
1042+
if (mainTextarea.placeholder == oldValue || oldValue == null && mainTextarea.placeholder == "") {
1043+
mainTextarea.placeholder = newValue;
1044+
}
9421045

9431046
this.scheduleHighlight();
9441047

0 commit comments

Comments
 (0)