diff --git a/assets/components/sendex/js/mgr/misc/utils.js b/assets/components/sendex/js/mgr/misc/utils.js
index 56bf1e7..839e10e 100644
--- a/assets/components/sendex/js/mgr/misc/utils.js
+++ b/assets/components/sendex/js/mgr/misc/utils.js
@@ -1,3 +1,11 @@
+Sendex.utils.escapeHtmlAttr = function(value) {
+ return String(value)
+ .replace(/&/g, '&')
+ .replace(/"/g, '"')
+ .replace(//g, '>');
+};
+
Sendex.utils.renderActions = function(value, props, row) {
var res = [];
for (var i in row.data.actions) {
diff --git a/assets/components/sendex/js/mgr/widgets/newsletters.grid.js b/assets/components/sendex/js/mgr/widgets/newsletters.grid.js
index 0e8cbe2..052c4dc 100644
--- a/assets/components/sendex/js/mgr/widgets/newsletters.grid.js
+++ b/assets/components/sendex/js/mgr/widgets/newsletters.grid.js
@@ -88,21 +88,13 @@ Ext.extend(Sendex.grid.Newsletters,MODx.grid.Grid,Ext.apply({
: '' + _('yes') + '';
}
- ,_escapeHtmlAttr: function(value) {
- return String(value)
- .replace(/&/g, '&')
- .replace(/"/g, '"')
- .replace(//g, '>');
- }
-
,_renderImage: function(val,cell,row) {
if (!val) {return '';}
else if (val.substr(0,1) != '/') {
val = '/' + val;
}
- return '
';
+ return '
';
}
,_renderTemplate: function(val,cell,row) {
diff --git a/core/components/sendex/docs/changelog.txt b/core/components/sendex/docs/changelog.txt
index a9d2511..fd20dec 100644
--- a/core/components/sendex/docs/changelog.txt
+++ b/core/components/sendex/docs/changelog.txt
@@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [2.0.1-pl] - 2026-07-29
### Fixed
-- [#114] Mgr newsletter create appeared to hang on «Загружается…» and the grid stayed empty after reload (row was saved; duplicate-name error on retry). Newsletter `getlist` no longer uses JOIN/subquery SQL (subscriber count and template name are added in `prepareRow`); grid refresh after save is deferred so the create window can close first; `getlist`/`get` accept `view_sendex` as well as `view_document`; create `beforeSet()` returns strict `true` for MODX 3.
+- [#114] Mgr newsletter create appeared to hang on «Загружается…» and the grid stayed empty after reload (row was saved; duplicate-name error on retry). Newsletter `getlist` no longer uses JOIN/subquery SQL (subscriber count and template name are added in `prepareRow`); grid refresh after save is deferred so the create window can close first; `getlist`/`get` accept `view_sendex` as well as `view_document`; create `beforeSet()` returns strict `true` for MODX 3. Image column renderer uses `Sendex.utils.escapeHtmlAttr` (ExtJS does not keep grid scope for column renderers).
- [#111] Mgr row-action and menu icons no longer force `font-family: "Font Awesome 5 Free"` (Sendex does not load FA5); icons inherit the mgr icon font on MODX 2.3+/3.x or bundled FA4 on older MODX.
- [#25666] Transport package built on MODX 3.x stored vehicle class as `xPDO\Transport\xPDOObjectVehicle`, which MODX 2.8.8/2.8.9 cannot load (install fails with ~30 "Could not load class" errors). Release build now runs on MODX 2.x so the manifest uses the legacy vehicle format that installs on both MODX 2.8+ and 3.x.
diff --git a/tests/Unit/MgrGridSelectionContractTest.php b/tests/Unit/MgrGridSelectionContractTest.php
index 64cd736..a3ecc29 100644
--- a/tests/Unit/MgrGridSelectionContractTest.php
+++ b/tests/Unit/MgrGridSelectionContractTest.php
@@ -84,11 +84,15 @@ public function testNewsletterGridRenderersEscapeImageAndCloseSpanTags()
);
$this->assertStringContainsString("''", $source);
- $this->assertStringContainsString('_escapeHtmlAttr: function(value)', $source);
- $this->assertStringContainsString(".replace(/\"/g, '"')", $source);
$this->assertStringContainsString(
- "return '
';",
+ "return '
';",
$source
);
+
+ $utils = file_get_contents(
+ dirname(__DIR__, 2) . '/assets/components/sendex/js/mgr/misc/utils.js'
+ );
+ $this->assertStringContainsString('Sendex.utils.escapeHtmlAttr = function(value)', $utils);
+ $this->assertStringContainsString(".replace(/\"/g, '"')", $utils);
}
}