Skip to content

Mockup lazy patterns 5.6.x - #1620

Open
petschki wants to merge 6 commits into
5.6.xfrom
mockup-lazy-patterns--5.6.x
Open

Mockup lazy patterns 5.6.x#1620
petschki wants to merge 6 commits into
5.6.xfrom
mockup-lazy-patterns--5.6.x

Conversation

@petschki

Copy link
Copy Markdown
Member

backports #1618 for Plone 6.2

MrTango added 5 commits July 17, 2026 12:29
…entation

pat-querystring contributed ~33KB src to the eager patterns chunk on every
page, though the widget only appears on Collection edit forms and the
querystring criteria UI. It also statically imported the contentbrowser
pattern, dragging an eager edge into pat-contentbrowser.

Split it into a thin registration module and querystring--implementation.js
(holding the widget and the contentbrowser import). The implementation is
grafted onto the single pattern instance in init(), so external consumers
that reach into instance state (pat-structure's textfilter reads
this.queryString.$sortOn/$sortOrder) keep working. Public options and
emitted markup are unchanged.

The implementation and its contentbrowser edge now load only on pages with a
.pat-querystring element.
…ntation

pat-recurrence was the single largest pattern in the eager patterns chunk
(~52KB src, incl. three statically-imported XML templates and the Modal
dependency), loaded on every page though the widget only appears on Event
add/edit forms.

Split it into a thin registration module (trigger, parser, and an init()
that dynamically imports the implementation on first match) plus
recurrence--implementation.js holding the widget, the XML templates and the
Modal import. Follows the existing tinymce--implementation lazy-pattern
convention. Public options and markup contract are unchanged.

The implementation now loads only on pages with a .pat-recurrence element,
in its own chunk.
Split the ~1000-line pat-modal implementation out of the every-page
eager patterns chunk. modal.js becomes a thin registration module that
loads modal--implementation.js on first .pat-plone-modal match; the
implementation grafts onto the instance from the prototype, since
imperative callers still do `new Modal()`.

jquery-form ($.fn.ajaxSubmit) moves from a top-level import to a lazy
`await import("jquery-form")` at its single call site in
handleFormAction, so it no longer loads on every page.

Imperative importers are repointed at modal--implementation:
controlpanels (registry / dexterity-types-listing / contentrule-elements)
and recurrence load it as part of their own lazy implementation chunks;
manageportlets is registered eagerly, so it loads the impl on demand
inside showEditPortlet. Side-effect registration imports (patterns.js,
tinymce links, structure actionmenu) keep pointing at the thin module.

Depends on the pat-recurrence lazification: recurrence is eagerly
registered, so its Modal import must live in recurrence--implementation
(a lazy chunk) for the modal body to actually leave the eager bundle.
Merge after the pat-recurrence PR.
…tion

pat-select2 contributed ~13KB src to the eager patterns chunk on every page,
plus a lazy select2_locale_* context map baked into the eager chunk, though
select2 widgets only appear on forms. (The select2 library itself was already
an async chunk; only the wrapper and the locale map were eager.)

Split it into a thin registration module and select2--implementation.js
holding the wrapper, the select2 library import and the select2_locale_*
context. The implementation is grafted onto the single pattern instance in
init(). Public options and emitted markup are unchanged.

pat-relateditems borrows select2's methods (Select2.prototype.* applied to
its own instance). To keep that working without pulling select2 back into the
eager chunk, relateditems now imports select2--implementation lazily in its
init() and calls the borrowed methods through it. This is the coordinated
change flagged between the select2 and relateditems lazification tickets.

The select2 wrapper and locale map now load only on pages with a .pat-select2
or .pat-relateditems element.
pat-upload contributed ~17KB src to the eager patterns chunk on every page,
though the upload UI only appears in folder contents and upload dialogs.

Split it into a thin registration module and upload--implementation.js
holding the jquery/underscore/i18n wiring and the lazily-loaded Dropzone
integration. The thin module keeps registering the .pat-upload trigger and
grafts the implementation prototype on first match. Public options and
emitted markup are unchanged.

pat-structure, pat-relateditems and the contentbrowser app construct upload
imperatively (new Upload(...)) and use the instance right away. The
implementation therefore stays a constructable Base.extend pattern and those
callers import it directly, so new Upload() yields a fully formed instance
synchronously. Registry.register is first-wins, so the eagerly imported thin
module remains the registered .pat-upload pattern; the implementation is
only reached via lazy chunks (the structure app view, the contentbrowser
component and the relateditems dynamic import).

Add a regression test asserting the implementation is constructable and
exposes its methods synchronously.

The implementation now loads only where a .pat-upload element exists.
@petschki
petschki requested a review from MrTango July 17, 2026 10:34
@petschki

Copy link
Copy Markdown
Member Author

/run-coredev-6.2-robottests

The pat-plone-modal lazification left links.js creating its modal via
registry.patterns["plone-modal"].init(...). That static initializer
constructs the *registered* pattern — now the thin registration module,
whose methods (show/hide/...) only appear after an async graft — while
LinkModal calls this.modal.show() synchronously right after construction.
First click on Insert Link/Image threw and the modal stayed broken, which
also failed every robot test funneling through it (tinymce, contentbrowser,
linkintegrity).

Construct modal--implementation directly instead; mockupParser reproduces
the option parsing of the registry path. links.js is only reached via the
lazily-loaded tinymce implementation, so the modal body stays out of the
eager bundle. Add a regression test asserting the implementation exposes
its methods synchronously.
@petschki

Copy link
Copy Markdown
Member Author

/run-coredev-6.2-robottests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants