@agent-native/core 0.169.0 → 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/bigquery-table-info.ts +3 -2
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
- package/corpus/templates/analytics/actions/search-bigquery-schema.ts +130 -4
- package/corpus/templates/analytics/agent-native.config.ts +1 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +36 -23
- package/corpus/templates/analytics/app/i18n-data.ts +28 -0
- package/corpus/templates/analytics/app/lib/dashboard-visibility.ts +41 -0
- package/corpus/templates/analytics/app/pages/Agents.tsx +25 -1
- package/corpus/templates/analytics/app/pages/DashboardOverview.tsx +34 -9
- 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-21-dashboard-filters-keep-other-users-dashboards-out-of-mine.md +6 -0
- 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/real-data-actions.ts +14 -3
- package/corpus/templates/analytics/server/lib/slack.ts +4 -2
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +33 -3
- 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/server/lib/brain.ts +27 -2
- 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/stop-meeting-recording.ts +87 -6
- package/corpus/templates/clips/actions/view-screen.ts +8 -1
- package/corpus/templates/clips/app/components/library/search-bar.tsx +1 -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 +1386 -92
- 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/EditPanel.tsx +15 -47
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +284 -136
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2060 -144
- 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 -8
- 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 +13 -8
- package/corpus/templates/design/app/i18n-data.ts +11 -10
- 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 +99 -57
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +39 -8
- package/corpus/templates/design/app/pages/DesignSystems.tsx +137 -43
- package/corpus/templates/design/app/pages/Index.tsx +3 -1
- 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/preview-navigation.ts +25 -0
- 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-emails.ts +13 -3
- 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/credential-errors.d.ts +1 -1
- package/dist/agent/engine/credential-errors.js +2 -2
- 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/AssistantChat.js +47 -15
- package/dist/client/ConnectBuilderCard.d.ts +3 -1
- package/dist/client/ConnectBuilderCard.js +6 -3
- 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/message-components.d.ts +7 -0
- package/dist/client/chat/message-components.js +1 -1
- package/dist/client/chat/run-recovery.js +5 -2
- package/dist/client/chat/tool-call-display.js +9 -3
- 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/error-format.js +12 -0
- 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/navigation/index.d.ts +1 -0
- package/dist/client/navigation/index.js +1 -0
- package/dist/client/resources/mcp-integration-catalog.js +0 -29
- package/dist/client/route-state.js +6 -0
- 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/client/workspace-app-navigation.d.ts +10 -0
- package/dist/client/workspace-app-navigation.js +38 -0
- package/dist/collab/struct-routes.d.ts +1 -1
- 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 +32 -0
- package/dist/deploy/build.js +241 -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 +4 -1
- package/dist/localization/core-messages/de-DE.js +4 -1
- package/dist/localization/core-messages/en-US.d.ts +4 -1
- package/dist/localization/core-messages/en-US.js +4 -1
- package/dist/localization/core-messages/es-ES.js +4 -1
- package/dist/localization/core-messages/fr-FR.js +4 -1
- package/dist/localization/core-messages/hi-IN.js +4 -1
- package/dist/localization/core-messages/ja-JP.js +4 -1
- package/dist/localization/core-messages/ko-KR.js +4 -1
- package/dist/localization/core-messages/pt-BR.js +4 -1
- package/dist/localization/core-messages/zh-CN.js +4 -1
- package/dist/localization/core-messages/zh-TW.js +4 -1
- package/dist/localization/core-messages.d.ts +4 -1
- 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/notifications/routes.d.ts +1 -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/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 +12 -12
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.js +2 -0
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/resources/store.js +13 -4
- package/dist/scripts/agent-engines/list-agent-engines.js +29 -3
- package/dist/scripts/db/check-scoping.js +9 -6
- package/dist/secrets/register-framework-secrets.js +1 -1
- package/dist/secrets/routes.d.ts +6 -6
- 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-browser.d.ts +4 -0
- package/dist/server/builder-browser.js +23 -1
- 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 +113 -21
- 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/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 +3 -3
- 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
- /package/corpus/templates/dispatch/app/routes/{apps.$appId.tsx → apps.$appId.$.tsx} +0 -0
|
@@ -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();
|
|
@@ -3954,9 +4348,8 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
3954
4348
|
// Cmd from Ctrl the way isPlatformPrimaryModifier does host-side, but
|
|
3955
4349
|
// forwarding is harmless when the host has no match for the combo.
|
|
3956
4350
|
"f",
|
|
3957
|
-
// Cmd/Ctrl+
|
|
3958
|
-
//
|
|
3959
|
-
"r",
|
|
4351
|
+
// Cmd/Ctrl+Shift+R paste-to-replace. Bare primary+r stays native
|
|
4352
|
+
// so browser refresh keeps its expected meaning.
|
|
3960
4353
|
// Cmd/Ctrl+K — open the host command menu even while the iframe has
|
|
3961
4354
|
// focus. DesignEditor routes this chord to openCommandMenu().
|
|
3962
4355
|
"k"
|
|
@@ -3965,7 +4358,7 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
3965
4358
|
// Cmd+H / Cmd+L — common OS "Hide app" / browser "focus address bar"
|
|
3966
4359
|
// shortcuts the host has no bare-primary binding for — are left
|
|
3967
4360
|
// alone (see useDesignHotkeys.ts: both require event.shiftKey).
|
|
3968
|
-
e.shiftKey && (normalized === "h" || normalized === "l") || // Cmd/Ctrl+Alt+B detach instance / Cmd/Ctrl+Alt+K create component
|
|
4361
|
+
e.shiftKey && (normalized === "h" || normalized === "l") || e.shiftKey && normalized === "r" || // Cmd/Ctrl+Alt+B detach instance / Cmd/Ctrl+Alt+K create component
|
|
3969
4362
|
// (onDetachInstance / onCreateComponent). Gated on altKey so bare
|
|
3970
4363
|
// Cmd+B is left alone — the host has no bare-primary binding for it.
|
|
3971
4364
|
e.altKey && (normalized === "b" || normalized === "k") || // Ctrl+Alt+H / Ctrl+Alt+T — distribute horizontal / tidy up
|
|
@@ -5345,8 +5738,7 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
5345
5738
|
if (cs.position === "absolute" || cs.position === "fixed") return false;
|
|
5346
5739
|
return true;
|
|
5347
5740
|
}
|
|
5348
|
-
function
|
|
5349
|
-
if (!gestureEl) return [];
|
|
5741
|
+
function collectSelectionMembers() {
|
|
5350
5742
|
var raw = [];
|
|
5351
5743
|
if (selectedEl) raw.push(selectedEl);
|
|
5352
5744
|
for (var i = 0; i < passiveSelectionEls.length; i += 1) {
|
|
@@ -5360,11 +5752,15 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
5360
5752
|
}
|
|
5361
5753
|
members.push(candidate);
|
|
5362
5754
|
}
|
|
5363
|
-
|
|
5755
|
+
return members.filter(function(member) {
|
|
5364
5756
|
return !members.some(function(other) {
|
|
5365
5757
|
return other !== member && other.contains(member);
|
|
5366
5758
|
});
|
|
5367
5759
|
});
|
|
5760
|
+
}
|
|
5761
|
+
function collectMoveGroupMembers(gestureEl) {
|
|
5762
|
+
if (!gestureEl) return [];
|
|
5763
|
+
var members = collectSelectionMembers();
|
|
5368
5764
|
var gestureMember = null;
|
|
5369
5765
|
for (var k = 0; k < members.length; k += 1) {
|
|
5370
5766
|
if (members[k] === gestureEl || members[k].contains && members[k].contains(gestureEl)) {
|
|
@@ -6365,84 +6761,584 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
6365
6761
|
}
|
|
6366
6762
|
return rects;
|
|
6367
6763
|
}
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
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);
|
|
6372
6817
|
for (var i = 0; i < candidates.length; i += 1) {
|
|
6373
6818
|
var candidate = candidates[i];
|
|
6374
|
-
var
|
|
6375
|
-
var
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
if (
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
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
|
+
);
|
|
6391
6844
|
}
|
|
6392
6845
|
}
|
|
6393
6846
|
}
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
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
|
+
)
|
|
6411
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
|
+
)
|
|
6412
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
|
+
);
|
|
6413
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));
|
|
6414
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 || "";
|
|
6415
7225
|
return {
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
guideV: bestX ? bestX.guide : null,
|
|
6419
|
-
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"
|
|
6420
7228
|
};
|
|
6421
7229
|
}
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
|
|
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);
|
|
6430
7262
|
} else {
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
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);
|
|
6439
7281
|
} else {
|
|
6440
|
-
|
|
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);
|
|
6441
7303
|
}
|
|
6442
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
|
+
}
|
|
6443
7336
|
function hideSnapGuides() {
|
|
6444
|
-
|
|
6445
|
-
|
|
7337
|
+
dragChromeSuppressed = false;
|
|
7338
|
+
if (snapGuideLayer.style.display === "none") return;
|
|
7339
|
+
snapGuideLayer.style.display = "none";
|
|
7340
|
+
snapGuideLayer.innerHTML = "";
|
|
7341
|
+
snapGuideNodeCount = 0;
|
|
6446
7342
|
}
|
|
6447
7343
|
function startMove(e, gestureElParam, pointerStartParam) {
|
|
6448
7344
|
if (readOnly) return;
|
|
@@ -7075,6 +7971,18 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7075
7971
|
var dragElStartRect = dragEl.getBoundingClientRect();
|
|
7076
7972
|
var dragElStartWidth = dragElStartRect.width;
|
|
7077
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");
|
|
7078
7986
|
if (!duplicatedForDrag && !isGroupDrag) {
|
|
7079
7987
|
postCrossScreenDrag("start", dragEl, e);
|
|
7080
7988
|
}
|
|
@@ -7110,17 +8018,33 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7110
8018
|
var snapBypass = Boolean(ev.metaKey || ev.ctrlKey);
|
|
7111
8019
|
var snapResult = !snapBypass && !duplicatedForDrag ? computeMoveSnapOffset(
|
|
7112
8020
|
{
|
|
7113
|
-
|
|
7114
|
-
|
|
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,
|
|
7115
8025
|
width: dragElStartWidth,
|
|
7116
8026
|
height: dragElStartHeight
|
|
7117
8027
|
},
|
|
7118
8028
|
snapCandidateRects,
|
|
7119
8029
|
// Convert the screen-space base to content px (1/zoom).
|
|
7120
|
-
SNAP_THRESHOLD_PX * chromeLineScale()
|
|
7121
|
-
|
|
7122
|
-
|
|
7123
|
-
|
|
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;
|
|
7124
8048
|
var appliedDx = nextLeft - originLeft;
|
|
7125
8049
|
var appliedDy = nextTop - originTop;
|
|
7126
8050
|
memberStates.forEach(function(state) {
|
|
@@ -7154,10 +8078,20 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7154
8078
|
setMembersOpacity(null);
|
|
7155
8079
|
}
|
|
7156
8080
|
}
|
|
7157
|
-
|
|
8081
|
+
var flowInsertPending = !!currentAutoLayoutTarget && currentAutoLayoutTarget.dropMode !== "absolute-container";
|
|
8082
|
+
if (flowInsertPending || !duplicatedForDrag && isOutsideIframeViewport(ev.clientX, ev.clientY)) {
|
|
7158
8083
|
hideSnapGuides();
|
|
8084
|
+
dragChromeSuppressed = true;
|
|
8085
|
+
hideSizeBadge();
|
|
8086
|
+
hideConstraintGuides();
|
|
7159
8087
|
} else {
|
|
7160
|
-
|
|
8088
|
+
dragChromeSuppressed = false;
|
|
8089
|
+
showSnapGuides(
|
|
8090
|
+
snapResult.guides,
|
|
8091
|
+
snapResult.spacingGuides,
|
|
8092
|
+
snapResult.measurements
|
|
8093
|
+
);
|
|
8094
|
+
showConstraintGuides(dragEl);
|
|
7161
8095
|
}
|
|
7162
8096
|
showTransformBadge(
|
|
7163
8097
|
Math.round(nextLeft) + ", " + Math.round(nextTop),
|
|
@@ -7190,6 +8124,8 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7190
8124
|
hideTransformBadge();
|
|
7191
8125
|
hideInsertionGuide();
|
|
7192
8126
|
hideSnapGuides();
|
|
8127
|
+
hideSizeBadge();
|
|
8128
|
+
hideConstraintGuides();
|
|
7193
8129
|
currentAutoLayoutTarget = null;
|
|
7194
8130
|
if (duplicatedForDrag) {
|
|
7195
8131
|
if (dragEl && dragEl.parentElement) {
|
|
@@ -7220,12 +8156,16 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7220
8156
|
hideTransformBadge();
|
|
7221
8157
|
hideInsertionGuide();
|
|
7222
8158
|
hideSnapGuides();
|
|
8159
|
+
hideSizeBadge();
|
|
8160
|
+
hideConstraintGuides();
|
|
7223
8161
|
return;
|
|
7224
8162
|
}
|
|
7225
8163
|
cleanupMoveDrag();
|
|
7226
8164
|
hideTransformBadge();
|
|
7227
8165
|
hideInsertionGuide();
|
|
7228
8166
|
hideSnapGuides();
|
|
8167
|
+
hideSizeBadge();
|
|
8168
|
+
hideConstraintGuides();
|
|
7229
8169
|
if (!dragEl) return;
|
|
7230
8170
|
var outsideOnDrop = ev ? isOutsideIframeViewport(ev.clientX, ev.clientY) : false;
|
|
7231
8171
|
if (ev && !duplicatedForDrag && !isGroupDrag && (outsideOnDrop || designCanvasBoardSurface)) {
|
|
@@ -7323,6 +8263,30 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7323
8263
|
document.addEventListener("keydown", onMoveKeyDown, true);
|
|
7324
8264
|
setActiveDragCancel(cancelMoveDrag);
|
|
7325
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
|
+
}
|
|
7326
8290
|
function startResize(handle, e) {
|
|
7327
8291
|
if (readOnly) return;
|
|
7328
8292
|
if (!selectedEl) return;
|
|
@@ -7393,6 +8357,13 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7393
8357
|
});
|
|
7394
8358
|
var widthTouched = false;
|
|
7395
8359
|
var heightTouched = false;
|
|
8360
|
+
var scaledTextTargetsCache = null;
|
|
8361
|
+
function scaledTextTargets() {
|
|
8362
|
+
if (!scaledTextTargetsCache) {
|
|
8363
|
+
scaledTextTargetsCache = collectScaleFontTargets(resizeEl);
|
|
8364
|
+
}
|
|
8365
|
+
return scaledTextTargetsCache;
|
|
8366
|
+
}
|
|
7396
8367
|
function nextRect(ev) {
|
|
7397
8368
|
var screenDx = ev.clientX - startX;
|
|
7398
8369
|
var screenDy = ev.clientY - startY;
|
|
@@ -7493,6 +8464,12 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7493
8464
|
if (originFontSize > 0) {
|
|
7494
8465
|
resizeEl.style.fontSize = Math.max(1, Math.round(originFontSize * kScaleFactor * 100) / 100) + "px";
|
|
7495
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
|
+
});
|
|
7496
8473
|
}
|
|
7497
8474
|
showTransformBadge(
|
|
7498
8475
|
Math.round(rect.width) + " x " + Math.round(rect.height),
|
|
@@ -7519,6 +8496,9 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7519
8496
|
resizeEl.style.height = originalInlineHeight;
|
|
7520
8497
|
resizeEl.style.borderWidth = originalInlineBorderWidth;
|
|
7521
8498
|
resizeEl.style.fontSize = originalInlineFontSize;
|
|
8499
|
+
(scaledTextTargetsCache || []).forEach(function(target) {
|
|
8500
|
+
target.el.style.fontSize = target.originalInlineFontSize;
|
|
8501
|
+
});
|
|
7522
8502
|
selectedEl = resizeEl;
|
|
7523
8503
|
positionOverlay(selectionOverlay, selectedEl);
|
|
7524
8504
|
}
|
|
@@ -7566,12 +8546,313 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7566
8546
|
},
|
|
7567
8547
|
"*"
|
|
7568
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
|
+
}
|
|
7569
8570
|
}
|
|
7570
8571
|
document.addEventListener(events.move, onMove, true);
|
|
7571
8572
|
document.addEventListener(events.up, onUp, true);
|
|
7572
8573
|
document.addEventListener("keydown", onResizeKeyDown, true);
|
|
7573
8574
|
setActiveDragCancel(cancelResizeDrag);
|
|
7574
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
|
+
}
|
|
7575
8856
|
function startRotate(e) {
|
|
7576
8857
|
if (readOnly) return;
|
|
7577
8858
|
if (!selectedEl) return;
|
|
@@ -7710,7 +8991,17 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7710
8991
|
preferSelected: selectedLayerDragPriorityEnabled
|
|
7711
8992
|
});
|
|
7712
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
|
+
});
|
|
7713
9003
|
if (!dragTarget || dragTarget === document.body || dragTarget === document.documentElement || isLayerInteractionBlocked(dragTarget)) {
|
|
9004
|
+
dndLog("shield:reject", { reason: "no-drag-target" });
|
|
7714
9005
|
return;
|
|
7715
9006
|
}
|
|
7716
9007
|
if (e.pointerId !== void 0 && shieldOverlay.setPointerCapture && !e.altKey) {
|
|
@@ -7743,6 +9034,8 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
7743
9034
|
if (readOnly) return;
|
|
7744
9035
|
if (Math.hypot(ev.clientX - startX, ev.clientY - startY) <= 3) return;
|
|
7745
9036
|
clearPendingShieldDrag();
|
|
9037
|
+
if (!didStartDrag)
|
|
9038
|
+
dndLog("shield:drag-start", { board: designCanvasBoardSurface });
|
|
7746
9039
|
didStartDrag = true;
|
|
7747
9040
|
var groupGestureMember = !e.altKey ? groupMemberForGestureTarget(dragTarget) : null;
|
|
7748
9041
|
if (groupGestureMember && collectMoveGroupMembers(groupGestureMember).length > 1) {
|
|
@@ -9399,6 +10692,7 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
9399
10692
|
]
|
|
9400
10693
|
});
|
|
9401
10694
|
}
|
|
10695
|
+
captureInitialSourceOwnership();
|
|
9402
10696
|
if (runtimeLayerSnapshotEnabled) scheduleRuntimeLayerSnapshot();
|
|
9403
10697
|
window.parent.postMessage(
|
|
9404
10698
|
{ type: "agent-native:editor-chrome-ready" },
|