diff --git a/jest.setup.js b/jest.setup.js index 6b3e9fcdd4..0707fc48d7 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -1,3 +1,4 @@ /* eslint-env jest */ jest.setTimeout(10000) +jest.retryTimes(3, { logErrorsBeforeRetry: true }) diff --git a/lib/extract-page-headings/fixtures/src/example-with-aliases.md.njk b/lib/extract-page-headings/fixtures/src/example-with-aliases.md.njk new file mode 100644 index 0000000000..7fc99771e4 --- /dev/null +++ b/lib/extract-page-headings/fixtures/src/example-with-aliases.md.njk @@ -0,0 +1,19 @@ +--- +title: Example with aliases +headingAliases: + Heading level 1: one + Heading level 2: two + Heading level 3: three +--- + +Contents + +# Heading level 1 + +Paragraph + +## Heading level 2 + +[Link](/) + +### Heading level 3 diff --git a/lib/extract-page-headings/index.js b/lib/extract-page-headings/index.js index b05567ee48..1b88a734e3 100644 --- a/lib/extract-page-headings/index.js +++ b/lib/extract-page-headings/index.js @@ -12,14 +12,26 @@ const plugin = () => { let tokens = lexer.lex(contents) let headingsArray = [] tokens.forEach(token => { - if (token.type === 'heading') { - let heading = { - depth: token.depth, - text: token.text, - url: token.text.toLowerCase().replace(/[^\w]+/g, '-') - } - headingsArray.push(heading) + if (token.type !== 'heading') { + return } + + let aliases = null + if (data.headingAliases) { + aliases = + Object.entries(data.headingAliases) + .filter(([text]) => { return text === token.text }) + .map(([text, alias]) => { return alias }) + .join() + } + + let heading = { + depth: token.depth, + text: token.text, + url: token.text.toLowerCase().replace(/[^\w]+/g, '-'), + aliases + } + headingsArray.push(heading) }) data.headings = headingsArray }) diff --git a/lib/extract-page-headings/index.test.js b/lib/extract-page-headings/index.test.js index 3598cf22a1..01fa1d886f 100644 --- a/lib/extract-page-headings/index.test.js +++ b/lib/extract-page-headings/index.test.js @@ -4,23 +4,35 @@ const metalsmith = require('metalsmith') const plugin = require('./index.js') describe('extract-page-headings plugin', () => { - it('generated heading metadata matches expected', (done) => { + let pages + beforeAll((done) => { metalsmith('lib/extract-page-headings/fixtures') .use(plugin()) .build((err, files) => { if (err) { return done(err) } - Object.keys(files).forEach((file) => { - const metadataHeadings = files[file].headings - const expectedHeadings = [ - { depth: 1, text: 'Heading level 1', url: 'heading-level-1' }, - { depth: 2, text: 'Heading level 2', url: 'heading-level-2' }, - { depth: 3, text: 'Heading level 3', url: 'heading-level-3' } - ] - expect(metadataHeadings).toEqual(expectedHeadings) - }) + pages = files + done() }) }) + it('generated heading metadata matches expected', () => { + const metadataHeadings = pages['example.md.njk'].headings + const expectedHeadings = [ + { aliases: null, depth: 1, text: 'Heading level 1', url: 'heading-level-1' }, + { aliases: null, depth: 2, text: 'Heading level 2', url: 'heading-level-2' }, + { aliases: null, depth: 3, text: 'Heading level 3', url: 'heading-level-3' } + ] + expect(metadataHeadings).toEqual(expectedHeadings) + }) + it('generates headings with aliases', () => { + const metadataHeadings = pages['example-with-aliases.md.njk'].headings + const expectedHeadings = [ + { aliases: 'one', depth: 1, text: 'Heading level 1', url: 'heading-level-1' }, + { aliases: 'two', depth: 2, text: 'Heading level 2', url: 'heading-level-2' }, + { aliases: 'three', depth: 3, text: 'Heading level 3', url: 'heading-level-3' } + ] + expect(metadataHeadings).toEqual(expectedHeadings) + }) }) diff --git a/lib/metalsmith-lunr-index/fixtures/src/with-page-headings.md.njk b/lib/metalsmith-lunr-index/fixtures/src/with-page-headings.md.njk index 67ddb9767b..896aec7182 100644 --- a/lib/metalsmith-lunr-index/fixtures/src/with-page-headings.md.njk +++ b/lib/metalsmith-lunr-index/fixtures/src/with-page-headings.md.njk @@ -1,6 +1,8 @@ --- title: Page with headings show_page_nav: true +headingAliases: + Heading level 2: two --- # Heading level 1 diff --git a/lib/metalsmith-lunr-index/index.js b/lib/metalsmith-lunr-index/index.js index d7a64f8a50..9d56922807 100644 --- a/lib/metalsmith-lunr-index/index.js +++ b/lib/metalsmith-lunr-index/index.js @@ -50,7 +50,8 @@ module.exports = function lunrPlugin () { path: `${documentPath}/#${heading.url}`, title: heading.text, page: file.title, - section: file.section + section: file.section, + aliases: heading.aliases === null ? undefined : heading.aliases } }) return headings @@ -98,7 +99,8 @@ module.exports = function lunrPlugin () { store[doc.path] = { title: doc.title, path: doc.path, - section: `${doc.section}${separator}${doc.page}` + section: `${doc.section}${separator}${doc.page}`, + aliases: doc.aliases } this.add(doc) }) diff --git a/lib/metalsmith-lunr-index/index.test.js b/lib/metalsmith-lunr-index/index.test.js index 22590f9611..3ffa6ca1b5 100644 --- a/lib/metalsmith-lunr-index/index.test.js +++ b/lib/metalsmith-lunr-index/index.test.js @@ -111,5 +111,12 @@ describe('metalsmith-lunr-index plugin', () => { expect(documentStore[resultRef].title).toEqual('Heading level 2') }) + + it('stores the aliases for the page heading of the page in the metadata', () => { + const searchResults = searchIndex.search('two') + const resultRef = searchResults[0].ref + + expect(documentStore[resultRef].title).toEqual('Heading level 2') + }) }) }) diff --git a/lib/metalsmith.js b/lib/metalsmith.js index 6a75aabc03..8f33d98b53 100644 --- a/lib/metalsmith.js +++ b/lib/metalsmith.js @@ -236,8 +236,6 @@ module.exports = metalsmith(__dirname) // __dirname defined by node.js: name of // Markdown engine options smartypants: true, // use "smart" typographic punctuation - gfm: true, - tables: true, pedantic: true, highlight: highlighter } diff --git a/package-lock.json b/package-lock.json index 705c3888dd..bd281901ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "clipboard": "^2.0.4", "connect": "^3.6.6", "eslint": "^5.16.0", - "govuk-frontend": "^4.2.0", + "govuk-frontend": "^4.3.1", "gray-matter": "^4.0.2", "highlight.js": "^10.4.1", "html5shiv": "^3.7.3", @@ -2024,9 +2024,9 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz", - "integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==", + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", + "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -3365,9 +3365,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001374", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001374.tgz", - "integrity": "sha512-mWvzatRx3w+j5wx/mpFN5v5twlPrabG8NqX2c6e45LCpymdoGqNvRkRutFUqpRTXKFQFNQJasvK0YT7suW6/Hw==", + "version": "1.0.30001387", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001387.tgz", + "integrity": "sha512-fKDH0F1KOJvR+mWSOvhj8lVRr/Q/mc5u5nabU2vi1/sgvlSqEsE8dOq0Hy/BqVbDkCYQPRRHB1WRjW6PGB/7PA==", "funding": [ { "type": "opencollective", @@ -3640,18 +3640,6 @@ "node": ">=0.10.0" } }, - "node_modules/clone-regexp": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", - "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", - "dev": true, - "dependencies": { - "is-regexp": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -3690,9 +3678,9 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/colord": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.2.tgz", - "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==", + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", "dev": true }, "node_modules/combined-stream": { @@ -4337,9 +4325,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "node_modules/electron-to-chromium": { - "version": "1.4.211", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.211.tgz", - "integrity": "sha512-BZSbMpyFQU0KBJ1JG26XGeFI3i4op+qOYGxftmZXFZoHkhLgsSv4DHDJfl8ogII3hIuzGt51PaZ195OVu0yJ9A==" + "version": "1.4.239", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.239.tgz", + "integrity": "sha512-XbhfzxPIFzMjJm17T7yUGZEyYh5XuUjrA/FQ7JUy2bEd4qQ7MvFTaKpZ6zXZog1cfVttESo2Lx0ctnf7eQOaAQ==" }, "node_modules/emittery": { "version": "0.8.1", @@ -5396,18 +5384,6 @@ "semver": "bin/semver" } }, - "node_modules/execall": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", - "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", - "dev": true, - "dependencies": { - "clone-regexp": "^2.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -6184,9 +6160,9 @@ } }, "node_modules/govuk-frontend": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/govuk-frontend/-/govuk-frontend-4.2.0.tgz", - "integrity": "sha512-IHbnz5DbnPjuCv4lQvtJGoCNAKAN6byKqmaej8hjd6Y/KTaAuw10npijeqfRJNO4WdDX9a34+n+SC/UmWdjfGQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/govuk-frontend/-/govuk-frontend-4.3.1.tgz", + "integrity": "sha512-uD0KVFds7drOwLEvfp4zRBOXuHCxkWLYDQcYvlbG+2baZ9po2TGZz8WjfzhfueYjo9+Uwk+bM0NQT6g4cg/Q+A==", "engines": { "node": ">= 4.2.0" } @@ -7029,15 +7005,6 @@ "node": ">= 0.4" } }, - "node_modules/is-regexp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", - "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", @@ -12958,9 +12925,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sass": { - "version": "1.54.3", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.3.tgz", - "integrity": "sha512-fLodey5Qd41Pxp/Tk7Al97sViYwF/TazRc5t6E65O7JOk4XF8pzwIW7CvCxYVOfJFFI/1x5+elDyBIixrp+zrw==", + "version": "1.54.8", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.8.tgz", + "integrity": "sha512-ib4JhLRRgbg6QVy6bsv5uJxnJMTS2soVcCp9Y88Extyy13A8vV0G1fAwujOzmNkFQbR3LvedudAMbtuNRPbQww==", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -13983,22 +13950,20 @@ "dev": true }, "node_modules/stylelint": { - "version": "14.9.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.9.1.tgz", - "integrity": "sha512-RdAkJdPiLqHawCSnu21nE27MjNXaVd4WcOHA4vK5GtIGjScfhNnaOuWR2wWdfKFAvcWQPOYe311iveiVKSmwsA==", + "version": "14.11.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.11.0.tgz", + "integrity": "sha512-OTLjLPxpvGtojEfpESWM8Ir64Z01E89xsisaBMUP/ngOx1+4VG2DPRcUyCCiin9Rd3kPXPsh/uwHd9eqnvhsYA==", "dev": true, "dependencies": { - "@csstools/selector-specificity": "^2.0.1", + "@csstools/selector-specificity": "^2.0.2", "balanced-match": "^2.0.0", - "colord": "^2.9.2", + "colord": "^2.9.3", "cosmiconfig": "^7.0.1", "css-functions-list": "^3.1.0", "debug": "^4.3.4", - "execall": "^2.0.0", "fast-glob": "^3.2.11", - "fastest-levenshtein": "^1.0.12", + "fastest-levenshtein": "^1.0.16", "file-entry-cache": "^6.0.1", - "get-stdin": "^8.0.0", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", @@ -14013,7 +13978,7 @@ "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.14", + "postcss": "^8.4.16", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", @@ -14027,7 +13992,7 @@ "svg-tags": "^1.0.0", "table": "^6.8.0", "v8-compile-cache": "^2.3.0", - "write-file-atomic": "^4.0.1" + "write-file-atomic": "^4.0.2" }, "bin": { "stylelint": "bin/stylelint.js" @@ -14282,23 +14247,11 @@ } }, "node_modules/stylelint/node_modules/flatted": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", - "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, - "node_modules/stylelint/node_modules/get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/stylelint/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -14486,16 +14439,16 @@ } }, "node_modules/stylelint/node_modules/write-file-atomic": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", - "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/supports-color": { @@ -14728,9 +14681,9 @@ } }, "node_modules/terser": { - "version": "5.14.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", - "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.0.tgz", + "integrity": "sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.2", @@ -15052,9 +15005,9 @@ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" }, "node_modules/uglify-js": { - "version": "3.16.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.3.tgz", - "integrity": "sha512-uVbFqx9vvLhQg0iBaau9Z75AxWJ8tqM9AV890dIZCLApF4rTcyHwmAvLeEdYRs+BzYWu8Iw81F79ah0EfTXbaw==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.0.tgz", + "integrity": "sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg==", "dev": true, "bin": { "uglifyjs": "bin/uglifyjs" @@ -17365,9 +17318,9 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz", - "integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==", + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", + "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", @@ -18426,9 +18379,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001374", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001374.tgz", - "integrity": "sha512-mWvzatRx3w+j5wx/mpFN5v5twlPrabG8NqX2c6e45LCpymdoGqNvRkRutFUqpRTXKFQFNQJasvK0YT7suW6/Hw==" + "version": "1.0.30001387", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001387.tgz", + "integrity": "sha512-fKDH0F1KOJvR+mWSOvhj8lVRr/Q/mc5u5nabU2vi1/sgvlSqEsE8dOq0Hy/BqVbDkCYQPRRHB1WRjW6PGB/7PA==" }, "caseless": { "version": "0.12.0", @@ -18644,15 +18597,6 @@ "shallow-clone": "^0.1.2" } }, - "clone-regexp": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", - "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", - "dev": true, - "requires": { - "is-regexp": "^2.0.0" - } - }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -18684,9 +18628,9 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "colord": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.2.tgz", - "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==", + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", "dev": true }, "combined-stream": { @@ -19217,9 +19161,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.4.211", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.211.tgz", - "integrity": "sha512-BZSbMpyFQU0KBJ1JG26XGeFI3i4op+qOYGxftmZXFZoHkhLgsSv4DHDJfl8ogII3hIuzGt51PaZ195OVu0yJ9A==" + "version": "1.4.239", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.239.tgz", + "integrity": "sha512-XbhfzxPIFzMjJm17T7yUGZEyYh5XuUjrA/FQ7JUy2bEd4qQ7MvFTaKpZ6zXZog1cfVttESo2Lx0ctnf7eQOaAQ==" }, "emittery": { "version": "0.8.1", @@ -20043,15 +19987,6 @@ } } }, - "execall": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", - "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", - "dev": true, - "requires": { - "clone-regexp": "^2.1.0" - } - }, "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -20653,9 +20588,9 @@ } }, "govuk-frontend": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/govuk-frontend/-/govuk-frontend-4.2.0.tgz", - "integrity": "sha512-IHbnz5DbnPjuCv4lQvtJGoCNAKAN6byKqmaej8hjd6Y/KTaAuw10npijeqfRJNO4WdDX9a34+n+SC/UmWdjfGQ==" + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/govuk-frontend/-/govuk-frontend-4.3.1.tgz", + "integrity": "sha512-uD0KVFds7drOwLEvfp4zRBOXuHCxkWLYDQcYvlbG+2baZ9po2TGZz8WjfzhfueYjo9+Uwk+bM0NQT6g4cg/Q+A==" }, "graceful-fs": { "version": "4.1.11", @@ -21323,12 +21258,6 @@ "has": "^1.0.1" } }, - "is-regexp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", - "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", - "dev": true - }, "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", @@ -25867,9 +25796,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sass": { - "version": "1.54.3", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.3.tgz", - "integrity": "sha512-fLodey5Qd41Pxp/Tk7Al97sViYwF/TazRc5t6E65O7JOk4XF8pzwIW7CvCxYVOfJFFI/1x5+elDyBIixrp+zrw==", + "version": "1.54.8", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.8.tgz", + "integrity": "sha512-ib4JhLRRgbg6QVy6bsv5uJxnJMTS2soVcCp9Y88Extyy13A8vV0G1fAwujOzmNkFQbR3LvedudAMbtuNRPbQww==", "requires": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -26730,22 +26659,20 @@ "dev": true }, "stylelint": { - "version": "14.9.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.9.1.tgz", - "integrity": "sha512-RdAkJdPiLqHawCSnu21nE27MjNXaVd4WcOHA4vK5GtIGjScfhNnaOuWR2wWdfKFAvcWQPOYe311iveiVKSmwsA==", + "version": "14.11.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.11.0.tgz", + "integrity": "sha512-OTLjLPxpvGtojEfpESWM8Ir64Z01E89xsisaBMUP/ngOx1+4VG2DPRcUyCCiin9Rd3kPXPsh/uwHd9eqnvhsYA==", "dev": true, "requires": { - "@csstools/selector-specificity": "^2.0.1", + "@csstools/selector-specificity": "^2.0.2", "balanced-match": "^2.0.0", - "colord": "^2.9.2", + "colord": "^2.9.3", "cosmiconfig": "^7.0.1", "css-functions-list": "^3.1.0", "debug": "^4.3.4", - "execall": "^2.0.0", "fast-glob": "^3.2.11", - "fastest-levenshtein": "^1.0.12", + "fastest-levenshtein": "^1.0.16", "file-entry-cache": "^6.0.1", - "get-stdin": "^8.0.0", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", @@ -26760,7 +26687,7 @@ "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.14", + "postcss": "^8.4.16", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", @@ -26774,7 +26701,7 @@ "svg-tags": "^1.0.0", "table": "^6.8.0", "v8-compile-cache": "^2.3.0", - "write-file-atomic": "^4.0.1" + "write-file-atomic": "^4.0.2" }, "dependencies": { "ajv": { @@ -26866,15 +26793,9 @@ } }, "flatted": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", - "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", - "dev": true - }, - "get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, "glob": { @@ -27016,9 +26937,9 @@ } }, "write-file-atomic": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", - "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, "requires": { "imurmurhash": "^0.1.4", @@ -27303,9 +27224,9 @@ } }, "terser": { - "version": "5.14.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", - "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.0.tgz", + "integrity": "sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==", "dev": true, "requires": { "@jridgewell/source-map": "^0.3.2", @@ -27556,9 +27477,9 @@ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" }, "uglify-js": { - "version": "3.16.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.3.tgz", - "integrity": "sha512-uVbFqx9vvLhQg0iBaau9Z75AxWJ8tqM9AV890dIZCLApF4rTcyHwmAvLeEdYRs+BzYWu8Iw81F79ah0EfTXbaw==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.0.tgz", + "integrity": "sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg==", "dev": true }, "uniq": { diff --git a/package.json b/package.json index 988554af80..3900de4ee7 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "clipboard": "^2.0.4", "connect": "^3.6.6", "eslint": "^5.16.0", - "govuk-frontend": "^4.2.0", + "govuk-frontend": "^4.3.1", "gray-matter": "^4.0.2", "highlight.js": "^10.4.1", "html5shiv": "^3.7.3", @@ -80,7 +80,10 @@ "stylelint-config-gds": "^0.2.0", "stylelint-order": "^5.0.0", "sitemap": "^2.1.0", - "standard": "^12.0.1" + "standard": "^12.0.1", + "stylelint": "^14.6.1", + "stylelint-config-gds": "^0.2.0", + "stylelint-order": "^5.0.0" }, "engines": { "node": "~16.14.2" diff --git a/src/javascripts/components/navigation.js b/src/javascripts/components/navigation.js index c7abfe297b..5e59c37b62 100644 --- a/src/javascripts/components/navigation.js +++ b/src/javascripts/components/navigation.js @@ -136,7 +136,13 @@ Navigation.prototype.init = function () { if (typeof window.matchMedia === 'function') { this.mql = window.matchMedia('(min-width: 40.0625em)') - this.mql.addEventListener('change', this.setHiddenStates.bind(this)) + + // IE and Safari < 14 do not support MediaQueryList.addEventListener + if ('addEventListener' in this.mql) { + this.mql.addEventListener('change', this.setHiddenStates.bind(this)) + } else { + this.mql.addListener(this.setHiddenStates.bind(this)) + } } this.setHiddenStates() diff --git a/src/stylesheets/components/_category-nav.scss b/src/stylesheets/components/_category-nav.scss new file mode 100644 index 0000000000..47b78dc824 --- /dev/null +++ b/src/stylesheets/components/_category-nav.scss @@ -0,0 +1,7 @@ +.category-nav { + padding-top: govuk-spacing(5); + + @include govuk-media-query($from: tablet) { + display: none; + } +} diff --git a/src/stylesheets/components/_footer.scss b/src/stylesheets/components/_footer.scss index ef397ac145..8fdbc24643 100644 --- a/src/stylesheets/components/_footer.scss +++ b/src/stylesheets/components/_footer.scss @@ -3,25 +3,7 @@ // // GOV.UK Frontend footer adapted for full width -@include govuk-exports("app-footer") { - .app-width-container--full { - min-width: calc(100% - #{$govuk-gutter * 2}); - max-width: 100%; - padding: 0; - @include govuk-media-query($from: desktop) { - margin: 0 auto; - padding: 0 govuk-spacing(6); - } - } - - .app-footer .govuk-footer__section-break { - margin-bottom: 0; - border-bottom: 0; - } - - // Fix the visually hidden 'Support links' heading causing Safari to pad out - // the bottom of the page or... something. - .app-footer .govuk-visually-hidden { - position: relative; - } +.app-footer .govuk-footer__section-break { + margin-bottom: 0; + border-bottom: 0; } diff --git a/src/stylesheets/components/_header.scss b/src/stylesheets/components/_header.scss index 1a9919fe67..55e08022e4 100644 --- a/src/stylesheets/components/_header.scss +++ b/src/stylesheets/components/_header.scss @@ -1,20 +1,17 @@ -@include govuk-exports("app-header") { - - // Move the blue border from the container to the header so that it spans - // the full width of the page - .app-header { - border-bottom: 10px solid $govuk-brand-colour; - } +// Move the blue border from the container to the header so that it spans +// the full width of the page +.app-header { + border-bottom: 10px solid $govuk-brand-colour; +} - .app-header__container { - margin-bottom: 0; - border-bottom: 0; - } +.app-header__container { + margin-bottom: 0; + border-bottom: 0; +} - // Override the default 33% width on the logo in GOV.UK Frontend (prevents - // unnecessary wrapping of "GOV.UK Design System" on smaller tablet / desktop - // viewports) - .app-header__logo { - width: auto; - } +// Override the default 33% width on the logo in GOV.UK Frontend (prevents +// unnecessary wrapping of "GOV.UK Design System" on smaller tablet / desktop +// viewports) +.app-header__logo { + width: auto; } diff --git a/src/stylesheets/components/_pane.scss b/src/stylesheets/components/_pane.scss deleted file mode 100644 index eb98f5e4f6..0000000000 --- a/src/stylesheets/components/_pane.scss +++ /dev/null @@ -1,76 +0,0 @@ -@include govuk-exports("app-pane") { - $toc-width: 260px; - $toc-width-tablet: 210px; - - .app-pane.app-pane--enabled { - @include govuk-media-query($from: tablet) { - display: flex; - flex-direction: column; - } - } - - .app-pane__body { - @include govuk-media-query($from: tablet) { - display: flex; - position: relative; - min-height: 0; - overflow: inherit; - } - - @include govuk-media-query(1160px) { - width: 100%; - } - } - - .app-pane__subnav { - @include govuk-media-query($until: tablet) { - display: none; - } - @include govuk-media-query($from: tablet) { - width: $toc-width-tablet; - flex: 0 0 auto; - } - @include govuk-media-query($from: desktop) { - width: $toc-width; - } - } - - .app-pane__subnav-mobile-overview { - @include govuk-media-query($from: tablet) { - display: none; - } - } - - .app-pane__content { - @include govuk-media-query($from: tablet) { - display: flex; - min-width: 0; - flex: 1 1 100%; - flex-direction: column; - } - } - - .no-flexbox.no-flexboxtweener { - .app-pane { - height: auto; - overflow: visible; - @include govuk-clearfix; - } - - .app-pane__body { - display: block; - } - - .app-pane__subnav { - width: $toc-width; - float: left; - overflow-x: hidden; - border-right: 0; - } - - .app-pane__content { - margin-left: -1px; - overflow-x: hidden; - } - } -} diff --git a/src/stylesheets/components/_phase-banner.scss b/src/stylesheets/components/_phase-banner.scss index 8ae5363896..e8cc6f3926 100644 --- a/src/stylesheets/components/_phase-banner.scss +++ b/src/stylesheets/components/_phase-banner.scss @@ -1,15 +1,3 @@ -.app-phase-banner { - @include govuk-media-query($until: tablet) { - margin-right: 0; - margin-left: 0; - } - - @include govuk-media-query($from: tablet) { - width: 100%; - // border-bottom: 0; - } -} - .app-phase-banner--no-border { border-bottom: 0; } diff --git a/src/stylesheets/components/_split-pane.scss b/src/stylesheets/components/_split-pane.scss new file mode 100644 index 0000000000..b10219652f --- /dev/null +++ b/src/stylesheets/components/_split-pane.scss @@ -0,0 +1,55 @@ +$toc-width: 260px; +$toc-width-tablet: 210px; + +.app-split-pane { + @include govuk-media-query($from: tablet) { + display: flex; + position: relative; + min-height: 0; + overflow: inherit; + } + + @include govuk-media-query(1160px) { + width: 100%; + } +} + +.app-split-pane__nav { + @include govuk-media-query($until: tablet) { + display: none; + } + + @include govuk-media-query($from: tablet) { + width: $toc-width-tablet; + flex: 0 0 auto; + } + + @include govuk-media-query($from: desktop) { + width: $toc-width; + } +} + +.app-split-pane__content { + @include govuk-media-query($from: tablet) { + display: flex; + min-width: 0; + flex: 1 1 100%; + flex-direction: column; + } +} + +.no-flexbox.no-flexboxtweener { + .app-split-pane { + @include govuk-clearfix; + } + + .app-split-pane__nav { + width: $toc-width; + float: left; + border-right: 0; + } + + .app-split-pane__content { + margin-left: $toc-width; + } +} diff --git a/src/stylesheets/components/_subnav.scss b/src/stylesheets/components/_subnav.scss index 16005f9088..455b22cbdb 100644 --- a/src/stylesheets/components/_subnav.scss +++ b/src/stylesheets/components/_subnav.scss @@ -1,61 +1,59 @@ -@include govuk-exports("app-subnav") { - .app-subnav { - // Since the back to top link is outside the flow of the document we need to create a space for it. - // This number is magic and was determined by manually judging the visual spacing. - margin-bottom: 100px; - padding: govuk-spacing(6) govuk-spacing(3) 0 0; - @include govuk-font(16); - } - - .app-subnav__section { - margin: 0 0 govuk-spacing(4); - padding: 0; - list-style-type: none; - } - - .app-subnav__link { - padding: 2px 0; - } - - .app-subnav__section-item { - margin-bottom: govuk-spacing(1); - padding-top: govuk-spacing(1); - padding-bottom: govuk-spacing(1); - } - - .app-subnav__section-item--current { - $_current-indicator-width: 4px; - margin-left: -(govuk-spacing(2) + $_current-indicator-width); - padding-left: govuk-spacing(2); - border-left: $_current-indicator-width solid govuk-colour("blue"); - background-color: govuk-colour("white"); - } - - .app-subnav__section-item--current .app-subnav__link { - font-weight: bold; - } - - .app-subnav__section--nested { - margin-top: govuk-spacing(2); - margin-bottom: 0; - padding-left: govuk-spacing(4); - } - - .app-subnav__section--nested .app-subnav__section-item:before { - content: "—"; - margin-left: -(govuk-spacing(4)); - color: govuk-colour("dark-grey"); - } - - .app-subnav__section--nested .app-subnav__link { - padding-left: 0; - font-weight: normal; - } - - .app-subnav__theme { - margin: 0; - padding: govuk-spacing(2) govuk-spacing(3) govuk-spacing(2) 0; - color: govuk-colour("dark-grey"); - @include govuk-font(19); - } +.app-subnav { + // Since the back to top link is outside the flow of the document we need to create a space for it. + // This number is magic and was determined by manually judging the visual spacing. + margin-bottom: 100px; + padding: govuk-spacing(6) govuk-spacing(3) 0 0; + @include govuk-font(16); +} + +.app-subnav__section { + margin: 0 0 govuk-spacing(4); + padding: 0; + list-style-type: none; +} + +.app-subnav__link { + padding: 2px 0; +} + +.app-subnav__section-item { + margin-bottom: govuk-spacing(1); + padding-top: govuk-spacing(1); + padding-bottom: govuk-spacing(1); +} + +.app-subnav__section-item--current { + $_current-indicator-width: 4px; + margin-left: -(govuk-spacing(2) + $_current-indicator-width); + padding-left: govuk-spacing(2); + border-left: $_current-indicator-width solid govuk-colour("blue"); + background-color: govuk-colour("white"); +} + +.app-subnav__section-item--current .app-subnav__link { + font-weight: bold; +} + +.app-subnav__section--nested { + margin-top: govuk-spacing(2); + margin-bottom: 0; + padding-left: govuk-spacing(4); +} + +.app-subnav__section--nested .app-subnav__section-item:before { + content: "—"; + margin-left: -(govuk-spacing(4)); + color: govuk-colour("dark-grey"); +} + +.app-subnav__section--nested .app-subnav__link { + padding-left: 0; + font-weight: normal; +} + +.app-subnav__theme { + margin: 0; + padding: govuk-spacing(2) govuk-spacing(3) govuk-spacing(2) 0; + color: govuk-colour("dark-grey"); + @include govuk-font(19); } diff --git a/src/stylesheets/main.scss b/src/stylesheets/main.scss index c3246cf6db..f50f511bd8 100644 --- a/src/stylesheets/main.scss +++ b/src/stylesheets/main.scss @@ -11,6 +11,7 @@ $app-code-color: #d13118; // App-specific components @import "components/back-to-top"; +@import "components/category-nav"; @import "components/contact-panel"; @import "components/cookies-page"; @import "components/example"; @@ -22,9 +23,9 @@ $app-code-color: #d13118; @import "components/navigation"; @import "components/options"; @import "components/page-navigation"; -@import "components/pane"; @import "components/phase-banner"; @import "components/site-search"; +@import "components/split-pane"; @import "components/subnav"; @import "components/tabs"; @import "components/table"; @@ -267,16 +268,6 @@ pre { @include govuk-responsive-margin(4, "bottom"); } -.no-js { - // Adjustments in app-pane layout as it has toc below - .app-pane__content .app-content { - - @include govuk-media-query($until: tablet) { - padding-bottom: 10px; - } - } -} - // Add styling for inline code li code, td code, diff --git a/views/layouts/_generic.njk b/views/layouts/_generic.njk index 675cdc889c..178831b220 100644 --- a/views/layouts/_generic.njk +++ b/views/layouts/_generic.njk @@ -45,14 +45,12 @@ {% block header %}{% endblock %} {% block main %} -