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;
};