Skip to content

Commit 2c0aef7

Browse files
committed
Complete working colour sync
1 parent 542806d commit 2c0aef7

File tree

2 files changed

+77
-46
lines changed

2 files changed

+77
-46
lines changed

code-input.css

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ code-input {
2222

2323
/* CSS variables rather than inline styles used for values synced from JavaScript
2424
to keep low precedence and thus overridability
25-
The variables may change and are for internal use. */
26-
--code-input_highlight-text-color: black; /* Set by JS to be base text color of pre code element */
27-
color: var(--code-input_highlight-text-color, black); /* Variable separate so can be overridden by CSS */
28-
--code-input_default-caret-color: black; /* Set by JS to be same as color property */
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: inherit; /* Set by JS for very short time to get whether color has been overriden */
28+
color: var(--code-input_no-override-color, inherit);
29+
/* --code-input_default-caret-color: Set by JS to be same as color property */
2930
caret-color: var(--code-input_default-caret-color, black); /* Set by JS to be equal to color property */
3031
background-color: white;
3132

@@ -135,7 +136,7 @@ code-input textarea:not([data-code-input-fallback]) {
135136
}
136137
code-input textarea:not([data-code-input-fallback]):placeholder-shown {
137138
/* Show placeholder */
138-
color: inherit;
139+
color: var(--code-input_highlight-text-color, inherit);
139140
}
140141

141142
/* Can be scrolled */
@@ -176,10 +177,8 @@ code-input .code-input_dialog-container {
176177
/* Dialog boxes' text is based on text-direction */
177178
text-align: inherit;
178179

179-
180180
/* Allow colour change to reflect properly;
181-
transition-behavior: allow-discrete could be used but this is better supported and
182-
works with the color property. */
181+
* transition-behavior: allow-discrete could be used but this is * better supported and works with the color property. */
183182
color: inherit;
184183
transition: color 0.001s;
185184
}
@@ -254,7 +253,7 @@ code-input:not(.code-input_loaded)::after {
254253
border-top: 1px solid currentColor;
255254
outline-top: 0;
256255
background-color: inherit;
257-
color: inherit;
256+
color: var(--code-input_highlight-text-color, inherit);
258257

259258
margin: 0;
260259
padding: 0;
@@ -277,7 +276,7 @@ code-input:has(textarea[data-code-input-fallback]) {
277276
code-input textarea[data-code-input-fallback] {
278277
overflow: auto;
279278
background-color: inherit;
280-
color: inherit;
279+
color: var(--code-input_highlight-text-color, inherit);
281280

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

code-input.js

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -530,20 +530,67 @@ var codeInput = {
530530
this.pluginEvt("afterHighlight");
531531
}
532532

533+
getStyledHighlightingElement() {
534+
if(this.templateObject.preElementStyled) {
535+
return this.preElement;
536+
} else {
537+
return this.codeElement;
538+
}
539+
}
540+
533541
/**
534542
* Set the size of the textarea element to the size of the pre/code element.
535543
*/
536544
syncSize() {
537545
// Synchronise the size of the pre/code and textarea elements
538-
if(this.templateObject.preElementStyled) {
539-
this.textareaElement.style.height = getComputedStyle(this.preElement).height;
540-
this.textareaElement.style.width = getComputedStyle(this.preElement).width;
541-
} else {
542-
this.textareaElement.style.height = getComputedStyle(this.codeElement).height;
543-
this.textareaElement.style.width = getComputedStyle(this.codeElement).width;
546+
this.textareaElement.style.height = getComputedStyle(this.getStyledHighlightingElement()).height;
547+
this.textareaElement.style.width = getComputedStyle(this.getStyledHighlightingElement()).width;
548+
}
549+
550+
/**
551+
* If the color attribute has been defined on the
552+
* code-input element by external code, return true.
553+
* Otherwise, make the aspects the color affects
554+
* (placeholder and caret colour) be the base colour
555+
* of the highlighted text, for best contrast, and
556+
* return false.
557+
*/
558+
isColorOverridenSyncIfNot() {
559+
this.style.setProperty("--code-input_no-override-color", "rgb(0, 0, 0)");
560+
if(getComputedStyle(this).color == "rgb(0, 0, 0)") {
561+
// May not be overriden
562+
this.style.setProperty("--code-input_no-override-color", "rgb(255, 255, 255)");
563+
if(getComputedStyle(this).color == "rgb(255, 255, 255)") {
564+
// Definitely not overriden
565+
this.style.removeProperty("--code-input_no-override-color");
566+
567+
this.style.setProperty("--code-input_highlight-text-color", getComputedStyle(this.getStyledHighlightingElement()).color);
568+
this.style.setProperty("--code-input_default-caret-color", getComputedStyle(this.getStyledHighlightingElement()).color);
569+
return false;
570+
}
571+
}
572+
this.style.removeProperty("--code-input_no-override-color");
573+
574+
return true;
575+
}
576+
577+
/**
578+
* Update the aspects the color affects
579+
* (placeholder and caret colour) to the correct
580+
* colour: either that defined on the code-input
581+
* element, or if none is defined externally the
582+
* base colour of the highlighted text.
583+
*/
584+
syncColorCompletely() {
585+
// color of code-input element
586+
if(this.isColorOverridenSyncIfNot()) {
587+
// color overriden
588+
this.style.removeProperty("--code-input_highlight-text-color");
589+
this.style.setProperty("--code-input_default-caret-color", getComputedStyle(this).color);
544590
}
545591
}
546592

593+
547594
/**
548595
* 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.
549596
* @param {string} instructions The instructions to display only if keyboard navigation is being used. If it's blank, no instructions will be shown.
@@ -778,38 +825,23 @@ var codeInput = {
778825
resizeObserver.observe(this);
779826

780827
// Synchronise colors
781-
if(this.templateObject.preElementStyled) {
782-
this.preElement.addEventListener("transitionend", (evt) => {
783-
if(evt.propertyName == "color") {
784-
// So previous variable value does not affect new value:
785-
// (required to deal with color being no longer specified in CSS)
786-
this.style.removeProperty("--code-input_highlight-text-color");
787-
788-
console.log("pre", evt, getComputedStyle(this.preElement).color);
789-
this.style.setProperty("--code-input_highlight-text-color", getComputedStyle(this.preElement).color);
790-
}
791-
});
792-
} else {
793-
this.codeElement.addEventListener("transitionend", (evt) => {
794-
if(evt.propertyName == "color") {
795-
// So previous variable value does not affect new value:
796-
// (required to deal with color being no longer specified in CSS)
797-
this.style.removeProperty("--code-input_highlight-text-color");
798-
799-
console.log("code", evt, getComputedStyle(this.codeElement).color);
800-
this.style.setProperty("--code-input_highlight-text-color", getComputedStyle(this.codeElement).color);
801-
}
802-
});
803-
}
804-
// Not on this element so CSS transition property which must be set for
805-
// listener to work does not conflict with library-user transition property
806-
this.dialogContainerElement.addEventListener("transitionend", (evt) => {
828+
const preColorChangeCallback = (evt) => {
807829
if(evt.propertyName == "color") {
808-
console.log("ci", evt, getComputedStyle(this).color);
809-
810-
this.style.setProperty("--code-input_default-caret-color", getComputedStyle(this).color);
830+
this.isColorOverridenSyncIfNot();
811831
}
812-
});
832+
};
833+
this.preElement.addEventListener("transitionend", preColorChangeCallback);
834+
this.preElement.addEventListener("-webkit-transitionend", preColorChangeCallback);
835+
const thisColorChangeCallback = (evt) => {
836+
if(evt.propertyName == "color") {
837+
this.syncColorCompletely();
838+
}
839+
};
840+
// Not on this element so CSS transition property which must be set for
841+
this.dialogContainerElement.addEventListener("transitionend", thisColorChangeCallback);
842+
this.dialogContainerElement.addEventListener("-webkit-transitionend", thisColorChangeCallback);
843+
844+
this.syncColorCompletely();
813845

814846
this.classList.add("code-input_loaded");
815847
}

0 commit comments

Comments
 (0)