You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+39Lines changed: 39 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,45 @@ All notable changes to this project will be documented in this file.
4
4
5
5
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
7
+
## [2.3.0] - 2026-05-14
8
+
9
+
### Added
10
+
11
+
-**`pattern:diff` command** (`src/Commands/PatternDiffCommand.php`) — compares a Gutenberg clipboard paste against an existing PHP pattern file and reports differences (missing translations, editor-only attributes, CSS drift, WooCommerce block issues). Options:
12
+
-`--from-stdin` — read Gutenberg HTML from stdin (pipe from `pbpaste`)
13
+
-`--apply` — merge clipboard changes into the PHP file, preserving all PHP translation wrappers (`esc_html_e`, `esc_attr_e`, `wp_kses_post`, `get_template_directory_uri`)
14
+
-`--dry-run` — with `--apply`: print the merged result to stdout instead of writing to disk
15
+
-`--theme` — theme config to use (default: `elayne`)
16
+
-`--json` — output diff results as JSON
17
+
-`--similarity-threshold` — minimum block similarity score to consider a match (0–1, default: `0.95`)
18
+
-`--show-suggestions` / `-s` — include fix suggestions in the output
19
+
20
+
-**`BlockNormalizer` class** (`src/PatternDiff/BlockNormalizer.php`) — normalises block HTML for comparison: strips editor-only attributes (`__privatePreviewState`, `isNotStackedOnMobile`, constrained layout flags, product-collection block flags), normalises CSS value tokens (font-size slugs → CSS variables, spacing presets), collapses whitespace, and decodes HTML entities. Exposes `detectEditorAttributes()`, `extractOuterBlockType()`, and `hasWooCommerceBlocks()` as public helpers.
21
+
22
+
-**`PatternDiffer` class** (`src/PatternDiff/PatternDiffer.php`) — calculates structural similarity between clipboard HTML and a PHP pattern file. Extracts block HTML from PHP, computes a similarity score via `similar_text`, and finds CSS, structural, and text-node differences. WooCommerce plugin paths (`wp-content/plugins/woocommerce/patterns/*`) are exempt via `isExempt()`.
23
+
24
+
-**`PatternSyncer` class** (`src/PatternDiff/PatternSyncer.php`) — implements the `--apply` merge strategy: extracts the PHP docblock header, builds a `text → PHP call` map from all translation wrappers in the original file, applies structural fixes to the clipboard (strips `__privatePreviewState`, normalises font-size slugs, removes nested `<p>` copy artefacts), then walks every HTML text node replacing raw strings with their original wrappers or generating new `esc_html_e()` calls for new strings.
25
+
26
+
-**`TranslationDetector` class** (`src/PatternDiff/TranslationDetector.php`) — finds text nodes in clipboard HTML that are not yet wrapped in a translation function in the existing PHP file. Generates `esc_html_e()` fix suggestions. Exposes `isTranslated()`, `generateTranslationWrapper()`, and `extractTranslatableText()` as public helpers.
27
+
28
+
-**`WooCommerceValidator` class** (`src/PatternDiff/WooCommerceValidator.php`) — validates WooCommerce-specific block structure in the diff context: checks `isDescendentOfQueryLoop` on WC blocks inside `product-template`, validates `<div>` wrappers and layout attributes, and inspects `product-collection` query metadata.
29
+
30
+
-**PHPUnit test suite for `PatternDiff`** — 6 new test files covering all public methods in the feature:
31
+
-`tests/PatternDiff/BlockNormalizerTest.php` — 29 tests for all normalisation methods
-**`PatternDiffer::isTranslatable()`** — the `if (preg_match(...))` guard around the CSS-value `return false` branch was accidentally omitted, causing the method to always return `false` after the single-character check. All text nodes after that point were silently skipped by the translation detector.
41
+
42
+
### Changed
43
+
44
+
-**`.vibe/config.toml`** — `python` and `python3` removed from the vibe tools denylist to allow local script execution during pattern diffing.
0 commit comments