Load Document button missing when MDXEditor mounts after documentLoaderMdxButton behavior runs
## Description ### Problem The **Load Document** toolbar button in `document_loader_mdx` is sometimes not injected into MDXEditor, especially after a cache rebuild or on first page load. The behavior in `modules/document_loader_mdx/js/mdx-editor-button.js` uses `once('dl-mdx-button', 'textarea[data-mdxeditor]', ...)` to attach once per textarea. MDXEditor is rendered asynchronously by React, so the toolbar often does not exist when the behavior first runs. Current logic: 1. If the toolbar exists → insert button (works) 2. If not, look for `textarea.previousElementSibling` as the MDX wrapper 3. **If that wrapper is not present yet → return without setting up a `MutationObserver`** 4. `once()` has already marked the textarea as processed, so the behavior never runs again 5. When React later mounts `.mdxeditor-wrapper` and `.mdxeditor-toolbar`, the button is never inserted ### Steps to reproduce 1. Enable `document_loader`, `document_loader_mdx`, and a module that renders MDXEditor on a form (e.g. a textarea with `data-mdxeditor`, such as AI Context Item add/edit forms) 2. Run `drush cr` 3. Load the form page (hard refresh helps) 4. Observe the MDXEditor toolbar — **Load Document** is intermittently missing ### Expected behavior The Load Document button appears in the MDXEditor toolbar whenever a `textarea[data-mdxeditor]` is present. ### Actual behavior The button is missing on some page loads. In the browser console/DOM: - `textarea[data-mdxeditor]` has `data-once` including `dl-mdx-button` - `.mdxeditor-wrapper` and `.mdxeditor-toolbar` exist - `.dl-mdx-load-btn` is absent Manually clearing `data-once` and re-attaching the behavior makes the button appear, confirming a one-shot race rather than missing library/settings. ### Proposed fix When the toolbar is not yet available: - If `textarea.previousElementSibling` is `.mdxeditor-wrapper`, observe it (current behavior) - **Otherwise, observe `textarea.parentNode` until the wrapper and toolbar appear**, instead of returning early Example approach: ```javascript const wrapper = textarea.previousElementSibling; const observeTarget = wrapper && wrapper.classList.contains('mdxeditor-wrapper') ? wrapper : textarea.parentNode; if (!observeTarget) { return; } const initObserver = new MutationObserver(function waitForToolbar() { const tb = findToolbarForTextarea(textarea); if (tb) { initObserver.disconnect(); insertButton(tb, editorId, textarea, dialogUrl, iconPath); } }); initObserver.observe(observeTarget, { childList: true, subtree: true }); ``` ### Environment - **Module:** `document_loader_mdx` (Document Loader 2.x) - **Drupal:** 10.5+ / 11.x - **Context:** Any form using MDXEditor via the AI module (`textarea[data-mdxeditor]`) ### Notes This is separate from site-specific issues such as duplicate module copies or stale extension caches. The race is in upstream JS timing between Drupal behaviors and React mount order. --- **Component suggestion:** `document_loader_mdx` **Category:** Bug report ## AI usage - [x] AI generated issue (with composer 2.5)
issue