@agent-native/core 0.169.1 → 0.170.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-native.eject.json +4 -1
- package/bin/agent-native.js +23 -5
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
- package/corpus/templates/analytics/app/i18n-data.ts +28 -0
- package/corpus/templates/analytics/app/pages/Agents.tsx +25 -1
- package/corpus/templates/analytics/app/routes/$.tsx +10 -0
- package/corpus/templates/analytics/app/routes.ts +3 -1
- package/corpus/templates/analytics/changelog/2026-08-22-fixed-the-agent-native-templates-first-party-dashboard-panel.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-22-org-admin-panels-no-longer-report-a-database-error-as-a-per.md +9 -0
- package/corpus/templates/analytics/changelog/2026-08-22-slack-requests-report-invalid-inputs.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-22-unknown-analytics-links-now-return-a-real-not-found-status.md +6 -0
- package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +2 -1
- package/corpus/templates/analytics/docs/schemas/tracked-events.md +2 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +29 -7
- package/corpus/templates/analytics/server/handlers/slack.ts +59 -5
- package/corpus/templates/analytics/server/lib/db-admin-connections.ts +11 -6
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +132 -2
- package/corpus/templates/analytics/server/lib/slack.ts +4 -2
- package/corpus/templates/analytics/vitest.config.ts +6 -1
- package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/assets/app/routes/library.tsx +5 -3
- package/corpus/templates/assets/app/routes.ts +3 -1
- package/corpus/templates/assets/changelog/2026-08-22-library-page-loads-again-instead-of-crashing-on-open.md +6 -0
- package/corpus/templates/assets/vitest.config.ts +6 -1
- package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/brain/app/components/ui/pointer-lock.ts +1 -0
- package/corpus/templates/brain/app/routes/sources.tsx +8 -3
- package/corpus/templates/brain/changelog/2026-08-22-tuning-or-adding-a-source-no-longer-leaves-the-sources-page.md +6 -0
- package/corpus/templates/brain/vitest.config.ts +1 -0
- package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/calendar/actions/list-booking-links.ts +83 -4
- package/corpus/templates/calendar/actions/update-booking-link.ts +4 -3
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +11 -3
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +1 -1
- package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +103 -44
- package/corpus/templates/calendar/app/components/calendar/OutOfOfficeEvent.tsx +28 -24
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +9 -2
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +47 -58
- package/corpus/templates/calendar/app/hooks/use-booking-links.ts +5 -1
- package/corpus/templates/calendar/app/lib/event-layout.ts +52 -26
- package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +126 -98
- package/corpus/templates/calendar/app/pages/CalendarView.tsx +1 -0
- package/corpus/templates/calendar/app/pages/Settings.tsx +88 -81
- package/corpus/templates/calendar/app/routes.ts +3 -1
- package/corpus/templates/calendar/changelog/2026-08-22-booking-link-visibility-respects-shared-access.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-clicking-an-out-of-office-event-s-marker-no-longer-creates-a.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-event-detail-views-now-show-your-calendar-timezone.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-google-calendar-can-now-connect-with-the-shared-google-oauth.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-overlapping-events-now-show-each-others-boundaries.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-public-booking-pages-now-offer-time-slots-from-the-host-s-we.md +6 -0
- package/corpus/templates/calendar/server/handlers/bookings.ts +5 -7
- package/corpus/templates/calendar/server/handlers/google-auth.ts +10 -2
- package/corpus/templates/calendar/server/lib/google-calendar.ts +139 -14
- package/corpus/templates/calendar/server/onboarding.ts +85 -0
- package/corpus/templates/calendar/server/plugins/agent-chat.ts +2 -0
- package/corpus/templates/calendar/shared/api.ts +9 -1
- package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/chat/app/routes.ts +3 -1
- package/corpus/templates/chat/vitest.config.ts +8 -0
- package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/clips/actions/get-meeting.ts +9 -4
- package/corpus/templates/clips/actions/list-recordings.ts +16 -3
- package/corpus/templates/clips/actions/search-meetings.ts +1 -0
- package/corpus/templates/clips/actions/view-screen.ts +8 -1
- package/corpus/templates/clips/app/components/meetings/meeting-history-row.tsx +32 -1
- package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +1 -1
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +29 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +5 -0
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +33 -4
- package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +1 -0
- package/corpus/templates/clips/app/routes/access-request.approve.tsx +16 -9
- package/corpus/templates/clips/app/routes/embed.$shareId.tsx +17 -7
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +17 -7
- package/corpus/templates/clips/changelog/2026-08-21-camera-bubble-black-circle.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-22-screen-recordings-respect-the-microphone-toggle.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-22-the-recordings-library-no-longer-fails-right-after-server-start.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-23-the-agent-can-see-your-library-right-after-server-start.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +1 -2
- package/corpus/templates/clips/chrome-extension/src/native-transcription.ts +39 -7
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +21 -25
- package/corpus/templates/clips/desktop/src/app.tsx +53 -24
- package/corpus/templates/clips/desktop/src/lib/bubble-playback.ts +68 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +3 -0
- package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +72 -14
- package/corpus/templates/clips/desktop/src/lib/updater.ts +8 -3
- package/corpus/templates/clips/desktop/src/overlays/bubble.tsx +162 -20
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +43 -6
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +150 -13
- package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +12 -0
- package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +28 -3
- package/corpus/templates/clips/server/lib/emails.ts +17 -33
- package/corpus/templates/content/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +140 -15
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +12 -14
- package/corpus/templates/content/app/components/ui/pointer-lock.ts +1 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +18 -2
- package/corpus/templates/content/app/hooks/use-local-storage.ts +38 -22
- package/corpus/templates/content/app/i18n-data.ts +25 -0
- package/corpus/templates/content/app/routes.ts +3 -1
- package/corpus/templates/content/changelog/2026-08-22-code-blocks-inserted-from-the-slash-menu-no-longer-get-stuck.md +6 -0
- package/corpus/templates/content/changelog/2026-08-22-the-sidebar-page-tree-no-longer-flashes-empty-after-creating-a-page.md +6 -0
- package/corpus/templates/content/docs/solutions/2026-08-21-content-mermaid-rendering-shape.md +233 -0
- package/corpus/templates/content/server/plugins/agent-chat.ts +9 -2
- package/corpus/templates/content/vitest.config.ts +7 -1
- package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/design/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +1383 -88
- package/corpus/templates/design/actions/generate-design.ts +98 -47
- package/corpus/templates/design/actions/get-design-system.ts +6 -1
- package/corpus/templates/design/actions/refresh-design-system-with-builder.ts +146 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +70 -26
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +284 -136
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2057 -141
- package/corpus/templates/design/app/components/design/editor/DesignBottomToolbar.tsx +6 -2
- package/corpus/templates/design/app/components/design/editor/DesignWorkspaceRail.tsx +4 -4
- package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +10 -1
- package/corpus/templates/design/app/components/design/multi-screen/alt-hover-measurement.ts +19 -2
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +9 -2
- package/corpus/templates/design/app/components/layout/Header.tsx +15 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +7 -2
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +11 -4
- package/corpus/templates/design/app/i18n-data.ts +1 -0
- package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +12 -0
- package/corpus/templates/design/app/lib/design-system-data.ts +68 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +77 -35
- package/corpus/templates/design/app/pages/DesignSystems.tsx +136 -42
- package/corpus/templates/design/app/pages/Index.tsx +2 -0
- package/corpus/templates/design/app/pages/Templates.tsx +0 -10
- package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +10 -0
- package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +50 -0
- package/corpus/templates/design/app/pages/design-editor/commands/apply-design-editor-command.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +10 -8
- package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +6 -6
- package/corpus/templates/design/app/pages/design-editor/commands/apply-pending-visual-styles-with-agent.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/commit-visual-styles.ts +18 -7
- package/corpus/templates/design/app/pages/design-editor/commands/escape-hotkey.ts +4 -90
- package/corpus/templates/design/app/pages/design-editor/commands/layer-marquee-selection-change.ts +2 -1
- package/corpus/templates/design/app/pages/design-editor/commands/layer-selection-change.ts +4 -3
- package/corpus/templates/design/app/pages/design-editor/commands/screen-element-select.ts +12 -2
- package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-style-change.ts +9 -2
- package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-move-semantic-handoff.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-semantic-handoff.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-state-semantic-handoff.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/start-sidebar-resize.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +11 -1
- package/corpus/templates/design/app/pages/design-editor/effects/adopt-db-file-content.ts +11 -19
- package/corpus/templates/design/app/pages/design-editor/effects/observe-collab-text.ts +6 -6
- package/corpus/templates/design/app/pages/design-editor/effects/publish-agent-selection-context.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/effects/seed-collab-content.ts +12 -15
- package/corpus/templates/design/app/pages/design-editor/selection-state.ts +5 -59
- package/corpus/templates/design/app/pages/design-editor/tool-state.ts +8 -0
- package/corpus/templates/design/app/pages/design-editor/types.ts +3 -3
- package/corpus/templates/design/app/routes.ts +3 -1
- package/corpus/templates/design/changelog/2026-08-20-canvas-edits-patch-the-frame-instead-of-rebuilding-it.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-builder-design-system-imports-reconcile-after-indexing.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-draw-mode-needs-shift-y.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-eyedropper-shortcut.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-figma-style-alignment-guides-and-snapping.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-group-transforms-keep-the-selection.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-inspector-fields-keep-focus-on-enter.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-pen-alt-keeps-the-incoming-handle.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-pen-on-the-board-creates-one-vector.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-scale-a-multi-selection-from-the-group-handles.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-scale-resizes-text-with-the-object.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-selecting-another-object-keeps-the-scale-tool-armed.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-the-shape-tool-remembers-the-shape-you-picked.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-vectors-drawn-in-a-frame-land-where-you-drew-them.md +6 -0
- package/corpus/templates/design/changelog/2026-08-22-multi-screen-generation-no-longer-loses-a-saved-screens-layo.md +6 -0
- package/corpus/templates/design/changelog/2026-08-22-rename-and-search-fields-are-labeled-for-screen-readers.md +6 -0
- package/corpus/templates/design/package.json +2 -0
- package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +311 -0
- package/corpus/templates/design/shared/canvas-math.ts +612 -206
- package/corpus/templates/design/shared/pen-path.ts +37 -0
- package/corpus/templates/design/vitest.config.ts +7 -1
- package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/dispatch/actions/list-workspace-connections.ts +34 -3
- package/corpus/templates/dispatch/app/routes/integrations.tsx +55 -21
- package/corpus/templates/dispatch/app/routes.ts +3 -1
- package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/factory/.env.example +2 -7
- package/corpus/templates/factory/AGENTS.md +3 -0
- package/corpus/templates/factory/README.md +5 -3
- package/corpus/templates/factory/actions/create-factory.ts +16 -3
- package/corpus/templates/factory/actions/get-slack-feedback-context.ts +2 -0
- package/corpus/templates/factory/actions/get-triage-item.ts +2 -0
- package/corpus/templates/factory/actions/list-factory-audit.ts +116 -36
- package/corpus/templates/factory/actions/list-factory-automations.ts +2 -1
- package/corpus/templates/factory/actions/list-triage-items.ts +22 -19
- package/corpus/templates/factory/actions/run-factory-automation.ts +7 -3
- package/corpus/templates/factory/actions/save-factory-automation.ts +5 -2
- package/corpus/templates/factory/actions/save-triage-config.ts +2 -8
- package/corpus/templates/factory/actions/start-builder-for-item.ts +21 -0
- package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +229 -297
- package/corpus/templates/factory/app/components/factory/FactorySettingsView.tsx +397 -247
- package/corpus/templates/factory/app/components/factory/FactorySourceSettingsGroup.tsx +33 -0
- package/corpus/templates/factory/app/components/factory/NewFactoryForm.tsx +202 -162
- package/corpus/templates/factory/app/i18n/en-US.ts +32 -4
- package/corpus/templates/factory/app/routes/factory.tsx +84 -11
- package/corpus/templates/factory/app/routes.ts +3 -1
- package/corpus/templates/factory/changelog/2026-08-21-activity-runs-use-automation-display-names.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-create-and-settings-source-cards.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-keep-automations-visible-while-running.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-nested-factory-automations-can-poll.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-settings-sticky-unsaved-bar.md +6 -0
- package/corpus/templates/factory/server/connectors/credentials.ts +10 -5
- package/corpus/templates/factory/server/lib/factory-audit-report.ts +412 -0
- package/corpus/templates/factory/server/lib/factory-config-reconcile.ts +321 -0
- package/corpus/templates/factory/server/lib/factory-scope.ts +25 -2
- package/corpus/templates/factory/server/lib/require-factory-automation.ts +13 -4
- package/corpus/templates/factory/server/plugins/factory-migrations.ts +148 -4
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +4 -6
- package/corpus/templates/factory/vitest.config.ts +17 -2
- package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/forms/app/routes/_app.settings.tsx +4 -1
- package/corpus/templates/forms/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +11 -1
- package/corpus/templates/forms/vitest.config.ts +1 -0
- package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/macros/app/routes.ts +3 -1
- package/corpus/templates/macros/vitest.config.ts +6 -1
- package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/mail/actions/manage-gmail-filters.ts +10 -2
- package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +100 -37
- package/corpus/templates/mail/app/components/email/IntegrationsSidebar.tsx +14 -2
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +66 -36
- package/corpus/templates/mail/app/hooks/use-google-auth.ts +2 -0
- package/corpus/templates/mail/app/lib/google-oauth-setup.ts +17 -0
- package/corpus/templates/mail/app/pages/InboxPage.tsx +69 -9
- package/corpus/templates/mail/app/routes/$.tsx +9 -0
- package/corpus/templates/mail/app/routes/$view.$threadId.tsx +23 -1
- package/corpus/templates/mail/app/routes/$view.tsx +47 -1
- package/corpus/templates/mail/app/routes.ts +3 -1
- package/corpus/templates/mail/changelog/2026-08-22-gmail-can-now-connect-with-the-shared-google-oauth.md +6 -0
- package/corpus/templates/mail/changelog/2026-08-22-gmail-filters-now-shows-the-real-error.md +6 -0
- package/corpus/templates/mail/changelog/2026-08-22-unknown-mail-urls-now-show-the-404-page.md +6 -0
- package/corpus/templates/mail/server/handlers/google-auth.ts +11 -2
- package/corpus/templates/mail/server/lib/google-auth.ts +92 -12
- package/corpus/templates/mail/server/onboarding.ts +66 -18
- package/corpus/templates/mail/vitest.config.ts +6 -1
- package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/plan/app/routes/settings.tsx +4 -1
- package/corpus/templates/plan/app/routes.ts +3 -1
- package/corpus/templates/plan/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
- package/corpus/templates/plan/netlify.toml +1 -1
- package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/slides/actions/patch-deck.ts +79 -10
- package/corpus/templates/slides/actions/update-slide.ts +11 -1
- package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +14 -4
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +10 -52
- package/corpus/templates/slides/app/components/editor/GoogleDocImportHint.tsx +8 -53
- package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +9 -75
- package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +8 -60
- package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +10 -2
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +19 -7
- package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +49 -36
- package/corpus/templates/slides/app/routes/access-request.approve.tsx +16 -9
- package/corpus/templates/slides/app/routes.ts +3 -1
- package/corpus/templates/slides/changelog/2026-08-22-already-uploaded-chat-images-are-no-longer-dropped.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-22-google-drive-and-slides-can-now-connect-with-the-shared-google-oauth.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-22-multi-slide-repairs-now-report-slides-that-still-overflow.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-22-update-slide-now-reports-which-batched-edit-was-skipped.md +6 -0
- package/corpus/templates/slides/server/handlers/google-docs-auth.ts +52 -1
- package/corpus/templates/slides/server/lib/chat-attachments.ts +29 -3
- package/corpus/templates/slides/server/lib/google-docs-oauth.ts +66 -16
- package/corpus/templates/slides/server/lib/slide-content-patch.ts +13 -2
- package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -2
- package/corpus/templates/slides/tsconfig.json +5 -0
- package/corpus/templates/slides/vitest.config.ts +6 -1
- package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/tasks/app/routes/settings.tsx +4 -1
- package/corpus/templates/tasks/app/routes.ts +3 -1
- package/corpus/templates/tasks/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
- package/corpus/templates/tasks/vitest.config.ts +7 -1
- package/dist/action.d.ts +91 -0
- package/dist/action.js +50 -0
- package/dist/agent/abort-reasons.d.ts +38 -0
- package/dist/agent/abort-reasons.js +49 -0
- package/dist/agent/engine/ai-sdk-engine.js +8 -5
- package/dist/agent/engine/anthropic-engine.js +7 -5
- package/dist/agent/engine/first-event-timeout.d.ts +42 -17
- package/dist/agent/engine/first-event-timeout.js +67 -25
- package/dist/agent/production-agent.d.ts +23 -0
- package/dist/agent/production-agent.js +107 -102
- package/dist/agent/run-loop-with-resume.d.ts +2 -28
- package/dist/agent/run-loop-with-resume.js +25 -40
- package/dist/agent/run-manager.js +5 -4
- package/dist/agent/run-store.d.ts +55 -0
- package/dist/agent/run-store.js +124 -1
- package/dist/agent/tool-search.js +2 -1
- package/dist/agent/types.d.ts +9 -4
- package/dist/app-config/configuration-error.d.ts +11 -0
- package/dist/app-config/configuration-error.js +14 -0
- package/dist/app-config/index.d.ts +1 -0
- package/dist/app-config/index.js +1 -0
- package/dist/app-config/integrations.d.ts +1 -0
- package/dist/app-config/integrations.js +10 -0
- package/dist/app-config/plugins.d.ts +34 -0
- package/dist/app-config/plugins.js +39 -0
- package/dist/app-config/run-lifecycle-invariants.d.ts +18 -9
- package/dist/app-config/run-lifecycle-invariants.js +18 -25
- package/dist/app-config/schema.d.ts +16 -0
- package/dist/app-config/schema.js +2 -0
- package/dist/chat-threads/schema-migrations.js +20 -0
- package/dist/chat-threads/store.js +21 -4
- package/dist/cli/native-dependencies.d.ts +4 -0
- package/dist/cli/native-dependencies.js +15 -0
- package/dist/client/EnvironmentBadge.d.ts +1 -1
- package/dist/client/EnvironmentBadge.js +40 -5
- package/dist/client/MultiTabAssistantChat.d.ts +1 -1
- package/dist/client/MultiTabAssistantChat.js +35 -14
- package/dist/client/agent-chat/index.d.ts +1 -1
- package/dist/client/agent-chat/index.js +1 -1
- package/dist/client/agent-page/use-jobs.d.ts +2 -1
- package/dist/client/agent-page/use-jobs.js +3 -5
- package/dist/client/agent-sidebar-state.js +3 -1
- package/dist/client/blocks/library/code-tabs.js +5 -0
- package/dist/client/blocks/library/code.js +1 -0
- package/dist/client/chat-first/apps-rail.js +2 -2
- package/dist/client/chat-model-groups.d.ts +12 -0
- package/dist/client/chat-model-groups.js +3 -2
- package/dist/client/integrations/GoogleProductLogo.d.ts +5 -0
- package/dist/client/integrations/GoogleProductLogo.js +45 -0
- package/dist/client/integrations/index.d.ts +2 -0
- package/dist/client/integrations/index.js +2 -0
- package/dist/client/integrations/workspace-provider-oauth.d.ts +8 -0
- package/dist/client/integrations/workspace-provider-oauth.js +13 -0
- package/dist/client/resources/mcp-integration-catalog.js +0 -29
- package/dist/client/settings/SettingsTabsPage.js +10 -6
- package/dist/client/sharing/ShareButton.js +11 -2
- package/dist/client/use-chat-models.d.ts +6 -0
- package/dist/client/use-chat-models.js +10 -0
- package/dist/client/use-db-sync.js +27 -9
- package/dist/connections/catalog.d.ts +111 -9
- package/dist/connections/catalog.js +86 -30
- package/dist/db/create-get-db.js +18 -0
- package/dist/db/ddl-guard.d.ts +0 -4
- package/dist/db/ddl-guard.js +46 -0
- package/dist/deploy/build.d.ts +19 -0
- package/dist/deploy/build.js +190 -16
- package/dist/deploy/function-bundle.d.ts +45 -0
- package/dist/deploy/function-bundle.js +337 -0
- package/dist/deploy/workspace-deploy.js +19 -1
- package/dist/eject/workspace-connections.js +4 -0
- package/dist/email-catalog/registry.d.ts +4 -0
- package/dist/email-catalog/registry.js +79 -14
- package/dist/extensions/content-patch.js +14 -2
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/integrations/plugin.d.ts +10 -0
- package/dist/integrations/plugin.js +40 -6
- package/dist/jobs/actions/run-automation-now.d.ts +2 -1
- package/dist/jobs/actions/run-automation-now.js +11 -5
- package/dist/jobs/frontmatter.js +53 -2
- package/dist/jobs/run-now.d.ts +11 -1
- package/dist/jobs/run-now.js +42 -7
- package/dist/jobs/scheduler.d.ts +1 -0
- package/dist/jobs/scheduler.js +2 -1
- package/dist/localization/core-messages/ar-SA.js +3 -0
- package/dist/localization/core-messages/de-DE.js +3 -0
- package/dist/localization/core-messages/en-US.d.ts +3 -0
- package/dist/localization/core-messages/en-US.js +3 -0
- package/dist/localization/core-messages/es-ES.js +3 -0
- package/dist/localization/core-messages/fr-FR.js +3 -0
- package/dist/localization/core-messages/hi-IN.js +3 -0
- package/dist/localization/core-messages/ja-JP.js +3 -0
- package/dist/localization/core-messages/ko-KR.js +3 -0
- package/dist/localization/core-messages/pt-BR.js +3 -0
- package/dist/localization/core-messages/zh-CN.js +3 -0
- package/dist/localization/core-messages/zh-TW.js +3 -0
- package/dist/localization/core-messages.d.ts +3 -0
- package/dist/localization/default-messages.d.ts +2 -5
- package/dist/localization/default-messages.js +2 -5
- package/dist/mcp/build-server.d.ts +9 -0
- package/dist/mcp/build-server.js +37 -8
- package/dist/mcp-client/oauth-client.d.ts +7 -0
- package/dist/mcp-client/oauth-client.js +12 -1
- package/dist/oauth-tokens/index.d.ts +1 -1
- package/dist/oauth-tokens/index.js +1 -1
- package/dist/oauth-tokens/lifecycle.d.ts +11 -0
- package/dist/oauth-tokens/lifecycle.js +17 -0
- package/dist/oauth-tokens/store.js +7 -0
- package/dist/observability/posthog-ai.d.ts +15 -1
- package/dist/observability/posthog-ai.js +24 -12
- package/dist/observability/routes.d.ts +3 -3
- package/dist/observability/traces.js +158 -28
- package/dist/onboarding/app-profile.js +2 -2
- package/dist/onboarding/plugin.js +10 -2
- package/dist/onboarding/types.d.ts +2 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +1 -1
- package/dist/provider-api/actions/provider-api.d.ts +2 -2
- package/dist/provider-api/index.js +2 -0
- package/dist/resources/store.js +13 -4
- package/dist/scripts/agent-engines/list-agent-engines.js +29 -3
- package/dist/secrets/register-framework-secrets.js +1 -1
- package/dist/server/action-discovery.js +5 -0
- package/dist/server/agent-chat/action-filters-a2a.d.ts +27 -3
- package/dist/server/agent-chat/action-filters-a2a.js +48 -9
- package/dist/server/agent-chat-plugin.js +36 -9
- package/dist/server/agent-discovery.js +43 -20
- package/dist/server/auth.js +18 -16
- package/dist/server/beta-opt-out-html.js +45 -4
- package/dist/server/better-auth-instance.d.ts +2 -1
- package/dist/server/better-auth-instance.js +23 -7
- package/dist/server/builder-design-systems.d.ts +4 -1
- package/dist/server/builder-design-systems.js +87 -6
- package/dist/server/builder-oauth.d.ts +1 -7
- package/dist/server/builder-oauth.js +80 -163
- package/dist/server/core-routes-plugin.d.ts +29 -0
- package/dist/server/core-routes-plugin.js +100 -20
- package/dist/server/default-plugins.d.ts +18 -0
- package/dist/server/default-plugins.js +22 -0
- package/dist/server/edge.d.ts +1 -0
- package/dist/server/edge.js +1 -0
- package/dist/server/framework-request-handler.js +31 -3
- package/dist/server/google-oauth.d.ts +3 -0
- package/dist/server/google-oauth.js +3 -0
- package/dist/server/index.d.ts +4 -4
- package/dist/server/index.js +3 -3
- package/dist/server/onboarding-html.js +37 -3
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/server/workspace-provider-oauth.d.ts +6 -1
- package/dist/server/workspace-provider-oauth.js +72 -20
- package/dist/shared/agent-sidebar-url.d.ts +1 -0
- package/dist/shared/agent-sidebar-url.js +1 -0
- package/dist/shared/environment-lanes.d.ts +2 -0
- package/dist/shared/environment-lanes.js +3 -1
- package/dist/shared/index.d.ts +3 -1
- package/dist/shared/index.js +3 -1
- package/dist/shared/surface-visibility.d.ts +31 -0
- package/dist/shared/surface-visibility.js +57 -0
- package/dist/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/templates/chat/app/routes.ts +3 -1
- package/dist/templates/chat/vitest.config.ts +8 -0
- package/dist/templates/default/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/templates/default/app/routes.ts +3 -1
- package/dist/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/tracking/registry.d.ts +11 -0
- package/dist/tracking/registry.js +5 -2
- package/dist/triggers/actions.js +10 -3
- package/dist/usage/store.js +23 -3
- package/dist/user-profile/actions/get-auth-methods.js +18 -5
- package/dist/vite/client.js +24 -5
- package/docs/content/actions-access-control.mdx +43 -4
- package/docs/content/actions-defining.mdx +16 -0
- package/docs/content/template-clips-capture-everywhere.mdx +29 -30
- package/docs/content/template-clips-developers.mdx +4 -4
- package/docs/content/template-clips.mdx +3 -1
- package/package.json +2 -2
- package/src/eject/workspace-connections.ts +4 -0
- package/src/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
- package/src/templates/chat/app/routes.ts +3 -1
- package/src/templates/chat/vitest.config.ts +8 -0
- package/src/templates/default/.agents/skills/secrets/SKILL.md +11 -4
- package/src/templates/default/app/routes.ts +3 -1
- package/src/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
- package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
|
@@ -584,7 +584,38 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
584
584
|
}
|
|
585
585
|
renderRuntimeInteractionStatePreviews();
|
|
586
586
|
}
|
|
587
|
-
var lastSourceHeadHtml = null;
|
|
587
|
+
var lastSourceHeadHtml = typeof __INITIAL_SOURCE_HEAD__ === "string" ? __INITIAL_SOURCE_HEAD__ || null : null;
|
|
588
|
+
function headNodeSignature(node) {
|
|
589
|
+
var tag = node.tagName.toLowerCase();
|
|
590
|
+
if (tag === "title" || tag === "base") return tag;
|
|
591
|
+
if (tag === "style") {
|
|
592
|
+
var attrs = node.attributes;
|
|
593
|
+
for (var i = 0; i < attrs.length; i += 1) {
|
|
594
|
+
var name = attrs[i].name;
|
|
595
|
+
if (name.indexOf("data-agent-native-") === 0) return "style:" + name;
|
|
596
|
+
}
|
|
597
|
+
return "";
|
|
598
|
+
}
|
|
599
|
+
if (tag === "meta") {
|
|
600
|
+
var meta = ["name", "property", "http-equiv", "charset"];
|
|
601
|
+
for (var m = 0; m < meta.length; m += 1) {
|
|
602
|
+
if (node.hasAttribute(meta[m])) {
|
|
603
|
+
return "meta:" + meta[m] + "=" + node.getAttribute(meta[m]);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
return "";
|
|
607
|
+
}
|
|
608
|
+
return "";
|
|
609
|
+
}
|
|
610
|
+
function findHeadNodeBySignature(signature) {
|
|
611
|
+
var children = document.head ? document.head.children : null;
|
|
612
|
+
if (!children) return null;
|
|
613
|
+
for (var i = 0; i < children.length; i += 1) {
|
|
614
|
+
var candidate = children[i];
|
|
615
|
+
if (headNodeSignature(candidate) === signature) return candidate;
|
|
616
|
+
}
|
|
617
|
+
return null;
|
|
618
|
+
}
|
|
588
619
|
function replaceSourceHeadNodes(previousSourceHtml, nextSourceHtml) {
|
|
589
620
|
if (!document.head) return;
|
|
590
621
|
var stale = document.createElement("head");
|
|
@@ -594,6 +625,12 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
594
625
|
var key = node.outerHTML;
|
|
595
626
|
staleCounts[key] = (staleCounts[key] || 0) + 1;
|
|
596
627
|
});
|
|
628
|
+
var retained = document.createElement("head");
|
|
629
|
+
retained.innerHTML = nextSourceHtml || "";
|
|
630
|
+
Array.prototype.forEach.call(retained.children, function(node) {
|
|
631
|
+
var key = node.outerHTML;
|
|
632
|
+
if (staleCounts[key]) staleCounts[key] -= 1;
|
|
633
|
+
});
|
|
597
634
|
Array.prototype.slice.call(document.head.children).forEach(function(node) {
|
|
598
635
|
var key = node.outerHTML;
|
|
599
636
|
if (!staleCounts[key]) return;
|
|
@@ -602,8 +639,29 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
602
639
|
});
|
|
603
640
|
var next = document.createElement("head");
|
|
604
641
|
next.innerHTML = nextSourceHtml || "";
|
|
642
|
+
var present = {};
|
|
643
|
+
Array.prototype.forEach.call(
|
|
644
|
+
document.head.children,
|
|
645
|
+
function(node) {
|
|
646
|
+
var key = node.outerHTML;
|
|
647
|
+
present[key] = (present[key] || 0) + 1;
|
|
648
|
+
}
|
|
649
|
+
);
|
|
605
650
|
var anchor = document.head.firstChild;
|
|
606
651
|
Array.prototype.slice.call(next.children).forEach(function(node) {
|
|
652
|
+
var key = node.outerHTML;
|
|
653
|
+
if (present[key]) {
|
|
654
|
+
present[key] -= 1;
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
var signature = previousSourceHtml === null ? headNodeSignature(node) : "";
|
|
658
|
+
if (signature) {
|
|
659
|
+
var existing = findHeadNodeBySignature(signature);
|
|
660
|
+
if (existing) {
|
|
661
|
+
document.head.replaceChild(document.importNode(node, true), existing);
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
607
665
|
document.head.insertBefore(document.importNode(node, true), anchor);
|
|
608
666
|
});
|
|
609
667
|
}
|
|
@@ -2117,6 +2175,17 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
2117
2175
|
spacingBadge.setAttribute("data-agent-native-edit-overlay", "spacing-badge");
|
|
2118
2176
|
spacingBadge.style.cssText = "position:fixed;z-index:100000;display:none;pointer-events:none;border-radius:3px;color:white;font:10px/1.2 ui-monospace,SFMono-Regular,Menlo,monospace;font-weight:700;padding:2px 4px;box-shadow:0 4px 14px rgba(0,0,0,0.18);";
|
|
2119
2177
|
document.body.appendChild(spacingBadge);
|
|
2178
|
+
var constraintGuideLayer = document.createElement("div");
|
|
2179
|
+
constraintGuideLayer.setAttribute(
|
|
2180
|
+
"data-agent-native-edit-overlay",
|
|
2181
|
+
"constraint-guide"
|
|
2182
|
+
);
|
|
2183
|
+
constraintGuideLayer.style.cssText = "position:fixed;inset:0;z-index:99999;display:none;pointer-events:none;";
|
|
2184
|
+
document.body.appendChild(constraintGuideLayer);
|
|
2185
|
+
var sizeBadge = document.createElement("div");
|
|
2186
|
+
sizeBadge.setAttribute("data-agent-native-edit-overlay", "size-badge");
|
|
2187
|
+
sizeBadge.style.cssText = "position:fixed;z-index:100000;display:none;pointer-events:none;border-radius:3px;background:var(--design-editor-accent-color);color:var(--design-editor-accent-contrast-color);font:10px/1.2 ui-monospace,SFMono-Regular,Menlo,monospace;padding:2px 4px;white-space:nowrap;";
|
|
2188
|
+
document.body.appendChild(sizeBadge);
|
|
2120
2189
|
var insertionGuide = document.createElement("div");
|
|
2121
2190
|
insertionGuide.setAttribute("data-agent-native-insertion-guide", "");
|
|
2122
2191
|
insertionGuide.setAttribute(
|
|
@@ -2125,14 +2194,10 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
2125
2194
|
);
|
|
2126
2195
|
insertionGuide.style.cssText = "position:fixed;z-index:100000;display:none;pointer-events:none;background:var(--design-editor-accent-color);border-radius:999px;box-shadow:0 0 0 1px var(--design-editor-accent-color);";
|
|
2127
2196
|
document.body.appendChild(insertionGuide);
|
|
2128
|
-
var
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
document.body.appendChild(
|
|
2132
|
-
var snapGuideH = document.createElement("div");
|
|
2133
|
-
snapGuideH.setAttribute("data-agent-native-edit-overlay", "snap-guide");
|
|
2134
|
-
snapGuideH.style.cssText = "position:fixed;z-index:100000;display:none;pointer-events:none;height:1px;background:hsl(var(--destructive) / 0.9);";
|
|
2135
|
-
document.body.appendChild(snapGuideH);
|
|
2197
|
+
var snapGuideLayer = document.createElement("div");
|
|
2198
|
+
snapGuideLayer.setAttribute("data-agent-native-edit-overlay", "snap-guide");
|
|
2199
|
+
snapGuideLayer.style.cssText = "position:fixed;inset:0;z-index:100000;display:none;pointer-events:none;";
|
|
2200
|
+
document.body.appendChild(snapGuideLayer);
|
|
2136
2201
|
var measurementOverlay = document.createElement("div");
|
|
2137
2202
|
measurementOverlay.setAttribute("data-agent-native-measurement-overlay", "");
|
|
2138
2203
|
measurementOverlay.setAttribute(
|
|
@@ -2274,6 +2339,7 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
2274
2339
|
}
|
|
2275
2340
|
function hideSelectionOverlay() {
|
|
2276
2341
|
selectionOverlay.style.display = "none";
|
|
2342
|
+
hideSizeBadge();
|
|
2277
2343
|
hideSpacingOverlay();
|
|
2278
2344
|
hideParentAutoLayoutOverlay();
|
|
2279
2345
|
clearComponentTag();
|
|
@@ -2404,7 +2470,7 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
2404
2470
|
"multi-selection-handle"
|
|
2405
2471
|
);
|
|
2406
2472
|
handle.setAttribute("data-corner", pos);
|
|
2407
|
-
handle.style.cssText = "position:absolute;z-index:1;width:7px;height:7px;border:1px solid var(--design-editor-accent-color);background:var(--design-editor-accent-contrast-color);box-sizing:border-box;border-radius:1px;pointer-events:
|
|
2473
|
+
handle.style.cssText = "position:absolute;z-index:1;width:7px;height:7px;border:1px solid var(--design-editor-accent-color);background:var(--design-editor-accent-contrast-color);box-sizing:border-box;border-radius:1px;pointer-events:auto;cursor:" + (pos === "nw" || pos === "se" ? "nwse-resize" : "nesw-resize") + ";";
|
|
2408
2474
|
if (pos.indexOf("n") !== -1) handle.style.top = "-4px";
|
|
2409
2475
|
if (pos.indexOf("s") !== -1) handle.style.bottom = "-4px";
|
|
2410
2476
|
if (pos.indexOf("w") !== -1) handle.style.left = "-4px";
|
|
@@ -2433,6 +2499,7 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
2433
2499
|
"[data-agent-native-edit-overlay='multi-selection-handle']"
|
|
2434
2500
|
).forEach(function(handle) {
|
|
2435
2501
|
var pos = handle.getAttribute("data-corner") || "";
|
|
2502
|
+
handle.style.pointerEvents = readOnly ? "none" : "auto";
|
|
2436
2503
|
handle.style.width = 7 * sx + "px";
|
|
2437
2504
|
handle.style.height = 7 * sy + "px";
|
|
2438
2505
|
handle.style.borderWidth = 1 * line + "px";
|
|
@@ -2527,6 +2594,320 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
2527
2594
|
}
|
|
2528
2595
|
});
|
|
2529
2596
|
}
|
|
2597
|
+
function sourceMetaFor(element) {
|
|
2598
|
+
return element.__anSourceMeta;
|
|
2599
|
+
}
|
|
2600
|
+
function isSourceOwned(node) {
|
|
2601
|
+
return node.__anSource === true;
|
|
2602
|
+
}
|
|
2603
|
+
function recordSourceOwnership(node) {
|
|
2604
|
+
node.__anSource = true;
|
|
2605
|
+
if (node.nodeType !== 1) return;
|
|
2606
|
+
var element = node;
|
|
2607
|
+
var names = [];
|
|
2608
|
+
for (var i = 0; i < element.attributes.length; i += 1) {
|
|
2609
|
+
names.push(element.attributes[i].name);
|
|
2610
|
+
}
|
|
2611
|
+
element.__anSourceMeta = {
|
|
2612
|
+
attrs: names,
|
|
2613
|
+
className: element.getAttribute("class") ?? "",
|
|
2614
|
+
style: element.getAttribute("style") ?? ""
|
|
2615
|
+
};
|
|
2616
|
+
}
|
|
2617
|
+
function recordSourceSubtree(root) {
|
|
2618
|
+
if (root.nodeType === 1 && root.hasAttribute("data-agent-native-edit-overlay")) {
|
|
2619
|
+
return;
|
|
2620
|
+
}
|
|
2621
|
+
recordSourceOwnership(root);
|
|
2622
|
+
if (root.nodeType !== 1) return;
|
|
2623
|
+
var template = templateContentOf(root);
|
|
2624
|
+
if (template) {
|
|
2625
|
+
var held = template.childNodes;
|
|
2626
|
+
for (var t = 0; t < held.length; t += 1) recordSourceSubtree(held[t]);
|
|
2627
|
+
return;
|
|
2628
|
+
}
|
|
2629
|
+
var children = root.childNodes;
|
|
2630
|
+
for (var i = 0; i < children.length; i += 1) {
|
|
2631
|
+
recordSourceSubtree(children[i]);
|
|
2632
|
+
}
|
|
2633
|
+
}
|
|
2634
|
+
function templateContentOf(element) {
|
|
2635
|
+
if (element.nodeName !== "TEMPLATE") return null;
|
|
2636
|
+
return element.content ?? null;
|
|
2637
|
+
}
|
|
2638
|
+
function scopedMorphContext(liveRoot, nextRoot) {
|
|
2639
|
+
var keyed = /* @__PURE__ */ new Map();
|
|
2640
|
+
liveRoot.querySelectorAll("[data-agent-native-node-id]").forEach(function(element) {
|
|
2641
|
+
if (!isSourceOwned(element)) return;
|
|
2642
|
+
var key = element.getAttribute("data-agent-native-node-id");
|
|
2643
|
+
if (key && !keyed.has(key)) keyed.set(key, element);
|
|
2644
|
+
});
|
|
2645
|
+
var nextKeys = /* @__PURE__ */ new Set();
|
|
2646
|
+
nextRoot.querySelectorAll("[data-agent-native-node-id]").forEach(function(element) {
|
|
2647
|
+
var key = element.getAttribute("data-agent-native-node-id");
|
|
2648
|
+
if (key) nextKeys.add(key);
|
|
2649
|
+
});
|
|
2650
|
+
return { keyed, nextKeys, obsolete: /* @__PURE__ */ new Set() };
|
|
2651
|
+
}
|
|
2652
|
+
function captureInitialSourceOwnership() {
|
|
2653
|
+
if (document.body) recordSourceSubtree(document.body);
|
|
2654
|
+
}
|
|
2655
|
+
function classTokens(value) {
|
|
2656
|
+
return value.split(/\\s+/).filter(function(token) {
|
|
2657
|
+
return token.length > 0;
|
|
2658
|
+
});
|
|
2659
|
+
}
|
|
2660
|
+
function applyClassAttribute(live, previousSource, nextSource) {
|
|
2661
|
+
var previous = classTokens(previousSource);
|
|
2662
|
+
var current = classTokens(live.getAttribute("class") ?? "");
|
|
2663
|
+
var result = classTokens(nextSource);
|
|
2664
|
+
for (var i = 0; i < current.length; i += 1) {
|
|
2665
|
+
var token = current[i];
|
|
2666
|
+
if (previous.indexOf(token) !== -1) continue;
|
|
2667
|
+
if (result.indexOf(token) === -1) result.push(token);
|
|
2668
|
+
}
|
|
2669
|
+
var value = result.join(" ");
|
|
2670
|
+
if ((live.getAttribute("class") ?? "") === value) return;
|
|
2671
|
+
if (value) live.setAttribute("class", value);
|
|
2672
|
+
else live.removeAttribute("class");
|
|
2673
|
+
}
|
|
2674
|
+
var styleProbe = null;
|
|
2675
|
+
function styleDeclarations(value) {
|
|
2676
|
+
var probe = styleProbe || (styleProbe = document.createElement("div"));
|
|
2677
|
+
probe.style.cssText = value || "";
|
|
2678
|
+
var out = [];
|
|
2679
|
+
for (var i = 0; i < probe.style.length; i += 1) {
|
|
2680
|
+
var property = probe.style.item(i);
|
|
2681
|
+
out.push([
|
|
2682
|
+
property,
|
|
2683
|
+
probe.style.getPropertyValue(property),
|
|
2684
|
+
probe.style.getPropertyPriority(property)
|
|
2685
|
+
]);
|
|
2686
|
+
}
|
|
2687
|
+
return out;
|
|
2688
|
+
}
|
|
2689
|
+
function applyStyleAttribute(live, previousSource, nextSource) {
|
|
2690
|
+
var previousOwned = {};
|
|
2691
|
+
styleDeclarations(previousSource).forEach(function(entry) {
|
|
2692
|
+
previousOwned[entry[0]] = entry[1];
|
|
2693
|
+
});
|
|
2694
|
+
var nextOwned = {};
|
|
2695
|
+
styleDeclarations(nextSource).forEach(function(entry) {
|
|
2696
|
+
nextOwned[entry[0]] = true;
|
|
2697
|
+
});
|
|
2698
|
+
var target = document.createElement("div");
|
|
2699
|
+
target.style.cssText = nextSource || "";
|
|
2700
|
+
styleDeclarations(live.getAttribute("style") ?? "").forEach(
|
|
2701
|
+
function(entry) {
|
|
2702
|
+
if (nextOwned[entry[0]]) return;
|
|
2703
|
+
var wasSource = Object.prototype.hasOwnProperty.call(
|
|
2704
|
+
previousOwned,
|
|
2705
|
+
entry[0]
|
|
2706
|
+
);
|
|
2707
|
+
if (wasSource && previousOwned[entry[0]] === entry[1]) return;
|
|
2708
|
+
target.style.setProperty(entry[0], entry[1], entry[2]);
|
|
2709
|
+
}
|
|
2710
|
+
);
|
|
2711
|
+
var value = target.style.cssText;
|
|
2712
|
+
if ((live.getAttribute("style") ?? "") === value) return;
|
|
2713
|
+
if (value) live.setAttribute("style", value);
|
|
2714
|
+
else live.removeAttribute("style");
|
|
2715
|
+
}
|
|
2716
|
+
function morphFormState(live, next) {
|
|
2717
|
+
if (live.nodeName === "INPUT") {
|
|
2718
|
+
var input = live;
|
|
2719
|
+
var nextChecked = next.hasAttribute("checked");
|
|
2720
|
+
if (input.defaultChecked !== nextChecked) {
|
|
2721
|
+
input.defaultChecked = nextChecked;
|
|
2722
|
+
input.checked = nextChecked;
|
|
2723
|
+
}
|
|
2724
|
+
var nextValue = next.getAttribute("value");
|
|
2725
|
+
if (nextValue !== null && input.defaultValue !== nextValue) {
|
|
2726
|
+
input.defaultValue = nextValue;
|
|
2727
|
+
input.value = nextValue;
|
|
2728
|
+
}
|
|
2729
|
+
return;
|
|
2730
|
+
}
|
|
2731
|
+
if (live.nodeName === "TEXTAREA") {
|
|
2732
|
+
var area = live;
|
|
2733
|
+
var nextText = next.textContent ?? "";
|
|
2734
|
+
if (area.defaultValue !== nextText) {
|
|
2735
|
+
area.defaultValue = nextText;
|
|
2736
|
+
area.value = nextText;
|
|
2737
|
+
}
|
|
2738
|
+
return;
|
|
2739
|
+
}
|
|
2740
|
+
if (live.nodeName === "OPTION") {
|
|
2741
|
+
var option = live;
|
|
2742
|
+
var nextSelected = next.hasAttribute("selected");
|
|
2743
|
+
if (option.defaultSelected !== nextSelected) {
|
|
2744
|
+
option.defaultSelected = nextSelected;
|
|
2745
|
+
option.selected = nextSelected;
|
|
2746
|
+
}
|
|
2747
|
+
}
|
|
2748
|
+
}
|
|
2749
|
+
function declaresRuntimeChildren(element) {
|
|
2750
|
+
return element.hasAttribute("x-text") || element.hasAttribute("x-html") || element.hasAttribute("v-text") || element.hasAttribute("v-html");
|
|
2751
|
+
}
|
|
2752
|
+
function scopeDirectiveChanged(live, next) {
|
|
2753
|
+
return (live.getAttribute("x-data") ?? "") !== (next.getAttribute("x-data") ?? "");
|
|
2754
|
+
}
|
|
2755
|
+
function morphNodeKey(node) {
|
|
2756
|
+
if (node.nodeType !== 1) return null;
|
|
2757
|
+
return node.getAttribute("data-agent-native-node-id");
|
|
2758
|
+
}
|
|
2759
|
+
function morphAttributes(live, next) {
|
|
2760
|
+
var meta = sourceMetaFor(live);
|
|
2761
|
+
var previousAttrs = meta ? meta.attrs : [];
|
|
2762
|
+
var previousClass = meta ? meta.className : "";
|
|
2763
|
+
var previousStyle = meta ? meta.style : "";
|
|
2764
|
+
var nextNames = [];
|
|
2765
|
+
var nextAttrs = next.attributes;
|
|
2766
|
+
for (var i = 0; i < nextAttrs.length; i += 1) {
|
|
2767
|
+
var attr = nextAttrs[i];
|
|
2768
|
+
nextNames.push(attr.name);
|
|
2769
|
+
if (attr.name === "class") {
|
|
2770
|
+
applyClassAttribute(live, previousClass, attr.value);
|
|
2771
|
+
continue;
|
|
2772
|
+
}
|
|
2773
|
+
if (attr.name === "style") {
|
|
2774
|
+
applyStyleAttribute(live, previousStyle, attr.value);
|
|
2775
|
+
continue;
|
|
2776
|
+
}
|
|
2777
|
+
if (attr.name === "x-cloak" && !live.hasAttribute("x-cloak")) continue;
|
|
2778
|
+
if (live.getAttribute(attr.name) === attr.value) continue;
|
|
2779
|
+
if (attr.namespaceURI) {
|
|
2780
|
+
live.setAttributeNS(attr.namespaceURI, attr.name, attr.value);
|
|
2781
|
+
} else {
|
|
2782
|
+
live.setAttribute(attr.name, attr.value);
|
|
2783
|
+
}
|
|
2784
|
+
}
|
|
2785
|
+
for (var j = 0; j < previousAttrs.length; j += 1) {
|
|
2786
|
+
var name = previousAttrs[j];
|
|
2787
|
+
if (nextNames.indexOf(name) !== -1) continue;
|
|
2788
|
+
if (name === "class") {
|
|
2789
|
+
applyClassAttribute(live, previousClass, "");
|
|
2790
|
+
continue;
|
|
2791
|
+
}
|
|
2792
|
+
if (name === "style") {
|
|
2793
|
+
applyStyleAttribute(live, previousStyle, "");
|
|
2794
|
+
continue;
|
|
2795
|
+
}
|
|
2796
|
+
live.removeAttribute(name);
|
|
2797
|
+
}
|
|
2798
|
+
live.__anSourceMeta = {
|
|
2799
|
+
attrs: nextNames,
|
|
2800
|
+
className: next.getAttribute("class") ?? "",
|
|
2801
|
+
style: next.getAttribute("style") ?? ""
|
|
2802
|
+
};
|
|
2803
|
+
}
|
|
2804
|
+
function morphChildren(live, next, context) {
|
|
2805
|
+
var cursor = live.firstChild;
|
|
2806
|
+
var nextChild = next.firstChild;
|
|
2807
|
+
while (nextChild) {
|
|
2808
|
+
var key = morphNodeKey(nextChild);
|
|
2809
|
+
var reuse = null;
|
|
2810
|
+
if (key) {
|
|
2811
|
+
var candidate = context.keyed.get(key) ?? null;
|
|
2812
|
+
if (candidate && !candidate.contains(live) && candidate.nodeName === nextChild.nodeName && candidate.namespaceURI === nextChild.namespaceURI) {
|
|
2813
|
+
reuse = candidate;
|
|
2814
|
+
context.keyed.delete(key);
|
|
2815
|
+
} else if (candidate) {
|
|
2816
|
+
context.obsolete.add(key);
|
|
2817
|
+
}
|
|
2818
|
+
} else {
|
|
2819
|
+
var probe = cursor;
|
|
2820
|
+
while (probe) {
|
|
2821
|
+
var probeKey = morphNodeKey(probe);
|
|
2822
|
+
if (probeKey) {
|
|
2823
|
+
if (context.nextKeys.has(probeKey) && !context.obsolete.has(probeKey)) {
|
|
2824
|
+
break;
|
|
2825
|
+
}
|
|
2826
|
+
probe = probe.nextSibling;
|
|
2827
|
+
continue;
|
|
2828
|
+
}
|
|
2829
|
+
if (!isSourceOwned(probe)) {
|
|
2830
|
+
probe = probe.nextSibling;
|
|
2831
|
+
continue;
|
|
2832
|
+
}
|
|
2833
|
+
if (probe.nodeType === nextChild.nodeType && probe.nodeName === nextChild.nodeName) {
|
|
2834
|
+
reuse = probe;
|
|
2835
|
+
}
|
|
2836
|
+
break;
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2839
|
+
if (reuse && reuse.nodeType === 1 && scopeDirectiveChanged(reuse, nextChild)) {
|
|
2840
|
+
var rebuilt = document.importNode(nextChild, true);
|
|
2841
|
+
live.insertBefore(rebuilt, cursor);
|
|
2842
|
+
if (reuse.parentNode) reuse.parentNode.removeChild(reuse);
|
|
2843
|
+
recordSourceSubtree(rebuilt);
|
|
2844
|
+
cursor = rebuilt.nextSibling;
|
|
2845
|
+
nextChild = nextChild.nextSibling;
|
|
2846
|
+
continue;
|
|
2847
|
+
}
|
|
2848
|
+
if (reuse) {
|
|
2849
|
+
if (reuse !== cursor) live.insertBefore(reuse, cursor);
|
|
2850
|
+
if (reuse.nodeType === 1) {
|
|
2851
|
+
morphElement(reuse, nextChild, context);
|
|
2852
|
+
} else if (reuse.nodeValue !== nextChild.nodeValue) {
|
|
2853
|
+
reuse.nodeValue = nextChild.nodeValue;
|
|
2854
|
+
}
|
|
2855
|
+
cursor = reuse.nextSibling;
|
|
2856
|
+
} else if (nextChild.nodeType === 1) {
|
|
2857
|
+
var shell = document.importNode(nextChild, false);
|
|
2858
|
+
live.insertBefore(shell, cursor);
|
|
2859
|
+
recordSourceOwnership(shell);
|
|
2860
|
+
morphElement(shell, nextChild, context);
|
|
2861
|
+
cursor = shell.nextSibling;
|
|
2862
|
+
} else {
|
|
2863
|
+
var imported = document.importNode(nextChild, true);
|
|
2864
|
+
live.insertBefore(imported, cursor);
|
|
2865
|
+
recordSourceSubtree(imported);
|
|
2866
|
+
}
|
|
2867
|
+
nextChild = nextChild.nextSibling;
|
|
2868
|
+
}
|
|
2869
|
+
while (cursor) {
|
|
2870
|
+
var stale = cursor;
|
|
2871
|
+
cursor = cursor.nextSibling;
|
|
2872
|
+
if (stale.parentNode !== live) continue;
|
|
2873
|
+
if (!isSourceOwned(stale)) continue;
|
|
2874
|
+
live.removeChild(stale);
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2877
|
+
function morphElement(live, next, context) {
|
|
2878
|
+
morphFormState(live, next);
|
|
2879
|
+
morphAttributes(live, next);
|
|
2880
|
+
if (declaresRuntimeChildren(next) || declaresRuntimeChildren(live)) return;
|
|
2881
|
+
var liveTemplate = templateContentOf(live);
|
|
2882
|
+
var nextTemplate = templateContentOf(next);
|
|
2883
|
+
if (liveTemplate && nextTemplate) {
|
|
2884
|
+
morphChildren(
|
|
2885
|
+
liveTemplate,
|
|
2886
|
+
nextTemplate,
|
|
2887
|
+
scopedMorphContext(liveTemplate, nextTemplate)
|
|
2888
|
+
);
|
|
2889
|
+
return;
|
|
2890
|
+
}
|
|
2891
|
+
morphChildren(live, next, context);
|
|
2892
|
+
}
|
|
2893
|
+
function morphRuntimeBody(nextBody) {
|
|
2894
|
+
var keyed = /* @__PURE__ */ new Map();
|
|
2895
|
+
document.querySelectorAll("[data-agent-native-node-id]").forEach(function(element) {
|
|
2896
|
+
if (!isSourceOwned(element)) return;
|
|
2897
|
+
var key = element.getAttribute("data-agent-native-node-id");
|
|
2898
|
+
if (key && !keyed.has(key)) keyed.set(key, element);
|
|
2899
|
+
});
|
|
2900
|
+
var nextKeys = /* @__PURE__ */ new Set();
|
|
2901
|
+
nextBody.querySelectorAll("[data-agent-native-node-id]").forEach(function(element) {
|
|
2902
|
+
var key = element.getAttribute("data-agent-native-node-id");
|
|
2903
|
+
if (key) nextKeys.add(key);
|
|
2904
|
+
});
|
|
2905
|
+
morphElement(document.body, nextBody, {
|
|
2906
|
+
keyed,
|
|
2907
|
+
nextKeys,
|
|
2908
|
+
obsolete: /* @__PURE__ */ new Set()
|
|
2909
|
+
});
|
|
2910
|
+
}
|
|
2530
2911
|
function replaceRuntimeDocument(html, preferredSelector, selectorCandidates, forceFullDocument, preserveTextEditingSession) {
|
|
2531
2912
|
if (typeof html !== "string") return;
|
|
2532
2913
|
exitStaleTextEditSession();
|
|
@@ -2571,6 +2952,7 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
2571
2952
|
var nextHeadHtml = nextDoc.head ? nextDoc.head.innerHTML : "";
|
|
2572
2953
|
ensureEditorChromeStyle();
|
|
2573
2954
|
if (lastSourceHeadHtml === null) {
|
|
2955
|
+
replaceSourceHeadNodes(null, nextHeadHtml);
|
|
2574
2956
|
lastSourceHeadHtml = nextHeadHtml;
|
|
2575
2957
|
}
|
|
2576
2958
|
var currentHeadHtml = lastSourceHeadHtml;
|
|
@@ -2639,13 +3021,10 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
2639
3021
|
ensureEditorChromeStyle();
|
|
2640
3022
|
lastSourceHeadHtml = nextHeadHtml;
|
|
2641
3023
|
}
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
});
|
|
2645
|
-
Array.prototype.slice.call(nextDoc.body.attributes).forEach(function(attribute) {
|
|
2646
|
-
document.body.setAttribute(attribute.name, attribute.value);
|
|
3024
|
+
persistentNodes.forEach(function(node) {
|
|
3025
|
+
if (node.parentNode) node.parentNode.removeChild(node);
|
|
2647
3026
|
});
|
|
2648
|
-
|
|
3027
|
+
morphRuntimeBody(nextDoc.body);
|
|
2649
3028
|
persistentNodes.forEach(function(node) {
|
|
2650
3029
|
document.body.appendChild(node);
|
|
2651
3030
|
});
|
|
@@ -3428,6 +3807,16 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
3428
3807
|
overlay.setAttribute("data-agent-native-multi-selection-bounds", "true");
|
|
3429
3808
|
overlay.style.cssText = "position:fixed;pointer-events:none;z-index:99996;border:1.5px solid var(--design-editor-accent-color);background:transparent;display:none;box-sizing:border-box;";
|
|
3430
3809
|
appendPassiveSelectionHandles(overlay);
|
|
3810
|
+
overlay.addEventListener(
|
|
3811
|
+
"mousedown",
|
|
3812
|
+
function(e) {
|
|
3813
|
+
if (readOnly) return;
|
|
3814
|
+
var corner = e.target && e.target.getAttribute && e.target.getAttribute("data-corner");
|
|
3815
|
+
if (!corner) return;
|
|
3816
|
+
startGroupResize(corner, e);
|
|
3817
|
+
},
|
|
3818
|
+
true
|
|
3819
|
+
);
|
|
3431
3820
|
document.body.appendChild(overlay);
|
|
3432
3821
|
multiSelectionBoundsOverlay = overlay;
|
|
3433
3822
|
return overlay;
|
|
@@ -3440,6 +3829,9 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
3440
3829
|
passiveSelectionEls.forEach(function(el) {
|
|
3441
3830
|
if (el && document.documentElement.contains(el)) members.push(el);
|
|
3442
3831
|
});
|
|
3832
|
+
setSelectionOverlayResizeChromeVisible(
|
|
3833
|
+
!readOnly && !activeTextEditEl && members.length < 2
|
|
3834
|
+
);
|
|
3443
3835
|
if (members.length < 2 || selectionChromeHidden) {
|
|
3444
3836
|
if (multiSelectionBoundsOverlay) {
|
|
3445
3837
|
multiSelectionBoundsOverlay.style.display = "none";
|
|
@@ -3504,6 +3896,7 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
3504
3896
|
updateSpacingOverlay(el);
|
|
3505
3897
|
updateComponentTag(el, rect);
|
|
3506
3898
|
updateParentAutoLayoutOverlay(el);
|
|
3899
|
+
showSizeBadge(el);
|
|
3507
3900
|
} else {
|
|
3508
3901
|
applyElementOverlayChrome(overlay, el);
|
|
3509
3902
|
}
|
|
@@ -3541,6 +3934,7 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
3541
3934
|
var overlay = passiveSelectionOverlays[index];
|
|
3542
3935
|
if (overlay) positionOverlay(overlay, el);
|
|
3543
3936
|
});
|
|
3937
|
+
if (passiveSelectionEls.length > 0) hideSizeBadge();
|
|
3544
3938
|
positionMultiSelectionBounds();
|
|
3545
3939
|
positionGradientOverlay();
|
|
3546
3940
|
syncOverlayObservers();
|
|
@@ -5344,8 +5738,7 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
5344
5738
|
if (cs.position === "absolute" || cs.position === "fixed") return false;
|
|
5345
5739
|
return true;
|
|
5346
5740
|
}
|
|
5347
|
-
function
|
|
5348
|
-
if (!gestureEl) return [];
|
|
5741
|
+
function collectSelectionMembers() {
|
|
5349
5742
|
var raw = [];
|
|
5350
5743
|
if (selectedEl) raw.push(selectedEl);
|
|
5351
5744
|
for (var i = 0; i < passiveSelectionEls.length; i += 1) {
|
|
@@ -5359,11 +5752,15 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
5359
5752
|
}
|
|
5360
5753
|
members.push(candidate);
|
|
5361
5754
|
}
|
|
5362
|
-
|
|
5755
|
+
return members.filter(function(member) {
|
|
5363
5756
|
return !members.some(function(other) {
|
|
5364
5757
|
return other !== member && other.contains(member);
|
|
5365
5758
|
});
|
|
5366
5759
|
});
|
|
5760
|
+
}
|
|
5761
|
+
function collectMoveGroupMembers(gestureEl) {
|
|
5762
|
+
if (!gestureEl) return [];
|
|
5763
|
+
var members = collectSelectionMembers();
|
|
5367
5764
|
var gestureMember = null;
|
|
5368
5765
|
for (var k = 0; k < members.length; k += 1) {
|
|
5369
5766
|
if (members[k] === gestureEl || members[k].contains && members[k].contains(gestureEl)) {
|
|
@@ -6364,84 +6761,584 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
6364
6761
|
}
|
|
6365
6762
|
return rects;
|
|
6366
6763
|
}
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6764
|
+
var SNAP_ALIGN_EPSILON = 1e-6;
|
|
6765
|
+
var SPACING_MATCH_EPSILON = 0.5;
|
|
6766
|
+
var PROXIMITY_RANGE_PX = 160;
|
|
6767
|
+
function axisSnapValues(bounds, axis) {
|
|
6768
|
+
return axis === "x" ? [bounds.left, bounds.centerX, bounds.right] : [bounds.top, bounds.centerY, bounds.bottom];
|
|
6769
|
+
}
|
|
6770
|
+
function axisStart(bounds, axis) {
|
|
6771
|
+
return axis === "x" ? bounds.left : bounds.top;
|
|
6772
|
+
}
|
|
6773
|
+
function axisEnd(bounds, axis) {
|
|
6774
|
+
return axis === "x" ? bounds.right : bounds.bottom;
|
|
6775
|
+
}
|
|
6776
|
+
function crossStart(bounds, axis) {
|
|
6777
|
+
return axis === "x" ? bounds.top : bounds.left;
|
|
6778
|
+
}
|
|
6779
|
+
function crossEnd(bounds, axis) {
|
|
6780
|
+
return axis === "x" ? bounds.bottom : bounds.right;
|
|
6781
|
+
}
|
|
6782
|
+
function crossAxisOverlaps(axis, a, b) {
|
|
6783
|
+
return crossStart(a, axis) < crossEnd(b, axis) && crossEnd(a, axis) > crossStart(b, axis);
|
|
6784
|
+
}
|
|
6785
|
+
function translateRectBounds(bounds, dx, dy) {
|
|
6786
|
+
return {
|
|
6787
|
+
left: bounds.left + dx,
|
|
6788
|
+
right: bounds.right + dx,
|
|
6789
|
+
centerX: bounds.centerX + dx,
|
|
6790
|
+
top: bounds.top + dy,
|
|
6791
|
+
bottom: bounds.bottom + dy,
|
|
6792
|
+
centerY: bounds.centerY + dy
|
|
6793
|
+
};
|
|
6794
|
+
}
|
|
6795
|
+
function findAxisSnapOffset(axis, moving, candidates, threshold) {
|
|
6796
|
+
var offset = null;
|
|
6797
|
+
var bestDistance = Infinity;
|
|
6798
|
+
var movingValues = axisSnapValues(moving, axis);
|
|
6799
|
+
for (var i = 0; i < candidates.length; i += 1) {
|
|
6800
|
+
var targets = axisSnapValues(candidates[i], axis);
|
|
6801
|
+
for (var mi = 0; mi < movingValues.length; mi += 1) {
|
|
6802
|
+
for (var ti = 0; ti < targets.length; ti += 1) {
|
|
6803
|
+
var candidate = targets[ti] - movingValues[mi];
|
|
6804
|
+
var distance = Math.abs(candidate);
|
|
6805
|
+
if (distance > threshold || distance >= bestDistance) continue;
|
|
6806
|
+
bestDistance = distance;
|
|
6807
|
+
offset = candidate;
|
|
6808
|
+
}
|
|
6809
|
+
}
|
|
6810
|
+
}
|
|
6811
|
+
return offset;
|
|
6812
|
+
}
|
|
6813
|
+
function buildAxisGuides(axis, moving, candidates) {
|
|
6814
|
+
var positions = [];
|
|
6815
|
+
var spans = [];
|
|
6816
|
+
var movingValues = axisSnapValues(moving, axis);
|
|
6371
6817
|
for (var i = 0; i < candidates.length; i += 1) {
|
|
6372
6818
|
var candidate = candidates[i];
|
|
6373
|
-
var
|
|
6374
|
-
var
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
if (
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6819
|
+
var targets = axisSnapValues(candidate, axis);
|
|
6820
|
+
for (var mi = 0; mi < movingValues.length; mi += 1) {
|
|
6821
|
+
for (var ti = 0; ti < targets.length; ti += 1) {
|
|
6822
|
+
if (Math.abs(targets[ti] - movingValues[mi]) > SNAP_ALIGN_EPSILON) {
|
|
6823
|
+
continue;
|
|
6824
|
+
}
|
|
6825
|
+
var slot = positions.indexOf(targets[ti]);
|
|
6826
|
+
if (slot === -1) {
|
|
6827
|
+
positions.push(targets[ti]);
|
|
6828
|
+
spans.push({
|
|
6829
|
+
start: Math.min(
|
|
6830
|
+
crossStart(moving, axis),
|
|
6831
|
+
crossStart(candidate, axis)
|
|
6832
|
+
),
|
|
6833
|
+
end: Math.max(crossEnd(moving, axis), crossEnd(candidate, axis))
|
|
6834
|
+
});
|
|
6835
|
+
} else {
|
|
6836
|
+
spans[slot].start = Math.min(
|
|
6837
|
+
spans[slot].start,
|
|
6838
|
+
crossStart(candidate, axis)
|
|
6839
|
+
);
|
|
6840
|
+
spans[slot].end = Math.max(
|
|
6841
|
+
spans[slot].end,
|
|
6842
|
+
crossEnd(candidate, axis)
|
|
6843
|
+
);
|
|
6390
6844
|
}
|
|
6391
6845
|
}
|
|
6392
6846
|
}
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6847
|
+
}
|
|
6848
|
+
var guides = [];
|
|
6849
|
+
for (var g = 0; g < positions.length; g += 1) {
|
|
6850
|
+
guides.push({
|
|
6851
|
+
orientation: axis === "x" ? "vertical" : "horizontal",
|
|
6852
|
+
position: positions[g],
|
|
6853
|
+
start: spans[g].start,
|
|
6854
|
+
end: spans[g].end
|
|
6855
|
+
});
|
|
6856
|
+
}
|
|
6857
|
+
return guides;
|
|
6858
|
+
}
|
|
6859
|
+
function collectAxisGapCandidates(axis, moving, candidates) {
|
|
6860
|
+
var gaps = [];
|
|
6861
|
+
for (var i = 0; i < candidates.length; i += 1) {
|
|
6862
|
+
var bounds = candidates[i];
|
|
6863
|
+
if (!crossAxisOverlaps(axis, bounds, moving)) continue;
|
|
6864
|
+
var band = {
|
|
6865
|
+
crossStart: Math.max(
|
|
6866
|
+
crossStart(bounds, axis),
|
|
6867
|
+
crossStart(moving, axis)
|
|
6868
|
+
),
|
|
6869
|
+
crossEnd: Math.min(crossEnd(bounds, axis), crossEnd(moving, axis))
|
|
6870
|
+
};
|
|
6871
|
+
if (axisEnd(bounds, axis) <= axisStart(moving, axis)) {
|
|
6872
|
+
gaps.push({
|
|
6873
|
+
side: "before",
|
|
6874
|
+
gap: axisStart(moving, axis) - axisEnd(bounds, axis),
|
|
6875
|
+
gapStart: axisEnd(bounds, axis),
|
|
6876
|
+
gapEnd: axisStart(moving, axis),
|
|
6877
|
+
crossStart: band.crossStart,
|
|
6878
|
+
crossEnd: band.crossEnd
|
|
6879
|
+
});
|
|
6880
|
+
} else if (axisStart(bounds, axis) >= axisEnd(moving, axis)) {
|
|
6881
|
+
gaps.push({
|
|
6882
|
+
side: "after",
|
|
6883
|
+
gap: axisStart(bounds, axis) - axisEnd(moving, axis),
|
|
6884
|
+
gapStart: axisEnd(moving, axis),
|
|
6885
|
+
gapEnd: axisStart(bounds, axis),
|
|
6886
|
+
crossStart: band.crossStart,
|
|
6887
|
+
crossEnd: band.crossEnd
|
|
6888
|
+
});
|
|
6889
|
+
}
|
|
6890
|
+
}
|
|
6891
|
+
return gaps;
|
|
6892
|
+
}
|
|
6893
|
+
function closestGapCandidate(gaps, side) {
|
|
6894
|
+
var best = null;
|
|
6895
|
+
for (var i = 0; i < gaps.length; i += 1) {
|
|
6896
|
+
if (gaps[i].side !== side) continue;
|
|
6897
|
+
if (!best || gaps[i].gap < best.gap) best = gaps[i];
|
|
6898
|
+
}
|
|
6899
|
+
return best;
|
|
6900
|
+
}
|
|
6901
|
+
function collectRhythmGaps(axis, moving, candidates) {
|
|
6902
|
+
var row = [];
|
|
6903
|
+
for (var i = 0; i < candidates.length; i += 1) {
|
|
6904
|
+
var entry = candidates[i];
|
|
6905
|
+
if (!crossAxisOverlaps(axis, entry, moving)) continue;
|
|
6906
|
+
if (axisStart(entry, axis) <= axisStart(moving, axis) && axisEnd(entry, axis) >= axisEnd(moving, axis)) {
|
|
6907
|
+
continue;
|
|
6908
|
+
}
|
|
6909
|
+
row.push(entry);
|
|
6910
|
+
}
|
|
6911
|
+
row.sort(function(a, b) {
|
|
6912
|
+
return axisStart(a, axis) - axisStart(b, axis);
|
|
6913
|
+
});
|
|
6914
|
+
var gaps = [];
|
|
6915
|
+
var previous = null;
|
|
6916
|
+
for (var r = 0; r < row.length; r += 1) {
|
|
6917
|
+
var bounds = row[r];
|
|
6918
|
+
var gap = previous ? axisStart(bounds, axis) - axisEnd(previous, axis) : 0;
|
|
6919
|
+
if (previous && gap > 0 && crossAxisOverlaps(axis, previous, bounds)) {
|
|
6920
|
+
gaps.push({
|
|
6921
|
+
gap,
|
|
6922
|
+
band: {
|
|
6923
|
+
gapStart: axisEnd(previous, axis),
|
|
6924
|
+
gapEnd: axisStart(bounds, axis),
|
|
6925
|
+
crossStart: Math.max(
|
|
6926
|
+
crossStart(previous, axis),
|
|
6927
|
+
crossStart(bounds, axis)
|
|
6928
|
+
),
|
|
6929
|
+
crossEnd: Math.min(
|
|
6930
|
+
crossEnd(previous, axis),
|
|
6931
|
+
crossEnd(bounds, axis)
|
|
6932
|
+
)
|
|
6410
6933
|
}
|
|
6934
|
+
});
|
|
6935
|
+
}
|
|
6936
|
+
if (!previous || axisEnd(bounds, axis) > axisEnd(previous, axis)) {
|
|
6937
|
+
previous = bounds;
|
|
6938
|
+
}
|
|
6939
|
+
}
|
|
6940
|
+
return gaps;
|
|
6941
|
+
}
|
|
6942
|
+
function findSpacingSnapOffset(axis, moving, candidates, tolerance) {
|
|
6943
|
+
var gaps = collectAxisGapCandidates(axis, moving, candidates);
|
|
6944
|
+
var before = closestGapCandidate(gaps, "before");
|
|
6945
|
+
var after = closestGapCandidate(gaps, "after");
|
|
6946
|
+
if (!before && !after) return { offset: 0, side: null };
|
|
6947
|
+
var offset = 0;
|
|
6948
|
+
var side = null;
|
|
6949
|
+
var bestDistance = Infinity;
|
|
6950
|
+
function consider(value, matched) {
|
|
6951
|
+
var distance = Math.abs(value);
|
|
6952
|
+
if (distance > tolerance || distance >= bestDistance) return;
|
|
6953
|
+
bestDistance = distance;
|
|
6954
|
+
offset = value;
|
|
6955
|
+
side = matched;
|
|
6956
|
+
}
|
|
6957
|
+
if (before && after) consider((after.gap - before.gap) / 2, "both");
|
|
6958
|
+
var rhythms = collectRhythmGaps(axis, moving, candidates);
|
|
6959
|
+
for (var i = 0; i < rhythms.length; i += 1) {
|
|
6960
|
+
if (before) consider(rhythms[i].gap - before.gap, "before");
|
|
6961
|
+
if (after) consider(after.gap - rhythms[i].gap, "after");
|
|
6962
|
+
}
|
|
6963
|
+
return { offset, side };
|
|
6964
|
+
}
|
|
6965
|
+
function gapCandidateBand(candidate) {
|
|
6966
|
+
return {
|
|
6967
|
+
gapStart: candidate.gapStart,
|
|
6968
|
+
gapEnd: candidate.gapEnd,
|
|
6969
|
+
crossStart: candidate.crossStart,
|
|
6970
|
+
crossEnd: candidate.crossEnd
|
|
6971
|
+
};
|
|
6972
|
+
}
|
|
6973
|
+
function matchingRhythmBands(rhythms, gap, tolerance) {
|
|
6974
|
+
var bands = [];
|
|
6975
|
+
for (var i = 0; i < rhythms.length; i += 1) {
|
|
6976
|
+
if (Math.abs(rhythms[i].gap - gap) <= tolerance)
|
|
6977
|
+
bands.push(rhythms[i].band);
|
|
6978
|
+
}
|
|
6979
|
+
return bands;
|
|
6980
|
+
}
|
|
6981
|
+
function buildSpacingGuides(axis, moving, candidates, tolerance, gaps, matchedSide) {
|
|
6982
|
+
gaps = gaps || collectAxisGapCandidates(axis, moving, candidates);
|
|
6983
|
+
var before = closestGapCandidate(gaps, "before");
|
|
6984
|
+
var after = closestGapCandidate(gaps, "after");
|
|
6985
|
+
var orientation = axis === "x" ? "vertical" : "horizontal";
|
|
6986
|
+
var rhythms = collectRhythmGaps(axis, moving, candidates);
|
|
6987
|
+
if (before && after && Math.abs(before.gap - after.gap) <= tolerance) {
|
|
6988
|
+
var pairGap = (before.gap + after.gap) / 2;
|
|
6989
|
+
return [
|
|
6990
|
+
{
|
|
6991
|
+
orientation,
|
|
6992
|
+
gap: pairGap,
|
|
6993
|
+
bands: [gapCandidateBand(before), gapCandidateBand(after)].concat(
|
|
6994
|
+
matchingRhythmBands(rhythms, pairGap, tolerance)
|
|
6995
|
+
)
|
|
6411
6996
|
}
|
|
6997
|
+
];
|
|
6998
|
+
}
|
|
6999
|
+
var neighbor = matchedSide === "after" ? after : matchedSide === "before" ? before : before || after;
|
|
7000
|
+
if (!neighbor) return [];
|
|
7001
|
+
var matched = matchingRhythmBands(rhythms, neighbor.gap, tolerance);
|
|
7002
|
+
if (!matched.length) return [];
|
|
7003
|
+
return [
|
|
7004
|
+
{
|
|
7005
|
+
orientation,
|
|
7006
|
+
gap: neighbor.gap,
|
|
7007
|
+
bands: [gapCandidateBand(neighbor)].concat(matched)
|
|
7008
|
+
}
|
|
7009
|
+
];
|
|
7010
|
+
}
|
|
7011
|
+
function computeProximityMeasurements(moving, candidates, range, gapsByAxis) {
|
|
7012
|
+
var measurements = [];
|
|
7013
|
+
var axes = ["x", "y"];
|
|
7014
|
+
for (var a = 0; a < axes.length; a += 1) {
|
|
7015
|
+
var axis = axes[a];
|
|
7016
|
+
var gaps = gapsByAxis && gapsByAxis[axis] || collectAxisGapCandidates(axis, moving, candidates);
|
|
7017
|
+
var nearest = null;
|
|
7018
|
+
for (var i = 0; i < gaps.length; i += 1) {
|
|
7019
|
+
if (!nearest || gaps[i].gap < nearest.gap) nearest = gaps[i];
|
|
7020
|
+
}
|
|
7021
|
+
if (!nearest || nearest.gap > range) continue;
|
|
7022
|
+
measurements.push({
|
|
7023
|
+
orientation: axis === "x" ? "vertical" : "horizontal",
|
|
7024
|
+
gap: nearest.gap,
|
|
7025
|
+
band: gapCandidateBand(nearest)
|
|
7026
|
+
});
|
|
7027
|
+
}
|
|
7028
|
+
return measurements;
|
|
7029
|
+
}
|
|
7030
|
+
function computeMoveSnapOffset(movingRect, candidates, threshold, isGroup, locked) {
|
|
7031
|
+
var moving = rectBounds(movingRect);
|
|
7032
|
+
locked = locked || {};
|
|
7033
|
+
var dx = locked.x ? null : findAxisSnapOffset("x", moving, candidates, threshold);
|
|
7034
|
+
var dy = locked.y ? null : findAxisSnapOffset("y", moving, candidates, threshold);
|
|
7035
|
+
var snapped = translateRectBounds(moving, dx || 0, dy || 0);
|
|
7036
|
+
var guides = (locked.x ? [] : buildAxisGuides("x", snapped, candidates)).concat(locked.y ? [] : buildAxisGuides("y", snapped, candidates));
|
|
7037
|
+
if (isGroup) {
|
|
7038
|
+
return {
|
|
7039
|
+
dx: dx || 0,
|
|
7040
|
+
dy: dy || 0,
|
|
7041
|
+
guides,
|
|
7042
|
+
spacingGuides: [],
|
|
7043
|
+
measurements: []
|
|
7044
|
+
};
|
|
7045
|
+
}
|
|
7046
|
+
var idle = { offset: 0, side: null };
|
|
7047
|
+
var spacingXResult = guides.some(function(guide) {
|
|
7048
|
+
return guide.orientation === "vertical";
|
|
7049
|
+
}) ? idle : locked.x ? idle : findSpacingSnapOffset("x", snapped, candidates, threshold);
|
|
7050
|
+
var spacingYResult = guides.some(function(guide) {
|
|
7051
|
+
return guide.orientation === "horizontal";
|
|
7052
|
+
}) ? idle : locked.y ? idle : findSpacingSnapOffset("y", snapped, candidates, threshold);
|
|
7053
|
+
var spacingX = spacingXResult.offset;
|
|
7054
|
+
var spacingY = spacingYResult.offset;
|
|
7055
|
+
var spaced = translateRectBounds(snapped, spacingX, spacingY);
|
|
7056
|
+
var settledGaps = {
|
|
7057
|
+
x: collectAxisGapCandidates("x", spaced, candidates),
|
|
7058
|
+
y: collectAxisGapCandidates("y", spaced, candidates)
|
|
7059
|
+
};
|
|
7060
|
+
var spacingGuides = buildSpacingGuides(
|
|
7061
|
+
"x",
|
|
7062
|
+
spaced,
|
|
7063
|
+
candidates,
|
|
7064
|
+
SPACING_MATCH_EPSILON,
|
|
7065
|
+
settledGaps.x,
|
|
7066
|
+
spacingXResult.side
|
|
7067
|
+
).concat(
|
|
7068
|
+
buildSpacingGuides(
|
|
7069
|
+
"y",
|
|
7070
|
+
spaced,
|
|
7071
|
+
candidates,
|
|
7072
|
+
SPACING_MATCH_EPSILON,
|
|
7073
|
+
settledGaps.y,
|
|
7074
|
+
spacingYResult.side
|
|
7075
|
+
)
|
|
7076
|
+
);
|
|
7077
|
+
var measurements = computeProximityMeasurements(
|
|
7078
|
+
spaced,
|
|
7079
|
+
candidates,
|
|
7080
|
+
PROXIMITY_RANGE_PX * threshold / SNAP_THRESHOLD_PX,
|
|
7081
|
+
settledGaps
|
|
7082
|
+
).filter(function(measurement) {
|
|
7083
|
+
return !spacingGuides.some(function(guide) {
|
|
7084
|
+
return guide.orientation === measurement.orientation;
|
|
7085
|
+
});
|
|
7086
|
+
});
|
|
7087
|
+
return {
|
|
7088
|
+
dx: (dx || 0) + spacingX,
|
|
7089
|
+
dy: (dy || 0) + spacingY,
|
|
7090
|
+
guides,
|
|
7091
|
+
spacingGuides,
|
|
7092
|
+
measurements
|
|
7093
|
+
};
|
|
7094
|
+
}
|
|
7095
|
+
var snapGuideNodeCount = 0;
|
|
7096
|
+
function beginSnapGuideNodes() {
|
|
7097
|
+
snapGuideNodeCount = 0;
|
|
7098
|
+
}
|
|
7099
|
+
function appendSnapGuideNode(cssText) {
|
|
7100
|
+
var node = snapGuideLayer.children[snapGuideNodeCount];
|
|
7101
|
+
if (!node) {
|
|
7102
|
+
node = document.createElement("div");
|
|
7103
|
+
snapGuideLayer.appendChild(node);
|
|
7104
|
+
}
|
|
7105
|
+
node.style.cssText = "position:fixed;" + cssText;
|
|
7106
|
+
node.textContent = "";
|
|
7107
|
+
snapGuideNodeCount += 1;
|
|
7108
|
+
return node;
|
|
7109
|
+
}
|
|
7110
|
+
function endSnapGuideNodes() {
|
|
7111
|
+
while (snapGuideLayer.children.length > snapGuideNodeCount) {
|
|
7112
|
+
snapGuideLayer.removeChild(snapGuideLayer.lastChild);
|
|
7113
|
+
}
|
|
7114
|
+
}
|
|
7115
|
+
function showSnapGuides(guides, spacingGuides, measurements) {
|
|
7116
|
+
measurements = measurements || [];
|
|
7117
|
+
if (!guides.length && !spacingGuides.length && !measurements.length) {
|
|
7118
|
+
hideSnapGuides();
|
|
7119
|
+
return;
|
|
7120
|
+
}
|
|
7121
|
+
beginSnapGuideNodes();
|
|
7122
|
+
if (snapGuideLayer.style.display !== "block") {
|
|
7123
|
+
snapGuideLayer.style.display = "block";
|
|
7124
|
+
}
|
|
7125
|
+
var scale = chromeLineScale();
|
|
7126
|
+
var line = 1 * scale;
|
|
7127
|
+
var fill = "background:var(--design-editor-measure-color);";
|
|
7128
|
+
for (var i = 0; i < guides.length; i += 1) {
|
|
7129
|
+
var guide = guides[i];
|
|
7130
|
+
var span = Math.max(1, guide.end - guide.start);
|
|
7131
|
+
appendSnapGuideNode(
|
|
7132
|
+
guide.orientation === "vertical" ? "left:" + guide.position + "px;top:" + guide.start + "px;width:" + line + "px;height:" + span + "px;" + fill : "top:" + guide.position + "px;left:" + guide.start + "px;height:" + line + "px;width:" + span + "px;" + fill
|
|
7133
|
+
);
|
|
7134
|
+
}
|
|
7135
|
+
for (var s = 0; s < spacingGuides.length; s += 1) {
|
|
7136
|
+
var spacing = spacingGuides[s];
|
|
7137
|
+
for (var b = 0; b < spacing.bands.length; b += 1) {
|
|
7138
|
+
appendSnapGuideNode(
|
|
7139
|
+
spacingBandCss(spacing.orientation, spacing.bands[b], line, fill)
|
|
7140
|
+
);
|
|
7141
|
+
appendSnapGuideNode(
|
|
7142
|
+
spacingSerifCss(
|
|
7143
|
+
spacing.orientation,
|
|
7144
|
+
spacing.bands[b],
|
|
7145
|
+
line,
|
|
7146
|
+
5 * scale,
|
|
7147
|
+
fill,
|
|
7148
|
+
true
|
|
7149
|
+
)
|
|
7150
|
+
);
|
|
7151
|
+
appendSnapGuideNode(
|
|
7152
|
+
spacingSerifCss(
|
|
7153
|
+
spacing.orientation,
|
|
7154
|
+
spacing.bands[b],
|
|
7155
|
+
line,
|
|
7156
|
+
5 * scale,
|
|
7157
|
+
fill,
|
|
7158
|
+
false
|
|
7159
|
+
)
|
|
7160
|
+
);
|
|
6412
7161
|
}
|
|
7162
|
+
var label = appendSnapGuideNode(
|
|
7163
|
+
spacingLabelCss(spacing.orientation, spacing.bands[0], scale)
|
|
7164
|
+
);
|
|
7165
|
+
label.textContent = String(Math.round(spacing.gap));
|
|
7166
|
+
}
|
|
7167
|
+
for (var m = 0; m < measurements.length; m += 1) {
|
|
7168
|
+
var measurement = measurements[m];
|
|
7169
|
+
appendSnapGuideNode(
|
|
7170
|
+
spacingBandCss(measurement.orientation, measurement.band, line, fill)
|
|
7171
|
+
);
|
|
7172
|
+
appendSnapGuideNode(
|
|
7173
|
+
spacingSerifCss(
|
|
7174
|
+
measurement.orientation,
|
|
7175
|
+
measurement.band,
|
|
7176
|
+
line,
|
|
7177
|
+
5 * scale,
|
|
7178
|
+
fill,
|
|
7179
|
+
true
|
|
7180
|
+
)
|
|
7181
|
+
);
|
|
7182
|
+
appendSnapGuideNode(
|
|
7183
|
+
spacingSerifCss(
|
|
7184
|
+
measurement.orientation,
|
|
7185
|
+
measurement.band,
|
|
7186
|
+
line,
|
|
7187
|
+
5 * scale,
|
|
7188
|
+
fill,
|
|
7189
|
+
false
|
|
7190
|
+
)
|
|
7191
|
+
);
|
|
7192
|
+
var measureLabel = appendSnapGuideNode(
|
|
7193
|
+
spacingLabelCss(measurement.orientation, measurement.band, scale)
|
|
7194
|
+
);
|
|
7195
|
+
measureLabel.textContent = String(Math.round(measurement.gap));
|
|
6413
7196
|
}
|
|
7197
|
+
endSnapGuideNodes();
|
|
7198
|
+
}
|
|
7199
|
+
function spacingBandCss(orientation, band, line, fill) {
|
|
7200
|
+
var crossMid = (band.crossStart + band.crossEnd) / 2;
|
|
7201
|
+
var length = Math.max(0, band.gapEnd - band.gapStart);
|
|
7202
|
+
return orientation === "vertical" ? "left:" + band.gapStart + "px;top:" + (crossMid - line / 2) + "px;width:" + length + "px;height:" + line + "px;" + fill : "top:" + band.gapStart + "px;left:" + (crossMid - line / 2) + "px;height:" + length + "px;width:" + line + "px;" + fill;
|
|
7203
|
+
}
|
|
7204
|
+
function spacingSerifCss(orientation, band, line, serif, fill, atStart) {
|
|
7205
|
+
var crossMid = (band.crossStart + band.crossEnd) / 2;
|
|
7206
|
+
var along = atStart ? band.gapStart : band.gapEnd;
|
|
7207
|
+
return orientation === "vertical" ? "left:" + (along - line / 2) + "px;top:" + (crossMid - serif) + "px;width:" + line + "px;height:" + serif * 2 + "px;" + fill : "top:" + (along - line / 2) + "px;left:" + (crossMid - serif) + "px;height:" + line + "px;width:" + serif * 2 + "px;" + fill;
|
|
7208
|
+
}
|
|
7209
|
+
function spacingLabelCss(orientation, band, scale) {
|
|
7210
|
+
var crossMid = (band.crossStart + band.crossEnd) / 2;
|
|
7211
|
+
var alongMid = (band.gapStart + band.gapEnd) / 2;
|
|
7212
|
+
return (orientation === "vertical" ? "left:" + alongMid + "px;top:" + crossMid + "px;" : "left:" + crossMid + "px;top:" + alongMid + "px;") + "transform:translate(-50%,-50%);border-radius:" + 3 * scale + "px;padding:" + 1 * scale + "px " + 4 * scale + "px;font:" + 10 * scale + "px/1 ui-monospace,SFMono-Regular,Menlo,monospace;white-space:nowrap;background:var(--design-editor-measure-color);color:white;";
|
|
7213
|
+
}
|
|
7214
|
+
function authoredOffset(value) {
|
|
7215
|
+
if (!value || value === "auto") return "";
|
|
7216
|
+
return value;
|
|
7217
|
+
}
|
|
7218
|
+
function elementConstraints(el) {
|
|
7219
|
+
var style = el.style;
|
|
7220
|
+
var left = authoredOffset(style.left);
|
|
7221
|
+
var right = authoredOffset(style.right);
|
|
7222
|
+
var top = authoredOffset(style.top);
|
|
7223
|
+
var bottom = authoredOffset(style.bottom);
|
|
7224
|
+
var transform = style.transform || "";
|
|
6414
7225
|
return {
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
guideV: bestX ? bestX.guide : null,
|
|
6418
|
-
guideH: bestY ? bestY.guide : null
|
|
7226
|
+
horizontal: style.width === "100%" ? "scale" : left && right ? "left-right" : right && !left ? "right" : transform.indexOf("translateX(-50%)") !== -1 ? "center" : "left",
|
|
7227
|
+
vertical: style.height === "100%" ? "scale" : top && bottom ? "top-bottom" : bottom && !top ? "bottom" : transform.indexOf("translateY(-50%)") !== -1 ? "center" : "top"
|
|
6419
7228
|
};
|
|
6420
7229
|
}
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
7230
|
+
var constraintNodeCount = 0;
|
|
7231
|
+
function appendConstraintLine(from, to, crossPosition, horizontal, thickness) {
|
|
7232
|
+
var start = Math.min(from, to);
|
|
7233
|
+
var length = Math.max(1, Math.abs(to - from));
|
|
7234
|
+
var node = constraintGuideLayer.children[constraintNodeCount];
|
|
7235
|
+
if (!node) {
|
|
7236
|
+
node = document.createElement("div");
|
|
7237
|
+
constraintGuideLayer.appendChild(node);
|
|
7238
|
+
}
|
|
7239
|
+
constraintNodeCount += 1;
|
|
7240
|
+
node.style.cssText = "position:fixed;" + (horizontal ? "left:" + start + "px;top:" + (crossPosition - thickness / 2) + "px;width:" + length + "px;height:0;border-top:" : "top:" + start + "px;left:" + (crossPosition - thickness / 2) + "px;height:" + length + "px;width:0;border-left:") + thickness + "px dashed var(--design-editor-accent-color);";
|
|
7241
|
+
}
|
|
7242
|
+
function showConstraintGuides(el) {
|
|
7243
|
+
if (!el || dragChromeSuppressed) return hideConstraintGuides();
|
|
7244
|
+
var parent = el.offsetParent || el.parentElement;
|
|
7245
|
+
if (!parent) return hideConstraintGuides();
|
|
7246
|
+
var rect = el.getBoundingClientRect();
|
|
7247
|
+
var frame = parent.getBoundingClientRect();
|
|
7248
|
+
if (rect.width <= 0 || rect.height <= 0) return hideConstraintGuides();
|
|
7249
|
+
if (!constraintGuideLayer.isConnected) {
|
|
7250
|
+
document.body.appendChild(constraintGuideLayer);
|
|
7251
|
+
}
|
|
7252
|
+
constraintNodeCount = 0;
|
|
7253
|
+
if (constraintGuideLayer.style.display !== "block") {
|
|
7254
|
+
constraintGuideLayer.style.display = "block";
|
|
7255
|
+
}
|
|
7256
|
+
var thickness = chromeLineScale();
|
|
7257
|
+
var midY = rect.top + rect.height / 2;
|
|
7258
|
+
var midX = rect.left + rect.width / 2;
|
|
7259
|
+
var constraints = elementConstraints(el);
|
|
7260
|
+
if (constraints.horizontal === "scale") {
|
|
7261
|
+
appendConstraintLine(frame.left, frame.right, midY, true, thickness);
|
|
6429
7262
|
} else {
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
7263
|
+
if (constraints.horizontal !== "right" && constraints.horizontal !== "center") {
|
|
7264
|
+
appendConstraintLine(frame.left, rect.left, midY, true, thickness);
|
|
7265
|
+
}
|
|
7266
|
+
if (constraints.horizontal === "right" || constraints.horizontal === "left-right") {
|
|
7267
|
+
appendConstraintLine(rect.right, frame.right, midY, true, thickness);
|
|
7268
|
+
}
|
|
7269
|
+
if (constraints.horizontal === "center") {
|
|
7270
|
+
appendConstraintLine(
|
|
7271
|
+
frame.left + frame.width / 2,
|
|
7272
|
+
midX,
|
|
7273
|
+
midY,
|
|
7274
|
+
true,
|
|
7275
|
+
thickness
|
|
7276
|
+
);
|
|
7277
|
+
}
|
|
7278
|
+
}
|
|
7279
|
+
if (constraints.vertical === "scale") {
|
|
7280
|
+
appendConstraintLine(frame.top, frame.bottom, midX, false, thickness);
|
|
6438
7281
|
} else {
|
|
6439
|
-
|
|
7282
|
+
if (constraints.vertical !== "bottom" && constraints.vertical !== "center") {
|
|
7283
|
+
appendConstraintLine(frame.top, rect.top, midX, false, thickness);
|
|
7284
|
+
}
|
|
7285
|
+
if (constraints.vertical === "bottom" || constraints.vertical === "top-bottom") {
|
|
7286
|
+
appendConstraintLine(rect.bottom, frame.bottom, midX, false, thickness);
|
|
7287
|
+
}
|
|
7288
|
+
if (constraints.vertical === "center") {
|
|
7289
|
+
appendConstraintLine(
|
|
7290
|
+
frame.top + frame.height / 2,
|
|
7291
|
+
midY,
|
|
7292
|
+
midX,
|
|
7293
|
+
false,
|
|
7294
|
+
thickness
|
|
7295
|
+
);
|
|
7296
|
+
}
|
|
7297
|
+
}
|
|
7298
|
+
trimConstraintNodes();
|
|
7299
|
+
}
|
|
7300
|
+
function trimConstraintNodes() {
|
|
7301
|
+
while (constraintGuideLayer.children.length > constraintNodeCount) {
|
|
7302
|
+
constraintGuideLayer.removeChild(constraintGuideLayer.lastChild);
|
|
6440
7303
|
}
|
|
6441
7304
|
}
|
|
7305
|
+
function hideConstraintGuides() {
|
|
7306
|
+
if (constraintGuideLayer.style.display === "none") return;
|
|
7307
|
+
constraintGuideLayer.style.display = "none";
|
|
7308
|
+
constraintGuideLayer.innerHTML = "";
|
|
7309
|
+
constraintNodeCount = 0;
|
|
7310
|
+
}
|
|
7311
|
+
var sizeBadgeKey = "";
|
|
7312
|
+
var dragChromeSuppressed = false;
|
|
7313
|
+
function showSizeBadge(el) {
|
|
7314
|
+
if (!el || dragChromeSuppressed) return hideSizeBadge();
|
|
7315
|
+
var rect = el.getBoundingClientRect();
|
|
7316
|
+
if (rect.width <= 0 || rect.height <= 0) return hideSizeBadge();
|
|
7317
|
+
var scale = chromeLineScale();
|
|
7318
|
+
var key = rect.left + "|" + rect.bottom + "|" + rect.width + "|" + rect.height + "|" + scale;
|
|
7319
|
+
if (key === sizeBadgeKey && sizeBadge.style.display === "block") return;
|
|
7320
|
+
sizeBadgeKey = key;
|
|
7321
|
+
if (!sizeBadge.isConnected) document.body.appendChild(sizeBadge);
|
|
7322
|
+
sizeBadge.textContent = Math.round(rect.width) + " \\xD7 " + Math.round(rect.height);
|
|
7323
|
+
sizeBadge.style.display = "block";
|
|
7324
|
+
sizeBadge.style.borderRadius = 3 * scale + "px";
|
|
7325
|
+
sizeBadge.style.padding = 2 * scale + "px " + 4 * scale + "px";
|
|
7326
|
+
sizeBadge.style.fontSize = 10 * scale + "px";
|
|
7327
|
+
sizeBadge.style.left = rect.left + rect.width / 2 + "px";
|
|
7328
|
+
sizeBadge.style.top = rect.bottom + 6 * scale + "px";
|
|
7329
|
+
sizeBadge.style.transform = "translateX(-50%)";
|
|
7330
|
+
}
|
|
7331
|
+
function hideSizeBadge() {
|
|
7332
|
+
if (sizeBadge.style.display === "none") return;
|
|
7333
|
+
sizeBadge.style.display = "none";
|
|
7334
|
+
sizeBadgeKey = "";
|
|
7335
|
+
}
|
|
6442
7336
|
function hideSnapGuides() {
|
|
6443
|
-
|
|
6444
|
-
|
|
7337
|
+
dragChromeSuppressed = false;
|
|
7338
|
+
if (snapGuideLayer.style.display === "none") return;
|
|
7339
|
+
snapGuideLayer.style.display = "none";
|
|
7340
|
+
snapGuideLayer.innerHTML = "";
|
|
7341
|
+
snapGuideNodeCount = 0;
|
|
6445
7342
|
}
|
|
6446
7343
|
function startMove(e, gestureElParam, pointerStartParam) {
|
|
6447
7344
|
if (readOnly) return;
|
|
@@ -7074,6 +7971,18 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7074
7971
|
var dragElStartRect = dragEl.getBoundingClientRect();
|
|
7075
7972
|
var dragElStartWidth = dragElStartRect.width;
|
|
7076
7973
|
var dragElStartHeight = dragElStartRect.height;
|
|
7974
|
+
function ancestorScale(el, axis) {
|
|
7975
|
+
var host = el && el.offsetParent;
|
|
7976
|
+
if (!host) return 1;
|
|
7977
|
+
var rect = host.getBoundingClientRect();
|
|
7978
|
+
var layout = axis === "x" ? host.offsetWidth : host.offsetHeight;
|
|
7979
|
+
var client = axis === "x" ? rect.width : rect.height;
|
|
7980
|
+
if (!(layout > 0)) return 1;
|
|
7981
|
+
var scale = client / layout;
|
|
7982
|
+
return scale > 0 && Number.isFinite(scale) ? scale : 1;
|
|
7983
|
+
}
|
|
7984
|
+
var dragElOffsetScaleX = ancestorScale(dragEl, "x");
|
|
7985
|
+
var dragElOffsetScaleY = ancestorScale(dragEl, "y");
|
|
7077
7986
|
if (!duplicatedForDrag && !isGroupDrag) {
|
|
7078
7987
|
postCrossScreenDrag("start", dragEl, e);
|
|
7079
7988
|
}
|
|
@@ -7109,17 +8018,33 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7109
8018
|
var snapBypass = Boolean(ev.metaKey || ev.ctrlKey);
|
|
7110
8019
|
var snapResult = !snapBypass && !duplicatedForDrag ? computeMoveSnapOffset(
|
|
7111
8020
|
{
|
|
7112
|
-
|
|
7113
|
-
|
|
8021
|
+
// snapCandidateRects are client space; nextLeft/nextTop are
|
|
8022
|
+
// offset-parent CSS space. Convert, or nothing ever matches.
|
|
8023
|
+
left: dragElStartRect.left + (nextLeft - originLeft) * dragElOffsetScaleX,
|
|
8024
|
+
top: dragElStartRect.top + (nextTop - originTop) * dragElOffsetScaleY,
|
|
7114
8025
|
width: dragElStartWidth,
|
|
7115
8026
|
height: dragElStartHeight
|
|
7116
8027
|
},
|
|
7117
8028
|
snapCandidateRects,
|
|
7118
8029
|
// Convert the screen-space base to content px (1/zoom).
|
|
7119
|
-
SNAP_THRESHOLD_PX * chromeLineScale()
|
|
7120
|
-
|
|
7121
|
-
|
|
7122
|
-
|
|
8030
|
+
SNAP_THRESHOLD_PX * chromeLineScale(),
|
|
8031
|
+
isGroupDrag,
|
|
8032
|
+
ev.shiftKey ? { x: rawDx === 0, y: rawDy === 0 } : null
|
|
8033
|
+
) : { dx: 0, dy: 0, guides: [], spacingGuides: [], measurements: [] };
|
|
8034
|
+
if (window.__DND_DEBUG)
|
|
8035
|
+
dndLog("snap:tick", {
|
|
8036
|
+
// Ordered so the fields that decide whether snapping ran at all come
|
|
8037
|
+
// first: the console collapses long objects behind an ellipsis.
|
|
8038
|
+
bypass: snapBypass,
|
|
8039
|
+
duplicated: duplicatedForDrag,
|
|
8040
|
+
mods: (ev.metaKey ? "M" : "") + (ev.ctrlKey ? "C" : "") + (ev.altKey ? "A" : "") + (ev.shiftKey ? "S" : "") || "none",
|
|
8041
|
+
guides: snapResult.guides.length,
|
|
8042
|
+
measurements: snapResult.measurements.length,
|
|
8043
|
+
candidates: snapCandidateRects.length,
|
|
8044
|
+
dropMode: currentAutoLayoutTarget ? currentAutoLayoutTarget.dropMode || "(none)" : "no-target"
|
|
8045
|
+
});
|
|
8046
|
+
nextLeft += snapResult.dx / dragElOffsetScaleX;
|
|
8047
|
+
nextTop += snapResult.dy / dragElOffsetScaleY;
|
|
7123
8048
|
var appliedDx = nextLeft - originLeft;
|
|
7124
8049
|
var appliedDy = nextTop - originTop;
|
|
7125
8050
|
memberStates.forEach(function(state) {
|
|
@@ -7153,10 +8078,20 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7153
8078
|
setMembersOpacity(null);
|
|
7154
8079
|
}
|
|
7155
8080
|
}
|
|
7156
|
-
|
|
8081
|
+
var flowInsertPending = !!currentAutoLayoutTarget && currentAutoLayoutTarget.dropMode !== "absolute-container";
|
|
8082
|
+
if (flowInsertPending || !duplicatedForDrag && isOutsideIframeViewport(ev.clientX, ev.clientY)) {
|
|
7157
8083
|
hideSnapGuides();
|
|
8084
|
+
dragChromeSuppressed = true;
|
|
8085
|
+
hideSizeBadge();
|
|
8086
|
+
hideConstraintGuides();
|
|
7158
8087
|
} else {
|
|
7159
|
-
|
|
8088
|
+
dragChromeSuppressed = false;
|
|
8089
|
+
showSnapGuides(
|
|
8090
|
+
snapResult.guides,
|
|
8091
|
+
snapResult.spacingGuides,
|
|
8092
|
+
snapResult.measurements
|
|
8093
|
+
);
|
|
8094
|
+
showConstraintGuides(dragEl);
|
|
7160
8095
|
}
|
|
7161
8096
|
showTransformBadge(
|
|
7162
8097
|
Math.round(nextLeft) + ", " + Math.round(nextTop),
|
|
@@ -7189,6 +8124,8 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7189
8124
|
hideTransformBadge();
|
|
7190
8125
|
hideInsertionGuide();
|
|
7191
8126
|
hideSnapGuides();
|
|
8127
|
+
hideSizeBadge();
|
|
8128
|
+
hideConstraintGuides();
|
|
7192
8129
|
currentAutoLayoutTarget = null;
|
|
7193
8130
|
if (duplicatedForDrag) {
|
|
7194
8131
|
if (dragEl && dragEl.parentElement) {
|
|
@@ -7219,12 +8156,16 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7219
8156
|
hideTransformBadge();
|
|
7220
8157
|
hideInsertionGuide();
|
|
7221
8158
|
hideSnapGuides();
|
|
8159
|
+
hideSizeBadge();
|
|
8160
|
+
hideConstraintGuides();
|
|
7222
8161
|
return;
|
|
7223
8162
|
}
|
|
7224
8163
|
cleanupMoveDrag();
|
|
7225
8164
|
hideTransformBadge();
|
|
7226
8165
|
hideInsertionGuide();
|
|
7227
8166
|
hideSnapGuides();
|
|
8167
|
+
hideSizeBadge();
|
|
8168
|
+
hideConstraintGuides();
|
|
7228
8169
|
if (!dragEl) return;
|
|
7229
8170
|
var outsideOnDrop = ev ? isOutsideIframeViewport(ev.clientX, ev.clientY) : false;
|
|
7230
8171
|
if (ev && !duplicatedForDrag && !isGroupDrag && (outsideOnDrop || designCanvasBoardSurface)) {
|
|
@@ -7322,6 +8263,30 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7322
8263
|
document.addEventListener("keydown", onMoveKeyDown, true);
|
|
7323
8264
|
setActiveDragCancel(cancelMoveDrag);
|
|
7324
8265
|
}
|
|
8266
|
+
function collectScaleFontTargets(root) {
|
|
8267
|
+
var targets = [];
|
|
8268
|
+
var nodes = root.querySelectorAll("*");
|
|
8269
|
+
for (var i = 0; i < nodes.length; i += 1) {
|
|
8270
|
+
var el = nodes[i];
|
|
8271
|
+
if (isOverlayElement(el)) continue;
|
|
8272
|
+
var inlineFontSize = el.style.fontSize || "";
|
|
8273
|
+
if (inlineFontSize && !/px\\s*$/i.test(inlineFontSize)) continue;
|
|
8274
|
+
var parent = el.parentElement;
|
|
8275
|
+
var cs = window.getComputedStyle(el);
|
|
8276
|
+
if (!inlineFontSize && parent && window.getComputedStyle(parent).fontSize === cs.fontSize) {
|
|
8277
|
+
continue;
|
|
8278
|
+
}
|
|
8279
|
+
var originFontSize = readPx(inlineFontSize || cs.fontSize);
|
|
8280
|
+
if (!(originFontSize > 0)) continue;
|
|
8281
|
+
rememberLiveVisualEditOriginalStyles(el);
|
|
8282
|
+
targets.push({
|
|
8283
|
+
el,
|
|
8284
|
+
originFontSize,
|
|
8285
|
+
originalInlineFontSize: el.style.fontSize
|
|
8286
|
+
});
|
|
8287
|
+
}
|
|
8288
|
+
return targets;
|
|
8289
|
+
}
|
|
7325
8290
|
function startResize(handle, e) {
|
|
7326
8291
|
if (readOnly) return;
|
|
7327
8292
|
if (!selectedEl) return;
|
|
@@ -7392,6 +8357,13 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7392
8357
|
});
|
|
7393
8358
|
var widthTouched = false;
|
|
7394
8359
|
var heightTouched = false;
|
|
8360
|
+
var scaledTextTargetsCache = null;
|
|
8361
|
+
function scaledTextTargets() {
|
|
8362
|
+
if (!scaledTextTargetsCache) {
|
|
8363
|
+
scaledTextTargetsCache = collectScaleFontTargets(resizeEl);
|
|
8364
|
+
}
|
|
8365
|
+
return scaledTextTargetsCache;
|
|
8366
|
+
}
|
|
7395
8367
|
function nextRect(ev) {
|
|
7396
8368
|
var screenDx = ev.clientX - startX;
|
|
7397
8369
|
var screenDy = ev.clientY - startY;
|
|
@@ -7492,6 +8464,12 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7492
8464
|
if (originFontSize > 0) {
|
|
7493
8465
|
resizeEl.style.fontSize = Math.max(1, Math.round(originFontSize * kScaleFactor * 100) / 100) + "px";
|
|
7494
8466
|
}
|
|
8467
|
+
scaledTextTargets().forEach(function(target) {
|
|
8468
|
+
target.el.style.fontSize = Math.max(
|
|
8469
|
+
1,
|
|
8470
|
+
Math.round(target.originFontSize * kScaleFactor * 100) / 100
|
|
8471
|
+
) + "px";
|
|
8472
|
+
});
|
|
7495
8473
|
}
|
|
7496
8474
|
showTransformBadge(
|
|
7497
8475
|
Math.round(rect.width) + " x " + Math.round(rect.height),
|
|
@@ -7518,6 +8496,9 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7518
8496
|
resizeEl.style.height = originalInlineHeight;
|
|
7519
8497
|
resizeEl.style.borderWidth = originalInlineBorderWidth;
|
|
7520
8498
|
resizeEl.style.fontSize = originalInlineFontSize;
|
|
8499
|
+
(scaledTextTargetsCache || []).forEach(function(target) {
|
|
8500
|
+
target.el.style.fontSize = target.originalInlineFontSize;
|
|
8501
|
+
});
|
|
7521
8502
|
selectedEl = resizeEl;
|
|
7522
8503
|
positionOverlay(selectionOverlay, selectedEl);
|
|
7523
8504
|
}
|
|
@@ -7565,12 +8546,313 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7565
8546
|
},
|
|
7566
8547
|
"*"
|
|
7567
8548
|
);
|
|
8549
|
+
if (scaleToolEnabled) {
|
|
8550
|
+
(scaledTextTargetsCache || []).forEach(function(target) {
|
|
8551
|
+
var textStyles = {
|
|
8552
|
+
fontSize: target.el.style.fontSize
|
|
8553
|
+
};
|
|
8554
|
+
window.parent.postMessage(
|
|
8555
|
+
{
|
|
8556
|
+
type: "visual-style-change",
|
|
8557
|
+
selector: getSelector(target.el),
|
|
8558
|
+
styles: textStyles,
|
|
8559
|
+
originalStyles: originalInlineStylesForPatch(
|
|
8560
|
+
target.el,
|
|
8561
|
+
textStyles
|
|
8562
|
+
),
|
|
8563
|
+
payload: getElementInfo(target.el),
|
|
8564
|
+
preserveSelection: true
|
|
8565
|
+
},
|
|
8566
|
+
"*"
|
|
8567
|
+
);
|
|
8568
|
+
});
|
|
8569
|
+
}
|
|
7568
8570
|
}
|
|
7569
8571
|
document.addEventListener(events.move, onMove, true);
|
|
7570
8572
|
document.addEventListener(events.up, onUp, true);
|
|
7571
8573
|
document.addEventListener("keydown", onResizeKeyDown, true);
|
|
7572
8574
|
setActiveDragCancel(cancelResizeDrag);
|
|
7573
8575
|
}
|
|
8576
|
+
function startGroupResize(handle, e) {
|
|
8577
|
+
if (readOnly) return;
|
|
8578
|
+
var members = collectSelectionMembers();
|
|
8579
|
+
if (members.length < 2) return;
|
|
8580
|
+
e.preventDefault();
|
|
8581
|
+
e.stopPropagation();
|
|
8582
|
+
var events = dragEventNames(e);
|
|
8583
|
+
var groupLeft = Infinity;
|
|
8584
|
+
var groupTop = Infinity;
|
|
8585
|
+
var groupRight = -Infinity;
|
|
8586
|
+
var groupBottom = -Infinity;
|
|
8587
|
+
var memberStates = members.map(function(member) {
|
|
8588
|
+
var el = member;
|
|
8589
|
+
var snapshot = {
|
|
8590
|
+
el,
|
|
8591
|
+
originalInlinePosition: el.style.position,
|
|
8592
|
+
originalInlineLeft: el.style.left,
|
|
8593
|
+
originalInlineTop: el.style.top,
|
|
8594
|
+
originalInlineWidth: el.style.width,
|
|
8595
|
+
originalInlineHeight: el.style.height,
|
|
8596
|
+
originalInlineBorderWidth: el.style.borderWidth,
|
|
8597
|
+
originalInlineFontSize: el.style.fontSize,
|
|
8598
|
+
originLeft: 0,
|
|
8599
|
+
originTop: 0,
|
|
8600
|
+
originWidth: 0,
|
|
8601
|
+
originHeight: 0,
|
|
8602
|
+
// The center is the one point rotation leaves alone: a rotated
|
|
8603
|
+
// member's client rect is its inflated axis-aligned box, so corners
|
|
8604
|
+
// would scale it to the wrong place.
|
|
8605
|
+
originCenterX: 0,
|
|
8606
|
+
originCenterY: 0,
|
|
8607
|
+
originBorderWidth: 0,
|
|
8608
|
+
originFontSize: 0,
|
|
8609
|
+
textTargets: null
|
|
8610
|
+
};
|
|
8611
|
+
rememberLiveVisualEditOriginalStyles(el);
|
|
8612
|
+
ensurePositionable(el);
|
|
8613
|
+
var cs = window.getComputedStyle(el);
|
|
8614
|
+
var rect = el.getBoundingClientRect();
|
|
8615
|
+
groupLeft = Math.min(groupLeft, rect.left);
|
|
8616
|
+
groupTop = Math.min(groupTop, rect.top);
|
|
8617
|
+
groupRight = Math.max(groupRight, rect.right);
|
|
8618
|
+
groupBottom = Math.max(groupBottom, rect.bottom);
|
|
8619
|
+
snapshot.originLeft = readPx(el.style.left || cs.left);
|
|
8620
|
+
snapshot.originTop = readPx(el.style.top || cs.top);
|
|
8621
|
+
snapshot.originWidth = readPx(cs.width);
|
|
8622
|
+
snapshot.originHeight = readPx(cs.height);
|
|
8623
|
+
snapshot.originCenterX = rect.left + rect.width / 2;
|
|
8624
|
+
snapshot.originCenterY = rect.top + rect.height / 2;
|
|
8625
|
+
snapshot.originBorderWidth = readPx(
|
|
8626
|
+
el.style.borderWidth || cs.borderWidth
|
|
8627
|
+
);
|
|
8628
|
+
snapshot.originFontSize = readPx(el.style.fontSize || cs.fontSize);
|
|
8629
|
+
return snapshot;
|
|
8630
|
+
});
|
|
8631
|
+
var groupWidth = Math.max(1, groupRight - groupLeft);
|
|
8632
|
+
var groupHeight = Math.max(1, groupBottom - groupTop);
|
|
8633
|
+
var anchorX = handle.indexOf("w") !== -1 ? groupRight : groupLeft;
|
|
8634
|
+
var anchorY = handle.indexOf("n") !== -1 ? groupBottom : groupTop;
|
|
8635
|
+
var minMemberWidth = Math.max(
|
|
8636
|
+
1,
|
|
8637
|
+
Math.min.apply(
|
|
8638
|
+
null,
|
|
8639
|
+
memberStates.map(function(state) {
|
|
8640
|
+
return Math.max(1, state.originWidth);
|
|
8641
|
+
})
|
|
8642
|
+
)
|
|
8643
|
+
);
|
|
8644
|
+
var minMemberHeight = Math.max(
|
|
8645
|
+
1,
|
|
8646
|
+
Math.min.apply(
|
|
8647
|
+
null,
|
|
8648
|
+
memberStates.map(function(state) {
|
|
8649
|
+
return Math.max(1, state.originHeight);
|
|
8650
|
+
})
|
|
8651
|
+
)
|
|
8652
|
+
);
|
|
8653
|
+
var minFactorX = 8 / minMemberWidth;
|
|
8654
|
+
var minFactorY = 8 / minMemberHeight;
|
|
8655
|
+
var startX = e.clientX;
|
|
8656
|
+
var startY = e.clientY;
|
|
8657
|
+
var groupGestureViewport = bridgeGestureViewport();
|
|
8658
|
+
var bridgeGroupResizeController = createCanvasGestureController({
|
|
8659
|
+
capabilities: { move: true, resize: true },
|
|
8660
|
+
drag: { threshold: 3, duplicateModifier: "alt" },
|
|
8661
|
+
minSize: 8,
|
|
8662
|
+
adapter: {
|
|
8663
|
+
preview: function() {
|
|
8664
|
+
return { handled: true };
|
|
8665
|
+
},
|
|
8666
|
+
commit: function() {
|
|
8667
|
+
return { handled: true };
|
|
8668
|
+
},
|
|
8669
|
+
cancel: function() {
|
|
8670
|
+
return { handled: true };
|
|
8671
|
+
}
|
|
8672
|
+
}
|
|
8673
|
+
});
|
|
8674
|
+
bridgeGroupResizeController.pointerDown({
|
|
8675
|
+
kind: "resize",
|
|
8676
|
+
objectIds: memberStates.map(function(state) {
|
|
8677
|
+
return getSelector(state.el);
|
|
8678
|
+
}),
|
|
8679
|
+
pointer: bridgeGesturePointer(e),
|
|
8680
|
+
viewport: groupGestureViewport,
|
|
8681
|
+
canvas: {
|
|
8682
|
+
width: groupGestureViewport.width,
|
|
8683
|
+
height: groupGestureViewport.height
|
|
8684
|
+
},
|
|
8685
|
+
handle,
|
|
8686
|
+
rect: {
|
|
8687
|
+
x: groupLeft,
|
|
8688
|
+
y: groupTop,
|
|
8689
|
+
width: groupWidth,
|
|
8690
|
+
height: groupHeight
|
|
8691
|
+
}
|
|
8692
|
+
});
|
|
8693
|
+
function groupFactors(ev) {
|
|
8694
|
+
var dx = ev.clientX - startX;
|
|
8695
|
+
var dy = ev.clientY - startY;
|
|
8696
|
+
var nextWidth = handle.indexOf("e") !== -1 ? groupWidth + dx : groupWidth - dx;
|
|
8697
|
+
var nextHeight = handle.indexOf("s") !== -1 ? groupHeight + dy : groupHeight - dy;
|
|
8698
|
+
var factorX = nextWidth / groupWidth;
|
|
8699
|
+
var factorY = nextHeight / groupHeight;
|
|
8700
|
+
if (ev.shiftKey || scaleToolEnabled) {
|
|
8701
|
+
var uniform = Math.max(
|
|
8702
|
+
Math.max(minFactorX, minFactorY),
|
|
8703
|
+
Math.abs(dx) > Math.abs(dy) ? factorX : factorY
|
|
8704
|
+
);
|
|
8705
|
+
return { x: uniform, y: uniform };
|
|
8706
|
+
}
|
|
8707
|
+
return {
|
|
8708
|
+
x: Math.max(minFactorX, factorX),
|
|
8709
|
+
y: Math.max(minFactorY, factorY)
|
|
8710
|
+
};
|
|
8711
|
+
}
|
|
8712
|
+
function memberTextTargets(state) {
|
|
8713
|
+
if (!state.textTargets) {
|
|
8714
|
+
state.textTargets = collectScaleFontTargets(state.el);
|
|
8715
|
+
}
|
|
8716
|
+
return state.textTargets;
|
|
8717
|
+
}
|
|
8718
|
+
function onMove(ev) {
|
|
8719
|
+
var controllerMove = bridgeGroupResizeController.pointerMove(
|
|
8720
|
+
bridgeGesturePointer(ev)
|
|
8721
|
+
);
|
|
8722
|
+
if (controllerMove.phase !== "active") return;
|
|
8723
|
+
var factor = groupFactors(ev);
|
|
8724
|
+
memberStates.forEach(function(state) {
|
|
8725
|
+
var nextCenterX = anchorX + (state.originCenterX - anchorX) * factor.x;
|
|
8726
|
+
var nextCenterY = anchorY + (state.originCenterY - anchorY) * factor.y;
|
|
8727
|
+
var nextWidth = state.originWidth * factor.x;
|
|
8728
|
+
var nextHeight = state.originHeight * factor.y;
|
|
8729
|
+
state.el.style.left = Math.round(
|
|
8730
|
+
state.originLeft + (nextCenterX - state.originCenterX) - (nextWidth - state.originWidth) / 2
|
|
8731
|
+
) + "px";
|
|
8732
|
+
state.el.style.top = Math.round(
|
|
8733
|
+
state.originTop + (nextCenterY - state.originCenterY) - (nextHeight - state.originHeight) / 2
|
|
8734
|
+
) + "px";
|
|
8735
|
+
state.el.style.width = Math.round(nextWidth) + "px";
|
|
8736
|
+
state.el.style.height = Math.round(nextHeight) + "px";
|
|
8737
|
+
if (!scaleToolEnabled) return;
|
|
8738
|
+
if (state.originBorderWidth > 0) {
|
|
8739
|
+
state.el.style.borderWidth = Math.max(
|
|
8740
|
+
0,
|
|
8741
|
+
Math.round(state.originBorderWidth * factor.x * 100) / 100
|
|
8742
|
+
) + "px";
|
|
8743
|
+
}
|
|
8744
|
+
if (state.originFontSize > 0) {
|
|
8745
|
+
state.el.style.fontSize = Math.max(
|
|
8746
|
+
1,
|
|
8747
|
+
Math.round(state.originFontSize * factor.x * 100) / 100
|
|
8748
|
+
) + "px";
|
|
8749
|
+
}
|
|
8750
|
+
memberTextTargets(state).forEach(function(target) {
|
|
8751
|
+
target.el.style.fontSize = Math.max(
|
|
8752
|
+
1,
|
|
8753
|
+
Math.round(target.originFontSize * factor.x * 100) / 100
|
|
8754
|
+
) + "px";
|
|
8755
|
+
});
|
|
8756
|
+
});
|
|
8757
|
+
showTransformBadge(
|
|
8758
|
+
Math.round(groupWidth * factor.x) + " x " + Math.round(groupHeight * factor.y),
|
|
8759
|
+
ev.clientX,
|
|
8760
|
+
ev.clientY
|
|
8761
|
+
);
|
|
8762
|
+
refreshOverlays();
|
|
8763
|
+
}
|
|
8764
|
+
function cleanupGroupResizeDrag() {
|
|
8765
|
+
document.removeEventListener(events.move, onMove, true);
|
|
8766
|
+
document.removeEventListener(events.up, onUp, true);
|
|
8767
|
+
document.removeEventListener("keydown", onGroupResizeKeyDown, true);
|
|
8768
|
+
clearActiveDragCancel(cancelGroupResizeDrag);
|
|
8769
|
+
}
|
|
8770
|
+
function cancelGroupResizeDrag() {
|
|
8771
|
+
bridgeGroupResizeController.cancel();
|
|
8772
|
+
cleanupGroupResizeDrag();
|
|
8773
|
+
hideTransformBadge();
|
|
8774
|
+
memberStates.forEach(function(state) {
|
|
8775
|
+
if (!document.documentElement.contains(state.el)) return;
|
|
8776
|
+
state.el.style.position = state.originalInlinePosition;
|
|
8777
|
+
state.el.style.left = state.originalInlineLeft;
|
|
8778
|
+
state.el.style.top = state.originalInlineTop;
|
|
8779
|
+
state.el.style.width = state.originalInlineWidth;
|
|
8780
|
+
state.el.style.height = state.originalInlineHeight;
|
|
8781
|
+
state.el.style.borderWidth = state.originalInlineBorderWidth;
|
|
8782
|
+
state.el.style.fontSize = state.originalInlineFontSize;
|
|
8783
|
+
(state.textTargets || []).forEach(function(target) {
|
|
8784
|
+
target.el.style.fontSize = target.originalInlineFontSize;
|
|
8785
|
+
});
|
|
8786
|
+
});
|
|
8787
|
+
suppressNextShieldClickBriefly();
|
|
8788
|
+
refreshOverlays();
|
|
8789
|
+
return true;
|
|
8790
|
+
}
|
|
8791
|
+
function onGroupResizeKeyDown(ev) {
|
|
8792
|
+
if (ev.key !== "Escape") return;
|
|
8793
|
+
stopNativeInteraction(ev);
|
|
8794
|
+
cancelGroupResizeDrag();
|
|
8795
|
+
}
|
|
8796
|
+
function onUp(ev) {
|
|
8797
|
+
var controllerEnd = bridgeGroupResizeController.pointerUp(
|
|
8798
|
+
bridgeGesturePointer(ev)
|
|
8799
|
+
);
|
|
8800
|
+
cleanupGroupResizeDrag();
|
|
8801
|
+
hideTransformBadge();
|
|
8802
|
+
if (!controllerEnd.committed) return;
|
|
8803
|
+
memberStates.forEach(function(state) {
|
|
8804
|
+
var styles = {
|
|
8805
|
+
position: state.el.style.position,
|
|
8806
|
+
left: state.el.style.left,
|
|
8807
|
+
top: state.el.style.top,
|
|
8808
|
+
width: state.el.style.width,
|
|
8809
|
+
height: state.el.style.height
|
|
8810
|
+
};
|
|
8811
|
+
if (scaleToolEnabled && state.originBorderWidth > 0) {
|
|
8812
|
+
styles.borderWidth = state.el.style.borderWidth;
|
|
8813
|
+
}
|
|
8814
|
+
if (scaleToolEnabled && state.originFontSize > 0) {
|
|
8815
|
+
styles.fontSize = state.el.style.fontSize;
|
|
8816
|
+
}
|
|
8817
|
+
window.parent.postMessage(
|
|
8818
|
+
{
|
|
8819
|
+
type: "visual-style-change",
|
|
8820
|
+
selector: getSelector(state.el),
|
|
8821
|
+
styles,
|
|
8822
|
+
originalStyles: originalInlineStylesForPatch(state.el, styles),
|
|
8823
|
+
payload: getElementInfo(state.el)
|
|
8824
|
+
},
|
|
8825
|
+
"*"
|
|
8826
|
+
);
|
|
8827
|
+
if (!scaleToolEnabled) return;
|
|
8828
|
+
(state.textTargets || []).forEach(function(target) {
|
|
8829
|
+
var textStyles = {
|
|
8830
|
+
fontSize: target.el.style.fontSize
|
|
8831
|
+
};
|
|
8832
|
+
window.parent.postMessage(
|
|
8833
|
+
{
|
|
8834
|
+
type: "visual-style-change",
|
|
8835
|
+
selector: getSelector(target.el),
|
|
8836
|
+
styles: textStyles,
|
|
8837
|
+
originalStyles: originalInlineStylesForPatch(
|
|
8838
|
+
target.el,
|
|
8839
|
+
textStyles
|
|
8840
|
+
),
|
|
8841
|
+
payload: getElementInfo(target.el),
|
|
8842
|
+
// A scaled descendant is a side effect of the gesture, not the
|
|
8843
|
+
// object the user is holding.
|
|
8844
|
+
preserveSelection: true
|
|
8845
|
+
},
|
|
8846
|
+
"*"
|
|
8847
|
+
);
|
|
8848
|
+
});
|
|
8849
|
+
});
|
|
8850
|
+
}
|
|
8851
|
+
document.addEventListener(events.move, onMove, true);
|
|
8852
|
+
document.addEventListener(events.up, onUp, true);
|
|
8853
|
+
document.addEventListener("keydown", onGroupResizeKeyDown, true);
|
|
8854
|
+
setActiveDragCancel(cancelGroupResizeDrag);
|
|
8855
|
+
}
|
|
7574
8856
|
function startRotate(e) {
|
|
7575
8857
|
if (readOnly) return;
|
|
7576
8858
|
if (!selectedEl) return;
|
|
@@ -7709,7 +8991,17 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7709
8991
|
preferSelected: selectedLayerDragPriorityEnabled
|
|
7710
8992
|
});
|
|
7711
8993
|
var clickTarget = hitTarget;
|
|
8994
|
+
if (window.__DND_DEBUG)
|
|
8995
|
+
dndLog("shield:down", {
|
|
8996
|
+
hit: getSelector(hit),
|
|
8997
|
+
dragTarget: getSelector(dragTarget),
|
|
8998
|
+
board: designCanvasBoardSurface,
|
|
8999
|
+
readOnly,
|
|
9000
|
+
position: dragTarget ? window.getComputedStyle(dragTarget).position : null,
|
|
9001
|
+
flowCandidate: dragTarget ? isFlowReorderCandidate(dragTarget) : null
|
|
9002
|
+
});
|
|
7712
9003
|
if (!dragTarget || dragTarget === document.body || dragTarget === document.documentElement || isLayerInteractionBlocked(dragTarget)) {
|
|
9004
|
+
dndLog("shield:reject", { reason: "no-drag-target" });
|
|
7713
9005
|
return;
|
|
7714
9006
|
}
|
|
7715
9007
|
if (e.pointerId !== void 0 && shieldOverlay.setPointerCapture && !e.altKey) {
|
|
@@ -7742,6 +9034,8 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7742
9034
|
if (readOnly) return;
|
|
7743
9035
|
if (Math.hypot(ev.clientX - startX, ev.clientY - startY) <= 3) return;
|
|
7744
9036
|
clearPendingShieldDrag();
|
|
9037
|
+
if (!didStartDrag)
|
|
9038
|
+
dndLog("shield:drag-start", { board: designCanvasBoardSurface });
|
|
7745
9039
|
didStartDrag = true;
|
|
7746
9040
|
var groupGestureMember = !e.altKey ? groupMemberForGestureTarget(dragTarget) : null;
|
|
7747
9041
|
if (groupGestureMember && collectMoveGroupMembers(groupGestureMember).length > 1) {
|
|
@@ -9398,6 +10692,7 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
9398
10692
|
]
|
|
9399
10693
|
});
|
|
9400
10694
|
}
|
|
10695
|
+
captureInitialSourceOwnership();
|
|
9401
10696
|
if (runtimeLayerSnapshotEnabled) scheduleRuntimeLayerSnapshot();
|
|
9402
10697
|
window.parent.postMessage(
|
|
9403
10698
|
{ type: "agent-native:editor-chrome-ready" },
|