UNPKG

@kcjpop/x-browser-compat

Version:

A Web Component to display browser compatibility data

121 lines (101 loc) 3.32 kB
const VERSION = "0.0.6"; const URL = `https://unpkg.com/@kcjpop/x-browser-compat@${VERSION}/bcd/`; const BrowserNameMap = new Map([ ["chrome", "Google Chrome"], ["chrome_android", "Google Chrome (Android)"], ["deno", "Deno"], ["edge", "Microsoft Edge"], ["firefox", "Mozilla Firefox"], ["firefox_android", "Firefox (Android)"], ["ie", "Internet Explorer"], ["nodejs", "Node.js"], ["oculus", "Meta Quest Browser"], ["opera", "Opera"], ["opera_android", "Opera (Android)"], ["safari", "Safari"], ["safari_ios", "Safari (iOS)"], ["samsunginternet_android", "Samsung Internet"], ["webview_android", "WebView (Android)"], ]); const SupportStatus = { support: "support", support_unknown_version: "support_unknown_version", no_support: "no_support", unknown: "unknown", }; /** * * @see https://github.com/mdn/browser-compat-data/blob/main/schemas/compat-data-schema.md#the-support_statement-object */ function getSupportStatus(entry) { if (entry.version_added === true) return { status: SupportStatus.support_unknown_version }; if (entry.version_added === false) return { status: SupportStatus.no_support }; if (entry.version_added === null) return { status: SupportStatus.unknown }; if (typeof entry.version_added === "string") return { status: SupportStatus.support, version: entry.version_added }; if (Array.isArray(entry)) { const needle = entry.find((item) => item.version_added != null); if (needle !== undefined) return { status: SupportStatus.support, version: needle.version_added }; } } function translateBrowserName(name) { return BrowserNameMap.get(name); } export class XBrowserCompat extends HTMLElement { constructor() { super(); this.shadow = this.attachShadow({ mode: "open" }); this.path = this.getAttribute("path"); const browsers = this.getAttribute("browsers"); this.browsers = browsers != null && browsers !== "" ? browsers.split(",").map((s) => s.trim()) : null; this.render(); } async render() { if (this.path == null || this.path?.length === 0) { this.shadow.innerHTML = 'Missing "path" attribute.'; return; } let data = null; try { data = await fetch( URL + this.path.replaceAll(".", "/") + "/index.json" ).then((res) => res.json()); } catch (e) { console.error(e); } if (data == null) { this.shadow.innerHTML = `No browser compat data found for "path": ${this.path}`; return; } const entries = Array.isArray(this.browsers) ? this.browsers .map((browserName) => data.support[browserName] != null ? [browserName, data.support[browserName]] : false ) .filter(Boolean) : Object.entries(data.support); this.shadow.innerHTML = entries .map(([browserName, browser]) => { const { status, version } = getSupportStatus(browser); return `<div part="browser ${status}"> <span part="name ${browserName}">${translateBrowserName( browserName )}</span> ${ version !== undefined ? `<span part="version">${version}</span>` : "" } </div>`; }) .join("\n"); } }