diff --git a/client/src/document/ingredients/browser-compatibility-table/feature-row.tsx b/client/src/document/ingredients/browser-compatibility-table/feature-row.tsx index d3a9df3ff70b..a3cd6a805948 100644 --- a/client/src/document/ingredients/browser-compatibility-table/feature-row.tsx +++ b/client/src/document/ingredients/browser-compatibility-table/feature-row.tsx @@ -15,6 +15,7 @@ import { } from "./utils"; import { LEGEND_LABELS } from "./legend"; import { DEFAULT_LOCALE } from "../../../../../libs/constants"; +import { BCD_TABLE } from "../../../telemetry/constants"; function getSupportClassName( support: SupportStatementExtended | undefined, @@ -545,7 +546,11 @@ export const FeatureRow = React.memo( `/${locale}/docs` ); titleNode = ( - + ${href}`} + > {title} {compat.status && } diff --git a/client/src/document/ingredients/browser-compatibility-table/index.tsx b/client/src/document/ingredients/browser-compatibility-table/index.tsx index b1abf0bb7716..3b7b23940c91 100644 --- a/client/src/document/ingredients/browser-compatibility-table/index.tsx +++ b/client/src/document/ingredients/browser-compatibility-table/index.tsx @@ -1,4 +1,4 @@ -import React, { useReducer } from "react"; +import React, { useReducer, useRef } from "react"; import { useLocation } from "react-router-dom"; import type BCD from "@mdn/browser-compat-data/types"; import { BrowserInfoContext } from "./browser-info"; @@ -6,7 +6,17 @@ import { BrowserCompatibilityErrorBoundary } from "./error-boundary"; import { FeatureRow } from "./feature-row"; import { Headers } from "./headers"; import { Legend } from "./legend"; -import { listFeatures } from "./utils"; +import { + getCurrentSupport, + hasMore, + hasNoteworthyNotes, + listFeatures, + SupportStatementExtended, + versionIsPreview, +} from "./utils"; +import { useViewed } from "../../../hooks"; +import { BCD_TABLE } from "../../../telemetry/constants"; +import { useGleanClick } from "../../../telemetry/glean-context"; // Note! Don't import any SCSS here inside *this* component. // It's done in the component that lazy-loads this component. @@ -84,11 +94,15 @@ type CellIndex = [number, number]; function FeatureListAccordion({ features, browsers, + browserInfo, locale, + query, }: { features: ReturnType; browsers: BCD.BrowserName[]; + browserInfo: BCD.Browsers; locale: string; + query: string; }) { const [[activeRow, activeColumn], dispatchCellToggle] = useReducer< React.Reducer @@ -100,6 +114,9 @@ function FeatureListAccordion({ [null, null] ); + const gleanClick = useGleanClick(); + const clickedCells = useRef(new Set()); + return ( <> {features.map((feature, i) => ( @@ -110,6 +127,92 @@ function FeatureListAccordion({ activeCell={activeRow === i ? activeColumn : null} onToggleCell={([row, column]: [number, number]) => { dispatchCellToggle([row, column]); + + const cell = `${column}:${row}`; + if (clickedCells.current.has(cell)) { + return; + } else { + clickedCells.current.add(cell); + } + + const feature = features[row]; + const browser = browsers[column]; + const support = feature.compat.support[browser]; + + function getCurrentSupportType( + support: SupportStatementExtended | undefined, + browser: BCD.BrowserStatement + ): + | "no" + | "yes" + | "partial" + | "preview" + | "removed" + | "removed-partial" + | "unknown" { + if (!support) { + return "unknown"; + } + + const currentSupport = getCurrentSupport(support)!; + + const { + flags, + version_added, + version_removed, + partial_implementation, + } = currentSupport; + + if (version_added === null) { + return "unknown"; + } else if (versionIsPreview(version_added, browser)) { + return "preview"; + } else if (version_added) { + if (version_removed) { + if (partial_implementation) { + return "removed-partial"; + } else { + return "removed"; + } + } else if (flags && flags.length) { + return "no"; + } else if (partial_implementation) { + return "partial"; + } else { + return "yes"; + } + } else { + return "no"; + } + } + + function getCurrentSupportAttributes( + support: SupportStatementExtended | undefined + ): string[] { + const supportItem = getCurrentSupport(support); + + if (!supportItem) { + return []; + } + + return [ + !!supportItem.prefix && "pre", + hasNoteworthyNotes(supportItem) && "note", + !!supportItem.alternative_name && "alt", + !!supportItem.flags && "flag", + hasMore(support) && "more", + ].filter((value) => typeof value === "string"); + } + + const supportType = getCurrentSupportType( + support, + browserInfo[browser] + ); + const attrs = getCurrentSupportAttributes(support); + + gleanClick( + `${BCD_TABLE}: click ${browser} ${query} -> ${feature.name} = ${supportType} [${attrs.join(",")}]` + ); }} locale={locale} /> @@ -130,6 +233,16 @@ export default function BrowserCompatibilityTable({ locale: string; }) { const location = useLocation(); + const gleanClick = useGleanClick(); + + const observedNode = useViewed( + () => { + gleanClick(`${BCD_TABLE}: view -> ${query}`); + }, + { + threshold: 0, + } + ); if (!data || !Object.keys(data).length) { throw new Error( @@ -177,7 +290,11 @@ export default function BrowserCompatibilityTable({
- +
diff --git a/client/src/document/ingredients/browser-compatibility-table/utils.ts b/client/src/document/ingredients/browser-compatibility-table/utils.ts index 6cbd5e773d62..ceb307c925b2 100644 --- a/client/src/document/ingredients/browser-compatibility-table/utils.ts +++ b/client/src/document/ingredients/browser-compatibility-table/utils.ts @@ -2,7 +2,8 @@ import type BCD from "@mdn/browser-compat-data/types"; // Extended for the fields, beyond the bcd types, that are extra-added // exclusively in Yari. -interface SimpleSupportStatementExtended extends BCD.SimpleSupportStatement { +export interface SimpleSupportStatementExtended + extends BCD.SimpleSupportStatement { // Known for some support statements where the browser *version* is known, // as opposed to just "true" and if the version release date is known. release_date?: string; @@ -116,7 +117,7 @@ export function versionIsPreview( export function hasNoteworthyNotes(support: BCD.SimpleSupportStatement) { return ( - (support.notes?.length || support.impl_url?.length) && + !!(support.notes?.length || support.impl_url?.length) && !support.version_removed && !support.partial_implementation ); diff --git a/client/src/telemetry/constants.ts b/client/src/telemetry/constants.ts index 75259652c2be..1f6735dd726a 100644 --- a/client/src/telemetry/constants.ts +++ b/client/src/telemetry/constants.ts @@ -28,6 +28,7 @@ export const AI_EXPLAIN = "ai_explain"; export const SETTINGS = "settings"; export const OBSERVATORY = "observatory"; export const CURRICULUM = "curriculum"; +export const BCD_TABLE = "bcd"; export const A11Y_MENU = "a11y_menu";