website: some UI updates to the lab

This commit is contained in:
Rasmus Andersson 2019-05-27 14:19:08 -07:00
parent e32aae98d3
commit 727977bd4e
22 changed files with 305 additions and 98 deletions

View file

@ -32,6 +32,11 @@ for f in *.svg; do
svgo --multipass -q "$f" & svgo --multipass -q "$f" &
done done
# crunch /docs/res/icons/*.svg
for f in icons/*.svg; do
svgo --multipass -q "$f" &
done
# crunch /docs/res/*.png # crunch /docs/res/*.png
for f in *.png; do for f in *.png; do
TMPNAME=.$f.tmp TMPNAME=.$f.tmp

View file

@ -717,7 +717,6 @@ samples.set('Repertoire', {
for (const g of glyphs) { for (const g of glyphs) {
// let [name, isEmpty, uc, ucName, color] = g // let [name, isEmpty, uc, ucName, color] = g
let name = g[0], isEmpty = g[1], uc = g[2], ucName = g[3], color = g[4] let name = g[0], isEmpty = g[1], uc = g[2], ucName = g[3], color = g[4]
console.log('g', g)
let style = '' let style = ''
if (color && color != '<derived>') { if (color && color != '<derived>') {
@ -755,7 +754,7 @@ samples.set('Repertoire', {
}) })
let combs = `ta es ar te ne an as ra la sa al si or ci na er at re ac gh ca ma is za ic ja va zi ce ze se in pa et ri en ti to me ec ol ni os on iz az st ke ka lo el de ro ve pe oz ie gi le ge fo uz us ur ag ah ad ko ez ig eg ak ga da tu ia so ul am it oc av su jo ru em li uc un io ao he yc gu iu ha og eh ho cn im ny sk aa sc ot ej ku lu nu go ju zo ok be ai ik nc je zn no od ek vy hu do co ed ky vi sl ut pr po aj ow ee mo iv ba mu ib uk ov ep om ym du bo zu cu di ev cj oi vo fa oe hh bh op ck bu ab fe rs ir rz ly il yo mi gj id ys ji ug um ob ns dz qe sn hr ap uh ea rc nt yu ae oj zj ud js fu pu cl vs gg cc hi oh zy ue zd ou ua ry zm of ub oð gl oy au ki kl hl ks yl bi ih ls lg hd zs zl gz tr ið sm ui oo að eb ty ct pi ij yz af uv lk ay rg ya vu ln dl ts ip sv up ht yr sr hm sy uy eo ei nh wa ss gd yv uj nz cs oa wg rt we zb ii if lc uu pl gr by ye sp þa fi zk ef kc yt wl sh zg wo sw hs lt yn dy ax kz zr ps mz jh ng pc cr bc yð eu hy uf lz eq jg zz ox gn ms dh oß cm th lm hq rn yj kr xa yi yk uo zt sj xe yb jc wu vc dr br tc tl my zv gs mc pt gm rl xi hc bl lb ds dn sg bt yp tn cd rd vz vr gb aß nk zc iq aq dc bs rk sb ex yh sd vn vd cv yd zw cb ml sz lp lv sf pn lr ws þo þy ix mr qu mt xo ld ll lw dm cy cp wz rb hb hn bz ch mh hj lh hz uß rm dg gw kt jz aw eð uð oq iþ rh hf mg iw kn fc iy cg vt hw wh hx gc ux cw aæ zf lj nd gt hg py tz kh nr nv vl fh tk oþ gk hk nm xh yf jl pz cf xu þu aþ nb pg yþ dk td jn fl ew gf bn þe gx nn np lf fy zp uq yg dt oæ tt zh jt kv tm ðo fs nj þi cz jd mk mn nl rr rv wi ða fn gy jr kg rp tj tp xy ði ßo æo` let combs = `ta es ar te ne an as ra la sa al si or ci na er at re ac gh ca ma is za ic ja va zi ce ze se in pa et ri en ti to me ec ol ni os on iz az st ke ka lo el de ro ve pe oz ie gi le ge fo uz us ur ag ah ad ko ez ig eg ak ga da tu ia so ul am it oc av su jo ru rt rf em li uc un io ao he yc gu iu ha og eh ho cn im ny sk aa sc ot ej ku lu nu go ju zo ok be ai ik nc je zn no od ek vy hu do co ed ky vi sl ut pr po aj ow ee mo iv ba mu ib uk ov ep om ym du bo zu cu di ev cj oi vo fa oe hh bh op ck bu ab fe rs ir rz ly il yo mi gj id ys ji ug um ob ns dz qe sn hr ap uh ea rc nt yu ae oj zj ud js fu pu cl vs gg cc hi oh zy ue zd ou ua ry zm of ub oð gl oy au ki kl hl ks yl bi ih ls lg hd zs zl gz tr ið sm ui oo að eb ty ct pi ij yz af uv lk ay rg ya vu ln dl ts ip sv up ht yr sr hm sy uy eo ei nh wa ss gd yv uj nz cs oa wg rt we zb ii if lc uu pl gr by ye sp þa fi zk ef kc yt wl sh zg wo sw hs lt yn dy ax kz zr ps mz jh ng pc cr bc yð eu hy uf lz eq jg zz ox gn ms dh oß cm th lm hq rn yj kr xa yi yk uo zt sj xe yb jc wu vc dr br tc tl my zv gs mc pt gm rl xi hc bl lb ds dn sg bt yp tn cd rd vz vr gb aß nk zc iq aq dc bs rk sb ex yh sd vn vd cv yd zw cb ml sz lp lv sf pn lr ws þo þy ix mr qu mt xo ld ll lw dm cy cp wz rb hb hn bz ch mh hj lh hz uß rm dg gw kt jz aw eð uð oq iþ rh hf mg iw kn fc iy cg vt hw wh hx gc ux cw aæ zf lj nd gt hg py tz kh nr nv vl fh tk oþ gk hk nm xh yf jl pz cf xu þu aþ nb pg yþ dk td jn fl ew gf bn þe gx nn np lf fy zp uq yg dt oæ tt zh jt kv tm ðo fs nj þi cz jd mk mn nl rr rv wi ða fn gy jr kg rp tj tp xy ði ßo æo`
let uniqueChars = new Set(combs.replace(/\s+/g, '').split('')) let uniqueChars = new Set(combs.replace(/\s+/g, '').split(''))
combs = combs.split(/\s+/) combs = combs.split(/\s+/)
@ -770,7 +769,6 @@ function getEnglishWords() {
if (_enWords) { if (_enWords) {
return return
} }
// const words = text.split('\n')
let combIndex = new Map() // comb => Set{ combWordsHTML } let combIndex = new Map() // comb => Set{ combWordsHTML }
console.log(`computing ${words.length} english words and ${words.length * combs.length} combinations...`) console.log(`computing ${words.length} english words and ${words.length * combs.length} combinations...`)
for (const comb of combs) { for (const comb of combs) {
@ -1411,6 +1409,7 @@ document.head.appendChild(fontCSS)
<label class="label-and-value"> <label class="label-and-value">
<span>Size:</span> <span>Size:</span>
<input type="number" value="22" step="1" min="4" max="1024" name="size"> <input type="number" value="22" step="1" min="4" max="1024" name="size">
<note><span class="unit">dp</span></note>
</label> </label>
<label class="label-and-value"> <label class="label-and-value">
@ -1429,41 +1428,27 @@ document.head.appendChild(fontCSS)
</div> </div>
<label class="label-and-value"> <label class="label-and-value">
<span>Anti-alias:</span> <span>Letter spacing:</span>
<select name="antialias"> <input type="number" value="" placeholder="" step="0.1" name="letterSpacing">
<option value="greyscale" selected>Greyscale</option> <note><span class="unit">%</span><div
<option value="subpixel">Subpixel</option> class="img-button reset-letter-spacing"
<option value="default">Browser default</option> tabindex="0"
</select> style="background-image:url(../res/icons/reset-black.svg)"></div>
</note>
</label> </label>
<label class="label-and-value"> <label class="label-and-value">
<span>Compare:</span> <span>Line height:</span>
<select name="compare">
<option value="-" selected>Nothing</option>
<option value="roboto">Roboto</option>
<option value="system">System font</option>
<option value="rasterization">Rasterization</option>
</select>
</label>
<label class="rasterizePhrase">
Rasterize phrase:<br>
<input type="text" value="Account expiration" name="rasterizePhrase">
</label>
<label class="label-and-value">
<span>letter-spacing:</span>
<input type="number" value="0" step="0.1" name="letterSpacing">
</label>
<label class="label-and-value">
<span>line-height:</span>
<input type="number" value="" placeholder="" step="1" min="0" max="1000" name="lineHeight"> <input type="number" value="" placeholder="" step="1" min="0" max="1000" name="lineHeight">
<note><span class="unit">dp</span><div
class="img-button reset-line-height"
tabindex="0"
style="background-image:url(../res/icons/reset-black.svg)"></div>
</note>
</label> </label>
<label class="label-and-value"> <label class="label-and-value">
<span>text-transform:</span> <span>Transform:</span>
<select name="text-transform"> <select name="text-transform">
<option value="none" selected>none</option> <option value="none" selected>none</option>
<option value="capitalize">capitalize</option> <option value="capitalize">capitalize</option>
@ -1473,7 +1458,7 @@ document.head.appendChild(fontCSS)
</select></label> </select></label>
<label class="label-and-value"> <label class="label-and-value">
<span>text-decoration:</span> <span>Decoration:</span>
<select name="text-decoration"> <select name="text-decoration">
<option value="none" selected>none</option> <option value="none" selected>none</option>
<option value="underline">underline</option> <option value="underline">underline</option>
@ -1525,8 +1510,32 @@ document.head.appendChild(fontCSS)
<option value="oldstyle-nums stacked-fractions">oldstyle-nums stacked-fractions</option> <option value="oldstyle-nums stacked-fractions">oldstyle-nums stacked-fractions</option>
</select></label--> </select></label-->
<h3>Display</h3>
<label class="label-and-value">
<span>Anti-alias:</span>
<select name="antialias">
<option value="greyscale" selected>Greyscale</option>
<option value="subpixel">Subpixel</option>
<option value="default">Browser default</option>
</select>
</label>
<label class="label-and-value">
<span>Compare:</span>
<select name="compare">
<option value="-" selected>Nothing</option>
<option value="roboto">Roboto</option>
<option value="system">System font</option>
</select>
</label>
<label title="White text on black background"><input type="checkbox" name="display-invert-colors"> Inverted colors</label>
<h3>Features</h3>
<div class="checkbox-group"> <div class="checkbox-group">
<span>Features:</span>
<label title="Discretionary ligatures, e.g. !? -> interrobang"><input type="checkbox" class="featopt" name="feat:dlig"> dlig &nbsp;(Discretionary ligatures)</label> <label title="Discretionary ligatures, e.g. !? -> interrobang"><input type="checkbox" class="featopt" name="feat:dlig"> dlig &nbsp;(Discretionary ligatures)</label>
<label title="Convert all numbers to numerators"><input type="checkbox" class="featopt" name="feat:numr"> numr &nbsp;(Numerators)</label> <label title="Convert all numbers to numerators"><input type="checkbox" class="featopt" name="feat:numr"> numr &nbsp;(Numerators)</label>
<label title="Convert all numbers to denominators"><input type="checkbox" class="featopt" name="feat:dnom"> dnom &nbsp;(Denominators)</label> <label title="Convert all numbers to denominators"><input type="checkbox" class="featopt" name="feat:dnom"> dnom &nbsp;(Denominators)</label>
@ -1586,14 +1595,18 @@ document.head.appendChild(fontCSS)
<sample contenteditable spellcheck="false" class="primary inter"></sample> <sample contenteditable spellcheck="false" class="primary inter"></sample>
<sample contenteditable spellcheck="false" class="secondary"></sample> <sample contenteditable spellcheck="false" class="secondary"></sample>
</samples> </samples>
<canvas id="displayCanvas" width="960" height="400"></canvas>
<canvas id="renderCanvas" width="120" height="50"></canvas>
</div> </div>
<div id="measure" class="inter">Åj</div> <div id="measure" class="inter">Åj</div>
</body>
<script type="text/javascript">(function(){
function InterDynamicTracking(fontSize) {
var a = -0.0223, b = 0.185, c = -0.1745;
// tracking = a + b * e ^ (c * fontSize)
return a + b * Math.pow(Math.E, c * fontSize)
}
<script type="text/javascript">
// provide hinted=1 to use TTF hinted fonts. // provide hinted=1 to use TTF hinted fonts.
// not exposed in UI as it only works when serving the site locally // not exposed in UI as it only works when serving the site locally
@ -1617,6 +1630,7 @@ class BoundVar {
this.lastValue = this.getValue() this.lastValue = this.getValue()
this.parentVars = parentVars this.parentVars = parentVars
this.defaultValue = this.lastValue this.defaultValue = this.lastValue
this._changeCallbacks = []
} }
refreshValue(ev) { refreshValue(ev) {
@ -1632,6 +1646,21 @@ class BoundVar {
: this.e.value : this.e.value
} }
onChange(callback) {
this._changeCallbacks.push(callback)
}
removeChangeListener(callback) {
let i = 0
for (; i < this._changeCallbacks.length; i++) {
if (this._changeCallbacks[i] === callback) {
this._changeCallbacks.splice(i, 1)
return true
}
}
return false
}
setValue(value) { setValue(value) {
if (this.isCheckbox && typeof value != 'boolean') { if (this.isCheckbox && typeof value != 'boolean') {
value = parseInt(value) value = parseInt(value)
@ -1650,14 +1679,22 @@ class BoundVar {
if (this.isCheckbox) { if (this.isCheckbox) {
this.e.checked = !!value this.e.checked = !!value
} else if (this.isNumber && typeof value == 'number') { } else if (this.isNumber && typeof value == 'number') {
if (this.e.valueAsNumber != value) { if (isNaN(value)) {
this.e.valueAsNumber = value this.e.value = null
} else {
if (this.e.valueAsNumber != value) {
this.e.valueAsNumber = value
}
} }
} else if (this.e.value != value) { } else if (this.e.value != value) {
this.e.value = value this.e.value = value
} }
this.lastValue = value this.lastValue = value
for (let f of this._changeCallbacks) {
f(value, this)
}
} }
} }
@ -1824,25 +1861,23 @@ class Vars {
function main() { function main() {
const vars = new Vars(document.location.search) const vars = new Vars(document.location.search)
let interUISample = document.querySelector('sample.inter'); const $ = (q, el) => (el || document).querySelector(q)
let secondarySample = document.querySelector('sample.secondary'); const $$ = (q, el) => [].slice.call((el || document).querySelectorAll(q))
let interUISample = $('sample.inter');
let secondarySample = $('sample.secondary');
secondarySample.innerText = interUISample.innerText; secondarySample.innerText = interUISample.innerText;
const renderCanvas = document.querySelector('#renderCanvas') const measureDiv = $('#measure')
const displayCanvas = document.querySelector('#displayCanvas')
const measureDiv = document.querySelector('#measure') const secondaryFontElements = $$('.secondaryFont')
const primaryFontElements = $$('.primaryFont')
const secondaryFontElements = const repertoireControl = $('.repertoireControl')
Array.prototype.slice.call(document.querySelectorAll('.secondaryFont')) const samplesElement = $('samples')
const primaryFontElements =
Array.prototype.slice.call(document.querySelectorAll('.primaryFont'))
const repertoireControl = document.querySelector('.repertoireControl')
const samplesElement = document.querySelector('samples')
// filter paste to match style // filter paste to match style
;[].slice.call(document.querySelectorAll('[contenteditable]')).forEach(el => { $$('[contenteditable]').forEach(el => {
el.addEventListener('paste', ev => { el.addEventListener('paste', ev => {
ev.preventDefault() ev.preventDefault()
let text = ev.clipboardData.getData("text/plain") let text = ev.clipboardData.getData("text/plain")
@ -1852,6 +1887,13 @@ function main() {
let sizeVar = null let sizeVar = null
// prevent clicks on img-button from changing focus
$$('.img-button').forEach(el => {
el.addEventListener('pointerdown', ev => {
ev.preventDefault()
}, {passive:false, capture:true})
})
function forEachGlyphlist(fn) { function forEachGlyphlist(fn) {
let elements = samplesElement.querySelectorAll('.glyphlist') let elements = samplesElement.querySelectorAll('.glyphlist')
if (elements) { if (elements) {
@ -1872,7 +1914,8 @@ function main() {
} }
const lineHeightInput = document.querySelector('[name="lineHeight"]') const lineHeightInput = $('[name="lineHeight"]')
let measurePending = false let measurePending = false
const measure = () => { const measure = () => {
const r = measureDiv.getBoundingClientRect() const r = measureDiv.getBoundingClientRect()
@ -1951,7 +1994,7 @@ function main() {
} }
// sample text // sample text
const samplesSelect = document.querySelector('select[name="sample"]') const samplesSelect = $('select[name="sample"]')
for (let [k,v] of samples) { for (let [k,v] of samples) {
const opt = document.createElement('option') const opt = document.createElement('option')
opt.innerText = k opt.innerText = k
@ -1975,12 +2018,12 @@ function main() {
} }
}) })
const boxes = document.querySelector('boxes') const boxes = $('boxes')
sizeVar = vars.bind('size', (e, v) => { sizeVar = vars.bind('size', (e, v) => {
boxes.style.display = (v > 20) ? 'none' : null boxes.style.display = (v > 20) ? 'none' : null
setCSSProp('font-size', v + 'px') setCSSProp('font-size', v + 'px')
setGlyphlistClass('hideNames', v < 36) setGlyphlistClass('hideNames', v < 36)
// setCSSProp('line-height', Math.ceil(v * 1.5) + 'px') return v
}) })
let usingVarFont = false let usingVarFont = false
@ -2102,20 +2145,6 @@ function main() {
secondarySampleClassNameAddition = className || null secondarySampleClassNameAddition = className || null
} }
const rasterizePhraseInput = document.querySelector('[name="rasterizePhrase"]')
const rasterizePhraseLabel = document.querySelector('label.rasterizePhrase')
const enableRasterization = () => {
displayCanvas.style.display = null
rasterizePhraseInput.disabled = false
rasterizePhraseLabel.style.display = null
}
const disableRasterization = () => {
displayCanvas.style.display = 'none'
rasterizePhraseInput.disabled = true
rasterizePhraseLabel.style.display = 'none'
}
const enableSecondarySample = className => { const enableSecondarySample = className => {
setSecondarySampleClassName(className) setSecondarySampleClassName(className)
secondarySample.style.display = null secondarySample.style.display = null
@ -2128,20 +2157,50 @@ function main() {
} }
vars.bind('compare', (e, v) => { vars.bind('compare', (e, v) => {
disableRasterization()
disableSecondarySample() disableSecondarySample()
switch (v) { switch (v) {
case 'roboto': enableSecondarySample('robotoFont'); break; case 'roboto': enableSecondarySample('robotoFont'); break;
case 'system': enableSecondarySample('systemFont'); break; case 'system': enableSecondarySample('systemFont'); break;
case 'rasterization': enableRasterization(); break;
default: return '-'; default: return '-';
} }
}, e => (e.value && e.value != '-') ? e.value : null) }, e => (e.value && e.value != '-') ? e.value : null)
vars.bind('letterSpacing', (e, v) => { function updateImplicitLetterSpacing(el, size) {
setCSSProp('letter-spacing', v + 'px') let t = InterDynamicTracking(size)
let v = parseFloat((t * 100).toFixed(1))
el.placeholder = v
return v
}
let letterSpacingVar = vars.bind('letterSpacing', (e, v) => {
if (!v) {
v = updateImplicitLetterSpacing(e, sizeVar.getValue())
}
setCSSProp('letter-spacing', (v / 100) + 'em')
}, (e, prevValue, ev) => {
if (ev && !ev.inputType && !prevValue) {
// step increment/decrement
let delta = e.valueAsNumber == 0 ? -1 : e.valueAsNumber
return parseFloat(e.placeholder) + delta
}
return e.value || ""
}) })
// update implicit letter spacing when size changes
sizeVar.onChange(size => {
let t = letterSpacingVar.lastValue
if (!t || isNaN(t)) {
updateImplicitLetterSpacing(letterSpacingVar.e, size)
}
})
$('.reset-letter-spacing').addEventListener('click', ev => {
vars.setValue('letterSpacing', '')
ev.stopPropagation()
ev.preventDefault()
}, {passive:false,capture:true})
vars.bind('lineHeight', lineHeightInput, (e, v) => { vars.bind('lineHeight', lineHeightInput, (e, v) => {
setCSSProp('line-height', v ? v + 'px' : null) setCSSProp('line-height', v ? v + 'px' : null)
}, (e, prevValue, ev) => { }, (e, prevValue, ev) => {
@ -2153,7 +2212,17 @@ function main() {
if (e.valueAsNumber < 0) { if (e.valueAsNumber < 0) {
return Math.abs(e.valueAsNumber) return Math.abs(e.valueAsNumber)
} }
return e.value || null return e.value || ""
})
$('.reset-line-height').addEventListener('click', ev => {
vars.setValue('lineHeight', '')
ev.stopPropagation()
ev.preventDefault()
}, {passive:false,capture:true})
vars.bind('display-invert-colors', (e, on) => {
document.body.classList[on ? 'add' : 'remove']('inverted-colors')
}) })
let spaaSelect = vars.bind('antialias', (e, v) => { let spaaSelect = vars.bind('antialias', (e, v) => {
@ -2207,7 +2276,7 @@ function main() {
// }) // })
for (let e of Array.from(document.querySelectorAll('input.featopt'))) { for (let e of $$('input.featopt')) {
let p = e.name.replace(/^feat\:/, '').split('=') let p = e.name.replace(/^feat\:/, '').split('=')
let name = p[0] let name = p[0]
let valueOn = parseInt(p[1] || '1') let valueOn = parseInt(p[1] || '1')
@ -2245,7 +2314,7 @@ function main() {
sampleText.substr(m.index + m[0].length) sampleText.substr(m.index + m[0].length)
) )
let directive = m[1].toLowerCase() let directive = m[1].toLowerCase()
console.log('dir', m[1], '=>', m[2]) // console.log('dir', m[1], '=>', m[2])
if (directive == 'enablefeatures') { if (directive == 'enablefeatures') {
// #!enableFeatures:tnum,dlig // #!enableFeatures:tnum,dlig
for (let feat of m[2].toLowerCase().split(/\s*,\s*/)) { for (let feat of m[2].toLowerCase().split(/\s*,\s*/)) {
@ -2270,14 +2339,34 @@ function main() {
} }
}) })
// ESC clears keyboard focus
document.addEventListener('keydown', ev => {
if (ev.keyCode == 27) {
document.activeElement.blur()
}
}/*, {capture:true, passive:false}*/)
// RETURN on control clears keyboard focus
$$('input').forEach(el => el.addEventListener('keypress', ev => {
if (ev.keyCode == 13) {
document.activeElement.blur()
}
}))
// clear keyboard focus when a select control changes
$$('select').forEach(el => el.addEventListener('change', ev => {
document.activeElement.blur()
window.requestAnimationFrame(() => document.activeElement.blur())
}))
} }
</script>
</body>
<script type="text/javascript"> main();
main(); document.title = (
document.title = ( (new Date()).toTimeString().split(':').slice(0,2).join(':') +
(new Date()).toTimeString().split(':').slice(0,2).join(':') + ' — ' + (new Date()).toDateString()
' — ' + (new Date()).toDateString() );
);
</script> })();</script>
</html> </html>

View file

@ -1,3 +1,19 @@
:root {
--fieldHeight: 24px;
/* P3 wide gamut colors */
--red: color(display-p3 0.94 0.19 0.04);
--yellow: color(display-p3 1 0.87 0.05);
--blue: rgb(3, 102, 214);
}
@supports not (color: color(display-p3 1 1 1)) {
/* sRGB colors */
:root {
--red: #F03009;
--yellow: #FFE310;
}
}
* { margin:0; padding:0; font-synthesis: none; } * { margin:0; padding:0; font-synthesis: none; }
html { } html { }
body { body {
@ -39,6 +55,41 @@ i, cite, em, var, address, dfn {
font-style: oblique; font-style: oblique;
} }
label {
display: block;
margin: 2px 0;
}
input[type="number"] {
width:50px;
background: none;
/*border: 1px solid rgba(0,0,0,0.2);*/
border: none;
padding: 4px;
border-radius: 2px;
background: white;
}
select {
height: var(--fieldHeight);
box-sizing: border-box;
-webkit-appearance: none;
border: none;
padding: 4px 18px 4px 4px;
border-radius: 2px;
background: white;
background-image: url(../res/icons/popup-black.svg);
background-repeat: no-repeat;
background-position: right center;
}
input[type="number"]:focus,
input[type="text"]:focus,
select:focus {
outline: none;
box-shadow: 0 0 0 2px black;
}
.options { .options {
width: 275px; width: 275px;
box-sizing:border-box; box-sizing:border-box;
@ -59,6 +110,11 @@ i, cite, em, var, address, dfn {
.options small { .options small {
opacity: 0.6; opacity: 0.6;
} }
.options h3 {
font-weight: 600;
font-size: 12px;
margin: 1rem 0 0.5rem 0;
}
.options input[type="radio"], .options input[type="checkbox"] { .options input[type="radio"], .options input[type="checkbox"] {
margin-right:4px; margin-right:4px;
} }
@ -66,6 +122,8 @@ i, cite, em, var, address, dfn {
display: flex; display: flex;
flex-wrap: nowrap; flex-wrap: nowrap;
justify-content: flex-start; justify-content: flex-start;
align-items: center;
height: var(--fieldHeight);
} }
.options .label-and-value span { .options .label-and-value span {
/*flex: 1 1 auto;*/ /*flex: 1 1 auto;*/
@ -76,8 +134,10 @@ i, cite, em, var, address, dfn {
} }
.options .label-and-value input { .options .label-and-value input {
width: 50px; width: 50px;
max-height: var(--fieldHeight);
box-sizing: border-box;
} }
.options .label-and-value select { .options select {
min-width:50px; min-width:50px;
max-width:130px; max-width:130px;
} }
@ -127,18 +187,45 @@ i, cite, em, var, address, dfn {
pointer-events: none; pointer-events: none;
opacity: 0.4; opacity: 0.4;
} }
.options .label-and-value input + note,
.options .label-and-value select + note {
display: flex;
align-items: center;
height: var(--fieldHeight);
line-height: var(--fieldHeight);
margin-left: 0.5em;
user-select: none; -webkit-user-select: none;
color: rgba(0,0,0,0.4);
}
.options .label-and-value input + note .unit,
.options .label-and-value select + note .unit {
flex: 0 0 auto;
display:flex;
width: 18px;
}
input[type="number"] {
width:50px; .img-button {
background: none; display: inline-block;
border: 1px solid rgba(0,0,0,0.2); width: var(--fieldHeight);
padding: 4px; height:var(--fieldHeight);
border-radius: 2px; background-size: 16px 16px;
background-position: center center;
background-repeat: no-repeat;
border-radius: 3px;
opacity: 0.8;
outline: none;
} }
.img-button:hover {
label { opacity: 1;
display: block; background-color: rgba(0,0,0,0.1);
margin: 2px 0; }
.img-button:hover:active {
opacity: 1;
background-color: rgba(0,0,0,0.2);
}
.img-button:focus {
box-shadow: 0 0 0 2px black;
} }
.checkbox-group label { .checkbox-group label {
@ -172,6 +259,7 @@ body.italic samples {
white-space: pre-wrap; white-space: pre-wrap;
outline: none; outline: none;
overflow-wrap: break-word; overflow-wrap: break-word;
color:black;
} }
sample p { sample p {
white-space: pre-wrap; white-space: pre-wrap;
@ -221,6 +309,13 @@ body.italic samples {
display:none; display:none;
} }
body.inverted-colors {
background: #020202;
}
body.inverted-colors sample {
color: white;
}
body.secondarySampleDisabled .showOnlyWithSecondarySample { body.secondarySampleDisabled .showOnlyWithSecondarySample {
display: none; display: none;
} }

View file

@ -94,10 +94,10 @@
height: var(--strip-height); height: var(--strip-height);
background-image: url(popup.svg); background-image: url(popup.svg);
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: left center;
width: 120px; width: 120px;
color: white; color: white;
opacity: 0.6; opacity: 0.6;
background-position: left center;
padding-left: 20px; padding-left: 20px;
line-height: var(--strip-height); line-height: var(--strip-height);
text-overflow: ellipsis; text-overflow: ellipsis;

1
docs/res/icons/close-black.svg Executable file
View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8 8.707l4.646 4.647.708-.708L8.707 8l4.647-4.646-.708-.708L8 7.293 3.354 2.646l-.708.708L7.293 8l-4.647 4.646.708.708L8 8.707z" fill="#000"/></svg>

After

Width:  |  Height:  |  Size: 232 B

1
docs/res/icons/close.svg Executable file
View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8 8.707l4.646 4.647.708-.708L8.707 8l4.647-4.646-.708-.708L8 7.293 3.354 2.646l-.708.708L7.293 8l-4.647 4.646.708.708L8 8.707z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 232 B

View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 8.293L3.354 3.646l-.708.708L8 9.707l5.354-5.353-.708-.708L8 8.293zM14 13H2v-1h12v1z" fill="#000"/></svg>

After

Width:  |  Height:  |  Size: 231 B

1
docs/res/icons/dismiss.svg Executable file
View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 8.293L3.354 3.646l-.708.708L8 9.707l5.354-5.353-.708-.708L8 8.293zM14 13H2v-1h12v1z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 231 B

View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2.245 12l.37-1.084h1.95L4.935 12h1.052L4.11 6.91H3.068L1.191 12h1.054zM3.56 8.147h.06l.671 1.964H2.89l.671-1.964zM8.415 12l.822-2.335h3.64L13.698 12h1.108l-3.205-8.727h-1.09L7.306 12h1.108zm2.59-7.347h.103l1.436 4.074H9.57l1.436-4.074z" fill="#000"/></svg>

After

Width:  |  Height:  |  Size: 341 B

1
docs/res/icons/font-size.svg Executable file
View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2.245 12l.37-1.084h1.95L4.935 12h1.052L4.11 6.91H3.068L1.191 12h1.054zM3.56 8.147h.06l.671 1.964H2.89l.671-1.964zM8.415 12l.822-2.335h3.64L13.698 12h1.108l-3.205-8.727h-1.09L7.306 12h1.108zm2.59-7.347h.103l1.436 4.074H9.57l1.436-4.074z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 341 B

View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5.415 12l.822-2.335h3.64L10.698 12h1.108L8.602 3.273h-1.09L4.306 12h1.108zm2.59-7.347h.103l1.436 4.074H6.57l1.436-4.074z" fill="#000"/><path fill-rule="evenodd" clip-rule="evenodd" d="M0 14V2h1v12H0zm15 0V2h1v12h-1z" fill="#000"/></svg>

After

Width:  |  Height:  |  Size: 321 B

View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5.415 12l.822-2.335h3.64L10.698 12h1.108L8.602 3.273h-1.09L4.306 12h1.108zm2.59-7.347h.103l1.436 4.074H6.57l1.436-4.074z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M0 14V2h1v12H0zm15 0V2h1v12h-1z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 321 B

View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5.297 12l.762-2.14h3.32L10.14 12h1.015L8.22 4h-1l-2.94 8h1.016zm1.066-3l1.324-3.734h.063L9.074 9h-2.71z" fill="#000"/><path fill-rule="evenodd" clip-rule="evenodd" d="M15 2H1V1h14v1zm0 13H1v-1h14v1z" fill="#000"/></svg>

After

Width:  |  Height:  |  Size: 304 B

1
docs/res/icons/line-height.svg Executable file
View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5.297 12l.762-2.14h3.32L10.14 12h1.015L8.22 4h-1l-2.94 8h1.016zm1.066-3l1.324-3.734h.063L9.074 9h-2.71z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M15 2H1V1h14v1zm0 13H1v-1h14v1z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 304 B

1
docs/res/icons/popup-black.svg Executable file
View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 3.293l3.354 3.353-.707.708L8 4.707 5.354 7.354l-.708-.708L8 3.293zm0 8L5.354 8.646l-.708.708L8 12.707l3.354-3.353-.707-.708L8 11.293z" fill="#000"/></svg>

After

Width:  |  Height:  |  Size: 281 B

1
docs/res/icons/popup.svg Executable file
View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 3.293l3.354 3.353-.707.708L8 4.707 5.354 7.354l-.708-.708L8 3.293zm0 8L5.354 8.646l-.708.708L8 12.707l3.354-3.353-.707-.708L8 11.293z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 281 B

1
docs/res/icons/reset-black.svg Executable file
View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.993.893L6.95 2.817l1.272.187A6 6 0 1 1 2 9h1a5 5 0 1 0 5.928-4.914l-.005.032-.79-.116A5.078 5.078 0 0 0 8 4v-.018L6.684 3.79l2.214 2.908-.796.606-3.287-4.319L9.459.047l.534.846z" fill="#000"/></svg>

After

Width:  |  Height:  |  Size: 285 B

1
docs/res/icons/reset.svg Executable file
View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.993.893L6.95 2.817l1.272.187A6 6 0 1 1 2 9h1a5 5 0 1 0 5.928-4.914l-.005.032-.79-.116A5.078 5.078 0 0 0 8 4v-.018L6.684 3.79l2.214 2.908-.796.606-3.287-4.319L9.459.047l.534.846z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 285 B

View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 4H6V3h8v1zM4 4H2V3h2v1zm10 3H6V6h8v1zM4 7H2V6h2v1zm10 3H6V9h8v1zM4 10H2V9h2v1zm10 3H6v-1h8v1zM4 13H2v-1h2v1z" fill="#000"/></svg>

After

Width:  |  Height:  |  Size: 257 B

1
docs/res/icons/settings.svg Executable file
View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14 4H6V3h8v1zM4 4H2V3h2v1zm10 3H6V6h8v1zM4 7H2V6h2v1zm10 3H6V9h8v1zM4 10H2V9h2v1zm10 3H6v-1h8v1zM4 13H2v-1h2v1z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 257 B

1
docs/res/icons/style-black.svg Executable file
View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 13V3h1v10H0zm3 0V3h2v10H3zm4 0V3h3v10H7zm5 0V3h4v10h-4z" fill="#000"/></svg>

After

Width:  |  Height:  |  Size: 203 B

1
docs/res/icons/style.svg Executable file
View file

@ -0,0 +1 @@
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 13V3h1v10H0zm3 0V3h2v10H3zm4 0V3h3v10H7zm5 0V3h4v10h-4z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 203 B