Egenverk Docs Viewer

Ändringslogg för Egenverk Docs Viewer

Vad som ändrats i varje tillägg, senaste först.

Ändringsloggens text är på engelska, som i tillägget.

Atom-flöde

Version 2.7.0

Tillagt

  • Syntax highlighting. Prism 1.30.0 (MIT) ships in assets/vendor/prism/ (core plus markup, clike, javascript, markup-templating, php, json, bash, yaml, sql, diff, css, scss, typescript, jsx, tsx, ini; the npm package's .min.js files concatenated unchanged, source and rebuild steps in its README). It is enqueued only on the viewer screen, in manual mode, and viewer.js highlights the rendered document (Markdown code blocks and non-Markdown files shown as code) before any heading jump; the Raw view stays plain. htm, conf and less map to markup, ini and css. Token colours use kit tokens in viewer.css (all at least 5:1 on the code background), not a Prism theme.

Åtgärdat

  • docs/ARCHITECTURE.md no longer says "Two options".

Version 2.6.0

Tillagt

  • What's new after an update. When a scan finds a plugin at a higher version than in the previous index (version_compare()), it records { from, to, at } in the new option egenverk_dv_updates (not autoloaded). The plugin's row on the Plugins screen then leads with What's new in X.Y (plugins with a root changelog or readme.txt only), linking to the changelog with &dv_version=<to>&dv_since=<from>.
  • Changelog::since() cuts a Markdown changelog (a readme.txt is converted first) to the release sections newer than from and not newer than to: a release heading is one that opens with a version ([2.1.0] — …, v2.1.0, 2.1.0), sections are split at the level of the first such heading, the cut stops at the next shallower heading (so a readme's Upgrade Notice is not included), and fenced code is skipped (a fence closes only with the same character and at least its length). The viewer shows that cut under a note with a link to the full changelog; when nothing matches it shows the whole file.
  • An administrator (manage_options) opening the cut changelog for the announced update (dv_since equal to the stored from) clears its entry for all users; readers with only the egenverk_dv_capability capability do not. Entries also expire after 30 days (Plugin::UPDATE_TTL), and are dropped when the plugin is gone or downgraded below the announced version. A second update before anyone reads the first keeps the original from, so both releases show. Only plugins are tracked, not themes or must-use plugins. The old-URL redirect keeps dv_since.

Åtgärdat

  • The Changelog link's dv_version is URL-encoded, so a version with + build metadata no longer arrives with a space.

Version 2.5.0

Tillagt

  • Themes and must-use plugins. The scan also indexes every installed theme (wp_get_themes(), all theme roots) and every must-use plugin that sits in its own folder under WPMU_PLUGIN_DIR, with the same file rules as plugins (root docs plus docs/). They are keyed theme:<stylesheet> and mu:<folder>; plugins keep their folder name. Records carry a type (plugin, theme, mu); records from an older index have none and are read as plugins, and the next scan rewrites them. Order: plugins, then themes, then must-use plugins.
  • Scanner::root_of() maps a key to its folder and URL from WordPress's own roots (never from stored paths); resolve_path() and asset_url() use it, so the three file gates and relative images work the same for themes and must-use plugins. Plugin folders whose name contains : are skipped so they cannot pass for a prefixed key. Keys whose folder part is empty or starts with . are rejected (so theme: cannot mean the active theme and theme:. cannot mean the whole themes folder), and asset_url() now also requires the key to be in the index.
  • The top-bar switcher groups entries under Plugins, Themes and Must-use plugins when more than one kind is indexed. Search covers all of them.
  • Theme installs, updates (upgrader_process_complete with type theme) and deletions (deleted_theme) queue a rescan like plugin changes.

Ändrat

  • The scan button reads "Scan for docs" (was "Scan plugins folder"); the empty state mentions themes.
  • The "View Docs" link setting shows only for plugins, since themes and must-use plugins have no Plugins-screen row.
  • Admin::clean_slug() rejects values containing /, \\ or .. instead of stripping characters from them.

Version 2.4.0

Tillagt

  • Read access for other roles. The egenverk_dv_capability filter sets the capability needed to open Tools → Docs Viewer and search (Admin::read_cap(), default manage_options; a non-string or empty value falls back to it). Scanning, the multisite auto-rescan and the "View Docs" link setting still require manage_options: users without it see no scan button and no link setting, the empty state asks them to have an administrator run a scan, and the admin-post handlers reject them as before. Documented in the readme FAQ, docs/USER_GUIDE.md and docs/SECURITY.md.
  • Plugins-screen links (View Docs, Changelog, Browse Docs) are only added for users who can open the viewer.

Ändrat

  • Third-party admin notices are removed only on the viewer screen itself (tools_page_egenverk-docs-viewer), not on any admin page that carries page=egenverk-docs-viewer.

Version 2.3.0

Tillagt

  • The old admin.php?page=egenverk-docs-viewer URL redirects (301) to Tools, keeping dv_plugin, dv_file, dv_mode, dv_search, dv_version and scanned; the browser keeps any #heading. To be removed after 2.3.x.

Ändrat

  • Tools → Docs Viewer. The viewer is a Tools sub-page (add_management_page, tools.php?page=egenverk-docs-viewer) instead of a top-level menu, per the Egenverk admin-menu rule; the menu icon constant is gone (sub-pages carry no icon). All links (Plugins screen row links, the plugin's own Browse Docs link, relative Markdown links, search, scan and toggle redirects) go through Admin::page_url(). Capability unchanged.

Version 2.2.2

Ändrat

  • Link_Injector hooks on load-plugins.php (and on wp_ajax_search-plugins, the Plugins screen's live search) instead of plugins_loaded, so front-end and other admin requests no longer load the scan index (a non-autoloaded option, one query per request) or add per-plugin filters. The rescan hooks stay registered on every request, so updates from cron and WP-CLI still rebuild the index.

Åtgärdat

  • Multisite: on a site a network activation did not reach, the injector read the settings before the lazy migration on admin_init, so the first Plugins screen visit had no View Docs links. load-plugins.php runs after admin_init.
  • egenverk_dv_scanned_at and egenverk_dv_plugins_changed_at are written with sprintf( '%.6F' ) (Plugin::stamp()). PHP 7.4 converts floats to strings using the locale, so with a comma decimal locale the fraction was lost and a site could miss a rebuild within the same second. Stored values stay numeric strings, read as before.
  • A rescan after a plugin change also removes option keys of the earlier names, which an old copy of the plugin that is still active can write back after the migration.

Version 2.2.1

Ändrat

  • The Egenverk symbol (signature lockup) and the Docs Viewer glyph are redrawn with centred, evenly spaced bars (kit 1.1.0 re-copied: brand/, glyphs/docs*.svg). Admin::MENU_ICON and the inline signature use the new paths; wordpress.org icon, banners and screenshots rebuilt.

Version 2.2.0

Ändrat

  • Egenverk admin look. The viewer and the empty state run on the shared Egenverk UI kit 1.1.0, shipped in assets/egenverk-ui/ (CSS, a small dependency-free JS, Geist and Geist Mono woff2 under the OFL, the Docs Viewer glyphs and the Egenverk symbol). It is enqueued only on the plugin's own screen and makes no external request. The wrapper carries egenverk-ui with data-product="docs", so links, the active file, the Preview/Raw switch and search highlights use the Docs Viewer colour; the plugin's own colours are mapped to kit tokens. Zebra rows in rendered Markdown tables are gone.
  • The empty state has the kit header (glyph, title, signature, hr.wp-header-end); the viewer's top bar shows the glyph in place of the dashicon. The admin menu icon is the Docs Viewer glyph (Admin::MENU_ICON, a base64 SVG data URI) instead of dashicons-media-document.
  • The "by egenverk" signature is the Egenverk lockup SVG. "by" is written literally and is no longer translatable, so the by entry is gone from the .pot.
  • The scan button shows the kit loader while the scan reloads the page.
  • New wordpress.org icon and banners (source in .wordpress-org/src/) and screenshots.

Åtgärdat

  • On screens up to 782 px the top bar wraps, so the search field and the scan button no longer run off the right edge.
  • The narrow-screen media query used range syntax (width <= 782px), which Safari before 16.4 ignores; it is max-width: 782px again, and stylelint now requires the prefix form.
  • "Tested up to" is declared only in readme.txt; the plugin header no longer repeats it (wordpress.org review).

Version 2.1.1

Tillagt

  • Activation moves settings and the scan index from the option keys of both earlier names (newest first, so the most recent value wins) and removes them, including the earlier network option on multisite. Sites a network activation did not reach migrate on their first admin visit; an autoloaded egenverk_dv_migrated flag keeps that check free once done.

Ändrat

  • Renamed to Egenverk Docs Viewer, on the slug wordpress.org assigned (egenverk-docs-viewer). Main file egenverk-docs-viewer.php, folder and text domain egenverk-docs-viewer (translation template languages/egenverk-docs-viewer.pot), namespace Egenverk\DocsViewer, constants EGENVERK_DV_*, option keys egenverk_dv_plugins / egenverk_dv_settings / egenverk_dv_scanned_at and the network option egenverk_dv_plugins_changed_at, admin page admin.php?page=egenverk-docs-viewer, admin-post actions egenverk_dv_scan / egenverk_dv_toggle, asset handles and CSS classes egenverk-dv-*, template helper egenverk_dv_render_tree(). npm run package builds dist/egenverk-docs-viewer-<version>.zip. Author is Egenverk (https://egenverk.se); the wordpress.org contributor is unchanged. The GitHub repository is egenverk-docs-viewer.
  • The admin menu and the viewer read "Docs Viewer", signed "by egenverk" with the egenverk symbol and wordmark.
  • Directory screenshots updated; wordpress.org banner (1544×500, 772×250) and icon (256, 128) added to .wordpress-org/.

Åtgärdat

  • In 2.1.0 heading ids gained a dv-h- prefix, but a link from another document to a heading (docs/guide.md#setup) and any bookmarked #slug URL still carry the bare slug, and nothing read the URL fragment on load, so the document opened at the top. The viewer now maps the fragment to the heading on load and when only the fragment changes (a link to a heading in the same document written as guide.md#setup).
  • On multisite, network activation built the index for the main site only and subsites showed the empty state; it now stamps the network so every site builds its index on its next admin visit. The change and scan stamps are now microtime floats, so a scan and a change in the same second are ordered correctly without rescanning the site that made the change.
  • The 2.1.0 changelog described heading ids as intro, intro-1; they are dv-h-intro, dv-h-intro-1. docs/ARCHITECTURE.md now covers the multisite rescan.

Version 2.1.0

Tillagt

  • Search all docs in the top bar: a case-insensitive search through every scanned document of every plugin, each read through Scanner::read_file() and its file gate. Results show plugin and file with up to three escaped, highlighted lines per file; queries need 2–100 characters and at most 100 files are listed. The query is matched as typed (so <div or %20 can be found; control characters are dropped), and files that are not UTF-8 are read as ISO-8859-1.
  • On this page in the sidebar: the current document's level 2–3 headings (1–3 when it has no level-2 heading) as jump links, shown when there are at least two. Markdown::document() returns the headings alongside the HTML. Jumps scroll the document pane itself, so the top bar stays in place (on narrow screens, where the page scrolls, the page moves instead). Heading ids now carry a dv-h- prefix so they cannot clash with wp-admin element ids; in-document #anchor links written with the bare slug still work.
  • Changelog action link on the Plugins screen next to View Docs, for plugins with a root CHANGELOG or readme.txt. It opens the file at the heading for the installed version (&dv_version=, matched as a whole version so 2.2.1 does not hit 2.2.10), else at the Changelog heading.
  • The index is rebuilt automatically after plugin installs and updates (upgrader_process_complete), activation, deactivation and deletion — once per request, on shutdown — and when this plugin is activated. On multisite, where plugins are shared but each site has its own index, a change also stamps the network (a network option) and every other site rebuilds its index on its next admin visit by an administrator; each site records when it last scanned. The scan button stays for changes made outside WordPress.

Ändrat

  • docs/USER_GUIDE.md rewritten for the current viewer (it still described a card-based list from before 1.0.0); docs/MARKDOWN_SUPPORT.md, docs/SECURITY.md and docs/ARCHITECTURE.md cover folder links, search and rescans. Directory screenshots updated, with a fourth showing search.

Åtgärdat

  • Two headings with the same text in one document got the same id, so the second could never be linked. Ids are now unique the way GitHub makes them (dv-h-intro, dv-h-intro-1, …).
  • A relative link to a folder found the folder's README case-insensitively on the folder name too, so x opened docs/README.md. Only the README file name is matched case-insensitively now.

Version 2.0.1

Tillagt

  • readme.txt FAQ: security issues go to the WordPress.org Plugins Team (plugins@wordpress.org), not the support forum.

Åtgärdat

  • Relative links and images in a rendered document were broken: esc_url() prefixes a target without a scheme with http://, so Guide pointed to http://docs/guide.md and ![](docs/shot.png) never loaded. Relative targets are now resolved against the document's folder. A link to another scanned doc of the same plugin, or to a folder whose README is scanned, opens in the viewer through the usual file gate; an image inside the plugin gets its plugins_url() address (image extensions only, realpath-contained, nothing is read); any other relative target renders as plain text. Targets with control characters are rejected, because a NUL byte reaching realpath() throws on PHP 8.
  • docs/ARCHITECTURE.md named a non-existent page=…-view viewer page.

Version 2.0.0

Tillagt

  • On activation, settings and the scan index move from the old docs_viewer_* option keys to the new ones (Plugin::migrate_legacy_options()); the stored format is unchanged, a value already under the new key wins, and the old keys are deleted.

Ändrat

  • Renamed from Docs Viewer to an interim name, because "Docs Viewer" is already the name of a commercial add-on and close to "Document Viewer" in the wordpress.org directory, and the directory rejects names confusingly similar to existing plugins. Main file, folder/slug, text domain, namespace, constants and option keys changed with it; this is breaking because WordPress sees a new plugin folder. The interim name was replaced by Egenverk Docs Viewer before the plugin was published (see 2.1.1).
  • Directory screenshots show the plugin under its new name.

Åtgärdat

  • The scanner skipped its own folder by the hard-coded slug docs-viewer; it now uses the plugin's real folder name, so it keeps skipping itself after the rename.

Version 1.1.4

Ändrat

  • The viewer template's own variables are prefixed with docs_viewer_, so Plugin Check reports no warnings. No visible change.

Åtgärdat

  • readme.txt still carried the WPORG_USERNAME placeholder in Contributors, which wordpress.org would reject. It now names the plugin's wordpress.org account.

Version 1.1.3

Åtgärdat

  • languages/docs-viewer.pot sent translation bug reports to the private GitHub repository that 1.1.2 stopped linking to. Report-Msgid-Bugs-To now points to the WordPress.org support forum.
  • README.md still listed the removed Plugin URI, and directory screenshot 3 showed the 1.1.1 plugin row with the removed "Visit plugin site" link. Both now match the current header.

Version 1.1.2

Tillagt

  • Directory screenshots in .wordpress-org/ (viewer, Raw mode, Plugins screen link) for the wordpress.org SVN assets/ folder; they are not part of the plugin zip.
  • npm run package checks every shipped file against an optional, untracked deny list (scripts/.release-deny) and refuses to build on a match, so no tooling reference can reach the published zip.
  • languages/docs-viewer.pot regenerated for 1.1.2; the removed header URIs are no longer translatable strings.

Åtgärdat

  • The Plugins screen showed a "Visit plugin site" link and the author name linked to GitHub, but the Plugin URI pointed at a private repository, so the link led to a 404. The Plugin URI and Author URI headers are removed.

Version 1.1.1

Tillagt

  • wordpress.org readiness: a readme.txt in the wp.org format (description, installation, FAQ on the security model, screenshots, changelog), a Domain Path: /languages header with a generated languages/docs-viewer.pot, and Tested up to: 7.1. load_plugin_textdomain() is deliberately not called: WordPress loads translations for wp.org-hosted plugins automatically since 4.6, below the plugin's 5.0 minimum.
  • npm run package builds dist/docs-viewer-<version>.zip from an allowlist (docs-viewer.php, readme.txt, LICENSE, CHANGELOG.md, includes/, templates/, assets/, languages/) and refuses to build when the version header, DOCS_VIEWER_VERSION and the readme's Stable tag disagree.

Ändrat

  • Every phpcs:ignore comment now states why the sniff does not apply. Two of them named a non-existent sniff (EscapingOutput instead of EscapeOutput), so Plugin Check reported the scan-form output as unescaped; they now name the real sniff.
  • The dv_plugin request value passes through sanitize_text_field() before the existing slug filter, and the scan count is cast to int at output, so Plugin Check sees the input sanitized and the output escaped. Accepted slugs are unchanged.

Åtgärdat

  • The Raw view's "Copied!" confirmation was hard-coded English in viewer.js, so translators could not reach it. The label now comes from the template through esc_attr_e().

Version 1.1.0

Tillagt

  • wordpress.org readme.txt files now render formatted instead of as a raw code block. The wp.org heading syntax (=== Title ===, == Section ==, = Sub =) and the Key: value metadata block under the title are converted to Markdown and passed through the existing formatter; .txt files without that structure keep the code-block fallback.

Version 1.0.0

Tillagt

  • Initial release.
  • Scanner that traverses wp-content/plugins for README, CHANGELOG and docs/ files (including nested docs/* folders).
  • Dependency-free, escaping-first Markdown formatter (headings, nested lists, tables, fenced & inline code, blockquotes, links, images, emphasis, rules).
  • Single GitHub-style viewer page: a file-tree sidebar, a plugin switcher and a scan button in the topbar, and the document with Preview / Raw tabs. The sidebar and document each scroll independently (vertical only); the page itself stays put.
  • Per-plugin opt-out toggle (in the sidebar) to inject a “View Docs” link onto the plugin's row on the Plugins screen — enabled by default.
  • Triple-gated file access: extension allow-list, scanned-file membership check, and realpath containment.
  • Developer tooling: PHPStan 2.x (level 5, targeting PHP 7.4) via szepeviktor/phpstan-wordpress, PHPCompatibility (testVersion 7.4-), ESLint flat config, Stylelint (stylelint-config-standard), and a dependency-free php:lint script. Lint everything with npm run lint.
  • Plugin switcher in the viewer topbar — a dropdown to jump straight to another plugin's docs.

Åtgärdat

  • Third-party admin notices (Elementor/Envo promos, update nags) no longer leak into the rendered document. WordPress's common.js relocates .notice elements after the first <h1> in .wrap — which was the document heading — so notices are now suppressed on the viewer screen, backed by a wp-header-end anchor and a CSS safety net.