human (Nov 10, 2024, 05:35 PM)
Build an artifact to render this data in a timeline
From https://bcd.developer.mozilla.org/bcd/api/v0/current/api.Lock.json
paste.txt
{"data":{"__compat":{"mdn_url":"/en-US/docs/Web/API/Lock","source_file":"api/Lock.json","spec_url":"https://w3c.github.io/web-locks/#api-lock","status":{"deprecated":false,"experimental":false,"standard_track":true},"support":{"chrome":[{"version_added":"69","release_date":"2018-09-04"}],"chrome_android":[{"version_added":"69","release_date":"2018-09-04"}],"edge":[{"version_added":"79","release_date":"2020-01-15"}],"firefox":[{"version_added":"96","release_date":"2022-01-11"}],"firefox_android":[{"version_added":"96","release_date":"2022-01-11"}],"ie":[{"version_added":false}],"oculus":[{"version_added":"6.0"}],"opera":[{"version_added":"56","release_date":"2018-09-25"}],"opera_android":[{"version_added":"48","release_date":"2018-11-08"}],"safari":[{"version_added":"15.4","release_date":"2022-03-14"}],"safari_ios":[{"version_added":"15.4","release_date":"2022-03-14"}],"samsunginternet_android":[{"version_added":"10.0","release_date":"2019-08-22"}],"webview_android":[{"version_added":"69","release_date":"2018-09-04"}],"webview_ios":[{"version_added":"15.4","release_date":"2022-03-14"}]},"tags":["web-features:web-locks"]},"mode":{"__compat":{"mdn_url":"/en-US/docs/Web/API/Lock/mode","source_file":"api/Lock.json","spec_url":"https://w3c.github.io/web-locks/#dom-lock-mode","status":{"deprecated":false,"experimental":false,"standard_track":true},"support":{"chrome":[{"version_added":"69","release_date":"2018-09-04"}],"chrome_android":[{"version_added":"69","release_date":"2018-09-04"}],"edge":[{"version_added":"79","release_date":"2020-01-15"}],"firefox":[{"version_added":"96","release_date":"2022-01-11"}],"firefox_android":[{"version_added":"96","release_date":"2022-01-11"}],"ie":[{"version_added":false}],"oculus":[{"version_added":"6.0"}],"opera":[{"version_added":"56","release_date":"2018-09-25"}],"opera_android":[{"version_added":"48","release_date":"2018-11-08"}],"safari":[{"version_added":"15.4","release_date":"2022-03-14"}],"safari_ios":[{"version_added":"15.4","release_date":"2022-03-14"}],"samsunginternet_android":[{"version_added":"10.0","release_date":"2019-08-22"}],"webview_android":[{"version_added":"69","release_date":"2018-09-04"}],"webview_ios":[{"version_added":"15.4","release_date":"2022-03-14"}]},"tags":["web-features:web-locks"]}},"name":{"__compat":{"mdn_url":"/en-US/docs/Web/API/Lock/name","source_file":"api/Lock.json","spec_url":"https://w3c.github.io/web-locks/#dom-lock-name","status":{"deprecated":false,"experimental":false,"standard_track":true},"support":{"chrome":[{"version_added":"69","release_date":"2018-09-04"}],"chrome_android":[{"version_added":"69","release_date":"2018-09-04"}],"edge":[{"version_added":"79","release_date":"2020-01-15"}],"firefox":[{"version_added":"96","release_date":"2022-01-11"}],"firefox_android":[{"version_added":"96","release_date":"2022-01-11"}],"ie":[{"version_added":false}],"oculus":[{"version_added":"6.0"}],"opera":[{"version_added":"56","release_date":"2018-09-25"}],"opera_android":[{"version_added":"48","release_date":"2018-11-08"}],"safari":[{"version_added":"15.4","release_date":"2022-03-14"}],"safari_ios":[{"version_added":"15.4","release_date":"2022-03-14"}],"samsunginternet_android":[{"version_added":"10.0","release_date":"2019-08-22"}],"webview_android":[{"version_added":"69","release_date":"2018-09-04"}],"webview_ios":[{"version_added":"15.4","release_date":"2022-03-14"}]},"tags":["web-features:web-locks"]}}},"query":"api.Lock","browsers":{"chrome":{"accepts_flags":true,"accepts_webextensions":true,"name":"Chrome","pref_url":"chrome://flags","preview_name":"Canary","releases":{"131":{"engine":"Blink","engine_version":"131","release_date":"2024-11-12","status":"current"},"132":{"engine":"Blink","engine_version":"132","release_date":"2025-01-14","status":"beta"},"133":{"engine":"Blink","engine_version":"133","release_date":"2025-02-04","status":"nightly"},"134":{"engine":"Blink","engine_version":"134","status":"planned"}},"type":"desktop"},"chrome_android":{"accepts_flags":true,"accepts_webextensions":false,"name":"Chrome Android","pref_url":"chrome://flags","releases":{"131":{"engine":"Blink","engine_version":"131","release_date":"2024-11-12","status":"current"},"132":{"engine":"Blink","engine_version":"132","release_date":"2025-01-14","status":"beta"},"133":{"engine":"Blink","engine_version":"133","release_date":"2025-02-04","status":"nightly"},"134":{"engine":"Blink","engine_version":"134","status":"planned"}},"type":"mobile","upstream":"chrome"},"deno":{"accepts_flags":true,"accepts_webextensions":false,"name":"Deno","releases":{"1.45":{"engine":"V8","engine_version":"12.7","release_date":"2024-07-11","release_notes":"https://deno.com/blog/v1.45","status":"current"}},"type":"server"},"edge":{"accepts_flags":true,"accepts_webextensions":true,"name":"Edge","pref_url":"about:flags","releases":{"130":{"engine":"Blink","engine_version":"130","release_date":"2024-10-17","release_notes":"https://learn.microsoft.com/en-us/deployedge/microsoft-edge-relnote-stable-channel#version-1300284946-october-17-2024","status":"current"},"131":{"engine":"Blink","engine_version":"131","release_date":"2024-11-14","status":"beta"},"132":{"engine":"Blink","engine_version":"132","release_date":"2025-01-09","status":"nightly"},"133":{"engine":"Blink","engine_version":"133","release_date":"2025-02-06","status":"planned"}},"type":"desktop","upstream":"chrome"},"firefox":{"accepts_flags":true,"accepts_webextensions":true,"name":"Firefox","pref_url":"about:config","preview_name":"Nightly","releases":{"128":{"engine":"Gecko","engine_version":"128","release_date":"2024-07-09","release_notes":"https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/128","status":"esr"},"132":{"engine":"Gecko","engine_version":"132","release_date":"2024-10-29","release_notes":"https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/132","status":"current"},"133":{"engine":"Gecko","engine_version":"133","release_date":"2024-11-26","release_notes":"https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/133","status":"beta"},"134":{"engine":"Gecko","engine_version":"134","release_date":"2025-01-07","release_notes":"https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/134","status":"nightly"},"135":{"engine":"Gecko","engine_version":"135","release_date":"2025-02-04","release_notes":"https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/135","status":"planned"}},"type":"desktop"},"firefox_android":{"accepts_flags":false,"accepts_webextensions":true,"name":"Firefox for Android","pref_url":"about:config","releases":{"128":{"engine":"Gecko","engine_version":"128","release_date":"2024-07-09","release_notes":"https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/128","status":"esr"},"132":{"engine":"Gecko","engine_version":"132","release_date":"2024-10-29","release_notes":"https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/132","status":"current"},"133":{"engine":"Gecko","engine_version":"133","release_date":"2024-11-26","release_notes":"https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/133","status":"beta"},"134":{"engine":"Gecko","engine_version":"134","release_date":"2025-01-07","release_notes":"https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/134","status":"nightly"},"135":{"engine":"Gecko","engine_version":"135","release_date":"2025-02-04","release_notes":"https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/135","status":"planned"}},"type":"mobile","upstream":"firefox"},"ie":{"accepts_flags":false,"accepts_webextensions":false,"name":"Internet Explorer","releases":{},"type":"desktop"},"nodejs":{"accepts_flags":true,"accepts_webextensions":false,"name":"Node.js","releases":{"22.0.0":{"engine":"V8","engine_version":"12.4","release_date":"2024-04-24","release_notes":"https://nodejs.org/en/blog/release/v22.0.0","status":"esr"},"23.0.0":{"engine":"V8","engine_version":"12.9","release_date":"2024-10-16","release_notes":"https://nodejs.org/en/blog/release/v23.0.0","status":"current"}},"type":"server"},"oculus":{"accepts_flags":true,"accepts_webextensions":false,"name":"Quest Browser","pref_url":"chrome://flags","releases":{"23.0":{"engine":"Blink","engine_version":"104","release_date":"2022-08-15","status":"current"}},"type":"xr","upstream":"chrome_android"},"opera":{"accepts_flags":true,"accepts_webextensions":true,"name":"Opera","pref_url":"opera://flags","releases":{"113":{"engine":"Blink","engine_version":"127","release_date":"2024-08-22","release_notes":"https://blogs.opera.com/desktop/2024/08/opera-113/","status":"current"},"114":{"engine":"Blink","engine_version":"128","status":"beta"},"115":{"engine":"Blink","engine_version":"129","status":"nightly"}},"type":"desktop","upstream":"chrome"},"opera_android":{"accepts_flags":false,"accepts_webextensions":false,"name":"Opera Android","releases":{"84":{"engine":"Blink","engine_version":"127","release_date":"2024-08-26","status":"current"}},"type":"mobile","upstream":"chrome_android"},"safari":{"accepts_flags":true,"accepts_webextensions":true,"name":"Safari","preview_name":"TP","releases":{"18.1":{"engine":"WebKit","engine_version":"619.2.8","release_date":"2024-10-28","release_notes":"https://developer.apple.com/documentation/safari-release-notes/safari-18_1-release-notes","status":"current"},"18.2":{"engine":"WebKit","engine_version":"620.1.11","release_notes":"https://developer.apple.com/documentation/safari-release-notes/safari-18_2-release-notes","status":"beta"}},"type":"desktop"},"safari_ios":{"accepts_flags":true,"accepts_webextensions":true,"name":"Safari on iOS","releases":{"18.1":{"engine":"WebKit","engine_version":"619.2.8","release_date":"2024-10-28","release_notes":"https://developer.apple.com/documentation/safari-release-notes/safari-18_1-release-notes","status":"current"},"18.2":{"engine":"WebKit","engine_version":"620.1.11","release_notes":"https://developer.apple.com/documentation/safari-release-notes/safari-18_2-release-notes","status":"beta"}},"type":"mobile","upstream":"safari"},"samsunginternet_android":{"accepts_flags":false,"accepts_webextensions":false,"name":"Samsung Internet","releases":{"26.0":{"engine":"Blink","engine_version":"122","release_date":"2024-06-07","status":"current"},"27.0":{"engine":"Blink","engine_version":"125","status":"beta"}},"type":"mobile","upstream":"chrome_android"},"webview_android":{"accepts_flags":false,"accepts_webextensions":false,"name":"WebView Android","releases":{"131":{"engine":"Blink","engine_version":"131","release_date":"2024-11-12","status":"current"},"132":{"engine":"Blink","engine_version":"132","release_date":"2025-01-14","status":"beta"},"133":{"engine":"Blink","engine_version":"133","release_date":"2025-02-04","status":"nightly"},"134":{"engine":"Blink","engine_version":"134","status":"planned"}},"type":"mobile","upstream":"chrome_android"},"webview_ios":{"accepts_flags":false,"accepts_webextensions":false,"name":"WebView on iOS","releases":{"18.1":{"engine":"WebKit","engine_version":"619.2.8","release_date":"2024-10-28","release_notes":"https://developer.apple.com/documentation/safari-release-notes/safari-18_1-release-notes","status":"current"},"18.2":{"engine":"WebKit","engine_version":"620.1.11","release_notes":"https://developer.apple.com/documentation/safari-release-notes/safari-18_2-release-notes","status":"beta"}},"type":"mobile","upstream":"safari_ios"}}}
assistant (Nov 10, 2024, 05:35 PM)
I'll create a timeline visualization to show when different browsers added support for the Web Locks API. I'll use React with Tailwind CSS to create this visualization.
import React from 'react';
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
const Timeline = () => {
// Parse and sort the browser support data
const supportData = [
{ browser: 'Chrome', date: '2018-09-04', version: '69' },
{ browser: 'Chrome Android', date: '2018-09-04', version: '69' },
{ browser: 'Opera', date: '2018-09-25', version: '56' },
{ browser: 'Opera Android', date: '2018-11-08', version: '48' },
{ browser: 'Samsung Internet', date: '2019-08-22', version: '10.0' },
{ browser: 'Edge', date: '2020-01-15', version: '79' },
{ browser: 'Firefox', date: '2022-01-11', version: '96' },
{ browser: 'Firefox Android', date: '2022-01-11', version: '96' },
{ browser: 'Safari', date: '2022-03-14
human (Nov 10, 2024, 05:36 PM)
don't use React, just HTML and CSS and JavaScript. Give me a textarea I can paste the JSON into
assistant (Nov 10, 2024, 05:36 PM)
I'll create a simple HTML page with a textarea for JSON input and a visualization that updates when the JSON changes.
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-family: system-ui, -apple-system, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
#input-section {
margin-bottom: 20px;
}
#json-input {
width: 100%;
height: 150px;
margin-bottom: 10px;
font-family: monospace;
padding: 8px;
}
#timeline {
position: relative;
border-left: 2px solid #ccc;
margin-left: 20px;
padding-left: 20px;
}
.event {
margin-bottom: 20px;
position: relative;
}
.event::before {
content: '';
position: absolute;
left: -26px;
top: 5px;
width: 10px;
height: 10px;
border-radius: 50%;
background: #3b82f6;
}
.event-date {
font-size: 0.875rem;
color: #666;
}
.event-browser {
font-weight: 600;
color: #1f2937;
}
.event-version {
color: #059669;
}
.error {
color: #dc2626;
margin-top: 8px;
display: none;
}
</style>
</head>
<body>
<div id="input-section">
<h2>Browser Support Timeline Viewer</h2>
<p>Paste BCD JSON data below to visualize browser support timeline:</p>
<textarea id="json-input" placeholder="Paste BCD JSON here..."></textarea>
<div id="error" class="error"></div>
</div>
<div id="timeline"></div>
<script>
const extractSupportData = (data) => {
const browsers = data.browsers;
const support = data.data.__compat.support;
const supportData = [];
for (const [browserName, supportInfo] of Object.entries(support)) {
if (!supportInfo[0]?.version_added || !supportInfo[0]?.release_date) continue;
supportData.push({
browser: browsers[browserName]?.name || browserName,
version: supportInfo[0].version_added,
date: supportInfo[0].release_date
});
}
return supportData.sort((a, b) => new Date(a.date) - new Date(b.date));
};
const formatDate = (dateStr) => {
return new Date(dateStr).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
};
const renderTimeline = (supportData) => {
const timeline = document.getElementById('timeline');
timeline.innerHTML = '';
supportData.forEach(item => {
const event = document.createElement('div');
event.className = 'event';
event.innerHTML = `
<div class="event-date">${formatDate(item.date)}</div>
<div>
<span class="event-browser">${item.browser}</span>
<span class="event-version">v${item.version}</span>
</div>
`;
timeline.appendChild(event);
});
};
const jsonInput = document.getElementById('json-input');
const errorDiv = document.getElementById('error');
jsonInput.addEventListener('input', () => {
try {
const data = JSON.parse(jsonInput.value);
const supportData = extractSupportData(data);
renderTimeline(supportData);
errorDiv.style.display = 'none';
} catch (err) {
errorDiv.textContent = 'Invalid JSON data: ' + err.message;
errorDiv.style.display = 'block';
}
});
</script>
</body>
</html>
I've created a simple HTML page with:
- A textarea where you can paste the BCD (Browser Compatibility Data) JSON
- A vertical timeline visualization that shows:
- When each browser added support for the Web Locks API
- The browser name and version number
- The release date in a readable format
Features:
- Automatically updates as you paste/edit the JSON
- Sorts events chronologically
- Shows error messages if the JSON is invalid
- Responsive design that works on different screen sizes
- Clean, minimal styling
You can paste the JSON data into the textarea and the timeline will automatically update to show when each browser added support for the Web Locks API. The visualization shows both the browser version and the exact date when support was added.
Would you like me to make any adjustments to the visualization or add any additional features?
human (Nov 10, 2024, 05:37 PM)
An error occurred while trying to run the generated artifact.
Unexpected token (79:7)
Can you fix this error in browser-timeline
?
assistant (Nov 10, 2024, 05:37 PM)
The error seems to be related to a partial content cutoff. Let me fix this by providing the complete HTML code.
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-family: system-ui, -apple-system, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
#input-section {
margin-bottom: 20px;
}
#json-input {
width: 100%;
height: 150px;
margin-bottom: 10px;
font-family: monospace;
padding: 8px;
}
#timeline {
position: relative;
border-left: 2px solid #ccc;
margin-left: 20px;
padding-left: 20px;
}
.event {
margin-bottom: 20px;
position: relative;
}
.event::before {
content: '';
position: absolute;
left: -26px;
top: 5px;
width: 10px;
height: 10px;
border-radius: 50%;
background: #3b82f6;
}
.event-date {
font-size: 0.875rem;
color: #666;
}
.event-browser {
font-weight: 600;
color: #1f2937;
}
.event-version {
color: #059669;
margin-left: 4px;
}
.error {
color: #dc2626;
margin-top: 8px;
display: none;
padding: 8px;
background: #fef2f2;
border-radius: 4px;
}
.not-supported {
margin-top: 20px;
padding: 12px;
background: #f3f4f6;
border-radius: 4px;
}
</style>
</head>
<body>
<div id="input-section">
<h2>Browser Support Timeline Viewer</h2>
<p>Paste BCD JSON data below to visualize browser support timeline:</p>
<textarea id="json-input" placeholder="Paste BCD JSON here..."></textarea>
<div id="error" class="error"></div>
</div>
<div id="timeline"></div>
<script>
const extractSupportData = (data) => {
const browsers = data.browsers;
const support = data.data.__compat.support;
const supportData = [];
const notSupported = [];
for (const [browserName, supportInfo] of Object.entries(support)) {
if (!supportInfo[0]) continue;
if (supportInfo[0].version_added === false) {
notSupported.push(browsers[browserName]?.name || browserName);
continue;
}
if (!supportInfo[0].version_added || !supportInfo[0].release_date) continue;
supportData.push({
browser: browsers[browserName]?.name || browserName,
version: supportInfo[0].version_added,
date: supportInfo[0].release_date
});
}
return {
supported: supportData.sort((a, b) => new Date(a.date) - new Date(b.date)),
notSupported
};
};
const formatDate = (dateStr) => {
return new Date(dateStr).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
};
const renderTimeline = (data) => {
const timeline = document.getElementById('timeline');
timeline.innerHTML = '';
// Add supported browsers timeline
data.supported.forEach(item => {
const event = document.createElement('div');
event.className = 'event';
event.innerHTML = `
<div class="event-date">${formatDate(item.date)}</div>
<div>
<span class="event-browser">${item.browser}</span>
<span class="event-version">v${item.version}</span>
</div>
`;
timeline.appendChild(event);
});
// Add not supported browsers section if any
if (data.notSupported.length > 0) {
const notSupportedDiv = document.createElement('div');
notSupportedDiv.className = 'not-supported';
notSupportedDiv.innerHTML = `
<strong>Not Supported:</strong> ${data.notSupported.join(', ')}
`;
timeline.appendChild(notSupportedDiv);
}
};
const jsonInput = document.getElementById('json-input');
const errorDiv = document.getElementById('error');
jsonInput.addEventListener('input', () => {
try {
const data = JSON.parse(jsonInput.value);
const supportData = extractSupportData(data);
renderTimeline(supportData);
errorDiv.style.display = 'none';
} catch (err) {
errorDiv.textContent = 'Invalid JSON data: ' + err.message;
errorDiv.style.display = 'block';
}
});
</script>
</body>
</html>
I've made several improvements to the code:
- Fixed the content cutoff issue
- Added better handling for browsers that don't support the feature
- Improved error message styling
- Added a separate section for browsers that explicitly don't support the feature
- Improved spacing and visual hierarchy
You can now paste the JSON into the textarea and it should work correctly. The timeline will show when each browser added support, and there's a separate section at the bottom that lists browsers that don't support the feature.
Would you like me to make any other adjustments to the visualization?
Details: https://simonwillison.net/2024/Nov/11/mdn-browser-support-timelines/