Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- run: npm ci
- run: npm run build
- run: npm run plugin-zip
- uses: softprops/action-gh-release@v2
- uses: softprops/action-gh-release@v3
with:
name: TOCflow ${{ github.ref_name }}
files: tocflow.zip
Expand Down
Binary file added .wordpress-org/screenshots/screenshot-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .wordpress-org/screenshots/screenshot-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .wordpress-org/screenshots/screenshot-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .wordpress-org/screenshots/screenshot-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .wordpress-org/screenshots/screenshot-5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
76 changes: 76 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,82 @@
All notable changes to TOCflow are documented here.
This project adheres to [Semantic Versioning](https://semver.org/).

## [1.3.0] - 2026-09-08

### Added
- **Settings → Design & Appearance**: global background colour, text colour, link colour, font size, font weight, line height, border (width / style / colour / radius), and padding. Applied as CSS custom properties (`--tocflow-bg`, `--tocflow-color`, `--tocflow-link-color`, `--tocflow-font-size`, etc.) so per-block editor overrides still cascade correctly.
- **Settings → Reading Guide & Study Tools**: global defaults for hover preview, guide mode, section previews, density bars, per-section read time, progress fade, emoji reactions, academic citations, and citation format.
- **Settings → Study Tools & Export**: global defaults for reading progress bar, resume bookmark, reader note pads, and export toolbar.
- **Settings → Accessibility**: focus ring style picker — Default (underline), Bold (3 px outline, WCAG 2.1 AA), or High-contrast (yellow background + black outline, WCAG 2.1 AAA). Rendered as `data-tocflow-focus` attribute on the `<nav>`.
- `admin/js/admin.js`: vanilla JS that syncs hex text inputs with companion `<input type=color>` swatches and toggles guide-mode sub-options when the guide-mode checkbox is toggled.
- `admin/css/admin.css`: styles for color-picker widget, section badge chips, and indented guide sub-options panel.

### Changed
- CSS custom properties now drive the root border, padding, background, font-size, and link colour so global design settings layer cleanly beneath block-level inline styles from Gutenberg's block supports.
- `is-style-minimal` preset explicitly resets design custom props to ensure the preset always wins over any global colour/padding setting.
- `block_attributes()` now passes Reading Guide, Study Tools, and Export defaults to auto-inserted blocks.

## [1.2.2] - 2026-09-08

### Fixed
- `TOCFLOW_VERSION` constant was `'1.2.0'` while the plugin header read `1.2.1` / `1.2.2`; in-admin version badge now matches.
- `Tested up to` updated from `6.7` to `7.1` (WordPress 7.1 "Mary Lou" released 2026-08-19).
- Removed third-party trademark tag `elementor`; replaced with descriptive `study tools`.
- PHP WPCS: fixed 3-tab indentation on Study-tool shortcode attributes (should be 4-tab like surrounding code).
- Admin view: fixed indentation on shortcode-docs `<p>` tags in `admin/views/settings.php`.

## [1.2.1] - 2026-09-08

### Changed
- Debounced bookmark `localStorage` writes to 500 ms (previously wrote on every `IntersectionObserver` callback during scroll — could fire once per heading during fast scrolling).

### Documentation
- `CHANGELOG.md`: completed v1.1.0 entry with hover preview, export/print toolbar, accessibility, and full page-builder compatibility details.
- `README.md`: added "What's new" feature tables for v1.1.0 and v1.2.0 for WordPress.org reviewers; added "Performance" section documenting asset-loading gates, `IntersectionObserver` use, no remote calls, debounced storage writes, and PHP static caches.

## [1.2.0] - 2026-09-08

### Added
- **Reader note pads** — a 📝 button per section lets readers jot personal notes stored privately in localStorage. No account, no server. Enable with `rnotes="1"` in the shortcode or the "Reader note pads" toggle in the block sidebar.
- **Reading progress bar** — a thin animated bar shows 0–100% of the document read (headings scrolled past via IntersectionObserver). Enable with `rprogress="1"`.
- **Resume reading bookmark** — automatically bookmarks the last-read heading in localStorage and shows a "↩ Resume" button on return visits. Enable with `bookmark="1"`.
- **Section Planner** — the "Section Notes" sidebar panel is now "Section Planner" with per-heading writing status (✏️ Draft / 🔄 In progress / ✅ Done) tracked in the editor canvas and a reader-facing teaser note.
- **Total read-time badge** — when Reading Guide + read-time are active, the TOC header shows the aggregated total read time for the entire post.
- New shortcode attributes: `rprogress`, `bookmark`, `rnotes`.
- New block attributes: `showReaderNotes`, `showReadingProgress`, `showBookmark`, `sectionStatus`.

## [1.1.0] - 2026-09-08

### Added
- **Reading Guide mode** — opt-in block feature that enriches the TOC into a full reading companion:
- **Section content previews** — opening ~20 words of each section, extracted server-side from parsed block content via `TOCflow_Headings::get_sections()` (no JS fetch, no external API).
- **Content density bars** — thin bar showing each section's word count relative to the longest section, computed at render time.
- **Per-section read-time estimates** — `~N min` badge based on word count ÷ 200 wpm.
- **Reading progress** — `IntersectionObserver` fades each TOC item as the reader scrolls past its heading (no scroll event handlers; passive main thread).
- **Author section notes** — block attribute `sectionNotes` (object keyed by heading slug). Writers type a per-section teaser or hook in the "Section Notes" sidebar panel; readers reveal it with a ✍ toggle button.
- **Emoji reactions** — readers react per section (💡 ⭐ 🤔 ✅); state stored in `localStorage`, zero server calls, zero accounts.
- **Per-section academic citations** — § button copies a formatted citation (APA / MLA / Chicago / Harvard / plain link) built entirely from WordPress post meta. No external API.
- **Hover section preview** — floating tooltip on TOC link hover/focus shows the section's opening sentence. Viewport-aware positioning (left or right). `aria-describedby` links the tooltip to the anchor for screen readers. `previewOnHover` attribute; works without full Reading Guide mode.
- **Export / print toolbar** — `showExport` attribute adds Copy (.md), Download (.md), Download (.doc), and Print buttons below the outline using only the Blob API and `navigator.clipboard`; zero server round-trips. Screen reader live region announces success.
- **Accessibility** — `aria-live="polite"` region for clipboard and export announcements; `focus-visible` outlines on all interactive elements; all buttons labeled; note and export toggles use `aria-expanded` / `aria-controls` / `hidden`.
- **Page-builder compatibility** — `TOCflow_Headings::get_all()` now falls back to builder-specific parsers when `parse_blocks()` finds no headings:
- **Elementor** — walks `_elementor_data` widget JSON to find heading widgets and Text Editor blocks.
- **Bricks Builder** — reads `_bricks_page_content_2` element JSON.
- **Divi, WPBakery, Oxygen, Beaver Builder, Breakdance, Classic Editor** — generic `<h*>` regex scan of `post_content`.
- `inject_builder_heading_ids()` runs as `the_content` filter at priority 999 so headings inside builder output receive matching `id` attributes.
- `should_inject_ids()` now scans builder meta for `[tocflow]` shortcodes so assets load correctly even when the shortcode lives inside a builder widget.
- `get_sections()` extended with `builder_raw_html()` and `flatten_html_to_sequence()` fallbacks so Reading Guide previews and read-time estimates work on builder-built pages.
- New block attributes: `guideMode`, `showPreviews`, `showDensity`, `showReadTime`, `trackProgress`, `showReactions`, `showCitations`, `citationStyle`, `sectionNotes`, `previewOnHover`, `showExport`.
- New PHP methods: `TOCflow_Headings::flatten_content()`, `get_sections()`, `citation_meta()`, `get_all_from_html()`, `get_all_from_elementor()`, `collect_elementor_headings()`, `get_all_from_bricks()`, `inject_ids_in_html()`, `builder_raw_html()`, `flatten_html_to_sequence()`, `builder_has_tocflow()`.
- New editor panels: "Reading Guide", "Section Notes", and "Behavior" enhancements in the block sidebar.
- Print CSS: expanded collapsed TOC, hidden all interactive controls, author notes shown expanded.

### Changed
- `render_list()` accepts an optional `$guide` array; fully backward-compatible.
- `render_nav()` merges section data and embeds citation meta on the `<nav>` when guide mode is active.
- `TOCflow_Plugin::inject_builder_heading_ids()` added as `the_content` hook (priority 999).
- `enqueue_front_assets()` broadened to cover page-builder pages via `should_inject_ids()`.

## [1.0.2] - 2026-09-01

WordPress.org Plugin Check cleanup for the directory review (v1.0.1 is Awaiting Review). Behavior is unchanged.
Expand Down
80 changes: 76 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,85 @@

---

## What's new — v1.2.2 (Sep 2026)

> For WordPress.org reviewers: the sections below describe every change since v1.0.2.

### v1.2.2 — WordPress.org compliance fixes

| Fix | Detail |
|---|---|
| **`TOCFLOW_VERSION` constant** | Was stuck at `1.2.0`; corrected to `1.2.2` — admin version badge now matches the plugin header |
| **`Tested up to`** | Updated from `6.7` → `7.1` (WP 7.1 "Mary Lou" released 2026-08-19) |
| **Tags** | Removed third-party trademark `elementor`; replaced with `study tools` |
| **PHP indentation** | Fixed WPCS 3-tab → 4-tab on shortcode Study-tool attrs and admin settings view |
| **readme.txt entries** | Added `= 1.2.1 =` and `= 1.2.2 =` Changelog + Upgrade Notice entries (stable tag must have matching entries) |
| **GitHub Actions** | Bumped `softprops/action-gh-release` from v2 → v3 (Node 20 → Node 24 runtime) |

### v1.2.1 — Performance patch

| Fix | Detail |
|---|---|
| **Bookmark localStorage debounce** | Debounced resume-bookmark writes from every `IntersectionObserver` callback to every 500 ms — prevents redundant writes during fast scrolling |

### v1.2.0 — Study assistant & writer tools

### v1.2.0 — Study assistant & writer tools

| Feature | How to enable | Where state lives |
|---|---|---|
| **Reading progress bar** (0–100 % of headings read) | "Study Tools" panel → "Reading progress bar", or `rprogress="1"` shortcode | Client only — `IntersectionObserver`, no server |
| **Resume reading bookmark** (↩ Resume button on return) | "Study Tools" → "Resume reading bookmark", or `bookmark="1"` | `localStorage` key `tocflow-bm-{post_id}` |
| **Reader note pads** (📝 per-section personal notes) | "Study Tools" → "Reader note pads", or `rnotes="1"` | `localStorage` key `tocflow-rn-{post_id}-{slug}` |
| **Section Planner** (writing status per heading for authors) | Block sidebar → "Section Planner" panel | `sectionStatus` block attribute — never sent to front end |
| **Total read-time badge** | Automatic when Reading Guide + read-time are both active | Computed server-side from word counts, no extra query |

All three reader tools are **off by default**. They only activate when the author explicitly enables them. No feature writes to the database; no feature makes a network call.

### v1.1.0 — Reading Guide, hover previews, citations, page-builder compatibility

| Feature | Default | Notes |
|---|---|---|
| **Reading Guide mode** (previews, density bars, read time, progress fading) | Off | `guideMode` attribute; server-side word-count extraction |
| **Hover section preview** (floating tooltip on TOC link) | Off | `previewOnHover`; `aria-describedby`; viewport-aware |
| **Emoji reactions** per section (💡 ⭐ 🤔 ✅) | Off | `localStorage` only |
| **Academic citations** (APA, MLA, Chicago, Harvard, plain) | Off | Built from WP post meta; no external API |
| **Export / print toolbar** (Copy .md, Download .md, Download .doc, Print) | Off | Blob API + `navigator.clipboard`; no server |
| **Elementor** heading extraction | Automatic fallback | Parses `_elementor_data` widget JSON |
| **Bricks Builder** heading extraction | Automatic fallback | Parses `_bricks_page_content_2` JSON |
| **Divi, WPBakery, Oxygen, Beaver, Breakdance** heading extraction | Automatic fallback | HTML regex scan of `post_content` |
| **Accessibility** (`aria-live`, `focus-visible`, `aria-expanded`) | Always on | WCAG 2.1 AA compatible |

Full entry-by-entry detail in [`CHANGELOG.md`](CHANGELOG.md).

---

## Performance

TOCflow is built to add **zero measurable overhead** on pages that don't use it, and minimal overhead on pages that do.

| Concern | How TOCflow handles it |
|---|---|
| **Assets on unrelated pages** | JS + CSS only load on singular posts/pages that contain the block, shortcode, or auto-insert target. The `enqueue_front_assets()` check gates all enqueues. |
| **Front-end JavaScript** | `view.js` — 13 KB minified, ~4 KB gzipped. Loaded via `block.json viewScript` (WordPress handles the dependency). No jQuery. No framework. |
| **Front-end CSS** | `style-index.css` — 19 KB minified, ~4 KB gzipped. One file; no render-blocking imports. |
| **Scroll event handlers** | None. All scroll-position features (`initScrollSpy`, `initProgressTracking`, `initReadingProgress`, `initBookmark`) use `IntersectionObserver` — passive, runs off the main thread. The only `scroll` listener (`window.addEventListener('scroll', pick, { passive: true })`) is in the scroll-spy fallback and is marked passive. |
| **localStorage writes** | Reader notes are debounced (400 ms). Bookmark writes are debounced (500 ms). localStorage is never read or written until the author explicitly enables a study tool. |
| **PHP database queries** | `TOCflow_Headings::get_all()` and `get_sections()` cache their results in a static array — at most one `get_post()` call per post per request. No extra `WP_Query` or custom table reads. |
| **Remote calls** | None, ever. No phone-home, no CDN assets, no tracking pixels, no external fonts loaded by the plugin. |
| **`the_content` filters** | Two filters run at priority 12 and 999, both guarded by `is_singular() && in_the_loop() && is_main_query()`. The builder ID-injection filter (999) short-circuits immediately on pure Gutenberg posts. |
| **`prefers-reduced-motion`** | Smooth scroll and CSS transitions respect the OS preference. |

---

## Why TOCflow

- **Zero config** — insert the block; the outline builds itself.
- **Server-rendered** — the list is in the first HTML response (SEO + screen readers).
- **Accurate anchors** — matching `id`s are injected into headings; custom HTML anchors win.
- **Accessible** — a `<nav>` landmark, keyboard-friendly collapse, `aria-current` while you read.
- **Focused** — one block done well, not a block library.
- **Study-ready** — reading progress, personal notes, bookmarks, citations, and export — all without any account or server dependency.
- **Compatible** — Gutenberg, Elementor, Divi, Bricks, Beaver Builder, WPBakery, Oxygen, Breakdance, and every major theme.

### Features

Expand All @@ -43,9 +115,9 @@
- Smooth scroll + offset for sticky headers (`prefers-reduced-motion` respected)
- Collapse/expand, sticky outline, scroll-spy highlight
- Auto-insert (top of content or after the first heading)
- `[tocflow]` shortcode for classic content
- `[tocflow]` shortcode for classic content and page builders
- Skip a heading with the class `no-toc`
- Optional ItemList JSON-LD
- Optional ItemList JSON-LD schema
- Settings + Docs & Support screens in wp-admin

The plugin slug, folder, and text domain are **`tocflow`**. Display name: **TOCflow**. See [`docs/NAMING.md`](docs/NAMING.md).
Expand All @@ -54,7 +126,7 @@ The plugin slug, folder, and text domain are **`tocflow`**. Display name: **TOCf

## Install

Current version: **1.0.2**.
Current version: **1.2.2**.

1. Download `tocflow.zip` from [Releases](https://github.com/matthummel-pa/tocflow/releases).
2. In WordPress: **Plugins → Add New → Upload Plugin**.
Expand Down
135 changes: 135 additions & 0 deletions admin/css/admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,137 @@
border-radius: 4px;
}

.tocflow-compat-card .description {
margin: 4px 0 14px;
}

.tocflow-compat-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 12px 24px;
margin: 10px 0 16px;
}

.tocflow-compat-group {
font-size: 13px;
}

.tocflow-compat-group strong {
display: block;
font-size: 13px;
margin-bottom: 4px;
color: #1c3d2e;
}

.tocflow-compat-group ul {
margin: 0;
padding-left: 16px;
color: #3c5a4a;
}

.tocflow-compat-group li {
margin: 2px 0;
}

.tocflow-badge-new {
display: inline-block;
background: #275c3e;
color: #fff;
font-size: 10px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
padding: 2px 7px;
border-radius: 4px;
margin-left: 6px;
vertical-align: middle;
line-height: 1.5;
}

/* ── Color picker widget ────────────────────────────────────────────────── */

.tocflow-color-field {
display: inline-flex;
align-items: center;
gap: 6px;
}

.tocflow-color-field input[type="text"] {
width: 90px;
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 12px;
}

.tocflow-color-field input[type="color"] {
width: 32px;
height: 30px;
padding: 1px 2px;
border: 1px solid #d8e2db;
border-radius: 4px;
cursor: pointer;
background: none;
}

.tocflow-color-clear {
font-size: 12px;
color: #888;
text-decoration: none;
white-space: nowrap;
}

.tocflow-color-clear:hover {
color: #d63638;
text-decoration: underline;
}

/* ── Section badges ─────────────────────────────────────────────────────── */

.tocflow-section-badge {
display: inline-block;
font-size: 10px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
padding: 2px 7px;
border-radius: 4px;
margin-left: 6px;
vertical-align: middle;
line-height: 1.5;
}

.tocflow-section-badge--guide {
background: #0a5c80;
color: #fff;
}

.tocflow-section-badge--study {
background: #5b4200;
color: #fff;
}

/* ── Guide sub-options indent ───────────────────────────────────────────── */

#tocflow-guide-subopts {
margin-top: 8px;
padding: 12px 16px;
background: #f6faf8;
border-left: 3px solid #2f6f4e;
border-radius: 0 4px 4px 0;
}

#tocflow-guide-subopts .form-table {
margin: 0;
}

#tocflow-guide-subopts .form-table th {
padding: 6px 10px 6px 0;
font-size: 13px;
}

#tocflow-guide-subopts .form-table td {
padding: 6px 0;
}

@media (max-width: 782px) {

.tocflow-admin__grid {
Expand All @@ -110,4 +241,8 @@
flex-direction: column;
align-items: flex-start;
}

.tocflow-compat-grid {
grid-template-columns: 1fr;
}
}
Loading