---
title: "Egenverk Docs Viewer — Ändringslogg"
description: "Ändringslogg för Egenverk Docs Viewer. Vad som ändrats i varje tillägg, senaste först."
canonical: https://egenverk.se/plugins/docs-viewer/changelog
lang: sv
updated: 2026-09-23
alternate: https://egenverk.se/en/plugins/docs-viewer/changelog.md
---
# Ä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.

## 2.7.0 — 2026-09-23

**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".

## 2.6.0 — 2026-09-23

**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.

## 2.5.0 — 2026-09-23

**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.

## 2.4.0 — 2026-09-23

**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`.

## 2.3.0 — 2026-09-23

**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.

## 2.2.2 — 2026-09-23

**Ä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.

## 2.2.1 — 2026-09-23

**Ä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.

## 2.2.0 — 2026-09-23

**Ä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).

## 2.1.1 — 2026-09-23

**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.

## 2.1.0 — 2026-09-23

**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.

## 2.0.1 — 2026-09-23

**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.

## 2.0.0 — 2026-09-22

**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.

## 1.1.4 — 2026-09-22

**Ä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.

## 1.1.3 — 2026-09-22

**Å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.

## 1.1.2 — 2026-09-22

**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.

## 1.1.1 — 2026-09-22

**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()`.

## 1.1.0 — 2026-06-30

**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.

## 1.0.0 — 2026-06-18

**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.

- [Produktsida](https://egenverk.se/plugins/docs-viewer)
- [Dokumentation](https://egenverk.se/plugins/docs-viewer/docs)
- [Atom-flöde](https://egenverk.se/feeds/changelog/docs-viewer.xml)
