feat: add Markdown rendering mechanism for AI crawlers#54
Open
matipojo wants to merge 550 commits into
Open
Conversation
2589d2a to
eda9991
Compare
…entor#35231) ## Summary - Add `Tooltip` wrapper to value component with `-webkit-line-clamp` for proper multi-line ellipsis truncation - Fix consistent spacing/padding across all indication list items (`pt: 1.5`, `pb: 1.5`, `pl: 2` instead of uneven `pl: 3`, `pb: 2`) - Simplify `box-shadow-transformer` and `repeater-to-items-transformer` to return flat content instead of nested `Stack` wrappers, eliminating extra spacing artifacts - Fix `array-transformer` to handle both single and array `ReactNode` values - Fix Infotip popover positioning by switching from `slotProps.popper.modifiers` to `PopperProps.modifiers` so the offset modifier reliably reaches the custom `StyledPopper` component ## Test plan - [ ] Open the style origin popover for a repeater property (e.g. box-shadow, background) and verify text is truncated with ellipsis when it overflows - [ ] Hover over a truncated value to confirm the full value is shown in a tooltip - [ ] Verify all indication items have consistent vertical and horizontal spacing - [ ] Verify the popover arrow aligns correctly with the trigger indicator (no horizontal shift) - [ ] Check RTL layout for correct popover positioning ## Jira [ED-21321](https://elementor.atlassian.net/browse/ED-21321) [ED-21321]: https://elementor.atlassian.net/browse/ED-21321?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Fix styling and layout issues in Repeater Indications Popovers to improve text truncation, spacing consistency, and tooltip functionality in the editor panel. Main changes: - Added Tooltip wrapper with text truncation using WebKit line clamp in ValueComponent for better overflow handling - Adjusted popover spacing and padding, replacing slotProps with PopperProps for proper offset positioning - Simplified array and repeater transformers by removing Stack components and using inline rendering for cleaner display _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
…#35236) ## PR Checklist <!-- Please check if your PR fulfills the following requirements: **Filling out the template is required.** Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. --> - [ ] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type What kind of change does this PR introduce? <!-- Please check the one that applies to this PR using "x" with no spaces eg: [x]. --> - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] CI related changes - [ ] Documentation content changes - [ ] Other... Please describe: ## Summary This PR can be summarized in the following changelog entry: * ## Description An explanation of what is done in this PR * ## Test instructions This PR can be tested by following these steps: * ## Quality assurance - [ ] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes #
…23474] (elementor#35257) ## Summary - Fixed a race condition where `e_opt_in_v4` and `e_atomic_elements` experiments were not activated on the very first page load of a fresh Elementor installation - Root cause: `Modules_Manager` (which registers experiments) is instantiated before `Core\Upgrade\Manager` (which writes `installs_history`) in `plugin.php::init_components()`. On first load, `install_compare()` found empty history and returned `false`, leaving experiment defaults as `STATE_INACTIVE` - Fix: when `installs_history` is empty, `install_compare()` now falls back to comparing `ELEMENTOR_VERSION` against the minimum — the current version IS the effective first-install version on that first request - Existing sites and upgrades are completely unaffected (their history is always populated before experiments are registered) - Added two test cases to `test-manager.php` covering the empty-history scenarios ## Test plan - [ ] Fresh install: verify `e_opt_in_v4` and `e_atomic_elements` experiments are active on the very first page load (before any subsequent requests) - [ ] Simulate by clearing the `elementor_install_history` DB option and reloading the admin — experiments should be active - [ ] Verify existing sites (non-empty history) are unaffected — experiments activate/deactivate as before - [ ] Run PHPUnit: `vendor/bin/phpunit tests/phpunit/elementor/core/experiments/test-manager.php --filter="test_is_feature_active__new_site"` — all 6 data-provider cases should pass, including the 2 new empty-history cases ## Jira [https://elementor.atlassian.net/browse/ED-23474](https://elementor.atlassian.net/browse/ED-23474) <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Fix new-site experiments activation by properly handling first installation requests before upgrade manager writes installation history. Main changes: - Modified install_compare() to use current plugin version when installation history is empty on first request - Added fallback logic comparing ELEMENTOR_VERSION against minimum version for fresh installations before history initialization - Added test cases validating experiment activation behavior with empty installation history scenarios _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
## PR Checklist <!-- Please check if your PR fulfills the following requirements: **Filling out the template is required.** Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. --> - [ ] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type What kind of change does this PR introduce? <!-- Please check the one that applies to this PR using "x" with no spaces eg: [x]. --> - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] CI related changes - [ ] Documentation content changes - [ ] Other... Please describe: ## Summary This PR can be summarized in the following changelog entry: * ## Description An explanation of what is done in this PR * ## Test instructions This PR can be tested by following these steps: * ## Quality assurance - [ ] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes # <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Fix unit selector highlighting logic in size control component to correctly display active state based on value presence and unit type. Main changes: - Renamed isActive prop to isUnitHighlighted and moved highlighting logic from resolve-bound-prop-value to size-field component - Removed hasSizeValue utility function and replaced with inline shouldHighlightUnit function checking size or auto unit - Updated unit selector tests to use isUnitHighlighted prop and added comprehensive test cases for highlighting behavior _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
…ic nested elements [ED-22825] (elementor#35223) ## Summary Undo/redo operations on atomic nested elements (e.g. Tabs widget children) fail because the undoable closures hold stale `V1Element` references. Atomic elements render children asynchronously via client-side Twig templates, so the Marionette view tree may not contain the recreated child views when an undo/redo closure executes. This PR adds a **fallback resolution strategy** to all undoable operations and legacy commands: - **`resolveContainer()`** — tries `container.lookup()` first, then falls back to `elementor.getContainer(id)` with DOM-connection validation - **Model-tree fallback** — when both view-based lookups fail, operations manipulate the Backbone model tree directly using `addModelToParent` / `removeModelFromParent` with `{ silent: true }`. When the parent is mid-render, its `_renderChildren` naturally picks up the silently-added models; when the parent has a live view, the two-step resolution in the legacy commands prefers the view-based path - **`findModelById`** — new utility in `document/component.js` to traverse the model tree independently of the view tree ### Why `rerenderAtomicAncestor` was removed The initial implementation included a `rerenderAtomicAncestor` helper that would force-render the nearest atomic widget after a silent model-tree change. Testing showed this is unnecessary: - **Legacy commands** use a two-step resolution: first try `findContainerById` to get a fresh container, prefer the view-based `addElement` path when a live view exists, and only fall through to the silent model-tree path when the parent is genuinely mid-render — in which case `_renderChildren` picks up the model automatically - **Undoable actions** in the turbo-repo follow the same pattern via `resolveContainer` + `addModelToParent`/`removeModelFromParent` ## Changes | File | Change | |------|--------| | `document/component.js` | Added `findModelById` utility for model-tree traversal | | `elements/commands/create.js` | Two-step container resolution with `findContainerById` fallback, `addViaModelTree` for viewless containers | | `elements/commands/delete.js` | Same two-step resolution pattern, `deleteViaModelTree` for viewless containers | | `resolve-element.ts` | New shared utilities: `resolveContainer`, `findModelInDocTree`, `addModelToParent`, `removeModelFromParent` | | `create-elements.ts` | Uses `resolveContainer` + model-tree fallback in undo/redo | | `remove-elements.ts` | Uses `resolveContainer` + model-tree fallback in undo/redo | | `duplicate-elements.ts` | Uses `resolveContainer` + model-tree fallback in undo/redo | | `move-elements.ts` | Uses `resolveContainer` in undo/redo | | `types.ts` | Added `BackboneModel`, `BackboneCollection` types and extended `ExtendedWindow` | | `create-elements.test.ts` | Tests for model-tree fallback on undo/redo | | `remove-elements.test.ts` | Updated test expectations for `resolveContainer` behavior | ## Test plan - [x] Unit tests pass for `resolve-element.ts`, `create-elements.test.ts`, `remove-elements.test.ts` - [x] Manual QA: Add Tabs widget → add tab → add element to tab → undo all → redo all (all cycles work, fourth tab renders correctly) - [x] Manual QA: Delete tab child → undo → redo (all cycles work) - [x] Manual QA: Multi-step undo all → redo all (widget removal + re-creation works) - [x] No new console errors from the implemented changes <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Fix stale element reference errors in undo/redo operations for nested atomic elements by implementing fallback model-tree manipulation when views are unavailable. Main changes: - Added resolveContainer utility with DOM connectivity check and fallback model lookup to handle async-rendered nested elements - Implemented direct model-tree manipulation methods (findModelById, addModelToParent, removeModelFromParent) as fallback for detached views - Updated all undoable operations (create, delete, duplicate, move, remove) to use container resolution with model-tree fallback _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
…lementor#35265) ## PR Checklist <!-- Please check if your PR fulfills the following requirements: **Filling out the template is required.** Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. --> - [ ] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type What kind of change does this PR introduce? <!-- Please check the one that applies to this PR using "x" with no spaces eg: [x]. --> - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] CI related changes - [ ] Documentation content changes - [ ] Other... Please describe: ## Summary This PR can be summarized in the following changelog entry: * ## Description An explanation of what is done in this PR * ## Test instructions This PR can be tested by following these steps: * ## Quality assurance - [ ] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes #
…e [ED-23473] (elementor#35269) ## Summary - Export `getComponentDocumentData` from `editor-components` public index - This export is needed by the components MCP tool to use async domain + resources instead of the synchronous list-components approach ## Test plan - [ ] Verify `getComponentDocumentData` is importable from `@elementor/editor-components` - [ ] Verify the components MCP tool works correctly with the async domain/resource implementation ## Jira [ED-23473](https://elementor.atlassian.net/browse/ED-23473) [ED-23473]: https://elementor.atlassian.net/browse/ED-23473?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Export getComponentDocumentData utility function to enable async MCP resource integration for component document data retrieval in external modules. Main changes: - Added public export of getComponentDocumentData from component-document-data utils module to package API surface - Enables external async MCP resource consumers to access component document metadata without internal imports _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## PR Checklist <!-- Please check if your PR fulfills the following requirements: **Filling out the template is required.** Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. --> - [ ] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type What kind of change does this PR introduce? <!-- Please check the one that applies to this PR using "x" with no spaces eg: [x]. --> - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] CI related changes - [ ] Documentation content changes - [ ] Other... Please describe: ## Summary This PR can be summarized in the following changelog entry: * ## Description An explanation of what is done in this PR * ## Test instructions This PR can be tested by following these steps: * ## Quality assurance - [ ] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes # <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Update Playwright screenshot tests to support WordPress 7.0 by implementing dynamic screenshot naming based on WordPress major version for nightly builds. Main changes: - Added getWpVersionedScreenshotName utility function to append version-specific suffix to screenshot filenames when WP_MAJOR_VERSION is set - Enhanced GitHub workflow to update both WordPress instances, run database migrations, and export major version as environment variable - Simplified Block Inserter interaction logic to use aria-expanded attribute check instead of complex visibility conditions _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
elementor#35263) ## PR Checklist <!-- Please check if your PR fulfills the following requirements: **Filling out the template is required.** Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. --> - [ ] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type What kind of change does this PR introduce? <!-- Please check the one that applies to this PR using "x" with no spaces eg: [x]. --> - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] CI related changes - [ ] Documentation content changes - [ ] Other... Please describe: ## Summary This PR can be summarized in the following changelog entry: * ## Description An explanation of what is done in this PR * ## Test instructions This PR can be tested by following these steps: * ## Quality assurance - [ ] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes # <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Remove inline children display feature from the structure panel navigator to simplify the UI and eliminate unused functionality for formatted text elements. Main changes: - Deleted InlineChildren class and all references, removing functionality that displayed nested formatted text nodes in navigator - Updated hasChildren() method to exclude inline children check, simplifying element hierarchy detection logic - Modified test suite to verify inline children are no longer displayed in navigator panel for formatted text widgets _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
## Summary - Added exponential backoff retry to the `@elementor/http-client` singleton Axios instance via a response interceptor — all 22+ call sites across the codebase get retry automatically with no changes required - Retries up to 3 times on network errors (no response), 5xx server errors, and 429 Too Many Requests; does **not** retry non-idempotent methods (POST, PATCH) to prevent duplicate operations on endpoints like create/lock/archive - Backoff delays: 1s → 2s → 4s with ±10% random jitter to avoid thundering-herd under load - Config object is never mutated — each retry receives a spread copy with an incremented `__retryCount` field - Added 17 unit tests covering initialization, success passthrough, all retry/no-retry conditions, delay timing, immutability, and 429 handling ## Test plan - [ ] Verify that GET requests against a temporarily unavailable endpoint are retried up to 3 times before surfacing an error - [ ] Verify that POST requests (e.g. saving a component, locking an element) are **not** retried on 5xx — they should fail immediately - [ ] Verify that 429 responses are retried with backoff - [ ] Verify that 4xx errors (400, 401, 403, 404) fail immediately with no retry - [ ] Run unit tests: `cd packages && npx jest packages/libs/http-client/src/__tests__/http.test.ts --no-coverage` - [ ] Confirm no regressions in editor save/load flows ## Jira [ED-23523](https://elementor.atlassian.net/browse/ED-23523) [ED-23523]: https://elementor.atlassian.net/browse/ED-23523?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Add exponential backoff retry mechanism to HTTP client to improve resilience against transient failures and rate-limiting errors. Main changes: - Implemented response interceptor with exponential backoff retry logic for safe HTTP methods (GET, HEAD, OPTIONS, PUT, DELETE) - Added automatic retry on 5xx server errors, 429 rate-limiting, and network failures with 3 max retries and progressive timeout scaling - Created comprehensive test suite covering retry behavior, timeout scaling, method filtering, and edge cases _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
…#35278) <img width="373" height="179" alt="image" src="https://github.com/user-attachments/assets/2f2c744e-e570-4ce6-96d6-ae8f4c8dc206" /> ## Summary - Remove `componentsProps` tooltip margin and `PopperProps` offset modifier from `Infotip` in styles-inheritance-infotip - Fixes popover/inheritance popover positioning so they appear above the editor panel instead of over Angie - Fixes the small triangle indicator - Prevents popovers from stacking on top of each other ## Test plan - [ ] Open Elementor editor with Angie active - [ ] Trigger styles inheritance infotip/popover - [ ] Verify popover appears above the editor panel, not over Angie - [ ] Verify the triangle indicator renders correctly - [ ] Verify multiple popovers don't stack on top of each other ## Jira [ED-23465](https://elementor.atlassian.net/browse/ED-23465) [ED-23465]: https://elementor.atlassian.net/browse/ED-23465?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Fix popover positioning logic in styles inheritance infotip to correctly handle RTL layouts when Angie (AI assistant) is active. Main changes: - Removed custom popover offset calculation logic that was causing incorrect positioning in RTL layouts - Changed Infotip placement from "top" to "top-end" for consistent anchor positioning across different UI states - Eliminated unused triggerRef and sectionWidth props from TooltipOrInfotip component to simplify implementation _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…activated [ED-23517] (elementor#35279) ## Summary Fixes [ED-23517](https://elementor.atlassian.net/browse/ED-23517): when Elementor Pro is deactivated, interactions saved with Pro-only triggers (hover, click, scrollOn) were still executed on page load via the free frontend `interactions.js` default path. ## Changes - Gate `applyAnimation` so only free-frontend-supported triggers (`load`, `scrollIn`, `scrollOut`) run on init. - Export `isFreeFrontendSupportedTrigger` from `interactions-utils.js` with documented trigger allowlist. ## Test plan - [ ] With Pro off, page with saved hover/click/scrollOn interactions does not run those animations on load. - [ ] Load/scrollIn/scrollOut still behave as before. Made with [Cursor](https://cursor.com) [ED-23517]: https://elementor.atlassian.net/browse/ED-23517?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Fix pro-only interaction triggers (hover, click, scrollOn) from executing on page load when pro features are deactivated in the free frontend bundle. Main changes: - Added FREE_FRONTEND_SUPPORTED_TRIGGERS whitelist containing only load, scrollIn, and scrollOut triggers for free tier - Implemented isFreeFrontendSupportedTrigger validation function to filter interaction triggers before execution - Updated processElementInteractions to skip applying animations for pro-only triggers in the free bundle _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder-->
…3463] (elementor#35252) ## PR Checklist <!-- Please check if your PR fulfills the following requirements: **Filling out the template is required.** Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. --> - [ ] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type What kind of change does this PR introduce? <!-- Please check the one that applies to this PR using "x" with no spaces eg: [x]. --> - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] CI related changes - [ ] Documentation content changes - [ ] Other... Please describe: ## Summary This PR can be summarized in the following changelog entry: * ## Description An explanation of what is done in this PR * ## Test instructions This PR can be tested by following these steps: * ## Quality assurance - [ ] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes # <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Add scroll interaction tracking system to synchronize grid overlay visualization with active scroll-based animation configurations in the editor. Main changes: - Created scroll interaction event system with CustomEvent dispatching to communicate active scroll parameters across components - Added popover lifecycle callbacks to Repeater component enabling grid overlay sync on interaction item open/close - Integrated syncGridOverlay calls in InteractionDetails and InteractionsList to update visual feedback when scroll settings change _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: Batsirai Muchareva <162136788+Batsirai-muchareva@users.noreply.github.com> Co-authored-by: Netanel Baba <50736016+Ntnelbaba@users.noreply.github.com> Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
## PR Checklist <!-- Please check if your PR fulfills the following requirements: **Filling out the template is required.** Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. --> - [ ] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type What kind of change does this PR introduce? <!-- Please check the one that applies to this PR using "x" with no spaces eg: [x]. --> - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] CI related changes - [ ] Documentation content changes - [ ] Other... Please describe: ## Summary This PR can be summarized in the following changelog entry: * ## Description An explanation of what is done in this PR * ## Test instructions This PR can be tested by following these steps: * ## Quality assurance - [ ] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes # <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Fix file upload validation to allow WordPress-managed temporary files from AI image generation while maintaining security for direct user uploads. Main changes: - Added conditional path validation that skips check when is_elementor_upload flag is true for WordPress filter context - Preserved strict path validation for direct method calls like import_template to prevent security vulnerabilities - Enhanced code documentation explaining the dual validation behavior for different upload scenarios _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder-->
…6] (elementor#35280) Angie “create widget” install promotions were shown to every editor user when the Angie plugin was not active. They are now limited to sites where the Angie plugin is active (any user) or to WordPress administrators (`manage_options`), who can still install the plugin. **Changes:** `is_angie_active` is added to editor config (via `is_plugin_active( 'angie/angie.php' )`). `@elementor/editor-mcp` exports `shouldShowAngieInstallPromotion()` (true when Angie is active or the current user is an administrator). The Elements panel widget-creation footer and the `CreateWidget` modal listener respect this flag. **Ticket:** https://elementor.atlassian.net/browse/ED-23546 **Merge order:** Core should merge before the matching Elementor Pro PR that consumes `shouldShowAngieInstallPromotion`. --- ## PR Checklist - [x] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type - [x] Bugfix ## Summary Hide Angie widget-creation install promotions for non-administrators when the Angie plugin is not active; keep promotions for all users when Angie is active, and for administrators when it is not. ## Description See top of this description. ## Test instructions 1. As **administrator**, Angie **inactive**: open Elements, search widgets — widget-creation footer with Angie CTA should appear; opening the install modal should work. 2. As **non-admin** (e.g. Editor), Angie **inactive**: same search — footer should **not** appear. 3. With Angie **active** (any role that can use the editor): footer should appear for users who could see it before (per existing panel rules). ## Quality assurance - [x] I have tested this code to the best of my abilities - [x] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes # <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Fix Angie promotion visibility in Elementor panel by restricting widget creation prompts to administrators or when Angie plugin is actively installed. Main changes: - Added elementorIsAngieIframeInDocument() helper function to detect active Angie plugin presence via iframe - Implemented access control in onSearchEmpty() to gate widget creation view based on Angie presence or administrator role - Empty widget creation region when neither Angie is installed nor user has administrator privileges _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
## PR Checklist <!-- Please check if your PR fulfills the following requirements: **Filling out the template is required.** Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. --> - [ ] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type What kind of change does this PR introduce? <!-- Please check the one that applies to this PR using "x" with no spaces eg: [x]. --> - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] CI related changes - [ ] Documentation content changes - [ ] Other... Please describe: ## Summary This PR can be summarized in the following changelog entry: * ## Description An explanation of what is done in this PR * ## Test instructions This PR can be tested by following these steps: * ## Quality assurance - [ ] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes # Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
## Summary - Fix `one-click-release.yml` passing `PACKAGE_VERSION` (e.g. `3.30.0-beta1`) directly to `publish-packages.yml`'s `version` input, which fails the strict `^X.Y.Z$` semver validation - For **beta**: passes `version=3.30.0`, `version_suffix=beta1`, `tag=beta` - For **GA**: passes `version=3.30.0`, `version_suffix=` (empty), `tag=latest` ## Test plan - [ ] Trigger `one-click-release` with `channel=beta`, `dry_run=true` — `Validate Inputs` step should pass - [ ] Trigger `one-click-release` with `channel=ga`, `dry_run=true` — `Validate Inputs` step should pass - [ ] Confirm beta packages publish as `X.Y.Z-betaN` under dist-tag `beta` - [ ] Confirm GA packages publish as `X.Y.Z` under dist-tag `latest` <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Fix package publishing workflow by correcting version and tag parameter passing to ensure proper NPM package release with appropriate version suffixes and distribution tags. Main changes: - Added three new job outputs (CLEAN_PACKAGE_VERSION, VERSION_SUFFIX, NPM_TAG) to release job for downstream workflow consumption - Implemented channel-based logic to compute VERSION_SUFFIX from package version and set NPM_TAG (latest for GA, channel name otherwise) - Updated publish-packages workflow inputs to use corrected version parameters instead of full PACKAGE_VERSION and PACKAGE_TAG _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
…or#35295) ## Summary Add Mixpanel tracking for Angie CTA and install flows in the widget search / Create Widget experience. ## PR Checklist - [x] The commit message follows our guidelines ## PR Type - [x] Feature ## Description This PR adds two new Mixpanel events to track user engagement with Angie promotion and installation from the widget search flow: 1. **`angie_cta_clicked`** — fires when user clicks "Create with Angie" CTA from the widget search empty state - `entry_point: "search_widget"` - `has_angie_installed: true | false` 2. **`angie_install_started`** — fires when user clicks "Install Angie" button in the install dialog - `trigger_source: "search_widget"` **Implementation:** - Added `@elementor/events` dependency to `@elementor/editor-widget-creation` - Integrated `trackEvent` calls in `CreateWidget` component (`handleShow` and `handleInstall`) - Unit tests verify both events fire with correct properties **Decision rationale:** - Used existing `trackEvent` from `@elementor/events` (same pattern as transition control analytics) - Events fire before any async operations to ensure tracking even if operations fail - Separate `entry_point` / `trigger_source` property names match the Jira spec exactly ## Test instructions 1. Open editor on test.local 2. Go to widgets panel → search for a non-existent widget (to trigger empty state) 3. Click "Create with Angie" CTA 4. Verify `angie_cta_clicked` event in Mixpanel with `entry_point: "search_widget"` and `has_angie_installed` boolean 5. If Angie not installed, click "Install Angie" button 6. Verify `angie_install_started` event in Mixpanel with `trigger_source: "search_widget"` Unit tests: ```bash npm run test:packages -- packages/core/editor-widget-creation/src/components/__tests__/create-widget.test.tsx ``` ## Quality assurance - [x] I have tested this code to the best of my abilities - [x] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) — not applicable for internal analytics Fixes https://elementor.atlassian.net/browse/ED-23550 Made with [Cursor](https://cursor.com) <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Add Mixpanel analytics tracking to Angie AI widget creation flow to monitor user engagement and installation patterns from search widget entry point. Main changes: - Implemented `angie_cta_clicked` event tracking with entry point context and Angie installation status on widget creation trigger - Added `angie_install_started` event tracking with trigger source parameter when user initiates Angie plugin installation - Extended CustomEvent detail type to include entry_point parameter and persist it using useRef across component lifecycle _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder-->
…23556] (elementor#35305) ## Summary - The modal close button was changed from a `<div>` to a `<button>` (ED-18852) for accessibility, but the browser-default button reset was only applied inside `#elementor-template-library-modal` - All other modals sharing the same header template were broken: Finder, Hotkeys, New Template, and Beta Tester showed a box-styled button instead of a clean icon - Moved the `button` reset into `_dialog-templates.scss` using `:is(button)` so it applies universally to every modal using `.elementor-templates-modal__header__close` - Added `align-items: center` to `__items-area` to fix vertical misalignment between close button and adjacent items (e.g. Beta Tester's "Don't Show Again" text) - Removed the now-redundant `button` reset from `_templates-modal.scss` and the partial `border: none` workaround from `_beta-tester.scss` ## Test plan - [ ] Open Finder (Cmd+E) — close button should show as a clean × icon with a left border, not a box - [ ] Open Keyboard Shortcuts modal — close button should look correct - [ ] WP Admin > Templates > Add New — close button styled correctly - [ ] WP Admin > Elementor > Beta Tester modal — close button and "Don't Show Again" text should be vertically aligned - [ ] Open Template Library (Add Template in editor) — regression check, close button still looks correct ## Jira [ED-23556](https://elementor.atlassian.net/browse/ED-23556) [ED-23556]: https://elementor.atlassian.net/browse/ED-23556?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Fix inconsistent close button styling in shared modal components by consolidating button reset styles into common dialog template styles. Main changes: - Removed duplicate button style resets from beta-tester.scss and templates-modal.scss to eliminate redundancy - Added centralized button reset styles in dialog-templates.scss using :is(button) selector for proper rendering - Fixed modal header items alignment by adding center alignment to items-area flexbox container _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…tomic elements [ED-23356] (elementor#35281)
Made String Translatable in controls.php <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Make promotional control text translatable in motion effects UI to support internationalization and improve user experience for non-English speakers. Main changes: - Wrapped hardcoded "None" string with esc_html__() translation function and 'elementor' text domain for i18n support _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com> Co-authored-by: Louis Wolmarans <louiswol94@gmail.com>
…ntor#35310) ## PR Checklist <!-- Please check if your PR fulfills the following requirements: **Filling out the template is required.** Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. --> - [x] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type What kind of change does this PR introduce? <!-- Please check the one that applies to this PR using "x" with no spaces eg: [x]. --> - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] CI related changes - [x] Documentation content changes - [ ] Other... Please describe: ## Description An explanation of what is done in this PR Applies small changes to the copy of the plugin description on both the plugin file and also the readme.txt to include information about the Atomic Editor and its features. ## Quality assurance - [x] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features)
## PR Checklist <!-- Please check if your PR fulfills the following requirements: **Filling out the template is required.** Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. --> - [ ] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type What kind of change does this PR introduce? <!-- Please check the one that applies to this PR using "x" with no spaces eg: [x]. --> - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] CI related changes - [ ] Documentation content changes - [ ] Other... Please describe: ## Summary This PR can be summarized in the following changelog entry: * ## Description An explanation of what is done in this PR * ## Test instructions This PR can be tested by following these steps: * ## Quality assurance - [ ] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes # <!--start_gitstream_placeholder--> ### ✨ PR Description Purpose: Temporarily disable video widget tests in regression and container test suites to unblock CI pipeline while video-related functionality is being fixed. Main changes: - Commented out 'video' widget from elements regression test suite template list - Skipped container test for widgets display with various directions and content width - Skipped container flex wrap widget display test with TODO references to ED-23584 _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder-->
…#35675) ## PR Checklist <!-- Please check if your PR fulfills the following requirements: **Filling out the template is required.** Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. --> - [ ] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type What kind of change does this PR introduce? <!-- Please check the one that applies to this PR using "x" with no spaces eg: [x]. --> - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] CI related changes - [ ] Documentation content changes - [ ] Other... Please describe: ## Summary This PR can be summarized in the following changelog entry: * ## Description An explanation of what is done in this PR * ## Test instructions This PR can be tested by following these steps: * ## Quality assurance - [ ] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes # <!--start_gitstream_placeholder--> ### ✨ PR Description ## 1. Problem & Context Introduces number-range prop type to support min/max value constraints for textarea fields during widget migration (ED-23579). Enables structured validation of bounded numeric inputs instead of flat scalar values. ## 2. What Changed (Where) - **Backend**: New `Number_Range_Prop_Type` class defines shape with min/max Number fields - **Frontend**: TypeScript prop type and schema export for editor-props package - **Migration**: Added number→number-range conversion ops and textarea maxlength→length field mapping in manifest ## 3. How It Works Migration converts legacy number values to number-range structure: scalar moves to `value.max.value`, type becomes `number-range`. Reverse migration extracts max value back to scalar on downgrade. Shape ensures min/max are both Number_Prop_Type instances for validation consistency. ## 4. Risks Migration ops assume source `$type === "number"` — if existing data lacks type field or has unexpected structure, conversion silently skips. Test with actual textarea data to confirm maxlength→length→number-range chain works end-to-end. _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
<!--start_gitstream_placeholder--> ### ✨ PR Description ## 1. Problem & Context Form input fields were inaccessible because the schema validation wasn't properly filtering non-configurable properties. The fix refactors `isPropKeyConfigurable` to accept both prop key and type, enabling context-aware filtering of internal properties like `_cssid`, `classes`, and `attributes`. ## 2. What Changed (Where) - **widgets-schema-resource.ts**: Moved property filtering into `Object.entries().filter()` chain using enhanced `isPropKeyConfigurable` check; removed post-processing deletion loop. - **validate-input.ts**: Updated `isPropKeyConfigurable` call to pass `propSchema` parameter for type-aware validation. - **props-to-llm-schema.ts**: Rewrote `isPropKeyConfigurable(key, propType?)` to allow LLM-configurable overrides via `propType.meta.llm_configurable`; removed unused `propsSchemaToJsonSchema` function. ## 3. How It Works Non-configurable keys are now checked in two stages: (1) if key is in blocklist, check if propType explicitly allows it via `llm_configurable` meta flag; (2) otherwise, property is configurable. This lets special properties opt-in to exposure when needed, rather than blanket exclusion. ## 4. Risks Minor: The signature change to `isPropKeyConfigurable` adds an optional parameter. Callers passing only the key still work but won't benefit from type-aware filtering—confirm all call sites get updated. No schema version bump needed since this is internal API. _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: Nikita (Mykyta) <134918658+mykytamurzin@users.noreply.github.com>
<!--start_gitstream_placeholder-->
### ✨ PR Description
## 1. Problem & Context
Refactoring design-system import flows to support both legacy
(single-file) and streaming (directory-based) formats with configurable
conflict resolution strategies. Centralizes import logic into reusable
utilities and decouples runner concerns from data handling.
## 2. What Changed (Where)
| File | Change |
|------|--------|
| `import.php` (route) | Added `include` and `customization` parameters
to API schema |
| `design-system-import-context.php` | New context resolver for import
flow type and conflict strategy |
| `processes/import.php` | Extracted runner data construction into
`build_runner_data()` method |
| `global-classes-repository.php` | Added `get_order()`,
`update_order_and_labels()`, `delete_all()` methods |
| `global-classes/runners/import.php` | Refactored to use context
resolver; delegates to `Import_Utils`/`Legacy_Import_Utils` |
| `import-utils.php`, `legacy-import-utils.php` | New utilities with
detailed conflict resolution (skip/replace/merge/override-all) |
| `variables/runners/import.php` | Updated to use context resolver;
returns structured result objects |
| Tests | Added comprehensive conflict resolution tests; fixed kit state
isolation bugs |
## 3. How It Works
Import request specifies `include: ['settings'|'design-system']` and
optional `customization.{settings|design-system}.conflict_resolution`.
`Design_System_Import_Context` normalizes this into a resolution
strategy. For v4.1.0+, `Import_Utils` streams directory of individual
class files with `order.json` metadata; legacy format falls back to
single JSON. Conflict resolution (skip/replace/merge/override-all)
applies per-item, tracking created/renamed/replaced/skipped/failed
results. Repository operations wrapped in transactions with runtime
cache invalidation.
## 4. Risks
**Backward compatibility**: Legacy format detection uses version
comparison—verify `manifest.elementor_version` is always present in old
exports. **Transaction safety**: ROLLBACK on exception assumes DB
isolation; test with concurrent imports. **Kit switching**:
`get_kit_for_reading()` logic assumes previous kit still exists after
new kit creation—dangling references will fail silently. Mitigate with
tests validating kit state transitions (added in test helpers).
_Generated by LinearB AI and added by gitStream._
<sub>AI-generated content may contain inaccuracies. Please verify before
using.
💡 **Tip:** You can customize your AI Description using **Guidelines**
[Learn
how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub>
<!--end_gitstream_placeholder-->
---------
Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
Co-authored-by: Omer Haim Israeli <omeri@elementor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
## PR Checklist
- [x] The commit message follows our guidelines
## PR Type
- [x] Feature
## Summary
This PR can be summarized in the following changelog entry:
* Internal: Export global classes in chunks to support up to 10k classes
per site [ED-23093]
## Description
Replaces the single `global-classes.json` export file with the chunked
layout the matching import (`Import_Utils::import_classes`) already
expects:
- `global-classes/order.json` — `[{ id, label }, ...]`
- `global-classes/<class_id>.json` — one file per class
Streams classes from the repository via
`Global_Classes_Repository::each_item()` and pre-encodes each entry to
JSON so the export framework writes raw strings into the zip without
holding a full in-memory array. This is the export-side counterpart of
the chunked import shipped in elementor#35677.
Also fixes a pre-existing perf bug in
`Site_Settings::get_classes_count()`: it was loading every global class
via `Global_Classes_Repository::all()->get()` just to count them, which
made export hang on sites with hundreds/thousands of classes. Now reads
the order array from kit meta instead — same number, no class data
loaded. O(N) → O(1).
Reopen of elementor#35681 (closed when the base
`feature/ED-23093/frontend-optimizations` was merged into main).
## Test instructions
1. Seed a site with a large number of global classes (e.g. 1000) —
`scratch/seed-global-classes.php` can be used for this.
2. Trigger an export from the editor (Tools → Export Kit) including site
settings.
3. Verify the exported zip contains `global-classes/order.json` plus one
`global-classes/<id>.json` per class.
4. Verify the export completes in seconds (was previously hanging for
minutes due to the count bug).
5. Re-import the resulting kit and verify all classes appear correctly.
## Quality assurance
- [x] I have tested this code to the best of my abilities
- [x] I have added unittests to verify the code works as intended
- [ ] Docs have been added / updated (for bug fixes / features)
Fixes ED-23093
Made with [Cursor](https://cursor.com)
[ED-23093]:
https://elementor.atlassian.net/browse/ED-23093?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
<!--start_gitstream_placeholder-->
### ✨ PR Description
## 1. Problem & Context
Refactoring global classes export to use chunked individual class files
instead of a single monolithic file, enabling better scalability and
incremental export of design system data. Part of ED-23093.
## 2. What Changed (Where)
- **export.php**: Export logic restructured to generate per-class JSON
files plus `order.json` manifest; sanitization logic extracted to
private methods
- **site-settings.php**: `get_classes_count()` now uses kit-scoped
`Global_Classes_Order` instead of repository-wide count
- **test-export-runner.php**: Tests updated to verify chunked file
structure, with new setUp() and helper method for file indexing
## 3. How It Works
Export now iterates kit-scoped classes via
`Global_Classes_Repository::each_item()`, sanitizing each via
`Global_Classes_Parser::parse_items()`. Valid items generate individual
JSON files keyed by class ID. Concurrently builds `order.json` mapping
IDs to labels from sanitized data. Invalid classes are silently dropped;
empty exports return bare manifest. Kit-scoped ordering replaces global
repository ordering, ensuring consistent per-kit exports.
## 4. Risks
**Data loss during export**: Invalid classes filtered silently—malformed
data won't surface in exports but won't error either. Mitigation:
logs/monitoring on parse failures advised. **Kit-scoped behavior
shift**: Count/order now kit-dependent vs. global—verify no code assumes
global state. **Test coverage**: New tests handle happy path and invalid
items, but no test for missing kit scenario (returns 0 count silently).
_Generated by LinearB AI and added by gitStream._
<sub>AI-generated content may contain inaccuracies. Please verify before
using.
💡 **Tip:** You can customize your AI Description using **Guidelines**
[Learn
how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub>
<!--end_gitstream_placeholder-->
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
…0] (elementor#35699) ## Summary - **Scope:** This PR only updates the **widget creation empty state and search footer** copy and CTA styling (the `e_widget_creation` experiment UI when searching the Elements panel). It does **not** implement the full persistent Angie section below the main widgets described in the ticket. - CTA label is **Create custom widget** when the Angie plugin is active, **Install Angie** when it is not (`Hints::is_plugin_active( 'angie' )`). Click behavior is unchanged: still dispatches `elementor/editor/create-widget` for the existing install modal / Angie flow. - CTA uses `--e-pink-900` for link color; AI icon removed from the CTA button markup (text-only CTA). - Playwright expectations updated for Angie-not-installed (search footer and empty state). ## Test plan - [ ] With `e_widget_creation` active and Angie inactive: search with results → footer CTA reads Install Angie; search with no matches → empty-state CTA reads Install Angie; click still opens the promotion modal / install flow. - [ ] With Angie active: CTA reads Create custom widget and opens Angie as before. - [ ] Run widget creation Playwright suite (or rely on CI). ## Jira [ED-23900](https://elementor.atlassian.net/browse/ED-23900) [ED-23900]: https://elementor.atlassian.net/browse/ED-23900?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!--start_gitstream_placeholder--> ### ✨ PR Description ## 1. Problem & Context Conditionally show "Install Angie" vs "Create custom widget" CTA based on Angie plugin status, and simplify button markup by removing redundant icon markup. Ticket: ED-23900. ## 2. What Changed (Where) - `panel-elements.php`: Added `Hints` import; compute CTA text server-side based on `Hints::is_plugin_active('angie')`; removed icon markup from both buttons. - `_elements.scss`: Changed button color from `var(--e-a-color-accent-promotion)` to `#{$e-pink-900}`. - `widget-creation.test.ts`: Updated assertions to expect "Install Angie" text instead of "Create custom widget". ## 3. How It Works Server-side logic checks plugin activation once per page load, stores result in `$widget_creation_cta_text`, and injects the appropriate label into both template buttons. Icon removed from markup (likely handled via CSS or not needed). ## 4. Risks Test expectations hardcoded to "Install Angie"—will fail if Angie becomes active in test environment. Verify test setup doesn't auto-activate Angie or add conditional logic. _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…tor#35716) ## Description Bumps the minimum required WordPress version from **6.7** to **6.8** per ED-23932. ## What changed - `readme.txt`: `Requires at least: 6.7` → `6.8` - `.github/workflows/phpunit.yml`: dropped `"6.7"` from the `wordpress_versions` matrices for both the PR/Merge job and the Nightly job, since 6.7 is no longer a supported minimum. ## Jira [ED-23932](https://elementor.atlassian.net/browse/ED-23932) Made with [Cursor](https://cursor.com) [ED-23932]: https://elementor.atlassian.net/browse/ED-23932?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!--start_gitstream_placeholder--> ### ✨ PR Description ## 1. Problem & Context Bumping WordPress minimum version from 6.7 to 6.8 across CI testing to align with updated project requirements. ## 2. What Changed (Where) `.github/workflows/phpunit.yml`: Updated WordPress version matrix for PR/merge tests (`["latest", "6.9", "6.8"]`) and nightly tests (`["latest", "6.9", "6.8", "nightly"]`), dropping 6.7 support. ## 3. How It Works PHPUnit runner workflows now test against WordPress 6.8+ instead of 6.7+, ensuring CI validates compatibility with the new minimum version floor. ## 4. Risks None — straightforward version bump in test matrix with no code logic changes or dependency modifications. _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
This PR bumps the version to **4.2.0**. **Changes:** - Updated version in `elementor.php` - Updated version in `package.json` files - Updated version in packages **Created by:** GitHub Actions workflow **Branch:** `version-4.2.0-to-main` Co-authored-by: elementorbot <admin@elementor.com>
<!--start_gitstream_placeholder-->
### ✨ PR Description
## 1. Problem & Context
CI flakiness in global classes deletion tests — the save button's state
transition wasn't being properly awaited after clicking, causing race
conditions. Replaced a commented-out wait on button `disabled` state
with a wait on `hidden` state using the project's centralized timeout
config.
## 2. What Changed (Where)
- `tests/playwright/sanity/modules/v4-tests/global-classes/utils.ts`:
Added timeout config import and replaced commented-out button state wait
with proper hidden state wait in `saveAndCloseClassManager()`
## 3. How It Works
After clicking save in the class manager, the test now explicitly waits
for the save button to disappear (hidden state) before attempting to
close the dialog. Uses `timeouts.expect` from centralized config instead
of hardcoded timeout, ensuring consistency with project-wide timing
expectations. The `.catch(() => {})` swallows errors if the button
disappears faster than expected.
## 4. Risks
None — this strictly improves test stability by synchronizing on UI
state that already exists.
_Generated by LinearB AI and added by gitStream._
<sub>AI-generated content may contain inaccuracies. Please verify before
using.
💡 **Tip:** You can customize your AI Description using **Guidelines**
[Learn
how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub>
<!--end_gitstream_placeholder-->
…ntor#35626) ## Summary - Add `wordpress/mcp-adapter` (^0.5.0) and lockfile updates including `wordpress/php-mcp-schema`. - Register the `mcp` module in `Modules_Manager` and implement `modules/mcp` wired to `WP\\MCP\\Core\\McpAdapter`. - Gate the module behind the `e_wp_abilities_api` experiment; register Elementor ability category, abilities (list pages, structure, settings, create page, globals), and an MCP server exposing those tools over HTTP transport. ## Test plan - [ ] Enable the `e_wp_abilities_api` experiment (target validation on 7.0 per ticket). - [ ] Confirm `McpAdapter` loads and MCP server registers without `WP_Error`. - [ ] Smoke-test MCP HTTP transport against the registered abilities (list pages, get structure, etc.) in a staging environment. ## Jira [ED-23888](https://elementor.atlassian.net/browse/ED-23888) Made with [Cursor](https://cursor.com) [ED-23888]: https://elementor.atlassian.net/browse/ED-23888?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!--start_gitstream_placeholder--> ### ✨ PR Description ## 1. Problem & Context Integrates WordPress MCP (Model Context Protocol) adapter to expose Elementor capabilities through a standardized API for AI/external tool integration. Enables remote clients to read/modify Elementor pages programmatically. ## 2. What Changed (Where) - **modules-manager.php**: Registered new 'mcp' module in module loading sequence - **modules/mcp/module.php**: Main module orchestrating ability registration and MCP server setup with WordPress Abilities API - **modules/mcp/abilities/**: Five ability classes (List_Pages, Get_Structure, Create_Page, Update_Settings, Get_Globals) wrapping core Elementor operations - **composer.json**: Added wordpress/mcp-adapter ^0.5.0 dependency ## 3. How It Works Module activates only when McpAdapter class exists and experiment feature flag 'e_wp_abilities_api' is enabled. On init, it registers an 'elementor' ability category, instantiates five ability handlers that call `wp_register_ability()` with input/output schemas and permission callbacks, then creates an MCP server binding these abilities. Each ability validates user permissions (edit_posts/edit_post) before executing core operations (creating drafts, fetching element trees, updating document settings, listing Elementor-built pages, reading global classes/variables). ## 4. Risks Permission model relies on `current_user_can()` checks—verify those are sufficient for MCP transport layer (HTTP assumed). No validation of schema conformance for settings updates (additionalProperties: true risks invalid data). Experiment flag defaults to ACTIVE which exposes API broadly; should default INACTIVE pending stability verification. _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…elementor#35718) ## PR Checklist <!-- Please check if your PR fulfills the following requirements: **Filling out the template is required.** Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. --> - [ ] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type What kind of change does this PR introduce? <!-- Please check the one that applies to this PR using "x" with no spaces eg: [x]. --> - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] CI related changes - [ ] Documentation content changes - [ ] Other... Please describe: ## Summary This PR can be summarized in the following changelog entry: * ## Description An explanation of what is done in this PR * ## Test instructions This PR can be tested by following these steps: * ## Quality assurance - [ ] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes #
Need to copy this workflow to elementor-pro Co-authored-by: Davids Seveloff <94905340+davseve@users.noreply.github.com>
…lementor#35724) ## Summary - Zero-pad the minor version in the generated release branch name so that branches `4.00`–`4.10` sort correctly lexicographically - Updated `scripts/create-version-change.js`: use `String(minor).padStart(2, '0')` instead of bare `minor` - Updated `.github/workflows/create-version-change.yml`: use `printf '%02d' $MINOR` instead of bare `$MINOR` ## Test plan - [ ] Run `node scripts/create-version-change.js` when `package.json` version is `4.2.0` and verify the branch name shown is `4.02` (not `4.2`) - [ ] Confirm branches sort correctly: `echo -e "4.02\n4.10\n4.09" | sort -V` should output `4.02 → 4.09 → 4.10` - [ ] Verify that versions >= `4.10` remain unaffected (no triple-padding) ## Jira [ED-23982](https://elementor.atlassian.net/browse/ED-23982) [ED-23982]: https://elementor.atlassian.net/browse/ED-23982?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!--start_gitstream_placeholder--> ### ✨ PR Description ## 1. Problem & Context Branch names like `4.0` were inconsistent with the upcoming `4.0x` versioning scheme. This standardizes branch naming to zero-pad minor versions (e.g., `4.00`, `4.01`) across both the Node.js script and GitHub Actions workflow, ensuring consistency as versions progress beyond single digits. ## 2. What Changed (Where) - `scripts/create-version-change.js`: Updated branch name format from `${major}.${minor}` to `${major}.${String(minor).padStart(2, '0')}` - `.github/workflows/create-version-change.yml`: Updated shell branch name format from `${MAJOR}.${MINOR}` to `${MAJOR}.$(printf '%02d' $MINOR)` ## 3. How It Works Both files now zero-pad the minor version to two digits when constructing branch names. The JavaScript implementation uses `String.padStart(2, '0')` while the bash workflow uses `printf '%02d'`. For version `4.0`, branch name becomes `4.00`; for `4.1` it becomes `4.01`, and so on through `4.99`. ## 4. Risks Existing branches with old naming format (`4.0`) won't automatically map to new format (`4.00`). Verify that any branch references in CI/CD, merge scripts, or documentation are updated to match the new convention. _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder-->
…ources [Ed 23921] (elementor#35692) ## PR Checklist <!-- Please check if your PR fulfills the following requirements: **Filling out the template is required.** Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. --> - [ ] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type What kind of change does this PR introduce? <!-- Please check the one that applies to this PR using "x" with no spaces eg: [x]. --> - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] CI related changes - [ ] Documentation content changes - [ ] Other... Please describe: ## Summary This PR can be summarized in the following changelog entry: * ## Description An explanation of what is done in this PR * ## Test instructions This PR can be tested by following these steps: * ## Quality assurance - [ ] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes # --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…sorignore (elementor#35708) ## Summary - Condense 5 workspace rules (`development-workflow`, `legacy-integration`, `react-typescript`, `turbo-repo`, `wordpress-php`) from verbose to concise, and switch them from `alwaysApply: true` to `alwaysApply: false` (on-demand), saving ~4k tokens per session - Add root `.cursorignore` to exclude generated directories (`node_modules/`, `build/`, `vendor/`, `.turbo/`, etc.) from Cursor indexing - Net reduction: 1,055 lines removed, 98 added ## Test plan - [ ] Verify Cursor still picks up on-demand rules when editing matching files (e.g. `.php` files trigger `wordpress-php.mdc`) - [ ] Verify Cursor indexing excludes directories listed in `.cursorignore` - [ ] Confirm no impact on existing development workflows Made with [Cursor](https://cursor.com) <!--start_gitstream_placeholder--> ### ✨ PR Description ## 1. Problem & Context Cursor's AI context was bloated with verbose rules (~1000+ lines) that always applied, slowing down every interaction and including irrelevant legacy/PHP context for TypeScript work. This optimizes token usage by condensing rules 5-10x, disabling auto-apply (`alwaysApply: false`), and excluding build artifacts via `.cursorignore`. ## 2. What Changed (Where) - `.cursor/rules/development-workflow.mdc` - Condensed from 261 to 38 lines (command reference only) - `.cursor/rules/legacy-integration.mdc` - Condensed from 304 to 55 lines (removed adapters, test patterns) - `.cursor/rules/react-typescript.mdc` - Condensed from 325 to 56 lines (kept core patterns, removed examples) - `.cursor/rules/turbo-repo.mdc` - Condensed from 150 to 49 lines (workflow and pluggable pattern focus) - `.cursor/rules/wordpress-php.mdc` - Condensed from 176 to 48 lines (security + performance essentials) - `.cursorignore` - New file excluding `node_modules/`, `vendor/`, build artifacts, test outputs ## 3. How It Works All rule files now act as quick-reference cheat sheets instead of comprehensive guides. Set `alwaysApply: false` so Cursor only loads rules when file globs match (e.g., PHP rules only for `**/*.php`). The `.cursorignore` prevents Cursor from indexing 10K+ files in `node_modules/`, `vendor/`, and build directories, reducing context window pollution. Developers manually reference rules when needed rather than auto-injecting ~1000 lines per query. ## 4. Risks **False negatives on rule application**: If globs are too narrow or developers forget rules exist, they might miss guidance. Mitigate by keeping rule names descriptive and ensuring common file patterns are covered. **Context starvation on complex tasks**: Removing detailed examples might force developers to external docs. Monitor if this increases back-and-forth or errors—can restore specific examples if needed. _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
…ementor#35701) ## Summary - Registers `custom-widgets` panel category fallback from Widget Creation module when the experiment is active, Angie is **not** active, and the category is not already registered. - `Elements_Manager::CATEGORY_CUSTOM_WIDGETS`, panel template hooks, Install Angie heading CTA, empty-state copy, SCSS, and panel JS (`create-widget` from category with `widgets_panel` entry point). - Playwright widget-creation suite updates included. ## Test plan - [ ] With `e_widget_creation` on and Angie inactive: Elements panel shows Custom widgets category and fallback UI as expected. - [ ] With Angie active: fallback category is not registered by core (existing Angie-owned category remains). - [ ] CI / targeted Playwright as appropriate. ## Jira [ED-23900](https://elementor.atlassian.net/browse/ED-23900) <img width="357" height="252" alt="image" src="https://github.com/user-attachments/assets/8efd90f8-d83e-4a53-8318-a8f2c248a3d4" /> Made with [Cursor](https://cursor.com) [ED-23900]: https://elementor.atlassian.net/browse/ED-23900?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!--start_gitstream_placeholder--> ### ✨ PR Description ## 1. Problem & Context When Angie (AI widget builder) is inactive, the custom widgets feature remains exposed but non-functional. This PR provides fallback UI and messaging to guide users toward installing Angie, preventing dead-end UX. ## 2. What Changed (Where) - **panel-elements.php**: Conditional CTA text ("Install Angie" vs "Create custom widget") based on Angie status; removed hardcoded icon markup. - **elements.php**: Added `CATEGORY_CUSTOM_WIDGETS` constant and category promotion logic. - **widget-creation/module.php**: New fallback category registration when Angie inactive; renders "Install Angie" button in panel heading and empty state messaging. - **category.js**: Wired custom widgets CTA click handler; reformatted sorting/events code (no logic change). - **widget-creation.js**: Extracted `CREATE_WIDGET_PROMPT` as exportable constant for reuse across entry points. - **_elements.scss**: Styled custom widgets empty state and heading CTA; changed color from accent variable to `$e-pink-900`. - **widget-creation.test.ts**: Added custom widgets category visibility test; updated CTA assertions to expect "Install Angie" when no Angie. ## 3. How It Works On editor load with widget creation experiment active, the module checks Angie status. If inactive, it registers a "Custom widgets" category via hook and attaches handlers to render a heading CTA and empty state. Both dispatch the same `create-widget` event with entry point tracking. When Angie is active, the normal flow takes over and these fallbacks are skipped. ## 4. Risks Minor: Color hardcoding (`$e-pink-900` instead of CSS variable) loses theme flexibility—verify this aligns with design intent. Test coverage added for the no-Angie path, but missing Angie-active scenario validation. _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…em panel [ED-23880] (elementor#35689) ## PR Checklist - [x] The commit message follows our guidelines ## PR Type - [x] Feature ## Summary This PR can be summarized in the following changelog entry: * Internal: Wire the design system import dialog to the unified import-export-customization REST flow and host it inside the design system panel header. ## Description Builds on top of elementor#35623 (which introduced the import dialog UI) by: * Moving the import code from `@elementor/editor-editing-panel` into a new `import/` module inside `@elementor/editor-design-system`, and rendering the trigger button in the design system panel header (left of the close button) instead of next to the class manager icon. * Connecting the producer to the unified import-export-customization REST flow introduced in elementor#35613 / elementor#35677: 1. `POST /elementor/v1/import-export-customization/upload` (multipart, field `e_import_file`) — returns a `session`. 2. `POST /elementor/v1/import-export-customization/import` with `{ session, include: ['design-system'], customization: { 'design-system': { conflict_resolution } } }` — returns the runner list. 3. `POST /elementor/v1/import-export-customization/import-runner` once per supported runner (`global-classes`, `global-variables`). * Mapping the UI conflict choice to the backend strategy: `replace -> replace`, `keep -> skip`. * Refreshing the editor after import: calls `reloadCurrentDocument()` (which already re-runs `loadCurrentDocumentClasses` via `editor/documents/attach-preview`) and dispatches `GLOBAL_STYLES_IMPORTED_EVENT`. The variables listener was flipped to call `service.load()` unconditionally because the runner response only carries imported IDs/labels, not full style definitions. * Adding Mixpanel analytics for the PRD-defined events (`importOpened`, `fileSelected`, `validationFailed`, `conflictChoice`, `confirmed`, `imported`, `importFailed`) and registering their names in `events-config.js`. * Distinguishing upload validation errors from generic import errors via a dedicated `DesignSystemUploadValidationError` so the analytics fire the right event. ## Test instructions 1. Open a page in the editor with the design system experiment enabled. 2. Open the design system panel and click the upload icon in its header. 3. Drop a `.zip` exported from `import-export-customization` (containing `design-system`), pick a conflict strategy, click *Import*. 4. Verify that: * The dialog closes immediately and an *Importing in progress* notification appears. * The 3-call backend flow runs (`upload` -> `import` -> `import-runner` per runner) — visible in the network tab. * On success, the *Design system imported* notification appears, the document reloads, the class manager shows the imported classes, and the variables panel shows the imported variables. * On failure, an error notification appears with a *Try again* button that reopens the dialog. * The trigger button is disabled while an import is running. ## Quality assurance - [x] I have tested this code to the best of my abilities - [x] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes ED-23880 Made with [Cursor](https://cursor.com) <!--start_gitstream_placeholder--> ### ✨ PR Description ## 1. Problem & Context **[ED-23880]** Wired up design system import/export UI to the backend API (`elementor/v1/import-export-customization`). Previously just had UI scaffolding—now it's functional. Export downloads a .zip of classes+variables; import uploads, runs backend runners (`global-classes`, `global-variables`), then triggers UI updates. Added tracking hooks for analytics, moved trigger from standalone button into header menu to consolidate UX, and simplified global-styles event handling to directly reload data instead of manual merges. ## 2. What Changed (Where) - **`design-system-header-menu.tsx`** (new): Menu with import/export items replacing old `TriggerButton`, disables during mutations - **`design-system-panel-content.tsx`**: Wired `DesignSystemHeaderMenu` into header with spacing adjustments - **`use-export-request.ts`** (new): POST to `/export`, decodes base64 → Blob, returns `{ blob, fileName }` - **`use-import-request.ts`** (new): 3-step flow—upload file → start import w/ conflict strategy → run runners sequentially - **`import-design-system-dialog.tsx`**: Hooked event handlers for tracking, typed error handling for validation failures - **`tracking.ts`** (new): Mixpanel wrapper for import/export events (7 events total) - **`export-notifications.ts`** (new): Toast notifications for export states (in-progress, success, failure w/ retry) - **`download.ts`** (new): Creates temp anchor element to trigger browser download - **`global-styles-import-listener.tsx`** (classes): Falls back to server reload when event has no payload - **`global-styles-import-listener.tsx`** (variables): Simplified to always call `service.load()`, removed manual merge logic - **`use-variables-manager-state.ts`**: Listens to `STORAGE_UPDATED_EVENT`, resets dirty/deleted state on external updates - **`storage.ts`**: Exported `STORAGE_UPDATED_EVENT` constant, renamed internal event dispatch - **`variables-resource.ts`**: Updated MCP listener to use new `STORAGE_UPDATED_EVENT` constant - **`events-config.js`**: Added `design_system` analytics event names (7 events) - **Tests**: Full coverage for import/export flows, validation failures, retry logic, mutation state, storage events ## 3. How It Works **Import flow:** User clicks "Import" → opens dialog → selects file → chooses conflict strategy ("keep"/"replace") → backend validates zip → uploads to `/upload` (returns session) → POSTs to `/import` with session+strategy → backend returns runner names → runs each runner (`/import-runner`) → reloads document → dispatches `GLOBAL_STYLES_IMPORTED_EVENT` → global-classes/variables listeners reload from storage. **Export flow:** User clicks "Export" → POST to `/export` with `{ include: ['settings'], customization: { settings: { theme: false, classes: true, variables: true }}}` → backend returns base64-encoded zip → decode to Blob → trigger browser download via temporary anchor element. **Key decision:** Import runs runners sequentially (not parallel) because backend may have dependencies between `global-classes` and `global-variables`. Only supported runners are executed; others are filtered out client-side. **Storage sync:** Variables/classes now listen to `STORAGE_UPDATED_EVENT` instead of custom events. Variables manager resets dirty state when storage updates externally (e.g., from import), preventing stale UI state bugs. ## 4. Risks **Timeout on large imports/exports:** 20s timeout (`IMPORT_REQUEST_TIMEOUT_MS`, `EXPORT_REQUEST_TIMEOUT_MS`) may be too low for large design systems. Backend should enforce reasonable limits, but consider user feedback on timeouts before adjusting. **Base64 decode failure:** `base64ToZipBlob` uses `atob()` which can throw on invalid base64. Currently caught by generic try/catch in `useExportRequest`, but errors are opaque to users—only shows generic "export failed" toast. Backend should validate export response structure. **Runner filtering:** Client filters runners to `['global-classes', 'global-variables']`. If backend adds new required runners later, imports will silently skip them. Document this contract or make filtering server-driven. **Race condition in retry logic:** Import failure retry checks `isMutating()` before reopening dialog to prevent double-imports, but there's a small window between mutation settling and check completing. Low probability but could result in duplicate imports if user spam-clicks retry. _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> [ED-23880]: https://elementor.atlassian.net/browse/ED-23880?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
… hang [ED-23093] (elementor#35730) ## Summary `Global_Classes_Parser::parse_items()` rebuilt a `Style_Parser` (via `Style_Schema::get()`) on every call. With the chunked global-classes export (elementor#35687) it's invoked once per class, and the resulting schema/parser construction explodes on large kits — turning a kit export of ~1k classes into a server hang. ## PR Type - [x] Bugfix ## Description * Memoize the `Style_Parser` per `Global_Classes_Parser` instance, so the style schema is built once regardless of how many `parse_items()` calls (or items) it processes. * Behaviour is unchanged for existing call sites that do `Global_Classes_Parser::make()->parse(...)` once — they get a fresh instance and a single schema build, exactly as before. * Fix lives in `Global_Classes_Parser` rather than the export runner so every consumer of `parse_items()` benefits, and the export runner stays decoupled from `Style_Parser` / `Style_Schema`. ### Why the export was the only visible symptom The chunked export streams classes via `Global_Classes_Repository::each_item()` and was calling `parse_items( [ id => class_data ] )` once per class, building a fresh `Style_Parser` (and triggering many internal `Style_Schema::get()` calls during parsing) every time. With ~1k classes this was ~127k `Style_Schema::get()` calls and the request never finished. Other call sites only call `parse(...)` once per request, so they were unaffected. ## Runtime evidence Reproduced locally with a kit seeded to 999 global classes (as in the original PR's test instructions). | | Before | After | |---|---|---| | `Style_Schema::get()` calls during export | 127,800+ (still going at 113s) | 1 | | `each_item` loop completion | never (timed out / hung) | 2.12s (998 classes, avg 1.66ms/class) | ## Test instructions 1. Seed a site with ~1000 global classes (`scratch/seed-global-classes.php`). 2. Trigger a kit export from Tools → Export Kit including site settings. 3. Verify the export completes in seconds (was hanging on `main`). 4. Re-import the resulting kit and verify all classes appear correctly. ## Quality assurance - [x] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes ED-23093 Made with [Cursor](https://cursor.com) <!--start_gitstream_placeholder--> ### ✨ PR Description ## 1. Problem & Context Fixes ED-23093 export hang caused by repeated `Style_Schema::get()` calls inside a loop. Each export item was instantiating a new `Style_Parser`, making schema retrieval O(n) instead of O(1). Memoization moves this overhead outside the loop. ## 2. What Changed (Where) - `modules/global-classes/global-classes-parser.php`: Added private `$style_parser` property and lazy-loading getter to cache `Style_Parser` instance across `parse_items()` iterations. ## 3. How It Works `parse_items()` now calls `get_style_parser()` once before the loop instead of instantiating `Style_Parser` per item. Lazy initialization pattern ensures the parser is created only when needed and reused for all subsequent items in the same request lifecycle. ## 4. Risks None. Change is internal to the class with no API surface modifications. The memoized instance lives only for the request duration via the parser object lifecycle. _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> Co-authored-by: Cursor <cursoragent@cursor.com>
Events changes at Angie entry points
<!--start_gitstream_placeholder-->
### ✨ PR Description
## 1. Problem & Context
Adding analytics instrumentation to track Angie AI widget entry points
across the editor. Establishes baseline metrics for CTA visibility,
clicks, install flows, and abandonment patterns.
## 2. What Changed (Where)
| File | Change |
|------|--------|
| `use-action-props.ts` | Added `useEffect` hook to fire
`ai_widget_cta_viewed` on mount when Angie unavailable; changed
entry_point from `'top_bar'` → `'top_bar_icon'` |
| `create-widget.tsx` | Renamed event constant `ANGIE_CTA_CLICKED_EVENT`
→ `AI_WIDGET_CTA_CLICKED_EVENT`; added `angie_install_completed` and
`angie_install_abandoned` tracking with state-aware abandon_step logic |
| `use-action-props.test.ts` | Added mocks for `trackEvent`; updated
entry_point assertions; added 2 new tests for CTA viewed tracking |
| `create-widget.test.tsx` | New 304-line test file covering all 4 event
scenarios with install state transitions |
## 3. How It Works
User triggers AI widget CTA → `ai_widget_cta_viewed` fires on render (if
Angie missing) → user clicks → `ai_widget_cta_clicked` fires with
entry_point and install status → on install: `angie_install_started` →
success triggers `angie_install_completed` OR close/error triggers
`angie_install_abandoned` with context-aware abandon_step
('install_modal' vs 'install_error'). Entry point threaded through
entire flow for attribution.
## 4. Risks
Entry point string now hardcoded as `'top_bar_icon'` — any future entry
points require code changes rather than configuration. No validation
that event names match backend schema; typos silently fail. Install
abandonment logic relies on accurate `installState` enum tracking —
should verify state transitions can't be missed under async race
conditions.
_Generated by LinearB AI and added by gitStream._
<sub>AI-generated content may contain inaccuracies. Please verify before
using.
💡 **Tip:** You can customize your AI Description using **Guidelines**
[Learn
how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub>
<!--end_gitstream_placeholder-->
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
elementor#35743) ## PR Checklist <!-- Please check if your PR fulfills the following requirements: **Filling out the template is required.** Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. --> - [ ] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type What kind of change does this PR introduce? <!-- Please check the one that applies to this PR using "x" with no spaces eg: [x]. --> - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] CI related changes - [ ] Documentation content changes - [ ] Other... Please describe: ## Summary This PR can be summarized in the following changelog entry: * ## Description An explanation of what is done in this PR * ## Test instructions This PR can be tested by following these steps: * ## Quality assurance - [ ] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes # <!--start_gitstream_placeholder--> ### ✨ PR Description ## 1. Problem & Context Removes hardcoded model preferences from 7 MCP tools across styling/design modules to rely on system defaults, standardizing model selection behavior rather than forcing specific model hints per tool. ## 2. What Changed (Where) | File | Change | |------|--------| | build-composition/tool.ts | Removed `modelPreferences` with claude-sonnet-4-5 hint | | configure-element/tool.ts | Removed `modelPreferences` with model hints + priority weights | | get-element-config/tool.ts | Removed `modelPreferences` with intelligence/speed priorities | | mcp-apply-unapply-global-classes.ts | Removed identical `modelPreferences` from 2 tool definitions | | mcp-get-global-class-usages.ts | Removed `modelPreferences` with priorities | | mcp-manage-global-classes.ts | Removed `modelPreferences` with inverted priorities | | manage-variable-tool.ts | Removed `modelPreferences` with balanced priorities | ## 3. How It Works Tools now use registry-level or global default preferences instead of tool-specific overrides. No functional changes to handlers or schemas—purely configuration-layer simplification. ## 4. Risks None identified. Removal of explicit preferences delegates to defaults; no behavioral regression if defaults are properly configured upstream. Verify registry defaults cover all priority scenarios previously set per-tool. _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> --------- Co-authored-by: Omer Israeli <94297319+Omerisra6@users.noreply.github.com>
…lementor#35748) ## PR Checklist <!-- Please check if your PR fulfills the following requirements: **Filling out the template is required.** Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. --> - [ ] The commit message follows our guidelines: https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md ## PR Type What kind of change does this PR introduce? <!-- Please check the one that applies to this PR using "x" with no spaces eg: [x]. --> - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] CI related changes - [ ] Documentation content changes - [ ] Other... Please describe: ## Summary This PR can be summarized in the following changelog entry: * ## Description An explanation of what is done in this PR * ## Test instructions This PR can be tested by following these steps: * ## Quality assurance - [ ] I have tested this code to the best of my abilities - [ ] I have added unittests to verify the code works as intended - [ ] Docs have been added / updated (for bug fixes / features) Fixes #
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add a new module that serves Elementor page content as Markdown when crawlers send Accept: text/markdown header or ?format=markdown param.
PR Checklist
PR Type
What kind of change does this PR introduce?
Summary
This PR can be summarized in the following changelog entry:
Description
An explanation of what is done in this PR
Test instructions
This PR can be tested by following these steps:
Quality assurance
Fixes #