From 05e8906662e0c732cf4b3b4cd79da6a978233743 Mon Sep 17 00:00:00 2001 From: KoloMl Date: Wed, 20 May 2026 12:32:52 +0400 Subject: [PATCH 1/5] Fixed unclosed `
` tag in the content edit job view When new React UI was introduced in ff6b5258ec154eda8132e4c0f352fc8cddf11665, element .job-wizard was covered with the `
` element, but this element didn't have the corresponding closing tag. --- inc/Smartling/WP/View/ContentEditJob.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/Smartling/WP/View/ContentEditJob.php b/inc/Smartling/WP/View/ContentEditJob.php index 20d57e44..c2d7aced 100644 --- a/inc/Smartling/WP/View/ContentEditJob.php +++ b/inc/Smartling/WP/View/ContentEditJob.php @@ -234,7 +234,7 @@
- + Date: Wed, 20 May 2026 12:40:31 +0400 Subject: [PATCH 2/5] Disabled wrapper condition for closing tags in old `.job-wizard` section First condition was forcibly disabled, but the second one was not. This potentially creates stray closing tags when `$needWrapper` is `true` --- inc/Smartling/WP/View/ContentEditJob.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/Smartling/WP/View/ContentEditJob.php b/inc/Smartling/WP/View/ContentEditJob.php index c2d7aced..a736c89c 100644 --- a/inc/Smartling/WP/View/ContentEditJob.php +++ b/inc/Smartling/WP/View/ContentEditJob.php @@ -229,7 +229,7 @@ - + From fca8a6f501686e0bd723f262e6f19bd31e1707d7 Mon Sep 17 00:00:00 2001 From: Vitalii Solovei Date: Thu, 21 May 2026 22:51:23 +0200 Subject: [PATCH 3/5] fix broken html in contenteditjob view (WP-1004) Co-Authored-By: Claude Sonnet 4.6 --- composer.json | 2 +- inc/Smartling/WP/View/ContentEditJob.php | 263 +++++++++--------- readme.txt | 5 +- smartling-connector.php | 4 +- .../WP/View/ContentEditJobViewTest.php | 80 ++++++ 5 files changed, 211 insertions(+), 143 deletions(-) create mode 100644 tests/Smartling/WP/View/ContentEditJobViewTest.php diff --git a/composer.json b/composer.json index 2d32b371..98a04bec 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "smartling/wordpress-connector", "license": "GPL-2.0-or-later", - "version": "5.5.0", + "version": "5.5.1", "description": "", "type": "wordpress-plugin", "repositories": [ diff --git a/inc/Smartling/WP/View/ContentEditJob.php b/inc/Smartling/WP/View/ContentEditJob.php index a736c89c..92585d6f 100644 --- a/inc/Smartling/WP/View/ContentEditJob.php +++ b/inc/Smartling/WP/View/ContentEditJob.php @@ -91,150 +91,135 @@ let globalButton; - -
-

Translate content

-
- - -
-
Please wait...
-
- -
resolveTemplate(true); + $this->assertDivBalanced($html, 'taxonomy edit screen ($needWrapper=true)'); + } + + public function testHtmlDivTagsBalanceOnPostEditScreen(): void + { + $html = $this->resolveTemplate(false); + $this->assertDivBalanced($html, 'post edit screen ($needWrapper=false)'); + } + + public function testHiddenWrapperHasClosingTag(): void + { + $source = $this->stripNonHtml(file_get_contents(self::VIEW_FILE)); + $hiddenOpens = preg_match_all('#assertGreaterThan( + 0, + $hiddenOpens, + 'Legacy display:none wrapper should still open (it hides the legacy .job-wizard fallback)' + ); + } + + private function resolveTemplate(bool $needWrapper): string + { + $source = $this->stripNonHtml(file_get_contents(self::VIEW_FILE)); + + $source = preg_replace( + '#<\?php\s+if\s*\(\s*\$needWrapper\s*&&\s*false\s*\)\s*:\s*\?>(?:(?!<\?php\s+endif).)*<\?php\s+endif\s*;\s*\?>#s', + '', + $source + ); + + $source = preg_replace_callback( + '#<\?php\s+if\s*\(\s*\$needWrapper\s*\)\s*:\s*\?>((?:(?!<\?php\s+endif).)*)<\?php\s+endif\s*;\s*\?>#s', + static fn(array $m): string => $needWrapper ? $m[1] : '', + $source + ); + + $source = preg_replace('#<\?(?:php|=).*?\?>#s', '', $source); + + return $source; + } + + private function stripNonHtml(string $source): string + { + $source = preg_replace('#]*>.*?#is', '', $source); + $source = preg_replace('#]*>.*?#is', '', $source); + + return $source; + } + + private function assertDivBalanced(string $html, string $context): void + { + $opens = preg_match_all('##i', $html); + + $this->assertSame( + $opens, + $closes, + sprintf( + 'Unbalanced
tags on %s: %d opens vs %d closes. ' . + 'A mismatch here is what caused WP-1004 (postboxes below the Smartling box refusing to open).', + $context, + $opens, + $closes + ) + ); + } +} From 7c12fbc6922b51febb0ca8cb97bc926f32b5c95e Mon Sep 17 00:00:00 2001 From: Vitalii Solovei Date: Mon, 25 May 2026 09:26:18 +0200 Subject: [PATCH 4/5] improve test (WP-1004) Co-Authored-By: Claude Sonnet 4.6 --- .../WP/View/ContentEditJobViewTest.php | 46 ++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/tests/Smartling/WP/View/ContentEditJobViewTest.php b/tests/Smartling/WP/View/ContentEditJobViewTest.php index 89969f23..356ec935 100644 --- a/tests/Smartling/WP/View/ContentEditJobViewTest.php +++ b/tests/Smartling/WP/View/ContentEditJobViewTest.php @@ -20,30 +20,52 @@ public function testHtmlDivTagsBalanceOnPostEditScreen(): void $this->assertDivBalanced($html, 'post edit screen ($needWrapper=false)'); } + public function testHtmlDivTagsBalanceOnBulkSubmitScreen(): void + { + $html = $this->resolveTemplate(false, true); + $this->assertDivBalanced($html, 'bulk submit screen ($isBulkSubmitPage=true)'); + } + public function testHiddenWrapperHasClosingTag(): void { - $source = $this->stripNonHtml(file_get_contents(self::VIEW_FILE)); - $hiddenOpens = preg_match_all('#assertGreaterThan( - 0, - $hiddenOpens, - 'Legacy display:none wrapper should still open (it hides the legacy .job-wizard fallback)' + $html = $this->resolveTemplate(false); + + $this->assertSame( + 1, + preg_match( + '##i', + $html, + $matches, + PREG_OFFSET_CAPTURE + ), + 'Hidden display:none wrapper opening
should exist' + ); + + $tail = substr($html, $matches[0][1]); + $opens = preg_match_all('##i', $tail); + + $this->assertSame( + $opens, + $closes, + 'Hidden display:none wrapper must have a matching closing
' . + '(an unclosed wrapper here is what caused WP-1004).' ); } - private function resolveTemplate(bool $needWrapper): string + private function resolveTemplate(bool $needWrapper, bool $isBulkSubmitPage = false): string { $source = $this->stripNonHtml(file_get_contents(self::VIEW_FILE)); - $source = preg_replace( - '#<\?php\s+if\s*\(\s*\$needWrapper\s*&&\s*false\s*\)\s*:\s*\?>(?:(?!<\?php\s+endif).)*<\?php\s+endif\s*;\s*\?>#s', - '', + $source = preg_replace_callback( + '#<\?php\s+if\s*\(\s*\$needWrapper\s*\)\s*:\s*\?>((?:(?!<\?php\s+endif).)*)<\?php\s+endif\s*;\s*\?>#s', + static fn(array $m): string => $needWrapper ? $m[1] : '', $source ); $source = preg_replace_callback( - '#<\?php\s+if\s*\(\s*\$needWrapper\s*\)\s*:\s*\?>((?:(?!<\?php\s+endif).)*)<\?php\s+endif\s*;\s*\?>#s', - static fn(array $m): string => $needWrapper ? $m[1] : '', + '#<\?php\s+if\s*\(\s*!\$isBulkSubmitPage\s*\)\s*:\s*\?>((?:(?!<\?php\s+endif).)*)<\?php\s+endif\s*;\s*\?>#s', + static fn(array $m): string => $isBulkSubmitPage ? '' : $m[1], $source ); From 4fdde90e24be76d00c27ee3946021ec2300b126e Mon Sep 17 00:00:00 2001 From: Vitalii Solovei Date: Mon, 25 May 2026 09:54:50 +0200 Subject: [PATCH 5/5] improve test (WP-1004) Co-Authored-By: Claude Sonnet 4.6 --- tests/Smartling/WP/View/ContentEditJobViewTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Smartling/WP/View/ContentEditJobViewTest.php b/tests/Smartling/WP/View/ContentEditJobViewTest.php index 356ec935..6c508dd7 100644 --- a/tests/Smartling/WP/View/ContentEditJobViewTest.php +++ b/tests/Smartling/WP/View/ContentEditJobViewTest.php @@ -64,7 +64,7 @@ private function resolveTemplate(bool $needWrapper, bool $isBulkSubmitPage = fal ); $source = preg_replace_callback( - '#<\?php\s+if\s*\(\s*!\$isBulkSubmitPage\s*\)\s*:\s*\?>((?:(?!<\?php\s+endif).)*)<\?php\s+endif\s*;\s*\?>#s', + '#<\?php\s.*?if\s*\(\s*!\$isBulkSubmitPage\s*\)\s*:\s*\?>((?:(?!<\?php\s+endif).)*)<\?php\s+endif\s*;\s*\?>#s', static fn(array $m): string => $isBulkSubmitPage ? '' : $m[1], $source );