fix: #2999328 Give every Ace Format field its own settings

Issue: https://www.drupal.org/project/ace_editor/issues/2999328

Alternative to !15 (merged) (mortona2k) and !2 (closed) (Harlor), whose per-field design this builds on - credit to both. Opened as a separate MR because the mechanism changed.

The settings now travel on each field's wrapper, as a data-ace-formatter-settings attribute, instead of through the single global drupalSettings.ace_formatter key that let the last field rendered decide the theme and syntax for all of them.

Why not a generated identifier per field: Html::getUniqueId() is a per-request counter, while entity render arrays (markup and attached settings together) are stored in the render cache as one unit. Two entities rendered in two requests both get ace-formatter-body-0, and a later page that shows both from cache ends up with one settings bucket again - so the reported bug survives on any listing page. Carrying the settings in the markup is cache-safe by construction and needs no identifier at all.

Also in this MR:

  • Only the nine keys the JavaScript reads are sent, so a display whose stored settings still carry the option lists of an older release does not ship them to every visitor.
  • js/formatter.js uses once() per container, reuses an existing editor element instead of stranding a stale one after an AJAX rebuild, skips cleanly when no settings are present, and no longer has the fallback that handed Ace ace/theme/undefined when the lookup missed.
  • The formatter library depends on core/once.

Tests: AceFormatterMultipleFieldsTest - two fields on one entity keeping their own theme and syntax; the same field on two entities with the identifier counter reset between renders (the render-cache case a generated identifier fails); one payload per delta of a multi-value field; and the option lists never reaching the browser.

Verified locally: kernel+unit suite green, PHPStan clean, PHPCS clean.

Recommendation: close !2 (closed) as superseded (its change is the syntax_field / modelist / inline feature and it does not touch the global settings key, so it does not fix the reported bug), and take either !15 (merged) or this MR for the isolation itself. The syntax_field / modelist / inline feature from !15 (merged) and !2 (closed) is not included here and deserves its own issue.

AI-Generated: Yes

Checkpoints:

  • File an issue
  • Addition/Change/Update/Fix
  • Testing to ensure no regression
  • Automated unit testing coverage
  • Automated functional testing coverage
  • UX/UI designer responsibilities
  • Readability
  • Accessibility
  • Performance
  • Security
  • Developer Documentation
  • User Guide Documentation
  • Reviewed by human
  • Code review by maintainers
  • Full testing and approval
  • Credit contributors
  • Review with the product owner
  • Release notes snippet
  • Release

Merge request reports

Loading