import React from "react"; import { Link } from "react-router-dom"; import { BrowserSupportDetail } from "./browser-support-detail"; import { BrowserSupportNotes } from "./browser-support-notes"; function buildCompatibilityObject(query, compatibilityData) { const features = {}; if (!!compatibilityData.__compat) { // The first row in the BCD data is the overall topic for the page, and // does not have its name within the data. Retrieve the name from the query // data and set a flag so that we do not render a `Link` for it since we // are already on that page. const name = query.split(".").pop(); features[name] = { ...compatibilityData.__compat, ...{ isFirst: true } }; } for (const compat in compatibilityData) { if (compat !== "__compat" && !!compatibilityData[compat]["__compat"]) { features[compat] = compatibilityData[compat]["__compat"]; } } return features; } function getVersionAdded(support) { // When version compatibility is "unknown", it will be `undefined`. // In that case, return `null` so we render the "?" block. if (support === undefined) { return null; } if (Array.isArray(support)) { return support[0].version_added; } return support.version_added; } function getIndexNoteForBrowserDetail(indexNotes, browserDetailIndex) { return indexNotes.find( (indexNotes) => indexNotes.index === browserDetailIndex ); } function computeDistinctKey(detail) { return `${detail.browser}:${detail.version_added}`; } function RenderBrowserSupportDetails({ browserSupportDetails, rowIndex, indexNotes, currentNoteId, onNotesClick, }) { return browserSupportDetails.map((browserSupportDetail, detailIndex) => ( )); } function buildIndexNotes( browserSupportDetails, rowIndex, currentNoteId, hasFlag, hasPrefix, hasAlternative, hasNotes ) { const indexNotes = browserSupportDetails.map( (browserSupportDetail, detailIndex) => { const support = browserSupportDetail.support; if (Array.isArray(support)) { const [notes, flags, prefixes, alternatives]: any[] = [[], [], [], []]; for (const supportItem of support) { if (!!supportItem.alternative_name) { hasAlternative = true; alternatives.push(supportItem); } else if (!!supportItem.prefix) { hasPrefix = true; prefixes.push(supportItem); } else if (Array.isArray(supportItem.flags)) { hasFlag = true; flags.concat(supportItem.flags); } else if (!!supportItem.notes) { hasNotes = true; if (Array.isArray(supportItem.notes)) { notes.concat(supportItem.notes); } else { notes.push(supportItem.notes); } } } return { index: `${rowIndex}-${detailIndex}`, browser: browserSupportDetail.browser, version_added: browserSupportDetail.version_added, support, prefixes, alternatives, flags, notes, }; } else { if (!hasFlag) { hasFlag = !!(support && support.flags); } if (!hasPrefix) { hasPrefix = !!(support && support.prefix); } if (!hasNotes) { hasNotes = !!(support && support.notes); } const prefixes = !!(support && support.prefix) ? [support] : []; const alternatives = !!(support && support.alternative_name) ? [support] : []; const flags = !!(support && support.flags) ? support.flags : []; const notes = gatherNotesForIndexNote(support); return { index: `${rowIndex}-${detailIndex}`, browser: browserSupportDetail.browser, version_added: browserSupportDetail.version_added, support, prefixes, alternatives, flags, notes, }; } } ); const filteredIndexNotes = indexNotes.filter( (indexNotes) => `bc-history-${indexNotes.index}` === currentNoteId ); return [filteredIndexNotes, hasFlag, hasPrefix, hasAlternative, hasNotes]; } // Find notes inside a support object and return as an array function gatherNotesForIndexNote(currentSupport) { if (!currentSupport) { return []; } if (Array.isArray(currentSupport.notes)) { return currentSupport.notes; } return !!currentSupport.notes ? [currentSupport.notes] : []; } export const Rows: any = ({ compatibilityData, displayBrowsers, onNotesClick, currentNoteId, setLegendIcons, }) => { let [ hasDeprecation, hasExperimental, hasNonStandard, hasFlag, hasPrefix, hasAlternative, hasNotes, ] = [false, false, false, false, false, false, false]; let indexNotes; const compatibility = buildCompatibilityObject( compatibilityData.query, compatibilityData.data ); const browserCompatibilityRows: any[] = []; for (const key in compatibility) { const currentRow = compatibility[key]; if (currentRow.status) { if (!hasDeprecation) { hasDeprecation = !!currentRow.status.deprecated; } if (!hasExperimental) { hasExperimental = !!currentRow.status.experimental; } if (!hasNonStandard) { hasNonStandard = !!currentRow.status.standard_track; } } const browserSupportDetails = displayBrowsers.map((browser) => { const support = currentRow.support[browser]; const version_added = getVersionAdded(support); return { browser, support, version_added }; }); [ indexNotes, hasFlag, hasPrefix, hasAlternative, hasNotes, ] = buildIndexNotes( browserSupportDetails, key, currentNoteId, hasFlag, hasPrefix, hasAlternative, hasNotes ); browserCompatibilityRows.push([ {currentRow.mdn_url && !currentRow.isFirst ? ( {key} ) : ( {key} )} {currentRow.status && (
{currentRow.status.deprecated && ( Deprecated )} {!currentRow.status.standard_track && ( Non-standard )} {currentRow.status.experimental && ( Experimental )}
)} , ...indexNotes.map((indexNote) => (
)), ]); } setLegendIcons( hasDeprecation, hasExperimental, hasNonStandard, hasFlag, hasPrefix, hasAlternative, hasNotes ); return browserCompatibilityRows; };