# Inline Context - Complete Changelog

This file contains the complete changelog for all versions of the Inline Context plugin.
For major version highlights, see README.md and readme.txt.

## Version 2.10.0 - October 20, 2026

Two features, and a full accessibility review of the plugin that found four
defects worth more than either of them.

### Search

* NEW: A reader who searches for a word that only exists inside a note now
  arrives to find that note open, with the word marked. WordPress search has
  always matched note text - it is cached into the post's own content, so no
  server-side work was ever needed - but the reader then landed on an article
  where the word they searched for was nowhere to be seen. This closes that
  gap, on the results page as well as on the article clicked through to, since
  many themes print whole posts in their results.
* The term comes from an explicit `?inline-context-search=`, from the search
  page's own query, or from a same-origin referrer. Cross-origin referrers are
  ignored: browsers strip the query from them, and guessing is worse than
  nothing.
* Marking walks text nodes rather than replacing in the HTML string, which
  would match inside tag names and attributes. The mark keeps the text as
  written, so "Albedo" stays capitalised when someone searched "albedo".
* Switchable under Settings, and off for terms under three characters, which
  would match almost every note on a page.

### Glossary

* NEW: The glossary prints itself as a schema.org `DefinedTermSet` of
  `DefinedTerm` entries, so a search engine can present the page as a glossary
  rather than infer one from a definition list. Scattered across inline notes
  that vocabulary says little; on a page built as a reference it is exactly
  what the markup describes. Switchable per block and filterable with
  `inline_context_glossary_schema`.
* FIX: Two glossaries on one page gave any note they both listed the same id
  twice - invalid markup, and a link to such a term reached only the first.
  Anchors are now unique across the whole response rather than within one
  listing.

### Three settings that did nothing

* FIX: `wp_localize_script()` turns every value into a string, so PHP `true`
  arrives as `'1'` and `false` as `''`. Three places compared one against the
  boolean `false`, which never matches. Two of them were settings people have
  been able to toggle for releases: **Animations** and **Images in notes**
  stored the option, showed it off in the admin, and changed nothing on the
  page. Measured with animations off, a note still ran its 0.3s reveal.

### Accessibility review

Reviewed against WCAG 2.1 AA with axe-core over every surface the plugin draws,
plus manual keyboard, focus, contrast, reduced-motion and reflow checks.

* FIX: A note trigger said it was a link while behaving as a disclosure. The
  server marks it `role="link"`, which is true without JavaScript - it is a
  link down to the endnote - and the script was meant to promote it to
  `role="button"` once it took over. That promotion sat behind "if it has no
  role", which is never true because the server always sets one, so the line
  had never run. It also carried `aria-expanded`, a state `role="link"` does
  not support.
* FIX: Escape now closes a note and returns focus in both display modes. It had
  worked in tooltip mode since 2.1 but never in the inline panel, which is the
  default - so the one keyboard promise in the readme held only in the mode
  most sites do not use. It matters more inline, because opening moves focus
  into the note.
* FIX: The eight formatting buttons in the note editor had no accessible name.
  Quill renders them as SVG with no text, title or label, so a screen reader
  announced eight identical "button"s and an author could not tell bold from
  the image picker.
* FIX: The filter in the Notes Library was a bare `<select>` with no label.
* FIX: Opening a note *for* the reader no longer takes focus, which used to
  drop a keyboard or screen reader user into the middle of the document before
  they had read a word. A polite live region says what was opened instead.

What the review found in good order: no axe violations on the article, search
results, glossary, settings or category screens; contrast far above the
requirement (18.9:1 on a trigger, 17.4:1 in a note, 16.8:1 on a search mark,
against 4.5:1); reduced motion honoured; no horizontal scrolling at 320px; and
the no-JavaScript endnotes carrying a labelled section, a heading, an ordered
list, ids and back links.

Not tested: how any of this sounds in an actual screen reader. The
accessibility tree and DOM behaviour were measured; VoiceOver, NVDA and JAWS
were not run.

## Version 2.9.2 - October 19, 2026

Found by reviewing the 2.9.x code against the WordPress Coding Standards and the
WPCS security sniffs, then checking by hand what sniffs cannot see.

* SECURITY: The one-time maintenance action that rebuilds note usage data was
  reachable through a URL parameter, guarded by the administrator capability but
  no nonce. Another site could therefore make a logged-in administrator run it
  simply by getting them to load a page. It wipes every note's usage meta and
  reads the content of every post and page to rebuild it, so it was also
  expensive to trigger repeatedly. It now requires a nonce, and refuses the
  request with a 403 without one.
* SECURITY: Two blocks of `@codingStandardsIgnoreStart` were switching off every
  sniff rather than the one they needed, including the nonce and escaping sniffs.
  That is why the missing nonce above went unreported for so long. Both are now
  narrowed to the sniff they actually suppress, and the request parameters around
  them are sanitised.
* FIX: Glossary entries always get an anchor that is both present and unique. Two
  notes sharing a title are numbered the way a file manager numbers a duplicate,
  and a title made only of punctuation no longer collapses to an empty id. Before
  this, duplicate titles produced duplicate ids - invalid markup, and a link to
  such a term reached only the first of them.
* FIX: A glossary no longer runs a database query per note to find its category.
  It was using `wp_get_object_terms()`, which deliberately bypasses the term
  cache; `get_the_terms()` reads the cache the note query has already filled.
  Measured over fifteen notes, rendering went from nineteen queries to eight.
* FIX: `render()` is a public method, so the wrapper attributes it accepts could
  come from anywhere. An attribute string that could close the tag is now refused
  rather than placed inside one.
* NEW: Filter `inline_context_glossary_query_args` for capping or paging the
  glossary query. A glossary lists everything by design, which is a lot on a site
  with thousands of notes, and this is the seam for bounding it.
* DEV: `tests/` is now covered by the PHP linting scripts. It had never been in
  scope, and had accumulated 85 violations that nothing reported.

## Version 2.9.1 - October 19, 2026

* FIX: Printing a page produces proper footnotes again: a number after each
  phrase, and the notes themselves at the foot of the page, each with a link
  back to where it was referenced.
* FIX: The print styles had been trying to expand every note in place, which
  could not work. The inline panel is built by the script when a reader opens a
  note, so for any note nobody had clicked there was no element for CSS to
  reveal. A printed page therefore carried whichever notes happened to be open
  on screen and silently dropped the rest, under a row of [1] [2] markers
  pointing at nothing. The endnotes section - rendered on the server for every
  note, numbered, with a link back to the text - was already the right
  apparatus; print now shows that instead. Nothing changes on screen: the
  fallback stays hidden once the script has taken over.
* FIX: The chevron printed alongside the footnote marker. Its own rule sets
  `display: inline-block !important`, so the print rule hiding it never won.
* FIX: A note opened on screen printed in its open-state colour. Printed
  phrases now read as ordinary text, with only the footnote number setting them
  apart.
* FIX: The rule that greys category icons in print targeted a class this plugin
  does not render, so it had never matched anything.
* NOTE: Tooltip mode prints the same footnotes. The endnotes section does not
  depend on the display mode.

## Version 2.9.0 - October 18, 2026

* NEW: A Glossary block, and an `[inline_context_glossary]` shortcode that takes
  the same options, listing your notes on a page you control. The terms in it are
  the same notes already explaining themselves inline throughout the site, so the
  page cannot drift out of date with the prose the way a hand-maintained glossary
  does.
* NEW: Entries group by first letter or by category, or not at all. Letter groups
  fold accents, so "Élan vital" files under E rather than in a group of its own,
  and numerals and symbols collect under "#" the way a printed glossary does.
* NEW: An A-Z jump bar over letter groups, listing only the letters that have
  entries. It is left out below two groups, and over category groups, where it
  would print the same short list twice.
* NEW: Every term and group heading carries an id, so a single term can be linked
  to directly.
* NEW: Options to filter to chosen categories, to include one-off notes as well as
  reusable ones, to hide notes nothing links to yet, and to list the posts each
  note explains - reusing the usage data already behind the Notes Library's "Used
  In" column.
* NEW: Those "Used in" links point at the note's own place in the article rather
  than the top of it. The frontend script opens a note whose anchor matches the
  hash and scrolls to it, so the reader arrives with the passage in view and the
  explanation already open; without JavaScript the same hash lands on that note's
  endnote. The anchor lives only in the article's markup - usage meta records
  which posts use a note, not where - so each article is read once per request
  and remembered, rather than once per note. A note used several times in one
  article links to where the reader meets it first, and an article whose markup
  no longer holds the note still gets a working link to itself.
* NOTE: The glossary is a block rather than an archive for the note post type.
  `inline_context_note` is registered private on purpose, and making it public to
  get archives for free would change URLs, sitemaps and site search on every
  existing install. A block keeps the post type private, lets you pick the URL,
  and lets you curate: a glossary is usually a chosen subset, not every note ever
  written, which an archive would force.
* NEW: Category icons can be drawn as SVG on WordPress 7.1 and later. The plugin
  registers its own `inline-context` icon collection with core's registry, as
  core's documentation asks third-party code to do, rather than registering into
  `core/`. Twelve icons, generated from @wordpress/icons by bin/build-icons.mjs.
* NEW: A visual picker on the category screen. The free-text field stays, because
  it has always accepted any Dashicons class and a curated set of twelve cannot
  replace 300.
* NEW: An opt-in switch, offered in Settings and on the category screen. It
  converts only categories where every icon has an exact match, names the ones it
  cannot convert along with the values that blocked them, and does nothing until
  asked. A category with one mappable icon and one unmappable icon is left alone
  rather than half converted.
* IMPROVED: SVG icons are centred with `calc(0.5cap - size/2)`, derived from the
  font's real cap height rather than tuned to one theme. Measured against the
  text's optical centre across Twenty Twenty-Five, Twenty Twenty-One, Twenty
  Twenty and Twenty Sixteen, they land within 0.001em every time; the Dashicons
  value ranged from 0.012em to 0.040em depending on the theme's typeface. That
  spread is why the `middle` / `0.05em` question kept coming back in 2.7.2, 2.7.3
  and 2.8.3: there was no correct constant, only one tuned to whichever theme was
  in front of you.
* IMPROVED: The Dashicons font is no longer enqueued on the front end once every
  category resolves to an SVG icon. The default chevron has been an SVG mask for
  some time and nothing in the plugin's stylesheet references the font, so it was
  being loaded on every page for category icons alone.
* IMPROVED: Sites installed on WordPress 7.1 start with SVG icons, and a newly
  added category defaults to one, instead of starting on Dashicons and being
  offered a conversion immediately.
* NOTE: No stored value is rewritten on upgrade. The icon value says which kind it
  is - a slash means SVG, a `dashicons-` prefix means a font glyph - so both kinds
  work side by side and a site moves over when it chooses to. Sites below
  WordPress 7.1 are unaffected: the registry arrived in 7.1 and the Dashicons path
  remains for them.

## Version 2.8.3 - October 17, 2026

* FIX: The editor popover opened at the far left of the screen instead of beside
  the text it belongs to. The anchor was read from the top document, but since
  WordPress 6.3 the editor canvas is an iframe and the selection lives inside
  it, so no position was found and the popover fell back to its default spot.
  Sites on WordPress 6.0 to 6.2 have no canvas iframe and were unaffected.
* FIX: A reusable note is shown in the popover but edited at its source, so the
  field is read-only - yet the full formatting toolbar sat above it, looking
  active and doing nothing. The toolbar is hidden and the content is styled as
  the preview it is.
* FIX: Cmd+Shift+I did nothing when the cursor sat inside an existing note. It
  required a text selection, so clicking into a note and pressing it appeared
  broken rather than being the wrong shortcut. It now opens the note under the
  cursor as well as creating one from a selection; Cmd+Shift+K is unchanged.
* IMPROVED: The "Edit source note" and "Copy link to this note" links in the
  reusable-note panel each carry an icon now. One opens a new tab and the other
  copies to the clipboard; an arrow on one and nothing on the other only looked
  inconsistent without saying which was which. The arrow also left the
  translatable string, where it could not be flipped for right-to-left reading.
* FIX: The note editor's help text showed the literal characters &lt;/&gt; where
  it meant to show `</>`. The entity was written into a JavaScript string, and
  JSX does not decode entities there the way it does in markup, so every editor
  displayed the escape sequence rather than the code icon it names.
* FIX: Note excerpts in the editor's "search existing notes" panel ended in
  &hellip; instead of an ellipsis. wp_trim_words() appends that entity by
  default and the result is rendered as text. Both call sites now pass the
  character explicitly: the REST search endpoint, and the Abilities API, which
  was handing the same escape sequence to AI clients.
* FIX: Icon placement "middle" now matches what WordPress.org has actually been
  serving since 2.7.2. The 2.7.3 entry below claims the value was reverted to the
  CSS keyword `middle`, and it was in git, but that change never reached the
  WordPress.org release - trunk and every tag from 2.7.3 through 2.8.2 kept
  `0.05em`. The discrepancy surfaced when git was reconciled with the published
  2.8.2 release in October 2026.
* NOTE: `0.05em` is kept rather than the keyword because it is the better value,
  not merely the shipped one. `vertical-align: middle` aligns the icon's midpoint
  to the baseline plus half the x-height; since x-height is far below cap height,
  the icon reads low for capitalised text and the error grows with font size.
  Measured in Twenty Twenty-Five at 48px: the keyword sits 4.3px (0.090em) below
  the optical centre, `0.05em` sits 1.9px (0.040em) above it. The trade-off is
  that `0.05em` is a fixed offset and does not adapt to fonts with unusual
  metrics, which is what the 2.7.3 note meant by cross-theme compatibility.
* FIX: The SCSS fallback for `--wp--custom--inline-context--icon-placement` now
  matches the PHP default, so both agree when the variable is absent.
* NOTE: Neither icon-placement change alters how the plugin looks. WordPress.org
  has shipped `0.05em` since 2.7.2; it was the repository that was out of step.
* DEV: Added a `@wordpress/env` configuration and `npm run env:*` scripts for a
  one-command local WordPress environment.
* DEV: Added `bin/seed-demo-content.php` (`npm run env:seed`), which seeds that
  environment with a long-form demo article, and `bin/screenshots.js`
  (`npm run env:screenshots`), which recaptures all nine WordPress.org
  screenshots from it in one pass.
* DEV: The plugin banner now has an SVG source in `assets-src/` and a render
  script, replacing artwork that existed only as PNGs - which is how a
  missing-glyph box for an emoji came to ship on the plugin page.
* DEV: The canonical repository moved to https://codeberg.org/joop/inline-context
  and every in-repo URL moved with it.
* DEV: `uninstall.php` now removes every plugin option, not just three of them.

## Version 2.8.2 - August 27, 2026

* FIX: The "Notes" fallback section could stay visible at the bottom of posts, and clicking a
  note jumped down to it instead of expanding the note in place. Root cause: `src/frontend.js`
  bound its initialisation to `DOMContentLoaded`. Caching and optimization plugins routinely
  defer, delay or combine the bundle so that it executes after that event has already fired,
  at which point the listener never runs, no triggers are bound, and every click falls through
  to its raw `href`. Startup now checks `document.readyState` and initialises immediately when
  the document is already parsed.
* FIX: Accessibility regression on themes that manage their own `js` class. The fallback was
  hidden by `.js .wp-inline-context-noscript-notes`, but Twenty Twenty, Twenty Seventeen,
  Twenty Sixteen and Twenty Fifteen all set `js` on the html element from an inline head
  script. `.js` means "JavaScript exists", not "Inline Context is working", so on those themes
  the fallback was hidden whenever this plugin's script failed to run - leaving screen reader
  and keyboard users with a link pointing at a `display:none` target and no route to the note
  text at all. Hiding is now keyed to `.inline-context-ready`, a plugin-owned class set on the
  html element only after the frontend script has finished binding its handlers. The
  accessible fallback survives whenever the enhancement does not.
* IMPROVED: Confirmed WordPress 7.1 compatibility - "Tested up to" header bumped to 7.1.
  Verified on WordPress 7.1 with PHP 8.2: 52 single-site, 12 ajax and 52 multisite PHPUnit
  tests pass, admin and frontend render without PHP notices, and the Abilities API registers
  all five abilities.
* DEV: Added `.wp-env.json` plus `npm run env:*` scripts, giving a one-command local
  WordPress environment with the plugin mounted and activated, WP_DEBUG/SCRIPT_DEBUG on, and
  PHPUnit runnable inside the container without `bin/install-wp-tests.sh`.
* DEV: Added `tests/test-frontend.php` - regression coverage for the endnotes fallback: that
  it is always generated, that each trigger's href resolves to a real target, that back-links
  are labelled, and that the server-rendered trigger is a plain link rather than a stale ARIA
  widget.
* DEV: `uninstall.php` now deletes every plugin option. Nine of the twelve were previously
  left behind in wp_options after uninstalling.

## Version 2.8.1 - May 2, 2026
* FIX: Inline context popover no longer closes when inserting an image from the WordPress
  Media Library. Root cause: the Media Library frame is a body-level modal, so its clicks
  registered as "outside the popover" and triggered the close handler. The fix flips a guard
  ref while the frame is open and releases it 200ms after close, which also covers the focus-
  restore click that happens immediately after the modal tears down.

## Version 2.8.0 - May 2, 2026
* NEW: Embed images inside inline context notes via the WordPress Media Library
* NEW: Image button in the note editor toolbar (shown when image support is enabled)
* NEW: "Allow images in notes" admin setting in the General tab (default: enabled)
* NEW: Custom Quill image blot preserves alt, loading, decoding, and class attributes
  through Quill's serialization, so attributes survive editor round-trips
* NEW: `inline_context_allowed_image_protocols` filter for sites that need data URIs or
  other schemes
* NEW: Three CSS variables for theme-level image sizing customization:
  --wp--custom--inline-context--image--tooltip-max-width (default 280px)
  --wp--custom--inline-context--image--tooltip-max-height (default 200px)
  --wp--custom--inline-context--image--inline-max-height (default 400px)
* IMPROVED: Tooltip mode caps images at ~280×200 to keep tooltips compact
* IMPROVED: Inline mode caps image height at 400px while allowing full content width
* IMPROVED: Print styles handle images with page-break avoidance and sensible sizing
* IMPROVED: Confirmed WordPress 7.0 compatibility — "Tested up to" header bumped to 7.0
* IMPROVED: Always sets alt="" on images missing alt text so screen readers don't fall
  back to announcing filenames
* IMPROVED: Image src restricted to http(s) and relative paths by default; data URIs and
  other protocols can be opted into via the new filter
* IMPROVED: Settings export/import now includes the image-support toggle
* DEV: Added project-wide babel.config.json so ESLint's parser stops warning when
  walking @wordpress/* dependencies
* DEV: Declared react-dom as an explicit dependency (was pulled in transitively, used
  via WordPress's wp-element global)
* DEV: Cleaned up pre-existing JSDoc and PHPCS suppression-comment placement issues

## Version 2.7.3 - March 21, 2026
* FIX: Category icons now align correctly with text at all icon placement settings
* FIX: Category icon double-scaling issue where font-size and width/height both used em values,
  causing icons to render at 0.49em instead of the intended 0.7em
* IMPROVED: Separated icon sizing between default chevron (width/height only) and category icons
  (font-size for glyph + 1em width/height to match), ensuring both render at the same physical size
* IMPROVED: Reverted middle placement to CSS keyword "middle" for cross-theme compatibility

## Version 2.7.2 - March 20, 2026
* FIX: Custom category icons now respond to size and placement settings
* FIX: Default chevron icon now responds to color and placement settings
* FIX: Tooltip hover mode no longer shows erratic show/hide behavior
* FIX: Admin settings JS toggles now work (screen ID mismatch prevented all JS from running)
* NEW: Icon right margin CSS variable (chevron-margin-right) for theme.json and admin settings
* IMPROVED: Refactored icon rendering from CSS ::after pseudo-element to real <span> elements
* IMPROVED: Shared base styles between default chevron and category icons for consistent positioning
* IMPROVED: Override Dashicons ::before sizing so category icon glyphs respect the Size setting
* IMPROVED: Fine-tuned icon placement: top (text-top), middle (0.05em), bottom (-0.15em)
* IMPROVED: Pill style always centers icons regardless of icon placement setting
* IMPROVED: Icon Placement option hidden in admin when Pill style is selected
* IMPROVED: Tooltip hover uses direct per-trigger event listeners instead of delegated capture events

## Version 2.6.0 - December 27, 2025
* NEW: Color preset system with five pre-configured professional color schemes
* NEW: Modern Blue (Default) preset - clean, professional look with blue accents
* NEW: Minimalist Gray preset - subtle, understated design in grayscale
* NEW: High Contrast preset - bold colors for maximum visibility and accessibility
* NEW: Warm Earth Tones preset - cozy, natural palette with browns and oranges
* NEW: Dark Mode preset - dark theme with light text for reduced eye strain
* NEW: Automatic preset detection and persistence across page reloads
* NEW: "Custom" indicator when user modifies preset values
* NEW: Warning dialog before applying preset over custom settings
* NEW: note-text-color CSS variable for better typography control (37 total variables)
* IMPROVED: All presets meet WCAG 2.1 AA accessibility standards (minimum 4.5:1 contrast)
* IMPROVED: Dark Mode text color with proper inheritance for WordPress block elements
* IMPROVED: One-click preset application with instant visual feedback
* IMPROVED: Seamless integration with existing WordPress Settings API

## Version 2.4.1 - December 19, 2025
* IMPROVED: documentation

## Version 2.4.0 - December 19, 2025
* NEW: Add new pill style
* NEW: WordPress 6.9+ Abilities API integration for AI assistant discovery
* NEW: Five REST API abilities for AI-powered content enhancement
* NEW: `create-note` ability - Create new inline context notes via API
* NEW: `search-notes` ability - Search existing notes by title/content
* NEW: `get-categories` ability - Retrieve all available categories
* NEW: `get-note` ability - Fetch specific note by ID
* NEW: `create-inline-note` ability - Create note and get ready-to-embed HTML markup (AI helper)
* NEW: Browser-based AI integration (Claude, ChatGPT) with automatic capability discovery
* NEW: Comprehensive ABILITIES-API.md documentation with workflows and examples
* NEW: Test infrastructure for Abilities API (test-abilities.sh, tests/test-abilities.php)
* NEW: AIFeatures component for future in-editor AI UI (currently disabled by default)
* IMPROVED: Authentication support via cookie auth (browser) or Application Passwords
* IMPROVED: Complete JSON Schema validation for all ability inputs
* IMPROVED: Permission callbacks ensure proper WordPress capability checks
* IMPROVED: Backward compatible - works on WordPress 6.0+ (Abilities API optional on 6.9+)
* IMPROVED: Updated "Tested up to" WordPress 6.9

## Version 2.3.5 - 2.3.9 - November 29, 2025
* Minor fixes, updated documentation and readme.txt, added Dutch translations

## Version 2.3.4 - November 28, 2025
* FIX: WordPress.org compliance - replaced all inline <script> tags with wp_add_inline_script()
* FIX: WordPress.org compliance - added source code documentation section to readme.txt
* NEW: Created .distignore file to exclude screenshots from plugin zip (belong in SVN assets only)
* IMPROVED: Script enqueueing follows WordPress best practices and plugin guidelines
* IMPROVED: Better separation of concerns - scripts properly enqueued via admin hooks

## Version 2.3.3 - November 21, 2025
* FIX: Tooltip hover event handling refactored for multi-link reliability
* FIX: Direct event listeners on triggers eliminate race conditions
* FIX: Tooltip DOM association with data-anchor-id attribute
* IMPROVED: Independent timeout management per trigger
* IMPROVED: Robust hover/click interaction without interference

## Version 2.3.2 - November 16, 2025
* FIX: Tooltip hover logic uses WeakMap for per-trigger state
* FIX: Event delegation improved for tooltip association
* IMPROVED: Timeout management isolated per trigger

## Version 2.3.1 - November 16, 2025
* FIX: Tooltip hover logic refactored for reliability with multiple links
* FIX: Each tooltip now manages its own open/close state and timeouts
* FIX: Rapid mouse movement between links no longer causes tooltips to fail
* FIX: Tooltip DOM association improved for robust event handling
* IMPROVED: Release process and documentation for bugfix branch

## Version 2.3.0 - November 16, 2025
* NEW: Hover activation option for tooltips with configurable 300ms delay
* NEW: Admin setting to enable tooltip display on mouse hover
* NEW: Smart hover behavior - keep tooltip open when moving mouse to tooltip content
* NEW: Conditional admin UI - hover option only visible when tooltip mode is selected
* NEW: 100ms grace period for smooth mouse transition between trigger and tooltip
* NEW: Separate show/hide timeout management for robust interaction
* IMPROVED: Enhanced user experience for interacting with tooltip content and links
* IMPROVED: Smooth transition between trigger and tooltip without closing
* IMPROVED: Demo.html page now includes hover functionality demonstration
* FIX: Settings persistence in demo.html using localStorage
* FIX: Direct link anchor reference corrected in demo.html

## Version 2.2.0 - November 15, 2025
* NEW: Convert reusable notes to non-reusable with automatic synchronization
* NEW: Modal confirmation dialog prevents accidental conversions
* NEW: PopoverActions component with reusable checkbox control
* NEW: PHPUnit testing infrastructure with WordPress Test Suite integration
* NEW: 18 comprehensive test methods covering CPT, REST API, and sync functionality
* NEW: .env configuration support for secure database credentials
* NEW: Testing documentation (TESTING.md, tests/README.md, TESTING-SETUP.md)
* NEW: Interactive test setup wizard (bin/setup-tests.sh)
* NEW: Display mode switcher in demo.html for testing inline/tooltip modes
* NEW: Dynamic display mode detection instead of static configuration
* NEW: Consolidated bin/ directory for all scripts
* NEW: Markdown linting for documentation consistency
* NEW: RELEASE.md documentation with complete release process
* IMPROVED: Enhanced PopoverActions component for better reusability control
* IMPROVED: Documentation structure and testing guides

## Version 2.1.0 - November 14, 2025
* NEW: Tooltip display mode as alternative to inline expansion
* NEW: General settings tab with display mode selection (inline/tooltip)
* NEW: Smart tooltip positioning with viewport boundary detection
* NEW: Automatic position flipping to prevent off-screen tooltips
* NEW: Close button on tooltips with proper event cleanup
* NEW: Full keyboard support (Space/Enter to activate, Escape to close)
* NEW: Automatic focus management for keyboard users
* NEW: DOMPurify integration for secure HTML rendering
* NEW: CSS animations for smooth tooltip reveal
* NEW: Click toggle behavior (click again to close)
* IMPROVED: Organized styling sections (shared settings first, mode-specific after)
* IMPROVED: Admin settings reorganized into 4 tabs (General, Categories, Styling, Uninstall)
* IMPROVED: Click/keyboard-only activation for tooltips (no hover by default)
* IMPROVED: Comprehensive tooltip accessibility with ARIA attributes
* REMOVED: Non-functional live preview from Styling tab (will be reimplemented properly later)

## Version 2.0.1 - November 12, 2025
* NEW: Taxonomy meta fields UI for managing category icons and colors
* NEW: Live icon preview in category add/edit forms
* NEW: WordPress color picker integration for category colors
* NEW: Custom columns in category list showing icon previews and colors
* IMPROVED: Frontend category icon rendering now works correctly
* IMPROVED: Post list display in Uninstall tab shows which posts contain inline context links
* IMPROVED: Uninstall cleanup query accuracy (excludes revisions, more specific matching)
* IMPROVED: Added backup warning for content cleanup option in Uninstall settings
* FIX: Category icons now display properly on frontend with correct colors
* FIX: Default chevron appears when no category is selected (proper CSS selector)

## Version 2.0.0 - November 12, 2025
* NEW: Complete modular class-based architecture (83% main file reduction from 2,291 to 395 lines)
* NEW: Six dedicated class-based modules for optimal separation of concerns
* NEW: Inline_Context_CPT class (855 lines) for Custom Post Type management
* NEW: Inline_Context_Taxonomy_Meta class (372 lines) for taxonomy meta fields
* NEW: Inline_Context_Sync class (496 lines) for synchronization and usage tracking
* NEW: Inline_Context_Deletion class (198 lines) for bulk deletion with cleanup
* NEW: Inline_Context_REST_API class (340 lines) for REST API endpoints
* NEW: Inline_Context_Frontend class (276 lines) for frontend rendering
* NEW: Inline_Context_Utils class (182 lines) for utility functions
* IMPROVED: Full WordPress coding standards compliance (JavaScript and PHP)
* IMPROVED: ESLint and PHPCS compliance with pre-release gates
* IMPROVED: Clean bootstrap pattern with class initialization
* IMPROVED: Enhanced maintainability and testability
* IMPROVED: Backward compatibility preserved (zero breaking changes)

## Version 1.5.0 - 2025
* NEW: Custom Post Type (inline_context_note) for reusable notes
* NEW: Category Taxonomy (inline_context_category)
* NEW: Editor popup with live search (AJAX query CPT by title)
* NEW: Two modes: Create new note / Select existing note
* NEW: Dual data storage: data-note-id + cached data-inline-context
* NEW: Frontend uses cached content (zero performance penalty)
* NEW: Usage tracking via REST API (non-blocking)
* NEW: Auto-sync for reusable notes - content automatically syncs to all posts using it
* NEW: Automatic data-inline-context attribute updates across all using posts
* NEW: Enhanced CPT list view with custom columns (Reusable, Usage Count, Used In)
* NEW: Filter dropdown for reusable notes
* NEW: Delete warnings in 3 locations (post list, quick edit, single post delete)
* NEW: QuillEditor component for rich text editing
* NEW: Comprehensive uninstall system with content cleanup options

## Version 1.4.1 - 2025
* NEW: Server-side rendering with endnotes for no-JS environments
* NEW: Full support for text-based browsers (Lynx, w3m, links)
* NEW: NoScript fallback with endnotes at bottom
* NEW: Print-friendly auto-expand all notes
* NEW: RSS feed content inclusion
* IMPROVED: Graceful degradation across all user agents

## Version 1.4.0 - 2025
* NEW: Progressive enhancement with server-side rendering
* NEW: NoScript fallback support
* IMPROVED: Text-based browser compatibility

## Version 1.3.0 - 2025
* NEW: Category management system with custom icons and colors
* NEW: Visual icon picker with 30 curated Dashicons
* NEW: Support for all 300+ Dashicons via manual entry
* NEW: Dual icon states (closed/open) with automatic toggling
* NEW: Keyboard-accessible icon picker (Esc, Tab navigation)
* NEW: Tabbed admin interface (Categories and Styling)
* NEW: Comprehensive styling controls
* NEW: Live preview with interactive note reveal
* NEW: CSS variable integration

## Version 1.2.1 - 2025
* FIX: Updated composer.json version number to match plugin version

## Version 1.2.0 - 2025
* NEW: HTML source editor toggle in ReactQuill toolbar
* NEW: Visual toggle between WYSIWYG and HTML source modes
* IMPROVED: Better icon sizing and styling for toolbar buttons
* IMPROVED: Smooth switching between visual and source editing
* IMPROVED: Automated linting and fixing before releases
* FIX: Toggle button functionality after multiple switches

## Version 1.1.5 - 2025
* NEW: HTML source editor toggle in ReactQuill toolbar for direct HTML editing
* NEW: Visual toggle between WYSIWYG and HTML source modes with dedicated icon
* IMPROVED: Better icon sizing and styling for toolbar buttons
* IMPROVED: Smooth switching between visual and source editing modes
* FIX: Toggle button functionality working correctly after multiple switches

## Version 1.1.4 - 2025
* NEW: Theme.json integration for WordPress Site Editor customization
* NEW: STYLING.md documentation with comprehensive theming examples
* IMPROVED: Conditional asset versioning (filemtime for dev, constant for production)
* IMPROVED: CSS custom properties now use --wp--custom--inline-context--* namespace
* REMOVED: Legacy --jooplaan-* CSS properties (breaking change)

## Version 1.1.3 - 2025
* IMPROVED: Minor updates and refinements
* FIX: Bug fixes and stability improvements

## Version 1.1.2 - 2025
* NEW: Copy link functionality - users can copy direct anchor links to any context note
* NEW: Developer filters for extensive plugin customization (11 filters available)
* IMPROVED: Complete namespace refactoring from trybes to jooplaan
* IMPROVED: Duplicate ID prevention system for copy/paste scenarios
* IMPROVED: HTML validity with semantic button elements instead of anchor tags
* IMPROVED: Automatic unique ID generation when duplicates are detected
* FIX: Frontend display issue - added wp-hooks dependency
* FIX: Demo.html compatibility with standalone usage
* FIX: ESLint compatibility issues with Node.js v24

## Version 1.1.1 - 2025
* FIX: Added wp-hooks dependency for frontend filters support
* FIX: Resolved console error preventing notes from displaying on frontend

## Version 1.1.0 - 2025
* NEW: WordPress LinkControl integration for easy internal page/post linking
* NEW: Familiar WordPress interface for selecting content and adding external URLs
* NEW: Developer filters for customizing plugin behavior (see FILTERS.md)
* IMPROVED: Enhanced rich text editor with better link management capabilities

## Version 1.0.1 - 2025
* IMPROVED: Enhanced VS Code development setup with WordPress coding standards
* IMPROVED: Build process optimization and error fixes
* IMPROVED: Better development workflow with automated formatting configuration
* FIX: Resolved SCSS compilation errors in build process
* FIX: PHP coding standards compliance issues resolved

## Version 1.0.0 - 2025
* NEW: Initial public release with anchor-first architecture
* NEW: Unique anchor IDs for every context note with direct URL linking
* NEW: Auto-opening notes when accessed via URL hash (#context-note-xxx)
* NEW: Subtle design - context links appear as regular text with icon indicator only
* NEW: Hover/focus states change text color to primary for clear interaction feedback
* NEW: Smart link behavior - internal links same tab, external links new tab with security
* NEW: ReactQuill rich text editor for enhanced note authoring experience
* NEW: DOMPurify integration for robust XSS protection on frontend rendering
* IMPROVED: Full WordPress coding standards compliance (PHP and JavaScript)
* IMPROVED: Comprehensive quality assurance with automated linting pipeline
* IMPROVED: Enhanced accessibility with better ARIA attributes and focus management
* REMOVED: Legacy support - v1.0 requires anchor IDs for all context notes

---

## Legend
* **NEW**: New feature or capability
* **IMPROVED**: Enhancement to existing feature
* **FIX**: Bug fix or correction
* **REMOVED**: Deprecated or removed feature
