From fe6dea25180f3de0ba4c1b7c0090a1f69296586c Mon Sep 17 00:00:00 2001 From: Carles Andres Date: Tue, 30 Jun 2020 15:10:59 +0100 Subject: [PATCH 01/11] Scaffolded footer-localiser --- .../dotcom-privacy-footer-localiser/README.md | 4 +++ .../package.json | 32 +++++++++++++++++ .../src/footer-manipulations.ts | 34 +++++++++++++++++++ .../src/main.ts | 33 ++++++++++++++++++ .../src/selectors.ts | 1 + .../tsconfig.json | 4 +++ 6 files changed, 108 insertions(+) create mode 100644 packages/dotcom-privacy-footer-localiser/README.md create mode 100644 packages/dotcom-privacy-footer-localiser/package.json create mode 100644 packages/dotcom-privacy-footer-localiser/src/footer-manipulations.ts create mode 100644 packages/dotcom-privacy-footer-localiser/src/main.ts create mode 100644 packages/dotcom-privacy-footer-localiser/src/selectors.ts create mode 100644 packages/dotcom-privacy-footer-localiser/tsconfig.json diff --git a/packages/dotcom-privacy-footer-localiser/README.md b/packages/dotcom-privacy-footer-localiser/README.md new file mode 100644 index 000000000..bd1219ba7 --- /dev/null +++ b/packages/dotcom-privacy-footer-localiser/README.md @@ -0,0 +1,4 @@ +# footer-localiser + +This package is meant to modify the default footer of dotcom pages based on the requirements of any local legislation that might apply to a user. + diff --git a/packages/dotcom-privacy-footer-localiser/package.json b/packages/dotcom-privacy-footer-localiser/package.json new file mode 100644 index 000000000..6bf607ce6 --- /dev/null +++ b/packages/dotcom-privacy-footer-localiser/package.json @@ -0,0 +1,32 @@ +{ + "name": "@financial-times/dotcom-privacy-footer-localiser", + "version": "0.0.0", + "description": "", + "browser": "src/main.ts", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "tsc": "../../node_modules/.bin/tsc --incremental", + "clean": "npm run clean:dist && npm run clean:node_modules", + "clean:dist": "rm -rf dist", + "clean:node_modules": "rm -rf node_modules", + "clean:install": "npm run clean && npm i", + "build": "npm run build:node", + "build:node": "npm run tsc -- --module commonjs --outDir ./dist/node", + "dev": "npm run build:node -- --watch" + }, + "keywords": [], + "author": "", + "license": "MIT", + "dependencies": { + "@financial-times/privacy-legislation-client": "^0.3.7" + }, + "engines": { + "node": ">= 12.0.0" + }, + "repository": { + "type": "git", + "repository": "https://github.com/Financial-Times/dotcom-page-kit.git", + "directory": "packages/dotcom-privacy-footer-localiser" + }, + "homepage": "https://github.com/Financial-Times/dotcom-page-kit/tree/master/packages/dotcom-privacy-footer-localiser" +} diff --git a/packages/dotcom-privacy-footer-localiser/src/footer-manipulations.ts b/packages/dotcom-privacy-footer-localiser/src/footer-manipulations.ts new file mode 100644 index 000000000..9073ba233 --- /dev/null +++ b/packages/dotcom-privacy-footer-localiser/src/footer-manipulations.ts @@ -0,0 +1,34 @@ +import { privacyLinkOnFooter } from './selectors' + +export function createCCPALink(consentPageUrl: string): void { + // Get a reference to the node we want to insert our link before + const termsLink = document.querySelector(privacyLinkOnFooter) as HTMLAnchorElement + + if (!termsLink || !termsLink.parentNode) { + throw new Error('A DOM node for Privacy link could not be found') + } + + // Clone the node to keep consistent with structure and style + const ccpaLink = termsLink.cloneNode(true) as HTMLAnchorElement + const ccpaLabel = 'Do Not Sell My Info' + + // Customise the attributes + ccpaLink.href = consentPageUrl + ccpaLink.dataset.trackable = ccpaLabel + ccpaLink.textContent = ccpaLabel + + // Prepend our new link + const parent = termsLink.parentNode + parent.insertBefore(ccpaLink, termsLink) +} + +export function changePrivacyLinkText(newText: string): void { + // Get a reference to the node we want to insert our link before + const termsLink = document.querySelector(privacyLinkOnFooter) as HTMLAnchorElement + + if (!termsLink) { + throw new Error('A Privacy link could not be found in the footer') + } + + termsLink.innerText = newText +} diff --git a/packages/dotcom-privacy-footer-localiser/src/main.ts b/packages/dotcom-privacy-footer-localiser/src/main.ts new file mode 100644 index 000000000..e94115f80 --- /dev/null +++ b/packages/dotcom-privacy-footer-localiser/src/main.ts @@ -0,0 +1,33 @@ +import { fetchLegislation, buildConsentPageUrl } from '@financial-times/privacy-legislation-client' +import { createCCPALink, changePrivacyLinkText } from './footer-manipulations' + +const CONSENT_URL = 'https://www.ft.com/preferences/privacy-ccpa' + +export async function addDNSLinkToFooter(): Promise { + try { + // Get a list of the applicable legislationIds for the user's region + const { legislation } = await fetchLegislation() + const consentPageUrl = buildConsentPageUrl({ url: CONSENT_URL, legislation }) + + // If the user is in California update our UI to meet CCPA requirements + if (legislation.has('ccpa')) { + createCCPALink(consentPageUrl) + } + } catch (err) { + console.error(err) //eslint-disable-line no-console + } +} + +export async function adaptPrivacyLinkToLegislation(): Promise { + try { + // Get a list of the applicable legislationIds for the user's region + const { legislation } = await fetchLegislation() + + // If the user is in California update our UI to meet CCPA requirements + if (legislation.has('ccpa')) { + changePrivacyLinkText('Privacy - CCPA Updates') + } + } catch (err) { + console.error(err) //eslint-disable-line no-console + } +} diff --git a/packages/dotcom-privacy-footer-localiser/src/selectors.ts b/packages/dotcom-privacy-footer-localiser/src/selectors.ts new file mode 100644 index 000000000..010f51a4e --- /dev/null +++ b/packages/dotcom-privacy-footer-localiser/src/selectors.ts @@ -0,0 +1 @@ +export const privacyLinkOnFooter = "#site-footer [href='http://help.ft.com/help/legal-privacy/privacy/']" diff --git a/packages/dotcom-privacy-footer-localiser/tsconfig.json b/packages/dotcom-privacy-footer-localiser/tsconfig.json new file mode 100644 index 000000000..e0b0a1e5b --- /dev/null +++ b/packages/dotcom-privacy-footer-localiser/tsconfig.json @@ -0,0 +1,4 @@ +{ + "rootDir": "./src/", + "extends": "../../tsconfig" +} From 39dca34134465fcdf0ded10e78f2e279e8311b25 Mon Sep 17 00:00:00 2001 From: Carles Andres Date: Wed, 1 Jul 2020 14:22:29 +0100 Subject: [PATCH 02/11] Added first set of tests for privacy-footer-localiser --- .../__test__/footer-manipulations.spec.tsx | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 packages/dotcom-privacy-footer-localiser/src/__test__/footer-manipulations.spec.tsx diff --git a/packages/dotcom-privacy-footer-localiser/src/__test__/footer-manipulations.spec.tsx b/packages/dotcom-privacy-footer-localiser/src/__test__/footer-manipulations.spec.tsx new file mode 100644 index 000000000..0673e6fda --- /dev/null +++ b/packages/dotcom-privacy-footer-localiser/src/__test__/footer-manipulations.spec.tsx @@ -0,0 +1,69 @@ +/** + * @jest-environment jsdom + */ +import 'jest-enzyme' +import React from 'react' +import { mount } from 'enzyme' +import { addDNSLinkToFooter } from '../main' + +const consentPagePath = 'foo' + +jest.mock('@financial-times/privacy-legislation-client', () => { + return { + fetchLegislation: jest.fn().mockResolvedValue({ legislation: new Set(['ccpa', 'gdpr']) }), + buildConsentPageUrl: jest.fn(() => consentPagePath) + } +}) + +const ValidFooter = () => ( +
+ +
+) +const InvalidFooter = () => ( +
+ +
+) +describe('dotcom-privacy-footer-localiser', () => { + describe('if there is a Privacy link in the footer', () => { + let links + + beforeAll(async () => { + const div = document.createElement('div') + document.body.appendChild(div) + mount(, { attachTo: document.querySelector('div') }) + await addDNSLinkToFooter() + links = document.querySelectorAll('a') + }) + + it('should insert a new link', () => { + expect(links.length).toBe(2) + }) + + it('should insert the new link before the privacy link', () => { + expect(links[0].href).toMatch(consentPagePath) + }) + + it('should insert the new link with the right label', () => { + expect(links[0].text).toBe('Do Not Sell My Info') + }) + }) + + describe('if there is no Privacy link in the footer', () => { + it('should throw an error', async () => { + const consoleErr = window.console.error + window.console.error = jest.fn() + const div = document.createElement('div') + document.body.appendChild(div) + mount(, { attachTo: document.querySelector('div') }) + await addDNSLinkToFooter() + expect(window.console.error).toHaveBeenCalled() + window.console.error = consoleErr + }) + }) +}) From 9fc2689146f81e4bab50ad509ecf8b0c5fbf4355 Mon Sep 17 00:00:00 2001 From: Carles Andres Date: Wed, 1 Jul 2020 15:56:39 +0100 Subject: [PATCH 03/11] Added missing test for dotcom-privacy-footer-localiser --- .../__test__/footer-manipulations.spec.tsx | 101 +++++++++++++----- .../src/footer-manipulations.ts | 2 +- .../src/main.ts | 2 +- 3 files changed, 75 insertions(+), 30 deletions(-) diff --git a/packages/dotcom-privacy-footer-localiser/src/__test__/footer-manipulations.spec.tsx b/packages/dotcom-privacy-footer-localiser/src/__test__/footer-manipulations.spec.tsx index 0673e6fda..359373514 100644 --- a/packages/dotcom-privacy-footer-localiser/src/__test__/footer-manipulations.spec.tsx +++ b/packages/dotcom-privacy-footer-localiser/src/__test__/footer-manipulations.spec.tsx @@ -4,7 +4,7 @@ import 'jest-enzyme' import React from 'react' import { mount } from 'enzyme' -import { addDNSLinkToFooter } from '../main' +import { addDNSLinkToFooter, adaptPrivacyLinkToLegislation } from '../main' const consentPagePath = 'foo' @@ -15,6 +15,8 @@ jest.mock('@financial-times/privacy-legislation-client', () => { } }) +const wait = (ms) => setTimeout(() => Promise.resolve(), ms) + const ValidFooter = () => (
) + const InvalidFooter = () => (
) + describe('dotcom-privacy-footer-localiser', () => { - describe('if there is a Privacy link in the footer', () => { - let links - - beforeAll(async () => { - const div = document.createElement('div') - document.body.appendChild(div) - mount(, { attachTo: document.querySelector('div') }) - await addDNSLinkToFooter() - links = document.querySelectorAll('a') - }) + describe('the addDNSLinkToFooter method', () => { + describe('if there is a Privacy link in the footer', () => { + let links - it('should insert a new link', () => { - expect(links.length).toBe(2) - }) + beforeAll(async () => { + document.body.innerHTML = '' + const div = document.createElement('div') + document.body.appendChild(div) + mount(, { attachTo: document.querySelector('div') }) + await addDNSLinkToFooter() + links = document.querySelectorAll('a') + }) + + it('should insert a new link', () => { + expect(links.length).toBe(2) + }) - it('should insert the new link before the privacy link', () => { - expect(links[0].href).toMatch(consentPagePath) + it('should insert the new link before the privacy link', () => { + expect(links[0].href).toMatch(consentPagePath) + }) + + it('should insert the new link with the right label', () => { + expect(links[0].text).toBe('Do Not Sell My Info') + }) }) - it('should insert the new link with the right label', () => { - expect(links[0].text).toBe('Do Not Sell My Info') + describe('if there is no Privacy link in the footer', () => { + it('should call console.error', async () => { + const consoleErr = window.console.error + window.console.error = jest.fn() + const div = document.createElement('div') + document.body.appendChild(div) + mount(, { attachTo: document.querySelector('div') }) + await addDNSLinkToFooter() + expect(window.console.error).toHaveBeenCalled() + window.console.error = consoleErr + }) }) }) - describe('if there is no Privacy link in the footer', () => { - it('should throw an error', async () => { - const consoleErr = window.console.error - window.console.error = jest.fn() - const div = document.createElement('div') - document.body.appendChild(div) - mount(, { attachTo: document.querySelector('div') }) - await addDNSLinkToFooter() - expect(window.console.error).toHaveBeenCalled() - window.console.error = consoleErr + describe('the adaptPrivacyLinkToLegislation method', () => { + describe('if there is a Privacy link in the footer', () => { + let links + + beforeAll(async () => { + document.body.innerHTML = '' + const div = document.createElement('div') + document.body.appendChild(div) + mount(, { attachTo: document.querySelector('div') }) + await wait(1000) + await adaptPrivacyLinkToLegislation() + await wait(1000) + links = document.querySelectorAll('a') + }) + + it('should NOT insert a new link', () => { + expect(links.length).toBe(1) + }) + + it('should change the link text to the right label', () => { + expect(links[0].text).toBe('Privacy - CCPA UPDATES') + }) + }) + + describe('if there is no Privacy link in the footer', () => { + it('should call console.error', async () => { + const consoleErr = window.console.error + window.console.error = jest.fn() + const div = document.createElement('div') + document.body.appendChild(div) + mount(, { attachTo: document.querySelector('div') }) + await adaptPrivacyLinkToLegislation() + expect(window.console.error).toHaveBeenCalled() + window.console.error = consoleErr + }) }) }) }) diff --git a/packages/dotcom-privacy-footer-localiser/src/footer-manipulations.ts b/packages/dotcom-privacy-footer-localiser/src/footer-manipulations.ts index 9073ba233..557babf90 100644 --- a/packages/dotcom-privacy-footer-localiser/src/footer-manipulations.ts +++ b/packages/dotcom-privacy-footer-localiser/src/footer-manipulations.ts @@ -30,5 +30,5 @@ export function changePrivacyLinkText(newText: string): void { throw new Error('A Privacy link could not be found in the footer') } - termsLink.innerText = newText + termsLink.innerHTML = newText } diff --git a/packages/dotcom-privacy-footer-localiser/src/main.ts b/packages/dotcom-privacy-footer-localiser/src/main.ts index e94115f80..056b427a5 100644 --- a/packages/dotcom-privacy-footer-localiser/src/main.ts +++ b/packages/dotcom-privacy-footer-localiser/src/main.ts @@ -25,7 +25,7 @@ export async function adaptPrivacyLinkToLegislation(): Promise { // If the user is in California update our UI to meet CCPA requirements if (legislation.has('ccpa')) { - changePrivacyLinkText('Privacy - CCPA Updates') + changePrivacyLinkText('Privacy - CCPA UPDATES') } } catch (err) { console.error(err) //eslint-disable-line no-console From 11f1a186ee1c460fde869e6ceb72ebb0b1d12688 Mon Sep 17 00:00:00 2001 From: Carles Andres Date: Wed, 1 Jul 2020 16:29:33 +0100 Subject: [PATCH 04/11] Added dotcom-privacy-footer-localiser README --- .../dotcom-privacy-footer-localiser/README.md | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/packages/dotcom-privacy-footer-localiser/README.md b/packages/dotcom-privacy-footer-localiser/README.md index bd1219ba7..d9028a634 100644 --- a/packages/dotcom-privacy-footer-localiser/README.md +++ b/packages/dotcom-privacy-footer-localiser/README.md @@ -1,4 +1,42 @@ -# footer-localiser +# @financial-times/dotcom-privacy-footer-localiser This package is meant to modify the default footer of dotcom pages based on the requirements of any local legislation that might apply to a user. + +## Getting started + +This package is compatible with Node 12+ and is distributed on npm. + +```bash +npm install --save @financial-times/dotcom-privacy-footer-localiser +``` + +### Server-side + +This module doesn't export any server-side functionality. + + +### Client-side + +This package exports two methods to manipulate the footer + +- `addDNSLinkToFooter`: adds a "Do Not Sell My Info" Link above the "Privacy" if the CCPA legislation applies to the user. +- `adaptPrivacyLinkToLegislation`: replaces the text of the "Privacy" link with one that matches the requirements of the legislation that applies to the user. + +Neither of those two methods accept any parameters. + +#### Examples + +```js +import { addDNSLinkToFooter } from '../main' + +// ... JS operations with higher priority +addDNSLinkToFooter() +``` + +```js +import { adaptPrivacyLinkToLegislation } from '../main' + +// ... JS operations with higher priority +adaptPrivacyLinkToLegislation() +``` From 2d5635eba9c01bcd26a64bc510227fb15db76d29 Mon Sep 17 00:00:00 2001 From: Carles Andres Date: Wed, 1 Jul 2020 16:36:11 +0100 Subject: [PATCH 05/11] Improved README --- packages/dotcom-privacy-footer-localiser/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/dotcom-privacy-footer-localiser/README.md b/packages/dotcom-privacy-footer-localiser/README.md index d9028a634..4240145f7 100644 --- a/packages/dotcom-privacy-footer-localiser/README.md +++ b/packages/dotcom-privacy-footer-localiser/README.md @@ -20,22 +20,22 @@ This module doesn't export any server-side functionality. This package exports two methods to manipulate the footer -- `addDNSLinkToFooter`: adds a "Do Not Sell My Info" Link above the "Privacy" if the CCPA legislation applies to the user. -- `adaptPrivacyLinkToLegislation`: replaces the text of the "Privacy" link with one that matches the requirements of the legislation that applies to the user. +- `addDNSLinkToFooter`: adds a "Do Not Sell My Info" link above the "Privacy" if the CCPA legislation applies to the user. +- `adaptPrivacyLinkToLegislation`: replaces the text of the "Privacy" link according to the legislation that applies to the user, if needed. -Neither of those two methods accept any parameters. +Neither of those two methods accept any parameters. Both methods rely on the presence of a DOM element that matches the selector: `#site-footer [href='http://help.ft.com/help/legal-privacy/privacy/']` #### Examples ```js -import { addDNSLinkToFooter } from '../main' +import { addDNSLinkToFooter } from '@financial-times/dotcom-privacy-footer-localiser' // ... JS operations with higher priority addDNSLinkToFooter() ``` ```js -import { adaptPrivacyLinkToLegislation } from '../main' +import { adaptPrivacyLinkToLegislation } from '@financial-times/dotcom-privacy-footer-localiser' // ... JS operations with higher priority adaptPrivacyLinkToLegislation() From 5d444cee346261ffcc434fd0149f6785648e344f Mon Sep 17 00:00:00 2001 From: Carles Andres Date: Wed, 1 Jul 2020 16:38:03 +0100 Subject: [PATCH 06/11] Renamed test file --- .../src/__test__/{footer-manipulations.spec.tsx => main.spec.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/dotcom-privacy-footer-localiser/src/__test__/{footer-manipulations.spec.tsx => main.spec.tsx} (100%) diff --git a/packages/dotcom-privacy-footer-localiser/src/__test__/footer-manipulations.spec.tsx b/packages/dotcom-privacy-footer-localiser/src/__test__/main.spec.tsx similarity index 100% rename from packages/dotcom-privacy-footer-localiser/src/__test__/footer-manipulations.spec.tsx rename to packages/dotcom-privacy-footer-localiser/src/__test__/main.spec.tsx From 268e9de2ea59191a356b79a6887cdda1b0ebca45 Mon Sep 17 00:00:00 2001 From: Carles Andres Date: Wed, 1 Jul 2020 16:43:34 +0100 Subject: [PATCH 07/11] Further improved README --- packages/dotcom-privacy-footer-localiser/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/dotcom-privacy-footer-localiser/README.md b/packages/dotcom-privacy-footer-localiser/README.md index 4240145f7..ab29265a7 100644 --- a/packages/dotcom-privacy-footer-localiser/README.md +++ b/packages/dotcom-privacy-footer-localiser/README.md @@ -1,6 +1,8 @@ # @financial-times/dotcom-privacy-footer-localiser -This package is meant to modify the default footer of dotcom pages based on the requirements of any local legislation that might apply to a user. +This package provides utilities to adapt the default footer of dotcom pages based on the specific requirements of the legislation that applies to each user. + +This module relies on `@financial-times/privacy-legislation-client` for determining the legislation that applies to the user. ## Getting started From 7310717e2608230c44bf78f74d2c2ed8760ed60f Mon Sep 17 00:00:00 2001 From: Carles Andres Date: Thu, 2 Jul 2020 13:41:32 +0100 Subject: [PATCH 08/11] Added privacy-footer-localiser to ft-ui example --- examples/ft-ui/README.md | 18 +++++++++++++++++- examples/ft-ui/client/main.js | 7 +++++++ examples/ft-ui/package.json | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/examples/ft-ui/README.md b/examples/ft-ui/README.md index 89d807b66..91d526974 100644 --- a/examples/ft-ui/README.md +++ b/examples/ft-ui/README.md @@ -1,5 +1,21 @@ # FT UI -This example demonstrates all the FT.com layout which includes the header, navigation, and footer components. It uses [Sucrase] to provide support for JSX syntax and ESM. +This example demonstrates all the FT.com layout which includes the header, navigation, footer and privacy-footer-localiser components. It uses [Sucrase] to provide support for JSX syntax and ESM. [Sucrase]: https://github.com/alangpierce/sucrase + +## Comments on `privacy-footer-localiser` + +Any of the two methods imported from `dotcom-privacy-footer-localiser` could well be called from `dotcom-ui-footer` if they needed to be applied to footer of all pages. +Currently, these methods will only change the defaut footer if the user is found to be in California by the `compliance-region` service. +The `compliance-region` service doesn't support CORS and it saves the user compliance-region in sessionStorage. Therefore, in order to get this example to make client-side changes to the footer, the following needs to happen: + + - The example is rendered from `local.ft.com` with a clean sessionStorage + - The user is located in California or uses a VPN to pretend to be there + +Alternatively a record can be saved in sessionStorage with: + +``` +key: user-compliance +value: {"region":"US-CA","legislation":"ccpa,gdpr"} +``` diff --git a/examples/ft-ui/client/main.js b/examples/ft-ui/client/main.js index e73182695..e559c23f1 100644 --- a/examples/ft-ui/client/main.js +++ b/examples/ft-ui/client/main.js @@ -1,6 +1,13 @@ import readyState from 'ready-state' import * as layout from '@financial-times/dotcom-ui-layout' +import { + addDNSLinkToFooter, + adaptPrivacyLinkToLegislation +} from '@financial-times/dotcom-privacy-footer-localiser' readyState.domready.then(() => { layout.init() + + addDNSLinkToFooter() + adaptPrivacyLinkToLegislation() }) diff --git a/examples/ft-ui/package.json b/examples/ft-ui/package.json index 91d5b486b..76ebc5029 100644 --- a/examples/ft-ui/package.json +++ b/examples/ft-ui/package.json @@ -12,6 +12,7 @@ }, "dependencies": { "@financial-times/dotcom-middleware-navigation": "file:../../packages/dotcom-middleware-navigation", + "@financial-times/dotcom-privacy-footer-localiser": "file:../../packages/dotcom-privacy-footer-localiser", "@financial-times/dotcom-ui-layout": "file:../../packages/dotcom-ui-layout", "@financial-times/dotcom-ui-shell": "file:../../packages/dotcom-ui-shell", "express": "^4.16.2", From 3d33680d03680e2ef02a055ab2a43a99800181b8 Mon Sep 17 00:00:00 2001 From: Carles Andres Date: Thu, 2 Jul 2020 13:49:55 +0100 Subject: [PATCH 09/11] Improved ft-ui example README --- examples/ft-ui/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/ft-ui/README.md b/examples/ft-ui/README.md index 91d526974..97d290e7f 100644 --- a/examples/ft-ui/README.md +++ b/examples/ft-ui/README.md @@ -1,6 +1,8 @@ # FT UI -This example demonstrates all the FT.com layout which includes the header, navigation, footer and privacy-footer-localiser components. It uses [Sucrase] to provide support for JSX syntax and ESM. +This example demonstrates all the FT.com layout which includes the header, navigation and footer components. It uses [Sucrase] to provide support for JSX syntax and ESM. + +It also shows how to use the utils exposed by privacy-footer-localiser on the client-side. [Sucrase]: https://github.com/alangpierce/sucrase From 3d6b7722a36252303b61a334db5056b4b99eb441 Mon Sep 17 00:00:00 2001 From: Carles Andres Date: Thu, 2 Jul 2020 13:51:03 +0100 Subject: [PATCH 10/11] Fixed removed Oxford comma by mistake --- examples/ft-ui/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ft-ui/README.md b/examples/ft-ui/README.md index 97d290e7f..a59325532 100644 --- a/examples/ft-ui/README.md +++ b/examples/ft-ui/README.md @@ -1,6 +1,6 @@ # FT UI -This example demonstrates all the FT.com layout which includes the header, navigation and footer components. It uses [Sucrase] to provide support for JSX syntax and ESM. +This example demonstrates all the FT.com layout which includes the header, navigation, and footer components. It uses [Sucrase] to provide support for JSX syntax and ESM. It also shows how to use the utils exposed by privacy-footer-localiser on the client-side. From 996fd6edc39672d596ae2be290ddd10f407e6a7a Mon Sep 17 00:00:00 2001 From: Carles Andres Date: Thu, 2 Jul 2020 13:59:40 +0100 Subject: [PATCH 11/11] Added clarification to ft-ui example code --- examples/ft-ui/client/main.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/ft-ui/client/main.js b/examples/ft-ui/client/main.js index e559c23f1..134df23ee 100644 --- a/examples/ft-ui/client/main.js +++ b/examples/ft-ui/client/main.js @@ -8,6 +8,9 @@ import { readyState.domready.then(() => { layout.init() + // These methods won't perform any changes to the footer unless the user is + // deemed to be in California. + // See this example's README for details on how to fake that. addDNSLinkToFooter() adaptPrivacyLinkToLegislation() })