Page MenuHomePhabricator

ToC: Allow the ToC to bold the correct section and subsection of the Table of Contents
Closed, ResolvedPublic5 Estimated Story Points

Description

User Story

As a reader, I want to be able to know which section I am on at all times, so that I have better context of what I am reading

Design spec

Prototype of final version

https://di-toc-phase2.web.app/Hokusai

States

no highlighted sectiontop-level section highlightedsubsection highlighted
Screen Shot 2022-01-11 at 12.14.34 PM.png (1×500 px, 99 KB)
Screen Shot 2022-01-11 at 12.15.39 PM.png (1×500 px, 99 KB)
Screen Shot 2022-01-11 at 12.15.22 PM.png (1×500 px, 99 KB)

Active section definition:

  • When a top-level section is highlighted, only that link should be highlighted
  • When a subsection is highlighted, that link along with it's corresponding top-level link should be highlighted.
  • Only one section (top-level or top-level + subsection) should be highlighted at any given time.

UI Behaviour

On Scroll
While scrolling the page, the ToC will:

  • "Stick" to the top of the page when scrolling down the page.
  • "activate" the link that corresponds to the current section.

On click
When clicking a link in the ToC:

  • The page will jump to the corresponding heading
  • "activate" the link that corresponds to the current section.

The current "section" problem

The main challenge in highlighting the "current section" of an article is that our content HTML does not contain actual sections, instead it's a flat series of paragraphs and headings (as opposed to parsoid or the mobile formatter, which have sections).

When implementing the user-facing prototype, several approaches to this problem were considered, however, leaning heavily on intersection observer was problematic because as explained in this stackOverflow question, intersection observer is not optimized for "high velocity" contexts (i.e fast scrolling), and therefore, is prone to missing section titles when they scroll by quickly.

The most reliable solution turns out to be looping through each heading and returning the last heading that is at or above the top of the page as the current section.

const headings = document.getElementById( 'bodyContent' ).querySelectorAll( 'h1,h2,h3,h4,h5,h6' );
[ ...headings ] // Convert to array.
    .reverse() // Reverse because find gives us the first match, we want the last one.
    .find( h => h.getBoundingClientRect().top <= 0 ); // If the heading is at or above the top of the page, then that's our current section.

Initially, this check was run during a scroll event, however, it's proven to be equally effective when running as an intersection observer callback with no rootMargin (which seems to increase the probability that the observer will catch the headings).

const headings = [ ...document.getElementById( 'bodyContent' ).querySelectorAll( 'h1,h2,h3,h4,h5,h6' ) ].reverse();
function findCurrent() {
   const h = headings.find( h => h.getBoundingClientRect().top <= 0 );
  // console.log( h ? h.innerText : 'no active section, at top of page' );
  return h;
}

let observer = new IntersectionObserver( findCurrent );
headings.forEach( h => observer.observe( h ) );

Linking the active section to headings

Setting the active section in the ToC requires matching the current article section heading with a link somewhere in the ToC.
Section headings should have id attributes that match the href value of the ToC links, however, there could be complications caused by unicode-encoding and mediawiki specific formatting that could produce invalid id attributes or attributes that don't match the`href`.

(We've been here before T238385)

This time around, we could try CSS.escape to guard against these issues (it's not spec compliant, but has decent browser support:

tocElement.querySelector( `a[href="#${CSS.escape( currentSectionHeading.id )}"]` );

Proof of concept (browser extension)
https://github.com/jandre3000/desktop-improvements-extension/blob/993193a2e56e5f5081a230fa5ffbfb2743b183de/app/content/prototypes/tableOfContents/toc.js#L275

Acceptance criteria

  • The section that a user currently has open (defined as having scrolled past the heading section for that section but before the heading section for the following section) should appear in bold
  • If a page has subsections, the subsection name and the section name should appear as bold whens scrolled to

QA Steps

Please perform the following steps in Chrome, Edge, Firefox, and Safari to ensure browser compatibility.

When user scrolls through sections

  1. Login and visit https://en.wikipedia.beta.wmflabs.org/wiki/Cat?tableofcontents=1
  2. As you are scrolling past the top of headings (h1, h2, h3, h4, h5, h6) in the content, verify that the relevant section is bolded in the table of contents. Per the acceptance criteria, if the section is a subsection, the parent section should also be bolded in the Table of contents. Please test different scroll speeds while doing this (e.g. slow scrolling and fast scrolling) and ensure nothing is obviously broken.

When user clicks on a top level section in the TOC

  1. Login and visit https://en.wikipedia.beta.wmflabs.org/wiki/Dog?tableofcontents=1
  2. Click on "External Links" in the Table of contents.
  3. Verify that "External Links" in the Table of contents is bolded

When user clicks on a child section in the TOC

  1. Login and visit https://en.wikipedia.beta.wmflabs.org/wiki/Dog?tableofcontents=1
  2. Click on "Coat" in the Table of contents.
  3. Verify that "Coat" in the Table of contents is bolded (child section ) and the top level section, "Biology" is bolded

QA Results - Beta

ACStatusDetails
1T297614#7687656
2T297614#7687656
3T297614#7687656

QA Results - Prod

ACStatusDetails
1T297614#7741543
2T297614#7741543
3T297614#7741543

Event Timeline

ovasileva removed ovasileva as the assignee of this task.
ovasileva triaged this task as Medium priority.
ovasileva raised the priority of this task from Medium to High.Jan 11 2022, 6:33 PM

Change 756675 had a related patch set uploaded (by Nray; author: Nray):

[mediawiki/skins/Vector@master] Add scroll observer to sidebar Table of Contents

https://gerrit.wikimedia.org/r/756675

Change 756716 had a related patch set uploaded (by Nray; author: Nray):

[mediawiki/skins/Vector@master] Update typescript to latest (v4.5.5)

https://gerrit.wikimedia.org/r/756716

I still need to provide more documentation for the TOC patch, but that doesn't need to stop code review, so I'm moving this into that column :)

nray removed nray as the assignee of this task.Jan 25 2022, 12:31 AM
nray added a subscriber: nray.

Change 756716 merged by jenkins-bot:

[mediawiki/skins/Vector@master] Update typescript to latest (v4.5.5)

https://gerrit.wikimedia.org/r/756716

nray removed nray as the assignee of this task.Jan 26 2022, 12:07 AM
nray assigned this task to Jdrewniak.

Change 756675 merged by jenkins-bot:

[mediawiki/skins/Vector@master] Add sectionObserver and tableOfContents component JS to respond to intersection changes

https://gerrit.wikimedia.org/r/756675

nray claimed this task.
nray moved this task from Code Review to QA on the Readers-Web-Backlog (Kanbanana-FY-2021-22) board.
nray added a subscriber: Edtadros.
nray updated the task description. (Show Details)

T300210 and T299065 will need to be merged before this can be qa'd as it will bring subsections (not only top level sections) back to the beta TOC

This is ready for QA now

Test Result - Beta

Status:
Environment: beta
OS: macOS Monterey
Browser: Chrome
Device: MBP
Emulated Device:NA

Test Artifact(s):

QA Steps

Please perform the following steps in Chrome, Edge, Firefox, and Safari to ensure browser compatibility.

✅ AC1: When user scrolls through sections
  1. Login and visit https://en.wikipedia.beta.wmflabs.org/wiki/Cat?tableofcontents=1
  2. As you are scrolling past the top of headings (h1, h2, h3, h4, h5, h6) in the content, verify that the relevant section is bolded in the table of contents. Per the acceptance criteria, if the section is a subsection, the parent section should also be bolded in the Table of contents. Please test different scroll speeds while doing this (e.g. slow scrolling and fast scrolling) and ensure nothing is obviously broken.
ChromeEdgeFirefoxSafari
Screen Recording 2022-02-06 at 6.38.53 PM.mov.gif (868×626 px, 3 MB)
Screen Recording 2022-02-06 at 6.59.25 PM.mov.gif (868×626 px, 3 MB)
Screen Recording 2022-02-06 at 6.58.27 PM.mov.gif (868×626 px, 3 MB)
Screen Recording 2022-02-06 at 7.02.07 PM.mov.gif (894×626 px, 3 MB)
❌ AC2: When user clicks on a top level section in the TOC

This doesn't work with Firefox. Additionally, for some reason "Hearing" is bolded in all browsers regardless of where the page is scrolled to.

  1. Login and visit https://en.wikipedia.beta.wmflabs.org/wiki/Dog?tableofcontents=1
  2. Click on "External Links" in the Table of contents.
  3. Verify that "External Links" in the Table of contents is bolded
ChromeEdgeFirefoxSafari
Screen Recording 2022-02-06 at 7.03.33 PM.mov.gif (894×626 px, 257 KB)
Screen Recording 2022-02-06 at 7.03.57 PM.mov.gif (894×626 px, 285 KB)
Screen Recording 2022-02-06 at 7.04.23 PM.mov.gif (894×626 px, 1 MB)
Screen Recording 2022-02-06 at 7.06.40 PM.mov.gif (894×626 px, 1 MB)
Screen Shot 2022-02-06 at 7.06.04 PM.png (1×848 px, 278 KB)
Screen Recording 2022-02-06 at 7.11.08 PM.mov.gif (894×626 px, 240 KB)
✅ AC3: When user clicks on a child section in the TOC
  1. Login and visit https://en.wikipedia.beta.wmflabs.org/wiki/Dog?tableofcontents=1
  2. Click on "Coat" in the Table of contents.
  3. Verify that "Coat" in the Table of contents is bolded (child section ) and the top level section, "Biology" is bolded
ChromeEdgeFirefoxSafari
Screen Recording 2022-02-06 at 7.13.14 PM.mov.gif (894×626 px, 289 KB)
Screen Recording 2022-02-06 at 7.13.58 PM.mov.gif (894×626 px, 243 KB)
Screen Recording 2022-02-06 at 7.14.40 PM.mov.gif (894×626 px, 204 KB)
Screen Recording 2022-02-06 at 7.15.32 PM.mov.gif (894×626 px, 222 KB)

Thank you @Edtadros! I can replicate the firefox bug and have made a patch that should address that.

The "Hearing" section always being bolded is a separate issue unrelated to this ticket. It's bolded because the wikitext bolds the section and the TOC is reflecting that.

Change 760663 merged by jenkins-bot:

[mediawiki/skins/Vector@master] Fix TOC section activation on link click bug

https://gerrit.wikimedia.org/r/760663

@Edtadros just fyi, the "When user clicks on a top level section in the TOC" is ready to be retested now. The patch (that hopefully fixes the problem) has been merged and is on beta

@Edtadros just fyi, the "When user clicks on a top level section in the TOC" is ready to be retested now. The patch (that hopefully fixes the problem) has been merged and is on beta

Can confirm this works in production. Going ahead and signing off

Test Result - Prod

Status:
Environment: enwiki
OS: macOS Monterey
Browser: Chrome
Device: MBP
Emulated Device:NA

Test Artifact(s):

QA Steps

Please perform the following steps in Chrome, Edge, Firefox, and Safari to ensure browser compatibility.

✅ AC1: When user scrolls through sections
  1. Login and visit https://en.wikipedia.org/wiki/Cat?tableofcontents=1
  2. As you are scrolling past the top of headings (h1, h2, h3, h4, h5, h6) in the content, verify that the relevant section is bolded in the table of contents. Per the acceptance criteria, if the section is a subsection, the parent section should also be bolded in the Table of contents. Please test different scroll speeds while doing this (e.g. slow scrolling and fast scrolling) and ensure nothing is obviously broken.
ChromeEdgeFirefoxSafari
Screen Recording 2022-02-28 at 6.17.27 AM.mov.gif (1×868 px, 3 MB)
Screen Recording 2022-02-28 at 6.20.05 AM.mov.gif (1×868 px, 3 MB)
Screen Recording 2022-02-28 at 6.23.39 AM.mov.gif (1×868 px, 2 MB)
Screen Recording 2022-02-28 at 6.40.29 AM.mov.gif (968×670 px, 1 MB)
❌ AC2: When user clicks on a top level section in the TOC
  1. Login and visit https://en.wikipedia.beta.wmflabs.org/wiki/Dog?tableofcontents=1
  2. Click on "External Links" in the Table of contents.
  3. Verify that "External Links" in the Table of contents is bolded
ChromeEdgeFirefoxSafari
Screen Recording 2022-02-28 at 6.15.53 AM.mov.gif (1×868 px, 550 KB)
Screen Recording 2022-02-28 at 6.20.37 AM.mov.gif (1×868 px, 519 KB)
❌ It looks like at some widths this doesn't work. At 975px it bounces back to Biology.
Screen Recording 2022-02-28 at 6.23.59 AM.mov.gif (1×868 px, 638 KB)
Screen Recording 2022-02-28 at 6.24.36 AM.mov.gif (1×868 px, 586 KB)
Screen Recording 2022-02-28 at 6.25.40 AM.mov.gif (544×1 px, 348 KB)
Screen Recording 2022-02-28 at 6.40.53 AM.mov.gif (968×670 px, 242 KB)
✅ AC3: When user clicks on a child section in the TOC
  1. Login and visit https://en.wikipedia.beta.wmflabs.org/wiki/Dog?tableofcontents=1
  2. Click on "Coat" in the Table of contents.
  3. Verify that "Coat" in the Table of contents is bolded (child section ) and the top level section, "Biology" is bolded
ChromeEdgeFirefoxSafari
Screen Recording 2022-02-28 at 6.16.29 AM.mov.gif (1×868 px, 512 KB)
Screen Recording 2022-02-28 at 6.20.53 AM.mov.gif (1×868 px, 577 KB)
Screen Recording 2022-02-28 at 6.35.34 AM.mov.gif (968×670 px, 385 KB)
Screen Recording 2022-02-28 at 6.41.05 AM.mov.gif (968×670 px, 312 KB)

@Edtadros Thank you for reporting that. What Firefox version are you using? I'm having trouble replicating this bug with my version (97.0.1)