Skip to content

Commit ab81411

Browse files
committed
refactor: use separate <input type=number> elements
1 parent 592dc26 commit ab81411

4 files changed

Lines changed: 110 additions & 68 deletions

File tree

contenteditable.js

Lines changed: 25 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,42 @@
11
(function() {
2-
var editables = $$('.param');
3-
function onInput(editable) {
4-
var sel = window.getSelection();
5-
var range = sel.getRangeAt(0);
6-
var startOffset = range.startOffset;
7-
8-
var content = editable.innerText;
9-
var isNegative = content[0] === '-';
10-
if (isNegative) {
11-
content = content.slice(1);
12-
}
13-
if (/[^0-9.]/g.test(content)) {
14-
content = content.replace(/[^0-9.]/g, '');
15-
startOffset = startOffset - 1;
16-
}
17-
content = isNegative ? '-' + content : content;
18-
19-
// only one decimal point
20-
var parts = content.split('.');
21-
if (parts.length > 2) {
22-
content = parts[0] + '.' + parts.slice(1).join('');
23-
startOffset = startOffset - 1;
24-
}
25-
content.replace(/<br\s*\/?>/gi, '');
26-
27-
editable.innerText = content;
28-
29-
if (editable.firstChild) {
30-
range.setStart(editable.firstChild, Math.min(startOffset, content.length));
31-
range.setEnd(editable.firstChild, Math.min(startOffset, content.length));
32-
sel.removeAllRanges();
33-
sel.addRange(range);
34-
}
2+
var inputList = $$('.param');
3+
var hiddenTextList = $$('.hidden-text');
4+
function onInput(input, index) {
5+
hiddenTextList[index].innerHTML = input.value || 0;
356
}
36-
37-
function onKeydown(event, editable, i) {
38-
if (event.key === 'Enter') {
7+
function onKeydown(event, input) {
8+
if (event.key === '-' && input.value[0] === '-') {
9+
event.preventDefault();
10+
} else if (event.key === 'Enter') {
3911
event.preventDefault();
40-
if (['.', '-'].includes(editable.innerText)) return;
41-
editable.blur();
12+
input.blur();
4213
}
4314
}
4415

45-
function onBlur(editable, index) {
46-
var xy = editable.innerText;
16+
function onBlur(input, index) {
17+
var xy = input.value;
4718
if (isNaN(xy) || (!(index % 2) && (xy < 0 || xy > 1))) {
48-
editable.innerText = 0;
19+
input.value = 0;
4920
}
50-
51-
updateBezier(editable.parentElement.innerText);
21+
let text = [...inputList].reduce(function(_text, item) {
22+
_text += item.value + ','
23+
return _text;
24+
}, '')
25+
text = text.slice(0, -1)
26+
updateBezier(text);
5227
update();
5328
updateDelayed();
5429
}
5530

56-
editables.forEach(function(editable, index) {
57-
editable.addEventListener('input', function() {
58-
onInput(editable, index);
31+
inputList.forEach(function(input, index) {
32+
input.addEventListener('keydown', function(event) {
33+
onKeydown(event, input);
5934
});
60-
editable.addEventListener('keydown', function(event) {
61-
onKeydown(event, editable, index);
35+
input.addEventListener('input', function(event) {
36+
onInput(input, index);
6237
});
63-
editable.addEventListener('blur', function() {
64-
onBlur(editable, index);
38+
input.addEventListener('blur', function() {
39+
onBlur(input, index);
6540
});
6641
});
6742
})()

index.html

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,33 @@
1212

1313
<header>
1414
<h1>
15-
<a href="" class="permalink"><code>cubic-bezier(<span id="values"><span
16-
id="P1x" class="param" contenteditable="true">0</span>,<span
17-
id="P1y" class="param" contenteditable="true">0</span>,<span
18-
id="P2x" class="param" contenteditable="true">.25</span>,<span
19-
id="P2y" class="param" contenteditable="true">1</span></span>)</code></a>
15+
<a href="" class="permalink">
16+
<code>
17+
<span>cubic-bezier(</span>
18+
<div id="values">
19+
<div class="input-wrapper">
20+
<span class="hidden-text" aria-hidden="true"></span>
21+
<input class="param" id="P1x" type="number" inputmode="decimal">
22+
</div>
23+
<span>,</span>
24+
<div class="input-wrapper">
25+
<span class="hidden-text" aria-hidden="true"></span>
26+
<input class="param" id="P1y" type="number" inputmode="decimal">
27+
</div>
28+
<span>,</span>
29+
<div class="input-wrapper">
30+
<span class="hidden-text" aria-hidden="true"></span>
31+
<input class="param" id="P2x" type="number" inputmode="decimal">
32+
</div>
33+
<span>,</span>
34+
<div class="input-wrapper">
35+
<span class="hidden-text" aria-hidden="true"></span>
36+
<input class="param" id="P2y" type="number" inputmode="decimal">
37+
</div>
38+
</div>
39+
<span>)</span>
40+
</code>
41+
</a>
2042
<div id="copybuttons">
2143
<button id="copy">Copy</button>
2244
<button id="copyoptionstoggle">&#9662;</button>

interaction.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -430,11 +430,13 @@ function update() {
430430

431431

432432
updateCopyInputs();
433-
var params = $$('.param', bezierCode),
433+
var params = $$('.param'),
434+
hiddenTextList = $$('.hidden-text'),
434435
prettyOffsets = bezier.coordinates.toString().split(',');
435-
436-
for(var i=params.length; i--;) {
437-
params[i].textContent = prettyOffsets[i];
436+
437+
for (var i=params.length; i--;) {
438+
hiddenTextList[i].innerHTML = prettyOffsets[i];
439+
params[i].value = prettyOffsets[i];
438440
}
439441
}
440442
function updateCopyInputs(){

style.css

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,58 @@ a:hover {
6868
text-decoration: none;
6969
}
7070

71-
h1 > a {
72-
font-size: clamp(1.2rem, 2vw + .75rem, 2.5rem);
73-
white-space: nowrap;
74-
color: inherit;
75-
text-decoration: none;
76-
}
71+
h1 > a {
72+
font-size: clamp(1.2rem, 2vw + .75rem, 2.5rem);
73+
white-space: nowrap;
74+
color: inherit;
75+
text-decoration: none;
76+
}
77+
h1 > a > code {
78+
display: inline-flex;
79+
}
80+
81+
.param,
82+
.hidden-text {
83+
font-size: clamp(1.2rem, 2vw + .75rem, 2.5rem);
84+
white-space: nowrap;
85+
text-decoration: none;
86+
}
87+
88+
.hidden-text {
89+
visibility: hidden;
90+
display: inline-block;
91+
opacity: 0;
92+
padding: 0 4px;
93+
box-sizing: border-box;
94+
min-width: clamp(1.2rem, 2vw + .75rem, 2.5rem);
95+
}
96+
97+
#values {
98+
display: flex;
99+
}
100+
101+
.input-wrapper {
102+
position: relative;
103+
}
104+
/* Remove spinner buttons for Chrome, Safari, Edge, Opera */
105+
.param::-webkit-outer-spin-button,
106+
.param::-webkit-inner-spin-button {
107+
-webkit-appearance: none;
108+
margin: 0;
109+
}
110+
/* Remove spinner buttons for Firefox */
111+
.param {
112+
position: absolute;
113+
top: 0;
114+
left: 0;
115+
right: 0;
116+
bottom: 0;
117+
-moz-appearance: textfield;
118+
min-width: clamp(1.2rem, 2vw + .75rem, 2.5rem);
119+
border: none;
120+
text-align: center;
121+
}
122+
77123

78124
button, .button {
79125
padding: .3em .5em;
@@ -330,9 +376,6 @@ header {
330376
color: #0ab;
331377
}
332378
/* Make the cursor unobstructed by the outline */
333-
#P1x, #P1y, #P2x, #P2y {
334-
padding: 0 4px;
335-
}
336379

337380
canvas#curve {
338381
background: #f0f0f0;

0 commit comments

Comments
 (0)