Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
99f1688
Make caret and placeholder use highlighted text's base colour or pref…
WebCoder49 Aug 21, 2025
542806d
Move from polling to transition listeners approach for better perform…
WebCoder49 Aug 25, 2025
2c0aef7
Complete working colour sync
WebCoder49 Aug 31, 2025
b76ea47
Make color/caret-color work when transition set on code-input element…
WebCoder49 Sep 3, 2025
d88176f
Auto Minified JS and CSS files
WebCoder49 Sep 18, 2025
243abe7
Release v2.6.8
WebCoder49 Sep 18, 2025
28f869a
Prevent no-override-color becoming visible when transition set
WebCoder49 Sep 20, 2025
6e50d69
Add tests for synchronise color; Make synchronise color not use the s…
WebCoder49 Sep 20, 2025
af1099f
Document caret/placeholder theme behaviour
WebCoder49 Sep 20, 2025
f7fe452
Merge pull request #195 from WebCoder49/synchronise-caret-color
WebCoder49 Sep 20, 2025
70c197d
Auto Minified JS and CSS files
WebCoder49 Sep 20, 2025
735ae76
Remove incorrect sentence about color override specificity in docs
WebCoder49 Sep 20, 2025
c07f898
Small fixes and clarifications for box-sizing
WebCoder49 Sep 20, 2025
28f40d3
Auto Minified JS and CSS files
WebCoder49 Sep 20, 2025
eb1c010
docs: Add note on :focus
WebCoder49 Sep 20, 2025
7ac46eb
Clean up autocomplete demo and make code-input retain focus so autoco…
WebCoder49 Sep 21, 2025
88175c4
Update minify action to revert wrongly-minified CSS so Prism line-num…
WebCoder49 Sep 21, 2025
57d9006
Auto Minify JS and CSS files
WebCoder49 Sep 21, 2025
21381eb
Document code-input_load event
WebCoder49 Sep 21, 2025
2c8302b
Make download links clearer in docs
WebCoder49 Sep 21, 2025
5ab559e
Add skip-to-contributing link on docs homepage
WebCoder49 Sep 21, 2025
6c7a9df
Release v2.7.0
WebCoder49 Sep 21, 2025
506e7d4
Document major version 3
WebCoder49 Sep 21, 2025
e709545
docs: Make demo code refer to latest version
WebCoder49 Sep 21, 2025
0659447
Clean up autodetect plugin demo
WebCoder49 Sep 21, 2025
7c425f6
Move major version 3 notice to clearer place
WebCoder49 Sep 21, 2025
5154c70
Improve compatibility with external CSS that includes overflow and ba…
WebCoder49 Sep 29, 2025
e05d8a7
Auto Minify JS and CSS files
WebCoder49 Sep 29, 2025
0277742
Remove attempted fix of background-colour incompatibility that was ac…
WebCoder49 Sep 29, 2025
83d56b4
Auto Minify JS and CSS files
WebCoder49 Sep 29, 2025
663b353
Readd accidentally-removed CSS
WebCoder49 Sep 30, 2025
17b710e
Auto Minify JS and CSS files
WebCoder49 Sep 30, 2025
5fcaac5
Release v2.7.1
WebCoder49 Sep 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions .github/workflows/minify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@ jobs:
runs-on: ubuntu-latest
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so auto-minify job can access it
- uses: actions/checkout@v2
- uses: actions/checkout@v5

- name: Auto Minify
uses: nizarmah/auto-minify@v2.1
uses: nizarmah/auto-minify@v3

# Auto commits minified files to the repository
# Ignore it if you don't want to commit the files to the repository
- name: Auto committing minified files
uses: stefanzweifel/git-auto-commit-action@v4
uses: stefanzweifel/git-auto-commit-action@v6
with:
commit_message: "Auto Minified JS and CSS files"
branch: ${{ github.ref }}
commit_message: "Auto Minify JS and CSS files"
46 changes: 36 additions & 10 deletions code-input.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@ code-input {
top: 0;
left: 0;

color: black;
/* CSS variables rather than inline styles used for values synced from JavaScript
to keep low precedence and thus overridability
The variable names may change and are for internal use. */
/* --code-input_highlight-text-color: Set by JS to be base text color of pre code element */
/* --code-input_no-override-color: Set by JS for very short time to get whether color has been overriden */
color: var(--code-input_no-override-color, black);
/* --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 */
caret-color: var(--code-input_default-caret-color, inherit);
background-color: white;

/* Normal inline styles */
Expand All @@ -30,21 +37,21 @@ code-input {
--padding-right: var(--padding, 16px);
--padding-top: var(--padding, 16px);
--padding-bottom: var(--padding, 16px);

height: 250px;
font-size: inherit;
font-family: monospace;
text-align: start;
line-height: 1.5; /* Inherited to child elements */
tab-size: 2;
caret-color: darkgrey;
white-space: pre;
padding: 0!important; /* Use --padding to set the code-input element's padding */
display: grid;
grid-template-columns: 100%;
grid-template-rows: 100%;
}

code-input * {
code-input :not(.code-input_dialog-container *) {
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. */
}

Expand All @@ -56,25 +63,33 @@ code-input textarea, code-input:not(.code-input_pre-element-styled) pre code, co
padding-top: var(--padding-top, 16px)!important;
padding-bottom: var(--padding-bottom, 16px)!important;
border: 0;

min-width: calc(100% - var(--padding-left, 16px) - var(--padding-right, 16px));
min-height: calc(100% - var(--padding-top, 16px) - var(--padding-bottom, 16px));
overflow: hidden;
resize: none;
overflow: hidden;
grid-row: 1;
grid-column: 1;
display: block;
}

code-input:not(.code-input_pre-element-styled) pre code, code-input.code-input_pre-element-styled pre {
height: max-content;
width: max-content;

/* Allow colour change to reflect properly;
transition-behavior: allow-discrete could be used but this is better supported and
works with the color property. */
transition: color 0.001s;
}

code-input:not(.code-input_pre-element-styled) pre, code-input.code-input_pre-element-styled pre code {
/* Remove all margin and padding from others */
margin: 0!important;
padding: 0!important;
border: 0!important;

min-width: 100%;
min-height: 100%;
}

code-input textarea, code-input pre, code-input pre * {
Expand All @@ -85,6 +100,9 @@ code-input textarea, code-input pre, code-input pre * {
tab-size: inherit!important;
text-align: inherit!important;
}
code-input textarea, code-input pre, code-input pre code {
overflow: visible!important;
}

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

code-input textarea:not([data-code-input-fallback]) {
color: transparent;
background: transparent;
caret-color: inherit!important; /* Or choose your favourite color */
color: transparent;
caret-color: inherit;
}
code-input textarea::placeholder {
color: lightgrey;
code-input textarea:not([data-code-input-fallback]):placeholder-shown {
/* Show placeholder */
color: var(--code-input_highlight-text-color, inherit);
}

/* Can be scrolled */
Expand Down Expand Up @@ -163,6 +182,11 @@ code-input .code-input_dialog-container {

/* Dialog boxes' text is based on text-direction */
text-align: inherit;

/* Allow colour change to reflect properly;
* transition-behavior: allow-discrete could be used but this is * better supported and works with the color property. */
color: inherit;
transition: color 0.001s;
}

[dir=rtl] code-input .code-input_dialog-container, code-input[dir=rtl] .code-input_dialog-container {
Expand Down Expand Up @@ -252,11 +276,13 @@ code-input:not(.code-input_loaded) pre, code-input:not(.code-input_loaded) texta
code-input:has(textarea[data-code-input-fallback]) {
padding: 0!important; /* Padding now in the textarea */
box-sizing: content-box;

caret-color: revert; /* JS not setting the colour since no highlighting */
}
code-input textarea[data-code-input-fallback] {
overflow: auto;
background-color: inherit;
color: inherit;
color: var(--code-input_highlight-text-color, inherit);

/* Don't overlap with message */
min-height: calc(100% - var(--padding-top, 16px) - 2em - var(--padding-bottom, 16px));
Expand Down
125 changes: 114 additions & 11 deletions code-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ var codeInput = {
}
},

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

/**
* Please see `codeInput.templates.prism` or `codeInput.templates.hljs`.
* Templates are used in `<code-input>` elements and once registered with
Expand Down Expand Up @@ -445,6 +447,16 @@ var codeInput = {
*/
dialogContainerElement = null;

/**
* Like style attribute, but with a specificity of 1
* element, 1 class. Present so styles can be set on only
* this element while giving other code freedom of use of
* the style attribute.
*
* For internal use only.
*/
internalStyle = null;

/**
* Form-Associated Custom Element Callbacks
* https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-face-example
Expand Down Expand Up @@ -530,22 +542,75 @@ var codeInput = {
this.pluginEvt("afterHighlight");
}

getStyledHighlightingElement() {
if(this.templateObject.preElementStyled) {
return this.preElement;
} else {
return this.codeElement;
}
}

/**
* Set the size of the textarea element to the size of the pre/code element.
*/
syncSize() {
// Synchronise the size of the pre/code and textarea elements
if(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;
} else {
this.style.backgroundColor = getComputedStyle(this.codeElement).backgroundColor;
this.textareaElement.style.height = getComputedStyle(this.codeElement).height;
this.textareaElement.style.width = getComputedStyle(this.codeElement).width;
this.textareaElement.style.height = getComputedStyle(this.getStyledHighlightingElement()).height;
this.textareaElement.style.width = getComputedStyle(this.getStyledHighlightingElement()).width;
}

/**
* If the color attribute has been defined on the
* code-input element by external code, return true.
* Otherwise, make the aspects the color affects
* (placeholder and caret colour) be the base colour
* of the highlighted text, for best contrast, and
* return false.
*/
isColorOverridenSyncIfNot() {
const oldTransition = this.style.transition;
this.style.transition = "unset";
window.requestAnimationFrame(() => {
this.internalStyle.setProperty("--code-input_no-override-color", "rgb(0, 0, 0)");
if(getComputedStyle(this).color == "rgb(0, 0, 0)") {
// May not be overriden
this.internalStyle.setProperty("--code-input_no-override-color", "rgb(255, 255, 255)");
if(getComputedStyle(this).color == "rgb(255, 255, 255)") {
// Definitely not overriden
this.internalStyle.removeProperty("--code-input_no-override-color");
this.style.transition = oldTransition;

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

this.internalStyle.setProperty("--code-input_highlight-text-color", highlightedTextColor);
this.internalStyle.setProperty("--code-input_default-caret-color", highlightedTextColor);
return false;
}
}
this.internalStyle.removeProperty("--code-input_no-override-color");
this.style.transition = oldTransition;
});

return true;
}

/**
* Update the aspects the color affects
* (placeholder and caret colour) to the correct
* colour: either that defined on the code-input
* element, or if none is defined externally the
* base colour of the highlighted text.
*/
syncColorCompletely() {
// color of code-input element
if(this.isColorOverridenSyncIfNot()) {
// color overriden
this.internalStyle.removeProperty("--code-input_highlight-text-color");
this.internalStyle.setProperty("--code-input_default-caret-color", getComputedStyle(this).color);
}
}


/**
* 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.
* @param {string} instructions The instructions to display only if keyboard navigation is being used. If it's blank, no instructions will be shown.
Expand Down Expand Up @@ -741,7 +806,6 @@ var codeInput = {
this.codeElement = code;
pre.append(code);
this.append(pre);

if (this.templateObject.isCode) {
if (lang != undefined && lang != "") {
code.classList.add("language-" + lang.toLowerCase());
Expand Down Expand Up @@ -780,7 +844,44 @@ var codeInput = {
// The only element that could be resized is this code-input element.
this.syncSize();
});
resizeObserver.observe(this.textareaElement);
resizeObserver.observe(this);


// Add internal style as non-externally-overridable alternative to style attribute for e.g. syncing color
this.classList.add("code-input_styles_" + codeInput.stylesheetI);
const stylesheet = document.createElement("style");
stylesheet.innerHTML = "code-input.code-input_styles_" + codeInput.stylesheetI + " {}";
this.appendChild(stylesheet);
this.internalStyle = stylesheet.sheet.cssRules[0].style;
codeInput.stylesheetI++;

// Synchronise colors
const preColorChangeCallback = (evt) => {
if(evt.propertyName == "color") {
this.isColorOverridenSyncIfNot();
}
};
this.preElement.addEventListener("transitionend", preColorChangeCallback);
this.preElement.addEventListener("-webkit-transitionend", preColorChangeCallback);
const thisColorChangeCallback = (evt) => {
if(evt.propertyName == "color") {
this.syncColorCompletely();
}
if(evt.target == this.dialogContainerElement) {
evt.stopPropagation();
// Prevent bubbling because code-input
// transitionend is separate
}
};
// Not on this element so CSS transition property does not override publicly-visible one
this.dialogContainerElement.addEventListener("transitionend", thisColorChangeCallback);
this.dialogContainerElement.addEventListener("-webkit-transitionend", thisColorChangeCallback);

// For when this code-input element has an externally-defined, different-duration transition
this.addEventListener("transitionend", thisColorChangeCallback);
this.addEventListener("-webkit-transitionend", thisColorChangeCallback);

this.syncColorCompletely();

this.classList.add("code-input_loaded");
}
Expand Down Expand Up @@ -938,7 +1039,9 @@ var codeInput = {
code.classList.add("language-" + newValue);
}

if (mainTextarea.placeholder == oldValue) mainTextarea.placeholder = newValue;
if (mainTextarea.placeholder == oldValue || oldValue == null && mainTextarea.placeholder == "") {
mainTextarea.placeholder = newValue;
}

this.scheduleHighlight();

Expand Down
Loading