From c11b09f74e891a5a9b23876ff6d8ce59ae916356 Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Thu, 29 Aug 2024 15:53:54 +0100 Subject: [PATCH] Add all+analytics JS file --- CHANGELOG.md | 2 + src/nationalarchives/all+analytics.mjs | 35 +++++++++++ src/nationalarchives/analytics.mjs | 7 ++- tasks/test-package.js | 81 ++++++++++++++++---------- webpack.config.js | 8 +++ 5 files changed, 100 insertions(+), 33 deletions(-) create mode 100644 src/nationalarchives/all+analytics.mjs diff --git a/CHANGELOG.md b/CHANGELOG.md index 18b1937d..ecd0e64f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - `$import-google-fonts` option (default: `true`) which can disable the inclusion of Google Fonts using an `@import` declaration +- A new `all+analytics.js` file now exists which can be used as a drop-in replacement for `all.js` +- Google Analytics 4 can be automatically be instantiated by adding a `data-ga4` property to the `` element ### Changed diff --git a/src/nationalarchives/all+analytics.mjs b/src/nationalarchives/all+analytics.mjs new file mode 100644 index 00000000..cafdc7e9 --- /dev/null +++ b/src/nationalarchives/all+analytics.mjs @@ -0,0 +1,35 @@ +import { + initAll, + Cookies, + Accordion, + Breadcrumbs, + CookieBanner, + ErrorSummary, + Footer, + Gallery, + GlobalHeader, + Header, + Picture, + SkipLink, + Tabs, +} from "./all.mjs"; +import { EventTracker, GA4, helpers } from "./analytics.mjs"; + +export { + initAll, + Cookies, + Accordion, + Breadcrumbs, + CookieBanner, + ErrorSummary, + Footer, + Gallery, + GlobalHeader, + Header, + Picture, + SkipLink, + Tabs, + EventTracker, + GA4, + helpers, +}; diff --git a/src/nationalarchives/analytics.mjs b/src/nationalarchives/analytics.mjs index 62f8f836..4c7276b7 100644 --- a/src/nationalarchives/analytics.mjs +++ b/src/nationalarchives/analytics.mjs @@ -38,7 +38,7 @@ const componentAnalytics = [ class EventTracker { /** @protected */ - cookies = new (window.TNAFrontend?.Cookies || Cookies)(); + cookies = new Cookies(); /** @protected */ events = []; @@ -344,6 +344,11 @@ class GA4 extends EventTracker { } } +const ga4Id = document.documentElement.getAttribute("data-ga4"); +if (ga4Id) { + new GA4({ id: ga4Id }); +} + const helpers = { getXPathTo, getClosestHeading, valueGetters }; export { EventTracker, GA4, helpers }; diff --git a/tasks/test-package.js b/tasks/test-package.js index d4376fb1..e1c2a519 100644 --- a/tasks/test-package.js +++ b/tasks/test-package.js @@ -41,6 +41,9 @@ const checkExists = [ "nationalarchives/all.js.map", "nationalarchives/all.mjs", "nationalarchives/all.scss", + "nationalarchives/all+analytics.js", + "nationalarchives/all+analytics.js.map", + "nationalarchives/all+analytics.mjs", "nationalarchives/analytics.js", "nationalarchives/analytics.js.map", "nationalarchives/analytics.mjs", @@ -258,39 +261,53 @@ Object.defineProperty(window, "matchMedia", { }); global.window = window; global.document = window.document; -const jsAllPackage = require("../package/nationalarchives/all.js"); -if ( - Object.keys(jsAllPackage).includes("initAll") && - typeof jsAllPackage.initAll === "function" -) { - pass(`all.js function exists: initAll()`); -} else { - fail(`all.js function missing: initAll()`); - process.exitCode = 1; - throw new Error("JavaScript test failed"); -} -if ( - Object.keys(jsAllPackage).includes("Cookies") && - typeof jsAllPackage.Cookies === "function" -) { - pass(`all.js class exists: Cookies`); -} else { - fail(`all.js class missing: Cookies`); - process.exitCode = 1; - throw new Error("JavaScript module test failed"); -} -Object.keys(componentsWithJavaScript).forEach((component) => { - const componentClass = componentsWithJavaScript[component]; - if ( - Object.keys(jsAllPackage).includes(componentClass) && - typeof jsAllPackage[componentClass] === "function" - ) { - pass(`all.js function exists: ${componentClass}()`); - } else { - fail(`all.js function missing: ${componentClass}()`); - process.exitCode = 1; - throw new Error("Component JavaScript test failed"); +["all.js", "analytics.js", "all+analytics.js"].forEach((file) => { + const jsAllPackage = require(`../package/nationalarchives/${file}`); + let exports = []; + if (file === "all.js" || file === "all+analytics.js") { + exports = [ + ...exports, + { name: "initAll", type: "function" }, + { name: "Cookies", type: "function" }, + ]; + Object.keys(componentsWithJavaScript).forEach((component) => { + const componentClass = componentsWithJavaScript[component]; + if ( + Object.keys(jsAllPackage).includes(componentClass) && + typeof jsAllPackage[componentClass] === "function" + ) { + pass(`${file} function exists: ${componentClass}()`); + } else { + fail(`${file} function missing: ${componentClass}()`); + process.exitCode = 1; + throw new Error("Component JavaScript test failed"); + } + }); + } + if (file === "analytics.js" || file === "all+analytics.js") { + exports = [ + ...exports, + { name: "EventTracker", type: "function" }, + { name: "GA4", type: "function" }, + { name: "helpers", type: "object" }, + ]; } + exports.forEach((eachExport) => { + if ( + Object.keys(jsAllPackage).includes(eachExport.name) && + typeof jsAllPackage[eachExport.name] === eachExport.type + ) { + pass( + `${file} ${eachExport.type} exists: ${eachExport.name}${eachExport.type === "function" ? "()" : ""}`, + ); + } else { + fail( + `${file} ${eachExport.type} missing: ${eachExport.name}${eachExport.type === "function" ? "()" : ""}`, + ); + process.exitCode = 1; + throw new Error("JavaScript test failed"); + } + }); }); Object.keys(componentsWithJavaScript).forEach((component) => { const componentClass = componentsWithJavaScript[component]; diff --git a/webpack.config.js b/webpack.config.js index b2d3046c..5fd32faa 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -19,6 +19,14 @@ module.exports = { type: "umd", }, }, + "all+analytics": { + import: "./src/nationalarchives/all+analytics.mjs", + filename: "all+analytics.js", + library: { + name: "TNAFrontend", + type: "umd", + }, + }, ...glob .sync("./src/nationalarchives/components/**/*.mjs") .reduce((acc, path) => {