From fb84f2abd4525371ff70c7609d8bff4fb358eaf1 Mon Sep 17 00:00:00 2001 From: andylizi Date: Thu, 1 Sep 2022 14:34:11 +0800 Subject: [PATCH 1/4] Shrink image assets 54.2 KiB -> 27.5 KiB Sources: * https://bytecodealliance.org/images/bytecode-alliance-logo.svg * https://commons.wikimedia.org/wiki/File:Google_Chrome_icon_(February_2022).svg * https://commons.wikimedia.org/wiki/File:Microsoft_Edge_logo_(2019).svg * https://commons.wikimedia.org/wiki/File:Firefox_logo,_2019.svg * https://nodejs.org/en/about/resources/ * https://commons.wikimedia.org/wiki/File:Safari_browser_logo.svg * https://wasmer.io/images/logo.svg --- _includes/header.html | 2 +- features.json | 6 +++--- images/bca.png | Bin 8526 -> 0 bytes images/bca.svg | 1 + images/chrome.svg | 2 +- images/edge.svg | 2 +- images/firefox.svg | 2 +- images/nodejs.svg | 2 +- images/safari.svg | 1 + images/safari_144x144.png | Bin 29896 -> 0 bytes images/safari_48x48.png | Bin 5240 -> 0 bytes images/safari_96x96.png | Bin 16045 -> 0 bytes images/wasmer.png | Bin 17230 -> 0 bytes images/wasmer.svg | 1 + 14 files changed, 11 insertions(+), 8 deletions(-) delete mode 100644 images/bca.png create mode 100644 images/bca.svg create mode 100644 images/safari.svg delete mode 100644 images/safari_144x144.png delete mode 100644 images/safari_48x48.png delete mode 100644 images/safari_96x96.png delete mode 100644 images/wasmer.png create mode 100644 images/wasmer.svg diff --git a/_includes/header.html b/_includes/header.html index b8969025..209b7400 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -31,7 +31,7 @@ WebAssembly 1.0 has shipped in 4 major browser engines.     -   +      ​Learn more diff --git a/features.json b/features.json index f8768ffb..79513bb6 100644 --- a/features.json +++ b/features.json @@ -128,7 +128,7 @@ }, "Safari": { "url": "https://www.apple.com/safari/", - "logo": "/images/safari_48x48.png", + "logo": "/images/safari.svg", "version": "15.2", "features": { "bigInt": true, @@ -144,7 +144,7 @@ }, "Wasmtime": { "url": "https://wasmtime.dev/", - "logo": "/images/bca.png", + "logo": "/images/bca.svg", "version": "0.33", "features": { "bigInt": null, @@ -162,7 +162,7 @@ }, "Wasmer": { "url": "https://wasmer.io/", - "logo": "/images/wasmer.png", + "logo": "/images/wasmer.svg", "version": "2.0", "features": { "bigInt": null, diff --git a/images/bca.png b/images/bca.png deleted file mode 100644 index 9baadb3627038f77dd05f64e116d0bbc8a6cee12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8526 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 w-$?-2fV2Ng+yB4*eE(nP53Bytecode Alliance logo \ No newline at end of file diff --git a/images/chrome.svg b/images/chrome.svg index 8d2d942e..381be82c 100644 --- a/images/chrome.svg +++ b/images/chrome.svg @@ -1 +1 @@ - \ No newline at end of file +Chrome logo \ No newline at end of file diff --git a/images/edge.svg b/images/edge.svg index e3707609..ad41c550 100644 --- a/images/edge.svg +++ b/images/edge.svg @@ -1 +1 @@ - \ No newline at end of file +Edge logo \ No newline at end of file diff --git a/images/firefox.svg b/images/firefox.svg index 951b6d2d..c530ab22 100644 --- a/images/firefox.svg +++ b/images/firefox.svg @@ -1 +1 @@ - \ No newline at end of file +Firefox logo \ No newline at end of file diff --git a/images/nodejs.svg b/images/nodejs.svg index 974a2b3e..db19b09b 100644 --- a/images/nodejs.svg +++ b/images/nodejs.svg @@ -1 +1 @@ - \ No newline at end of file +Node.js Logo \ No newline at end of file diff --git a/images/safari.svg b/images/safari.svg new file mode 100644 index 00000000..9c40a6f6 --- /dev/null +++ b/images/safari.svg @@ -0,0 +1 @@ +Safari logo \ No newline at end of file diff --git a/images/safari_144x144.png b/images/safari_144x144.png deleted file mode 100644 index a91a1e1b01c81d1e2b23690ca4048d2b8f4f35ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29896 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 diff --git a/images/wasmer.png b/images/wasmer.png deleted file mode 100644 index 3b136d1b45860e9ac866f8587b3d1456403adb6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17230 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 MGz#LCqDJ5T4`U-T;Q#;t diff --git a/images/wasmer.svg b/images/wasmer.svg new file mode 100644 index 00000000..c38c773f --- /dev/null +++ b/images/wasmer.svg @@ -0,0 +1 @@ +Wasmer logo \ No newline at end of file From 17542914d307d29ed3835a9d73ade9f2330657c0 Mon Sep 17 00:00:00 2001 From: andylizi Date: Tue, 23 Aug 2022 14:40:53 +0800 Subject: [PATCH 2/4] Extract feature table to separate JS file --- roadmap.js | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++ roadmap.md | 98 +----------------------------------------------------- 2 files changed, 96 insertions(+), 97 deletions(-) create mode 100644 roadmap.js diff --git a/roadmap.js b/roadmap.js new file mode 100644 index 00000000..f4c85fb9 --- /dev/null +++ b/roadmap.js @@ -0,0 +1,95 @@ +(async () => { + function partitionArray(arr, condition) { + const matched = []; + const unmatched = []; + + for (const item of arr) { + if (condition(item)) { + matched.push(item); + } else { + unmatched.push(item); + } + } + + return { matched, unmatched }; + } + + const { features, browsers } = await fetch('/features.json').then(res => res.json()); + const table = document.getElementById('feature-support'); + + function h(name, props = {}, children = []) { + const node = Object.assign(document.createElement(name), props); + node.append(...children); + return node; + } + + const tBody = document.createElement('tbody'); + + table.append( + h('thead', {}, [ + h('tr', {}, [ + h('th'), + h('th', {}, ['Your browser']), + ...Object.entries(browsers).map(([name, { url, logo, version }]) => + h('th', {}, [ + h('a', { href: url }, [ + h('img', { src: logo, width: 32, height: 32 }), + h('br'), + name, + h('sup', {}, [version]), + ]) + ]) + ) + ]) + ]), + tBody + ); + + let featureGroups = partitionArray( + Object.entries(features).map(([name, feature]) => Object.assign(feature, { name })), + feature => feature.phase >= 4 + ); + + featureGroups = [ + { name: 'Standardized features', features: featureGroups.matched }, + { name: 'In-progress proposals', features: featureGroups.unmatched }, + ]; + + const columnCount = 2 + Object.keys(browsers).length; + + for (const { name, features } of featureGroups) { + tBody.append( + h('tr', {}, [ + h('th', { colSpan: columnCount }, [name]) + ]) + ); + for (const { name, description, url, phase } of features) { + const supportHTML = h('td'); + Promise.resolve() + // Make sure to call `wasmFeatureDetect` inside a promise-chained + // function so that we can still render table rows for features that + // we don't have a detector yet. + .then(() => wasmFeatureDetect[name]()) + .then( + supported => (supported ? '✔️' : '❌'), + err => '❌' + ) + .then(textContent => { + supportHTML.textContent = textContent; + }); + tBody.append( + h('tr', {}, [ + h('th', {}, [h('a', { href: url }, [description])]), + supportHTML, + ...Object.values(browsers).map(({ features }) => { + const support = features[name]; + if (typeof support === 'string') { + return h('td', { title: support, tabIndex: 0 }, ['⏳']); + } + return h('td', {}, [support ? '✔️' : support === null ? 'ⁿ/ₐ' : '❌']); + }) + ]) + ); + } + } +})(); diff --git a/roadmap.md b/roadmap.md index 0780fabf..e4f5e22c 100644 --- a/roadmap.md +++ b/roadmap.md @@ -11,102 +11,6 @@ After the initial release, WebAssembly has been gaining new features through the The table below aims to track implemented features in popular engines: - + To detect supported features at runtime from JavaScript, check out the [`wasm-feature-detect` library](https://github.com/GoogleChromeLabs/wasm-feature-detect), which powers the "Your browser" column above. From 330b032a7ae9d45da17f62033e06de4bd4303dd8 Mon Sep 17 00:00:00 2001 From: andylizi Date: Tue, 23 Aug 2022 18:07:46 +0800 Subject: [PATCH 3/4] Add first-introduced versions to roadmap --- _includes/header.html | 12 +- css/custom.css | 131 ++++++++++++++++- features.json | 84 +++++------ roadmap.js | 327 +++++++++++++++++++++++++++++++++++++----- roadmap.md | 30 +++- 5 files changed, 489 insertions(+), 95 deletions(-) diff --git a/_includes/header.html b/_includes/header.html index 209b7400..85142076 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -1,5 +1,5 @@ - + @@ -13,7 +13,7 @@
- +
diff --git a/css/custom.css b/css/custom.css index fefb1846..64ef07bd 100644 --- a/css/custom.css +++ b/css/custom.css @@ -14,7 +14,7 @@ body { } a { - color: #6797e2; + color: #4772b5; text-decoration: none; } @@ -1880,7 +1880,8 @@ dl dd { } table { - display: block; + /* https://bugzilla.mozilla.org/show_bug.cgi?id=1005271 */ + /* display: block; */ width: 100%; overflow: auto; } @@ -1890,7 +1891,7 @@ table th { } table th, table td { - padding: 6px 13px; + padding: 6px 11px; border: 1px solid #ddd; } @@ -1957,9 +1958,15 @@ pre code::before, pre code::after { content: normal; } +#feature-support-scrollbox { + overflow: auto; + margin: 0 0 16px 0; +} + #feature-support { white-space: nowrap; cursor: default; + margin: 0; } #feature-support>caption { @@ -1984,7 +1991,119 @@ pre code::before, pre code::after { height: 32px; } -#feature-support td[title] { - text-decoration: underline dashed; - text-underline-position: under; +#feature-support td { + position: relative; /* for tooltip */ +} + +#feature-support td:hover, #feature-support td:focus, #feature-support td:focus-within { + background: rgba(0, 0, 0, .04); +} + +.feature-cell { + position: relative; + height: 24px; /* height of the icon inside */ + line-height: 24px; +} + +.feature-cell > sup { + font-size: .7em; + position: absolute; + top: .2em; +} + +.feature-cell > svg { + width: 24px; + height: 24px; +} + +.feature-cell.icon-yes { + color: #1B5E20; +} + +.feature-cell.icon-yes > svg .svg-stroke { + fill: #1B5E20; +} + +.feature-cell.icon-no { + color: #a96e8e; +} + +.feature-cell.icon-no > svg .svg-stroke { + fill: #a96e8e; +} + +.feature-cell.icon-flag { + color: #575581; +} + +.feature-cell.icon-flag > svg .svg-stroke { + fill: #575581; } + +.feature-cell.icon-na { + color: #78909C; +} + +.feature-cell.icon-unknown > svg .svg-stroke { + fill: #78909C; +} + +#feature-support-scrollbox + ol { + list-style: lower-alpha; + font-size: 0.7em; + margin: 0 0 1em 0; +} + +#feature-support-scrollbox + ol > li { + transition: background-color .08s ease-in-out; +} + +#feature-support-scrollbox + ol .ref-highlight { + background: #ECEFF1; +} + +.feature-tooltip { + text-align: left; + text-align: start; + white-space: normal; + background: #fefefe; + font-size: 0.8em; + border-radius: 2px; + outline: none; + + top: 0; + left: 0; + z-index: 1; + max-width: 16em; + width: max-content; + height: max-content; + padding: 12px; +} + +/* Only apply transition after the initial position was set */ +.feature-tooltip[data-placement] { + transition: transform .2s ease-in-out; +} + +.feature-tooltip, .feature-tooltip-arrow { + position: absolute; + contain: layout style; + --shadow-size: 3px; + box-shadow: 0 0 var(--shadow-size) rgba(0, 0, 0, .30); +} + +.feature-tooltip-arrow { + --arrow-size: 8px; + background: inherit; + width: var(--arrow-size); + height: var(--arrow-size); + + --c0: calc(var(--shadow-size) * -1); + --c1: calc(100% + var(--shadow-size)); + clip-path: polygon(var(--c0) var(--c1), var(--c0) var(--c0), var(--c1) var(--c0)); +} + +[data-placement="top"] > .feature-tooltip-arrow { bottom: 0; transform: translateY(50%) rotate(-135deg); } +[data-placement="bottom"] > .feature-tooltip-arrow { top: 0; transform: translateY(-50%) rotate(45deg); } +[data-placement="left"] > .feature-tooltip-arrow { right: 0; transform: translateX(50%) rotate(135deg); } +[data-placement="right"] > .feature-tooltip-arrow { left: 0; transform: translateX(-50%) rotate(-45deg); } diff --git a/features.json b/features.json index 79513bb6..b3f2a991 100644 --- a/features.json +++ b/features.json @@ -90,56 +90,53 @@ "Chrome": { "url": "https://www.google.com/chrome/", "logo": "/images/chrome.svg", - "version": "96", "features": { - "bigInt": true, - "bulkMemory": true, - "exceptions": true, - "multiValue": true, - "mutableGlobals": true, - "referenceTypes": true, - "saturatedFloatToInt": true, - "signExtensions": true, - "simd": true, - "tailCall": "#enable-experimental-webassembly-features", - "threads": true + "bigInt": "85", + "bulkMemory": "75", + "exceptions": "95", + "multiValue": "85", + "mutableGlobals": "74", + "referenceTypes": "96", + "saturatedFloatToInt": "75", + "signExtensions": "74", + "simd": "91", + "tailCall": ["flag", "Requires flag `#enable-experimental-webassembly-features`"], + "threads": "74" } }, "Firefox": { "url": "https://www.mozilla.org/firefox/", "logo": "/images/firefox.svg", - "version": "90", "features": { - "bigInt": true, - "bulkMemory": true, - "exceptions": true, - "extendedConstantExprs": "Enabled in Nightly, unavailable in Beta/Release", - "memory64": "Enabled in Nightly, unavailable in Beta/Release", - "multiValue": true, - "mutableGlobals": true, - "referenceTypes": true, - "relaxedSimd": "Enabled in Nightly, unavailable in Beta/Release", - "saturatedFloatToInt": true, - "signExtensions": true, - "simd": true, - "threads": true, - "typeReflection": "Enabled in Nightly, unavailable in Beta/Release" + "bigInt": "78", + "bulkMemory": "79", + "exceptions": "100", + "extendedConstantExprs": ["flag", "Enabled in Nightly, unavailable in Beta/Release"], + "memory64": ["flag", "Enabled in Nightly, unavailable in Beta/Release"], + "multiValue": "78", + "mutableGlobals": "61", + "referenceTypes": "79", + "relaxedSimd": ["flag", "Enabled in Nightly, unavailable in Beta/Release"], + "saturatedFloatToInt": "64", + "signExtensions": "62", + "simd": "89", + "threads": "79", + "typeReflection": ["flag", "Enabled in Nightly, unavailable in Beta/Release"] } }, "Safari": { "url": "https://www.apple.com/safari/", "logo": "/images/safari.svg", - "version": "15.2", "features": { - "bigInt": true, - "bulkMemory": true, - "exceptions": true, + "bigInt": ["14.1", "Supported in desktop Safari since 14.1 and iOS Safari since 14.5"], + "bulkMemory": "15", + "exceptions": "15.2", "multiValue": true, "mutableGlobals": true, - "referenceTypes": true, - "saturatedFloatToInt": true, - "signExtensions": true, - "threads": true + "referenceTypes": "15", + "saturatedFloatToInt": "15", + "signExtensions": ["14.1", "Supported in desktop Safari since 14.1 and iOS Safari since 14.5"], + "threads": ["14.1", "Supported in desktop Safari since 14.1 and iOS Safari since 14.5"] } }, "Wasmtime": { @@ -149,9 +146,9 @@ "features": { "bigInt": null, "bulkMemory": true, - "memory64": "--enable-memory64", - "multiMemory": "--enable-multi-memory", - "moduleLinking": "--enable-module-linking", + "memory64": ["flag", "Requires flag `--enable-memory64`"], + "multiMemory": ["flag", "Requires flag `--enable-multi-memory`"], + "moduleLinking": ["flag", "Requires flag `--enable-module-linking`"], "multiValue": true, "mutableGlobals": true, "referenceTypes": true, @@ -163,7 +160,6 @@ "Wasmer": { "url": "https://wasmer.io/", "logo": "/images/wasmer.svg", - "version": "2.0", "features": { "bigInt": null, "bulkMemory": true, @@ -173,31 +169,29 @@ "saturatedFloatToInt": true, "signExtensions": true, "simd": true, - "threads": "--enable-threads" + "threads": ["flag", "Requires flag `--enable-threads`"] } }, "Node.js": { "url": "https://nodejs.org/", "logo": "/images/nodejs.svg", - "version": "16.4", "features": { "bigInt": true, "bulkMemory": true, - "exceptions": "--experimental-wasm-eh", + "exceptions": ["flag", "Requires flag `--experimental-wasm-eh`"], "multiValue": true, "mutableGlobals": true, - "referenceTypes": "--experimental-wasm-reftypes", + "referenceTypes": ["flag", "Requires flag `--experimental-wasm-reftypes`"], "saturatedFloatToInt": true, "signExtensions": true, "simd": true, - "tailCall": "--experimental-wasm-return-call", + "tailCall": ["flag", "Requires flag `--experimental-wasm-return-call`"], "threads": true } }, "Deno": { "url": "https://deno.land/", "logo": "/images/deno.svg", - "version": "1.21.3", "features": { "bigInt": true, "bulkMemory": true, diff --git a/roadmap.js b/roadmap.js index f4c85fb9..0f9cbe77 100644 --- a/roadmap.js +++ b/roadmap.js @@ -1,4 +1,6 @@ (async () => { + 'use strict'; + function partitionArray(arr, condition) { const matched = []; const unmatched = []; @@ -14,29 +16,58 @@ return { matched, unmatched }; } - const { features, browsers } = await fetch('/features.json').then(res => res.json()); - const table = document.getElementById('feature-support'); - function h(name, props = {}, children = []) { const node = Object.assign(document.createElement(name), props); node.append(...children); return node; } - const tBody = document.createElement('tbody'); + // Convert number to lowercase hexavigesimal like "a, b, c, .., x, y, z, aa, ab, ..", starting from zero. + // This is the same format as CSS `list-style: lower-alpha`, which is used for our footnote lists. + function toAlphabet(num) { + const digit = num % 26, + char = String.fromCharCode(97 + digit), + rem = num - digit; + return rem ? toAlphabet(Math.floor(rem / 26) - 1) + char : char; + } + + // Map names to HTML ids. For example, idMap['table-col']('Chrome') will return 'table-col-chrome'. + // This is to satisfy the need for unique ids in `headers` attributes. + // Hardcoded array makes it easier to find typos, since it would throw an error if the namespace is mistyped. + const idMap = ['table-group', 'table-col', 'table-row'].reduce((map, namespace) => { + map[namespace] = (str) => namespace + '-' + str.toLowerCase().replace(/[^\w\d-_]+/g, '-'); + return map; + }, {}); + + // Get a copy of the requested SVG icon. Those are defined in the markdown as templates. + function icon(key) { + return document.getElementById(`support-symbol-${key}`).content.firstElementChild.cloneNode(true); + } + const scrollbox = document.getElementById('feature-support-scrollbox'); + const table = document.getElementById('feature-support'); + + const detectWasmFeature = _loadFeatureDetectModule(); + const addTooltip = _loadTooltipModule(); + + const { features, browsers } = await fetch('/features.json', { + credentials: 'include', // https://stackoverflow.com/a/63814972 + mode: 'no-cors' + }).then(res => res.json()); + + const tBody = document.createElement('tbody'); table.append( h('thead', {}, [ h('tr', {}, [ - h('th'), - h('th', {}, ['Your browser']), - ...Object.entries(browsers).map(([name, { url, logo, version }]) => - h('th', {}, [ - h('a', { href: url }, [ - h('img', { src: logo, width: 32, height: 32 }), + h('th', { id: 'table-blank' }), + h('th', { scope: 'col', id: idMap['table-col']('Your browser') }, ['Your browser']), + ...Object.entries(browsers).map(([name, { url, logo }]) => + h('th', { scope: 'col', id: idMap['table-col'](name) }, [ + h('a', { href: url, target: '_blank' }, [ + // https://www.w3.org/WAI/WCAG22/Techniques/html/H2 + h('img', { src: logo, width: 32, height: 32, alt: '' }), h('br'), - name, - h('sup', {}, [version]), + name ]) ]) ) @@ -55,41 +86,269 @@ { name: 'In-progress proposals', features: featureGroups.unmatched }, ]; + // Collect all notes and assign an index to each unique item + // { "First unique note": 0, "Second unique note": 1, ...} + const notes = Object.values(browsers).flatMap(b => + Object.values(b.features) + .filter(s => Array.isArray(s)) + .map(s => s[1]) + ); + const note2index = new Map(); + let noteIndex = 0; + for (const note of notes) { + if (!note2index.has(note)) { + note2index.set(note, noteIndex++); + } + } + + // Generate the footnote list. They are later referenced in the actual table. + const noteList = document.createElement('ol'); + // Place footnote list outside of the scolling area + scrollbox.parentNode.insertBefore(noteList, scrollbox.nextSibling); + for (const [note, index] of note2index) { + const item = h('li', { id: `feature-note-${index}` }); + item.innerHTML = renderNote(note); + noteList.appendChild(item); + } + + // Create an element that links to the specified footnote. + // Also returns the HTML id of the footnote it refers to. + function createNoteRef(index) { + const id = `feature-note-${index}`; + return [id, h('a', { href: `#${id}` }, [`[${toAlphabet(index)}]`])]; + } + const columnCount = 2 + Object.keys(browsers).length; - for (const { name, features } of featureGroups) { + for (const { name: groupName, features } of featureGroups) { tBody.append( h('tr', {}, [ - h('th', { colSpan: columnCount }, [name]) + h('th', { + scope: 'colgroup', + colSpan: columnCount, + id: idMap['table-group'](groupName), + headers: 'table-blank', + // Chrome doesn't handle `headers` attribute correctly. + // Just hide the group headers for now... + // https://bugs.chromium.org/p/chromium/issues/detail?id=1081201 + // + // Actually Firefox doesn't support `ariaHidden` attribute. + // This is a happy coincidence, since `headers` works fine on Firefox anyway. + ariaHidden: true + }, [groupName]) ]) ); - for (const { name, description, url, phase } of features) { - const supportHTML = h('td'); - Promise.resolve() - // Make sure to call `wasmFeatureDetect` inside a promise-chained - // function so that we can still render table rows for features that - // we don't have a detector yet. - .then(() => wasmFeatureDetect[name]()) - .then( - supported => (supported ? '✔️' : '❌'), - err => '❌' - ) - .then(textContent => { - supportHTML.textContent = textContent; - }); + for (const { name: featName, description, url } of features) { + const detectResult = h('td', { + headers: [idMap['table-col']('Your browser'), idMap['table-row'](featName)].join(' ') + }, [buildCellInner('loading')]); + + detectWasmFeature(featName).then(supported => { + detectResult.textContent = ''; + detectResult.appendChild(buildCellInner(supported ? 'yes' : 'no')); + addTooltip(detectResult, supported ? '✓ Supported' : '✗ Not supported', [tBody, scrollbox]); + }, _err => { + detectResult.textContent = ''; + detectResult.appendChild(buildCellInner('unknown')); + addTooltip(detectResult, 'Detection unavailable for this feature', [tBody, scrollbox]); + }); + tBody.append( h('tr', {}, [ - h('th', {}, [h('a', { href: url }, [description])]), - supportHTML, - ...Object.values(browsers).map(({ features }) => { - const support = features[name]; + h('th', { + scope: 'row', + id: idMap['table-row'](featName), + headers: idMap['table-group'](groupName) + }, [h('a', { href: url, target: '_blank' }, [description])]), + detectResult, + ...Object.entries(browsers).map(([browserName, { features }]) => { + // Meaning of each entry: + // * null => not applicable for this browser + // * true/false => supported/unsupported + // * "version" => supported since "version" + // * "flag" => flag required (must be lowercase) + // * [true, "footnotes"] => supported, with "footnotes" + // * ["version", "footnotes"] => supported since "version", with "footnotes" + // ...and any combination thereof + let support = features[featName]; + let box, note; + + // First extract the footnote part if it's an array + if (Array.isArray(support)) { + note = support[1]; + support = support[0]; + } + if (typeof support === 'string') { - return h('td', { title: support, tabIndex: 0 }, ['⏳']); + if (support === 'flag') { + // 'flag' is treated specially as the "requires flag" icon + box = buildCellInner('flag'); + } else { + // Otherwise it's a version number, like "95" + box = buildCellInner('yes', support); + if (!note) note = `✓ Supported since version ${support}`; + } + } else if (!support) { + if (support === null) { + box = buildCellInner('na', 'N/A'); + if (!note) note = '✗ Not applicable for this browser/engine'; + } else { + box = buildCellInner('no'); + if (!note) note = '✗ Not supported'; + } + } else { + if (support !== true) throw new TypeError(); + box = buildCellInner('yes'); + // Magic value, keep in sync with `renderNote` + if (!note) note = '✓ Supported, introduced in unknown version'; + } + + const cell = h('td', { + headers: [idMap['table-col'](browserName), idMap['table-row'](featName)].join(' ') + }, [box]); + + if (note && note2index.has(note)) { + cell.tabIndex = 0; // focusable + const index = note2index.get(note); + const [noteId, refLink] = createNoteRef(index); + box.appendChild(h('sup', {}, [refLink])); + + const noteItem = document.getElementById(noteId); + if (noteItem) { + cell.addEventListener('mouseenter', () => noteItem.classList.add('ref-highlight')); + cell.addEventListener('mouseleave', () => noteItem.classList.remove('ref-highlight')); + } } - return h('td', {}, [support ? '✔️' : support === null ? 'ⁿ/ₐ' : '❌']); + + // Clip to both and the scrollbox. + // the former is to avoid blocking out the headers; + // the latter is to keep the tooltip inside the scrollable area + addTooltip(cell, note, [tBody, scrollbox]); + return cell; }) ]) ); + tBody.lastElementChild.setAttribute('aria-describedby', idMap['table-row'](featName)); } } + + function buildCellInner(type, text) { + const content = text || icon(type); + return h('div', { className: `feature-cell icon-${type}`}, [content]); + } + + function renderNote(note) { + // No point for screen readers to pronounce those symbols out loud. + for (const symbol of ['✓', '✗']) { + if (note.startsWith(symbol)) { + note = `${note.substring(1)}`; + break; + } + } + + // Transform markdown-like backticks into html + note = note.replace(/`([^`]+)`/g, '$1'); + + if (note.includes('introduced in unknown version')) { + note += ` + + (contribute data) + `; + } + + return note; + } + + // Lazy-loading + function _loadTooltipModule() { + // Be sure to change the preloads in markdown when updating url. + // The ESM bundle of this package doesn't work with unpkg.com. + const module = import('https://cdn.jsdelivr.net/npm/@floating-ui/dom@1/+esm'); + + const subscribers = new Set(); + const updateAll = () => { for (const fn of subscribers) fn(); }; + + document.addEventListener('scroll', updateAll, { passive: true }); + scrollbox.addEventListener('scroll', updateAll, { passive: true }); + window.addEventListener('resize', updateAll, { passive: true }); + + let counter = 0; + return (reference, note, boundary) => + module.then(({ computePosition, offset, flip, shift, arrow }) => { + const tooltipId = `tooltip-${counter++}`; + const tooltip = h('div', { id: tooltipId, className: 'feature-tooltip', role: 'tooltip' }); + tooltip.innerHTML = renderNote(note); + + const arrowElement = h('div', { className: 'feature-tooltip-arrow' }); + tooltip.appendChild(arrowElement); + + const update = () => computePosition(reference, tooltip, { + placement: 'top', + middleware: [ + offset(6), + flip({ boundary }), + shift({ padding: 6, boundary }), + arrow({ element: arrowElement, padding: 3, boundary }) + ], + }).then(({ x, y, placement, middlewareData }) => { + const { x: arrowX, y: arrowY } = middlewareData.arrow; + Object.assign(arrowElement.style, { + left: arrowX !== null ? `${arrowX}px` : '', + top: arrowY !== null ? `${arrowY}px` : '', + }); + + tooltip.style.transform = `translate(${x}px, ${y}px)`; + // Force the browser to apply CSS changes first + if (tooltip.dataset.placement !== placement) tooltip.offsetHeight; + // This will then enable the transition effect + tooltip.dataset.placement = placement; + }); + + const setVisible = (visible) => { + if (visible) { + tooltip.style.removeProperty('display'); + update(); + subscribers.add(update); + } else { + subscribers.delete(update); + tooltip.style.display = 'none'; + delete tooltip.dataset.placement; // disable the transition effect + } + }; + + setVisible(false); + + const monitor = (name, state, listener = () => setVisible(state)) => + reference.addEventListener(name, listener); + monitor('focusin', true); + monitor('focusout', false); + + // Add a bit of delay to mouse events + let timeout = null; + monitor('mouseenter', true, () => { + clearTimeout(timeout); + if (subscribers.size) { + timeout = setTimeout(() => setVisible(true), 80); + } else { + // Immediately show if there aren't other tooltips visible + setVisible(true); + } + }); + monitor('mouseleave', false, () => { + clearTimeout(timeout); + timeout = setTimeout(() => setVisible(false), 80); + }); + + reference.appendChild(tooltip); + reference.setAttribute('aria-describedby', tooltipId); + return tooltip; + }); + } + + function _loadFeatureDetectModule() { + // Be sure to change the preloads in markdown when updating url. + const module = import('https://cdn.jsdelivr.net/npm/wasm-feature-detect@1/dist/esm/index.js'); + return (featureName) => module + .then(wasmFeatureDetect => wasmFeatureDetect[featureName]()); + } })(); diff --git a/roadmap.md b/roadmap.md index e4f5e22c..ee201218 100644 --- a/roadmap.md +++ b/roadmap.md @@ -7,10 +7,32 @@ In November 2017, WebAssembly CG members representing four browsers, Chrome, Edg After the initial release, WebAssembly has been gaining new features through the [standardization process](https://github.com/WebAssembly/meetings/blob/master/process/phases.md). For the complete list of current proposals and their respective stages, check out the [`WebAssembly/proposals` repo](https://github.com/WebAssembly/proposals). - - -
The table below aims to track implemented features in popular engines:
- + + + + + + + + +The table below aims to track implemented features in popular engines: + +
+
+
+ + + To detect supported features at runtime from JavaScript, check out the [`wasm-feature-detect` library](https://github.com/GoogleChromeLabs/wasm-feature-detect), which powers the "Your browser" column above. From c1cf82582c9312933055d73251e19b4a531f9202 Mon Sep 17 00:00:00 2001 From: andylizi Date: Fri, 23 Sep 2022 12:36:31 +0800 Subject: [PATCH 4/4] Address review comments --- roadmap.js | 81 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 23 deletions(-) diff --git a/roadmap.js b/roadmap.js index 0f9cbe77..951a8651 100644 --- a/roadmap.js +++ b/roadmap.js @@ -107,8 +107,7 @@ scrollbox.parentNode.insertBefore(noteList, scrollbox.nextSibling); for (const [note, index] of note2index) { const item = h('li', { id: `feature-note-${index}` }); - item.innerHTML = renderNote(note); - noteList.appendChild(item); + noteList.appendChild(item).appendChild(renderNote(note)); } // Create an element that links to the specified footnote. @@ -186,27 +185,34 @@ } else { // Otherwise it's a version number, like "95" box = buildCellInner('yes', support); - if (!note) note = `✓ Supported since version ${support}`; + note ||= `✓ Supported since version ${support}`; } } else if (!support) { if (support === null) { box = buildCellInner('na', 'N/A'); - if (!note) note = '✗ Not applicable for this browser/engine'; + note ||= '✗ Not applicable for this browser/engine'; } else { box = buildCellInner('no'); - if (!note) note = '✗ Not supported'; + note ||= '✗ Not supported'; } } else { if (support !== true) throw new TypeError(); box = buildCellInner('yes'); // Magic value, keep in sync with `renderNote` - if (!note) note = '✓ Supported, introduced in unknown version'; + note ||= '✓ Supported, introduced in unknown version'; } - const cell = h('td', { + const cell = h('td', { headers: [idMap['table-col'](browserName), idMap['table-row'](featName)].join(' ') }, [box]); + // Give the cell itself an `aria-lebel` to avoid screen readers calling it "empty cell". + const icon = box.firstElementChild; + if (icon?.hasAttribute('aria-label')) { + cell.setAttribute('aria-label', icon.getAttribute('aria-label')); + icon.removeAttribute('aria-label'); + } + if (note && note2index.has(note)) { cell.tabIndex = 0; // focusable const index = note2index.get(note); @@ -238,25 +244,54 @@ } function renderNote(note) { - // No point for screen readers to pronounce those symbols out loud. - for (const symbol of ['✓', '✗']) { - if (note.startsWith(symbol)) { - note = `${note.substring(1)}`; - break; - } - } + const fragment = document.createDocumentFragment(); + const isMissingData = note.includes('introduced in unknown version'); // Transform markdown-like backticks into html - note = note.replace(/`([^`]+)`/g, '$1'); + while (note) { + const [head, body, tail] = splitParts(note, '`'); + head && fragment.append(head); + body && fragment.appendChild(h('code', {}, [body])); + note = tail; + } + + const firstNode = fragment.firstChild; + if (firstNode.nodeType === Node.TEXT_NODE) { + // No point for screen readers to pronounce those symbols out loud. + for (const symbol of ['✓', '✗']) { + if (firstNode.nodeValue?.startsWith(symbol)) { + // Before: <#text>✓ Supported + // After: <#text> Supported + firstNode.splitText(1); + const symbolNode = h('span', {}, firstNode.nodeValue); + symbolNode.setAttribute('aria-hidden', ''); + fragment.replaceChild(symbolNode, firstNode); + break; + } + } + } - if (note.includes('introduced in unknown version')) { - note += ` - - (contribute data) - `; + if (isMissingData) { + fragment.appendChild(h('a', { + href: 'https://github.com/WebAssembly/website/blob/master/features.json', + target: '_blank' + }, [' (contribute data)'])) } - return note; + return fragment; + } + + // Break a string into three parts using the given delimiter. + function splitParts(str, delim) { + const start = str.indexOf(delim); + const end = str.indexOf(delim, start + 1); + if (start >= 0 && end > start) { + const head = str.substring(0, start); + const body = str.substring(start + 1, end); + const tail = str.substring(end + 1); + return [head, body, tail]; + } + return [str, '', ''] } // Lazy-loading @@ -277,7 +312,7 @@ module.then(({ computePosition, offset, flip, shift, arrow }) => { const tooltipId = `tooltip-${counter++}`; const tooltip = h('div', { id: tooltipId, className: 'feature-tooltip', role: 'tooltip' }); - tooltip.innerHTML = renderNote(note); + tooltip.appendChild(renderNote(note)); const arrowElement = h('div', { className: 'feature-tooltip-arrow' }); tooltip.appendChild(arrowElement); @@ -317,7 +352,7 @@ }; setVisible(false); - + const monitor = (name, state, listener = () => setVisible(state)) => reference.addEventListener(name, listener); monitor('focusin', true);