Skip to content

Commit 6e50d69

Browse files
committed
Add tests for synchronise color; Make synchronise color not use the style attribute for long-term storage and document use of class attribute
1 parent 28f869a commit 6e50d69

File tree

6 files changed

+68
-15
lines changed

6 files changed

+68
-15
lines changed

code-input.css

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ code-input {
2727
/* --code-input_no-override-color: Set by JS for very short time to get whether color has been overriden */
2828
color: var(--code-input_no-override-color, black);
2929
/* --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, black);
30+
caret-color: var(--code-input_default-caret-color, inherit);
3131
background-color: white;
3232

3333
/* Normal inline styles */
@@ -132,7 +132,7 @@ code-input pre {
132132
code-input textarea:not([data-code-input-fallback]) {
133133
background: transparent;
134134
color: transparent;
135-
caret-color: inherit; /* Or choose your favourite color */
135+
caret-color: inherit;
136136
}
137137
code-input textarea:not([data-code-input-fallback]):placeholder-shown {
138138
/* Show placeholder */
@@ -253,7 +253,7 @@ code-input:not(.code-input_loaded)::after {
253253
border-top: 1px solid currentColor;
254254
outline-top: 0;
255255
background-color: inherit;
256-
color: var(--code-input_highlight-text-color, inherit);
256+
color: inherit;
257257

258258
margin: 0;
259259
padding: 0;

code-input.js

Lines changed: 32 additions & 9 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
@@ -559,23 +571,23 @@ var codeInput = {
559571
const oldTransition = this.style.transition;
560572
this.style.transition = "unset";
561573
window.requestAnimationFrame(() => {
562-
this.style.setProperty("--code-input_no-override-color", "rgb(0, 0, 0)");
574+
this.internalStyle.setProperty("--code-input_no-override-color", "rgb(0, 0, 0)");
563575
if(getComputedStyle(this).color == "rgb(0, 0, 0)") {
564576
// May not be overriden
565-
this.style.setProperty("--code-input_no-override-color", "rgb(255, 255, 255)");
577+
this.internalStyle.setProperty("--code-input_no-override-color", "rgb(255, 255, 255)");
566578
if(getComputedStyle(this).color == "rgb(255, 255, 255)") {
567579
// Definitely not overriden
568-
this.style.removeProperty("--code-input_no-override-color");
580+
this.internalStyle.removeProperty("--code-input_no-override-color");
569581
this.style.transition = oldTransition;
570582

571583
const highlightedTextColor = getComputedStyle(this.getStyledHighlightingElement()).color;
572584

573-
this.style.setProperty("--code-input_highlight-text-color", highlightedTextColor);
574-
this.style.setProperty("--code-input_default-caret-color", highlightedTextColor);
585+
this.internalStyle.setProperty("--code-input_highlight-text-color", highlightedTextColor);
586+
this.internalStyle.setProperty("--code-input_default-caret-color", highlightedTextColor);
575587
return false;
576588
}
577589
}
578-
this.style.removeProperty("--code-input_no-override-color");
590+
this.internalStyle.removeProperty("--code-input_no-override-color");
579591
this.style.transition = oldTransition;
580592
});
581593

@@ -593,8 +605,8 @@ var codeInput = {
593605
// color of code-input element
594606
if(this.isColorOverridenSyncIfNot()) {
595607
// color overriden
596-
this.style.removeProperty("--code-input_highlight-text-color");
597-
this.style.setProperty("--code-input_default-caret-color", getComputedStyle(this).color);
608+
this.internalStyle.removeProperty("--code-input_highlight-text-color");
609+
this.internalStyle.setProperty("--code-input_default-caret-color", getComputedStyle(this).color);
598610
}
599611
}
600612

@@ -832,6 +844,15 @@ var codeInput = {
832844
});
833845
resizeObserver.observe(this);
834846

847+
848+
// Add internal style as non-externally-overridable alternative to style attribute for e.g. syncing color
849+
this.classList.add("code-input_styles_" + codeInput.stylesheetI);
850+
const stylesheet = document.createElement("style");
851+
stylesheet.innerHTML = "code-input.code-input_styles_" + codeInput.stylesheetI + " {}";
852+
this.appendChild(stylesheet);
853+
this.internalStyle = stylesheet.sheet.cssRules[0].style;
854+
codeInput.stylesheetI++;
855+
835856
// Synchronise colors
836857
const preColorChangeCallback = (evt) => {
837858
if(evt.propertyName == "color") {
@@ -993,7 +1014,9 @@ var codeInput = {
9931014
code.classList.add("language-" + newValue);
9941015
}
9951016

996-
if (mainTextarea.placeholder == oldValue) mainTextarea.placeholder = newValue;
1017+
if (mainTextarea.placeholder == oldValue || oldValue == null && mainTextarea.placeholder == "") {
1018+
mainTextarea.placeholder = newValue;
1019+
}
9971020

9981021
this.scheduleHighlight();
9991022

docs/interface/css/_index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ title = 'Styling `code-input` elements with CSS'
1010
* 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`).
1111
* 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.
1212
* For now, elements on top of `code-input` elements should have a CSS `z-index` at least 3 greater than the `code-input` element.
13+
14+
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.

tests/hljs.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<title>code-input Tester</title>
77

88
<!--Import Highlight.JS-->
9-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
9+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" id="theme-stylesheet">
1010
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
1111
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/xml.min.js"></script>
1212
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/css.min.js"></script>
@@ -42,7 +42,7 @@ <h4><a href="prism.html">Test for Prism.js</a></h4>
4242

4343
<details id="collapse-results"><summary>Test Results (Click to Open)</summary><pre id="test-results"></pre></details>
4444
<form method="GET" action="afterform.html" target="_blank">
45-
<code-input><textarea data-code-input-fallback name="q">console.log("Hello, World!");
45+
<code-input><textarea data-code-input-fallback name="q" placeholder="language auto-detected">console.log("Hello, World!");
4646
// A second line
4747
// A third line with &lt;html> tags</textarea></code-input>
4848
<input type="submit" value="Test HTML Form"/>

tests/prism.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
66
<title>code-input Tester</title>
77
<!--Import Prism-->
8-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css">
8+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css" id="theme-stylesheet">
99
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js" data-manual></script><!--Remove data-manual if also using Prism normally-->
1010
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
1111
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/line-numbers/prism-line-numbers.min.js"></script>

tests/tester.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,34 @@ console.log("I've got another line!", 2 &lt; 3, "should be true.");
326326
// A third line with &lt;html&gt; tags
327327
`); // Extra newline so line numbers visible if enabled.
328328

329+
// Delete all code
330+
textarea.selectionStart = 0;
331+
textarea.selectionEnd = textarea.value.length;
332+
backspace(textarea);
333+
codeInputElement.setAttribute("language", "JavaScript"); // for placeholder
334+
335+
await waitAsync(100); // Wait for rendered value to update
336+
testAssertion("Core", "Light theme Caret/Placeholder Color Correct", confirm("Are the caret and placeholder near-black? (OK=Yes)"), "user-judged");
337+
338+
if(isHLJS) {
339+
document.getElementById("theme-stylesheet").href = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/dark.min.css";
340+
} else {
341+
document.getElementById("theme-stylesheet").href = "https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-okaidia.min.css";
342+
}
343+
await waitAsync(200); // Wait for colours to update
344+
testAssertion("Core", "Dark theme Caret/Placeholder Color Correct", confirm("Are the caret and placeholder near-white? (OK=Yes)"), "user-judged");
345+
346+
codeInputElement.style.color = "red";
347+
await waitAsync(200); // Wait for colours to update
348+
testAssertion("Core", "Overriden color Caret/Placeholder Color Correct", confirm("Are the caret and placeholder (for Firefox) or just caret (for Chromium/WebKit, for consistency with textareas) red? (OK=Yes)"), "user-judged");
349+
350+
codeInputElement.style.removeProperty("color");
351+
codeInputElement.style.caretColor = "red";
352+
await waitAsync(200); // Wait for colours to update
353+
testAssertion("Core", "Overriden caret-color Caret/Placeholder Color Correct", confirm("Is the caret red and placeholder near-white? (OK=Yes)"), "user-judged");
354+
355+
codeInputElement.style.removeProperty("caret-color");
356+
329357
/*--- Tests for plugins ---*/
330358
// AutoCloseBrackets
331359
testAddingText("AutoCloseBrackets", textarea, function(textarea) {

0 commit comments

Comments
 (0)