From f8d81e377c0ee10b59155565e609b1a74113ed1b Mon Sep 17 00:00:00 2001 From: Alija Sabic Date: Mon, 6 Mar 2023 11:56:50 +0100 Subject: [PATCH 1/7] Provide accessible markdown-it-anchor configuration --- src/node/markdown/markdown.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/node/markdown/markdown.ts b/src/node/markdown/markdown.ts index 54b8edc1764e..53a4e85dbbe4 100644 --- a/src/node/markdown/markdown.ts +++ b/src/node/markdown/markdown.ts @@ -99,7 +99,11 @@ export const createMarkdownRenderer = async ( // mdit-vue plugins md.use(anchorPlugin, { slugify, - permalink: anchorPlugin.permalink.ariaHidden({}), + permalink: anchorPlugin.permalink.linkAfterHeader({ + style: 'aria-label', + assistiveText: (title) => `Permalink to "${title}"`, + wrapper: ['
', '
'] + }), ...options.anchor } as anchorPlugin.AnchorOptions).use(frontmatterPlugin, { ...options.frontmatter From 7b941cd1b04ea32f86e42d0035f0090ddf824018 Mon Sep 17 00:00:00 2001 From: Alija Sabic Date: Mon, 6 Mar 2023 11:57:06 +0100 Subject: [PATCH 2/7] Update theme-default style for accessible header-anchors --- .../styles/components/vp-doc.css | 56 ++++++++++++------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/src/client/theme-default/styles/components/vp-doc.css b/src/client/theme-default/styles/components/vp-doc.css index 11d8bb00fbe2..2b42bbb79419 100644 --- a/src/client/theme-default/styles/components/vp-doc.css +++ b/src/client/theme-default/styles/components/vp-doc.css @@ -2,12 +2,7 @@ * Headings * -------------------------------------------------------------------------- */ -.vp-doc h1, -.vp-doc h2, -.vp-doc h3, -.vp-doc h4, -.vp-doc h5, -.vp-doc h6 { +.vp-doc .header-wrapper { position: relative; font-weight: 600; outline: none; @@ -36,7 +31,8 @@ } .vp-doc .header-anchor { - float: left; + position: absolute; + top: 0; margin-left: -0.87em; padding-right: 0.23em; font-weight: 500; @@ -45,18 +41,40 @@ transition: color 0.25s, opacity 0.25s; } -.vp-doc h1:hover .header-anchor, -.vp-doc h1 .header-anchor:focus, -.vp-doc h2:hover .header-anchor, -.vp-doc h2 .header-anchor:focus, -.vp-doc h3:hover .header-anchor, -.vp-doc h3 .header-anchor:focus, -.vp-doc h4:hover .header-anchor, -.vp-doc h4 .header-anchor:focus, -.vp-doc h5:hover .header-anchor, -.vp-doc h5 .header-anchor:focus, -.vp-doc h6:hover .header-anchor, -.vp-doc h6 .header-anchor:focus { +.vp-doc h1 + .header-anchor { + line-height: 40px; + font-size: 32px; +} + +.vp-doc h2 + .header-anchor { + padding-top: 25px; + line-height: 32px; + font-size: 24px; +} + +.vp-doc h3 + .header-anchor { + line-height: 28px; + font-size: 20px; +} + +.vp-doc h1:hover + .header-anchor, +.vp-doc h1 + .header-anchor:focus, +.vp-doc h1 + .header-anchor:hover, +.vp-doc h2:hover + .header-anchor, +.vp-doc h2 + .header-anchor:focus, +.vp-doc h2 + .header-anchor:hover, +.vp-doc h3:hover + .header-anchor, +.vp-doc h3 + .header-anchor:focus, +.vp-doc h3 + .header-anchor:hover, +.vp-doc h4:hover + .header-anchor, +.vp-doc h4 + .header-anchor:focus, +.vp-doc h4 + .header-anchor:hover, +.vp-doc h5:hover + .header-anchor, +.vp-doc h5 + .header-anchor:focus, +.vp-doc h5 + .header-anchor:hover, +.vp-doc h6:hover + .header-anchor, +.vp-doc h6 + .header-anchor:focus, +.vp-doc h6 + .header-anchor:hover { opacity: 1; } From 72b8db4ae21782777370b35900055efd09c4ade7 Mon Sep 17 00:00:00 2001 From: Alija Sabic Date: Tue, 14 Mar 2023 00:01:21 +0100 Subject: [PATCH 3/7] Revert "Update theme-default style for accessible header-anchors" This reverts commit 7b941cd1b04ea32f86e42d0035f0090ddf824018. --- .../styles/components/vp-doc.css | 56 +++++++------------ 1 file changed, 19 insertions(+), 37 deletions(-) diff --git a/src/client/theme-default/styles/components/vp-doc.css b/src/client/theme-default/styles/components/vp-doc.css index 2b42bbb79419..11d8bb00fbe2 100644 --- a/src/client/theme-default/styles/components/vp-doc.css +++ b/src/client/theme-default/styles/components/vp-doc.css @@ -2,7 +2,12 @@ * Headings * -------------------------------------------------------------------------- */ -.vp-doc .header-wrapper { +.vp-doc h1, +.vp-doc h2, +.vp-doc h3, +.vp-doc h4, +.vp-doc h5, +.vp-doc h6 { position: relative; font-weight: 600; outline: none; @@ -31,8 +36,7 @@ } .vp-doc .header-anchor { - position: absolute; - top: 0; + float: left; margin-left: -0.87em; padding-right: 0.23em; font-weight: 500; @@ -41,40 +45,18 @@ transition: color 0.25s, opacity 0.25s; } -.vp-doc h1 + .header-anchor { - line-height: 40px; - font-size: 32px; -} - -.vp-doc h2 + .header-anchor { - padding-top: 25px; - line-height: 32px; - font-size: 24px; -} - -.vp-doc h3 + .header-anchor { - line-height: 28px; - font-size: 20px; -} - -.vp-doc h1:hover + .header-anchor, -.vp-doc h1 + .header-anchor:focus, -.vp-doc h1 + .header-anchor:hover, -.vp-doc h2:hover + .header-anchor, -.vp-doc h2 + .header-anchor:focus, -.vp-doc h2 + .header-anchor:hover, -.vp-doc h3:hover + .header-anchor, -.vp-doc h3 + .header-anchor:focus, -.vp-doc h3 + .header-anchor:hover, -.vp-doc h4:hover + .header-anchor, -.vp-doc h4 + .header-anchor:focus, -.vp-doc h4 + .header-anchor:hover, -.vp-doc h5:hover + .header-anchor, -.vp-doc h5 + .header-anchor:focus, -.vp-doc h5 + .header-anchor:hover, -.vp-doc h6:hover + .header-anchor, -.vp-doc h6 + .header-anchor:focus, -.vp-doc h6 + .header-anchor:hover { +.vp-doc h1:hover .header-anchor, +.vp-doc h1 .header-anchor:focus, +.vp-doc h2:hover .header-anchor, +.vp-doc h2 .header-anchor:focus, +.vp-doc h3:hover .header-anchor, +.vp-doc h3 .header-anchor:focus, +.vp-doc h4:hover .header-anchor, +.vp-doc h4 .header-anchor:focus, +.vp-doc h5:hover .header-anchor, +.vp-doc h5 .header-anchor:focus, +.vp-doc h6:hover .header-anchor, +.vp-doc h6 .header-anchor:focus { opacity: 1; } From d38dcaf0d9cd11913950127c8f70d79fb5baf434 Mon Sep 17 00:00:00 2001 From: Alija Sabic Date: Tue, 14 Mar 2023 00:01:32 +0100 Subject: [PATCH 4/7] Revert "Provide accessible markdown-it-anchor configuration" This reverts commit f8d81e377c0ee10b59155565e609b1a74113ed1b. --- src/node/markdown/markdown.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/node/markdown/markdown.ts b/src/node/markdown/markdown.ts index 53a4e85dbbe4..54b8edc1764e 100644 --- a/src/node/markdown/markdown.ts +++ b/src/node/markdown/markdown.ts @@ -99,11 +99,7 @@ export const createMarkdownRenderer = async ( // mdit-vue plugins md.use(anchorPlugin, { slugify, - permalink: anchorPlugin.permalink.linkAfterHeader({ - style: 'aria-label', - assistiveText: (title) => `Permalink to "${title}"`, - wrapper: ['
', '
'] - }), + permalink: anchorPlugin.permalink.ariaHidden({}), ...options.anchor } as anchorPlugin.AnchorOptions).use(frontmatterPlugin, { ...options.frontmatter From 2f49c28fe12c763ef73c92ab40ecab686f7a0930 Mon Sep 17 00:00:00 2001 From: Alija Sabic Date: Tue, 14 Mar 2023 01:53:22 +0100 Subject: [PATCH 5/7] Provide accessible markdown-it-anchor configuration using ZeroWidthSpace (HTML Entity) and custom renderAttrs --- src/node/markdown/markdown.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/node/markdown/markdown.ts b/src/node/markdown/markdown.ts index 54b8edc1764e..375841401cba 100644 --- a/src/node/markdown/markdown.ts +++ b/src/node/markdown/markdown.ts @@ -99,7 +99,22 @@ export const createMarkdownRenderer = async ( // mdit-vue plugins md.use(anchorPlugin, { slugify, - permalink: anchorPlugin.permalink.ariaHidden({}), + permalink: anchorPlugin.permalink.linkInsideHeader({ + symbol: '​', + renderAttrs: (slug, state) => { + // Find `heading_open` with the id identical to slug + const idx = state.tokens.findIndex((token) => { + const attrs = token.attrs + const id = attrs?.find((attr) => attr[0] === 'id') + return id && slug === id[1] + }) + // Get the actual heading content + const title = state.tokens[idx + 1].content + return { + 'aria-label': `Permalink to "${title}"` + } + } + }), ...options.anchor } as anchorPlugin.AnchorOptions).use(frontmatterPlugin, { ...options.frontmatter From e8de8c27a2ce35d4fe1984e098ea22f2d604293f Mon Sep 17 00:00:00 2001 From: Alija Sabic Date: Tue, 14 Mar 2023 01:59:37 +0100 Subject: [PATCH 6/7] Add symbol for header anchor as CSS variable and rule using :before --- src/client/theme-default/styles/components/vp-doc.css | 4 ++++ src/client/theme-default/styles/vars.css | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/client/theme-default/styles/components/vp-doc.css b/src/client/theme-default/styles/components/vp-doc.css index 11d8bb00fbe2..5c8349b7010b 100644 --- a/src/client/theme-default/styles/components/vp-doc.css +++ b/src/client/theme-default/styles/components/vp-doc.css @@ -45,6 +45,10 @@ transition: color 0.25s, opacity 0.25s; } +.vp-doc .header-anchor:before { + content: var(--vp-header-anchor-symbol); +} + .vp-doc h1:hover .header-anchor, .vp-doc h1 .header-anchor:focus, .vp-doc h2:hover .header-anchor, diff --git a/src/client/theme-default/styles/vars.css b/src/client/theme-default/styles/vars.css index 84ea1af652a6..29a1c527c22d 100644 --- a/src/client/theme-default/styles/vars.css +++ b/src/client/theme-default/styles/vars.css @@ -193,6 +193,14 @@ --vp-layout-max-width: 1440px; } +/** + * Component: Header Anchor + * -------------------------------------------------------------------------- */ + +:root { + --vp-header-anchor-symbol: '#'; +} + /** * Component: Code * -------------------------------------------------------------------------- */ From dd30aa6da4ec0092883fe54ee163cf8f7c654f9b Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 14 Mar 2023 14:19:45 +0800 Subject: [PATCH 7/7] chore: fix tests --- __tests__/e2e/home.test.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/__tests__/e2e/home.test.ts b/__tests__/e2e/home.test.ts index 9b02c1a239c3..76868361f671 100644 --- a/__tests__/e2e/home.test.ts +++ b/__tests__/e2e/home.test.ts @@ -14,12 +14,12 @@ describe('render correct content', async () => { pLocator.allTextContents() ]) - expect(h1Contents).toEqual(['Lorem Ipsum #']) - expect(h2Contents).toEqual([ - 'What is Lorem Ipsum? #', - 'Where does it come from? #', - 'Why do we use it? #', - 'Where can I get some? #' + expect(h1Contents).toEqual(['Lorem Ipsum \u200b']) + expect(h2Contents.map((s) => s.trim())).toEqual([ + 'What is Lorem Ipsum? \u200b', + 'Where does it come from? \u200b', + 'Why do we use it? \u200b', + 'Where can I get some? \u200b' ]) expect(pContents).toMatchSnapshot() })