@threadlabs/looma 0.29.3 → 0.29.5
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/editor/mobile-dock.d.ts +29 -0
- package/editor/requests.d.ts +5 -26
- package/package.json +3 -3
- package/styles/ui-action-bar.css +1 -1
- package/styles/ui-affordance-scope.css +1 -1
- package/styles/ui-avatar-group.css +1 -1
- package/styles/ui-avatar.css +1 -1
- package/styles/ui-badge.css +1 -1
- package/styles/ui-breadcrumb-item.css +1 -1
- package/styles/ui-breadcrumbs.css +1 -1
- package/styles/ui-button.css +1 -1
- package/styles/ui-callout.css +1 -1
- package/styles/ui-card.css +1 -1
- package/styles/ui-checkbox.css +1 -1
- package/styles/ui-cluster.css +1 -1
- package/styles/ui-combobox.css +1 -1
- package/styles/ui-container.css +1 -1
- package/styles/ui-context-menu.css +1 -1
- package/styles/ui-cover.css +1 -1
- package/styles/ui-description-item.css +1 -1
- package/styles/ui-description-list.css +1 -1
- package/styles/ui-dialog.css +1 -1
- package/styles/ui-disclosure.css +1 -1
- package/styles/ui-editable.css +1 -1
- package/styles/ui-editor-block-actions.css +1 -1
- package/styles/ui-editor-chip-editor.css +1 -1
- package/styles/ui-editor-code-language.css +1 -1
- package/styles/ui-editor-image-toolbar.css +1 -1
- package/styles/ui-editor-insert-table-grid.css +1 -1
- package/styles/ui-editor-link-card.css +1 -1
- package/styles/ui-editor-link-form.css +1 -1
- package/styles/ui-editor-mention-menu-item.css +1 -1
- package/styles/ui-editor-mention-menu.css +1 -1
- package/styles/ui-editor-slash-menu-group.css +1 -1
- package/styles/ui-editor-slash-menu-item.css +1 -1
- package/styles/ui-editor-slash-menu.css +1 -1
- package/styles/ui-editor-surface.css +1 -1
- package/styles/ui-editor-table-context-menu.css +1 -1
- package/styles/ui-editor-table-overlay.css +1 -1
- package/styles/ui-editor-table-toolbar.css +1 -1
- package/styles/ui-editor-toolbar.css +1 -1
- package/styles/ui-floating-action-button.css +1 -1
- package/styles/ui-form-field.css +1 -1
- package/styles/ui-grid.css +1 -1
- package/styles/ui-icon-button.css +1 -1
- package/styles/ui-icon.css +1 -1
- package/styles/ui-image.css +1 -1
- package/styles/ui-input-group.css +1 -1
- package/styles/ui-input.css +1 -1
- package/styles/ui-list-item.css +1 -1
- package/styles/ui-list.css +1 -1
- package/styles/ui-listbox.css +1 -1
- package/styles/ui-menu-group.css +1 -1
- package/styles/ui-menu-item.css +1 -1
- package/styles/ui-menu.css +1 -1
- package/styles/ui-meter.css +1 -1
- package/styles/ui-nav-item.css +1 -1
- package/styles/ui-page-header.css +1 -1
- package/styles/ui-popover.css +1 -1
- package/styles/ui-radio-group.css +1 -1
- package/styles/ui-radio.css +1 -1
- package/styles/ui-reel.css +1 -1
- package/styles/ui-scroll-area.css +1 -1
- package/styles/ui-search-result-row.css +1 -1
- package/styles/ui-search-shell.css +1 -1
- package/styles/ui-section.css +1 -1
- package/styles/ui-select.css +1 -1
- package/styles/ui-separator.css +1 -1
- package/styles/ui-sidebar.css +1 -1
- package/styles/ui-spinner.css +1 -1
- package/styles/ui-stack.css +1 -1
- package/styles/ui-status-message.css +1 -1
- package/styles/ui-swatch.css +1 -1
- package/styles/ui-switch.css +1 -1
- package/styles/ui-switcher.css +1 -1
- package/styles/ui-table.css +1 -1
- package/styles/ui-tabs.css +1 -1
- package/styles/ui-text.css +1 -1
- package/styles/ui-textarea.css +1 -1
- package/styles/ui-toast-region.css +1 -1
- package/styles/ui-toast.css +1 -1
- package/styles/ui-tooltip.css +1 -1
- package/styles/ui-top-bar.css +1 -1
- package/styles/ui-tree-item.css +1 -1
- package/styles/ui-tree.css +1 -1
- package/vanilla/UiActionBar.d.ts +1 -1
- package/vanilla/UiActionBar.js +1 -1
- package/vanilla/UiAffordanceScope.d.ts +1 -1
- package/vanilla/UiAffordanceScope.js +1 -1
- package/vanilla/UiAvatar.d.ts +1 -1
- package/vanilla/UiAvatar.js +1 -1
- package/vanilla/UiAvatarGroup.d.ts +1 -1
- package/vanilla/UiAvatarGroup.js +1 -1
- package/vanilla/UiBadge.d.ts +1 -1
- package/vanilla/UiBadge.js +1 -1
- package/vanilla/UiBreadcrumbItem.d.ts +1 -1
- package/vanilla/UiBreadcrumbItem.js +1 -1
- package/vanilla/UiBreadcrumbs.d.ts +1 -1
- package/vanilla/UiBreadcrumbs.js +1 -1
- package/vanilla/UiButton.d.ts +1 -1
- package/vanilla/UiButton.js +1 -1
- package/vanilla/UiCallout.d.ts +1 -1
- package/vanilla/UiCallout.js +1 -1
- package/vanilla/UiCard.d.ts +1 -1
- package/vanilla/UiCard.js +1 -1
- package/vanilla/UiCheckbox.d.ts +1 -1
- package/vanilla/UiCheckbox.js +1 -1
- package/vanilla/UiCluster.d.ts +1 -1
- package/vanilla/UiCluster.js +1 -1
- package/vanilla/UiCombobox.d.ts +1 -1
- package/vanilla/UiCombobox.js +1 -1
- package/vanilla/UiContainer.d.ts +1 -1
- package/vanilla/UiContainer.js +1 -1
- package/vanilla/UiContextMenu.d.ts +1 -1
- package/vanilla/UiContextMenu.js +1 -1
- package/vanilla/UiCover.d.ts +1 -1
- package/vanilla/UiCover.js +1 -1
- package/vanilla/UiDescriptionItem.d.ts +1 -1
- package/vanilla/UiDescriptionItem.js +1 -1
- package/vanilla/UiDescriptionList.d.ts +1 -1
- package/vanilla/UiDescriptionList.js +1 -1
- package/vanilla/UiDialog.d.ts +1 -1
- package/vanilla/UiDialog.js +1 -1
- package/vanilla/UiDisclosure.d.ts +1 -1
- package/vanilla/UiDisclosure.js +1 -1
- package/vanilla/UiEditable.d.ts +1 -1
- package/vanilla/UiEditable.js +1 -1
- package/vanilla/UiEditorBlockActions.d.ts +1 -1
- package/vanilla/UiEditorBlockActions.js +1 -1
- package/vanilla/UiEditorChipEditor.d.ts +1 -1
- package/vanilla/UiEditorChipEditor.js +1 -1
- package/vanilla/UiEditorCodeLanguage.d.ts +1 -1
- package/vanilla/UiEditorCodeLanguage.js +1 -1
- package/vanilla/UiEditorImageToolbar.d.ts +1 -1
- package/vanilla/UiEditorImageToolbar.js +1 -1
- package/vanilla/UiEditorInsertTableGrid.d.ts +1 -1
- package/vanilla/UiEditorInsertTableGrid.js +1 -1
- package/vanilla/UiEditorLinkCard.d.ts +1 -1
- package/vanilla/UiEditorLinkCard.js +1 -1
- package/vanilla/UiEditorLinkForm.d.ts +1 -1
- package/vanilla/UiEditorLinkForm.js +1 -1
- package/vanilla/UiEditorMentionMenu.d.ts +1 -1
- package/vanilla/UiEditorMentionMenu.js +1 -1
- package/vanilla/UiEditorMentionMenuItem.d.ts +1 -1
- package/vanilla/UiEditorMentionMenuItem.js +1 -1
- package/vanilla/UiEditorSlashMenu.d.ts +1 -1
- package/vanilla/UiEditorSlashMenu.js +1 -1
- package/vanilla/UiEditorSlashMenuGroup.d.ts +1 -1
- package/vanilla/UiEditorSlashMenuGroup.js +1 -1
- package/vanilla/UiEditorSlashMenuItem.d.ts +1 -1
- package/vanilla/UiEditorSlashMenuItem.js +1 -1
- package/vanilla/UiEditorSurface.d.ts +1 -1
- package/vanilla/UiEditorSurface.js +1 -1
- package/vanilla/UiEditorTableContextMenu.d.ts +1 -1
- package/vanilla/UiEditorTableContextMenu.js +1 -1
- package/vanilla/UiEditorTableOverlay.d.ts +1 -1
- package/vanilla/UiEditorTableOverlay.js +1 -1
- package/vanilla/UiEditorTableToolbar.d.ts +1 -1
- package/vanilla/UiEditorTableToolbar.js +1 -1
- package/vanilla/UiEditorToolbar.d.ts +1 -1
- package/vanilla/UiEditorToolbar.js +1 -1
- package/vanilla/UiFloatingActionButton.d.ts +1 -1
- package/vanilla/UiFloatingActionButton.js +1 -1
- package/vanilla/UiFormField.d.ts +1 -1
- package/vanilla/UiFormField.js +1 -1
- package/vanilla/UiGrid.d.ts +1 -1
- package/vanilla/UiGrid.js +1 -1
- package/vanilla/UiIcon.d.ts +1 -1
- package/vanilla/UiIcon.js +1 -1
- package/vanilla/UiIconButton.d.ts +1 -1
- package/vanilla/UiIconButton.js +1 -1
- package/vanilla/UiImage.d.ts +1 -1
- package/vanilla/UiImage.js +1 -1
- package/vanilla/UiInput.d.ts +1 -1
- package/vanilla/UiInput.js +1 -1
- package/vanilla/UiInputGroup.d.ts +1 -1
- package/vanilla/UiInputGroup.js +1 -1
- package/vanilla/UiList.d.ts +1 -1
- package/vanilla/UiList.js +1 -1
- package/vanilla/UiListItem.d.ts +1 -1
- package/vanilla/UiListItem.js +1 -1
- package/vanilla/UiListbox.d.ts +1 -1
- package/vanilla/UiListbox.js +1 -1
- package/vanilla/UiMenu.d.ts +1 -1
- package/vanilla/UiMenu.js +1 -1
- package/vanilla/UiMenuGroup.d.ts +1 -1
- package/vanilla/UiMenuGroup.js +1 -1
- package/vanilla/UiMenuItem.d.ts +1 -1
- package/vanilla/UiMenuItem.js +1 -1
- package/vanilla/UiMeter.d.ts +1 -1
- package/vanilla/UiMeter.js +1 -1
- package/vanilla/UiNavItem.d.ts +1 -1
- package/vanilla/UiNavItem.js +1 -1
- package/vanilla/UiPageHeader.d.ts +1 -1
- package/vanilla/UiPageHeader.js +1 -1
- package/vanilla/UiPopover.d.ts +1 -1
- package/vanilla/UiPopover.js +1 -1
- package/vanilla/UiRadio.d.ts +1 -1
- package/vanilla/UiRadio.js +1 -1
- package/vanilla/UiRadioGroup.d.ts +1 -1
- package/vanilla/UiRadioGroup.js +1 -1
- package/vanilla/UiReel.d.ts +1 -1
- package/vanilla/UiReel.js +1 -1
- package/vanilla/UiScrollArea.d.ts +1 -1
- package/vanilla/UiScrollArea.js +1 -1
- package/vanilla/UiSearchResultRow.d.ts +1 -1
- package/vanilla/UiSearchResultRow.js +1 -1
- package/vanilla/UiSearchShell.d.ts +1 -1
- package/vanilla/UiSearchShell.js +1 -1
- package/vanilla/UiSection.d.ts +1 -1
- package/vanilla/UiSection.js +1 -1
- package/vanilla/UiSelect.d.ts +1 -1
- package/vanilla/UiSelect.js +1 -1
- package/vanilla/UiSeparator.d.ts +1 -1
- package/vanilla/UiSeparator.js +1 -1
- package/vanilla/UiSidebar.d.ts +1 -1
- package/vanilla/UiSidebar.js +1 -1
- package/vanilla/UiSpinner.d.ts +1 -1
- package/vanilla/UiSpinner.js +1 -1
- package/vanilla/UiStack.d.ts +1 -1
- package/vanilla/UiStack.js +1 -1
- package/vanilla/UiStatusMessage.d.ts +1 -1
- package/vanilla/UiStatusMessage.js +1 -1
- package/vanilla/UiSwatch.d.ts +1 -1
- package/vanilla/UiSwatch.js +1 -1
- package/vanilla/UiSwitch.d.ts +1 -1
- package/vanilla/UiSwitch.js +1 -1
- package/vanilla/UiSwitcher.d.ts +1 -1
- package/vanilla/UiSwitcher.js +1 -1
- package/vanilla/UiTable.d.ts +1 -1
- package/vanilla/UiTable.js +1 -1
- package/vanilla/UiTabs.d.ts +1 -1
- package/vanilla/UiTabs.js +1 -1
- package/vanilla/UiText.d.ts +1 -1
- package/vanilla/UiText.js +1 -1
- package/vanilla/UiTextarea.d.ts +1 -1
- package/vanilla/UiTextarea.js +1 -1
- package/vanilla/UiToast.d.ts +1 -1
- package/vanilla/UiToast.js +1 -1
- package/vanilla/UiToastRegion.d.ts +1 -1
- package/vanilla/UiToastRegion.js +1 -1
- package/vanilla/UiTooltip.d.ts +1 -1
- package/vanilla/UiTooltip.js +1 -1
- package/vanilla/UiTopBar.d.ts +1 -1
- package/vanilla/UiTopBar.js +1 -1
- package/vanilla/UiTree.d.ts +1 -1
- package/vanilla/UiTree.js +1 -1
- package/vanilla/UiTreeItem.d.ts +1 -1
- package/vanilla/UiTreeItem.js +1 -1
- package/vue/UiActionBar.vue +1 -1
- package/vue/UiAffordanceScope.vue +1 -1
- package/vue/UiAvatar.vue +1 -1
- package/vue/UiAvatarGroup.vue +1 -1
- package/vue/UiBadge.vue +1 -1
- package/vue/UiBreadcrumbItem.vue +1 -1
- package/vue/UiBreadcrumbs.vue +1 -1
- package/vue/UiButton.vue +1 -1
- package/vue/UiCallout.vue +1 -1
- package/vue/UiCard.vue +1 -1
- package/vue/UiCheckbox.vue +1 -1
- package/vue/UiCluster.vue +1 -1
- package/vue/UiCombobox.vue +1 -1
- package/vue/UiContainer.vue +1 -1
- package/vue/UiContextMenu.vue +1 -1
- package/vue/UiCover.vue +1 -1
- package/vue/UiDescriptionItem.vue +1 -1
- package/vue/UiDescriptionList.vue +1 -1
- package/vue/UiDialog.vue +1 -1
- package/vue/UiDisclosure.vue +1 -1
- package/vue/UiEditable.vue +1 -1
- package/vue/UiEditorBlockActions.vue +1 -1
- package/vue/UiEditorChipEditor.vue +1 -1
- package/vue/UiEditorCodeLanguage.vue +1 -1
- package/vue/UiEditorImageToolbar.vue +1 -1
- package/vue/UiEditorInsertTableGrid.vue +1 -1
- package/vue/UiEditorLinkCard.vue +1 -1
- package/vue/UiEditorLinkForm.vue +1 -1
- package/vue/UiEditorMentionMenu.vue +1 -1
- package/vue/UiEditorMentionMenuItem.vue +1 -1
- package/vue/UiEditorSlashMenu.vue +1 -1
- package/vue/UiEditorSlashMenuGroup.vue +1 -1
- package/vue/UiEditorSlashMenuItem.vue +1 -1
- package/vue/UiEditorSurface.vue +1 -1
- package/vue/UiEditorTableContextMenu.vue +1 -1
- package/vue/UiEditorTableOverlay.vue +1 -1
- package/vue/UiEditorTableToolbar.vue +1 -1
- package/vue/UiEditorToolbar.vue +1 -1
- package/vue/UiFloatingActionButton.vue +1 -1
- package/vue/UiFormField.vue +1 -1
- package/vue/UiGrid.vue +1 -1
- package/vue/UiIcon.vue +1 -1
- package/vue/UiIconButton.vue +1 -1
- package/vue/UiImage.vue +1 -1
- package/vue/UiInput.vue +1 -1
- package/vue/UiInputGroup.vue +1 -1
- package/vue/UiList.vue +1 -1
- package/vue/UiListItem.vue +1 -1
- package/vue/UiListbox.vue +1 -1
- package/vue/UiMenu.vue +1 -1
- package/vue/UiMenuGroup.vue +1 -1
- package/vue/UiMenuItem.vue +1 -1
- package/vue/UiMeter.vue +1 -1
- package/vue/UiNavItem.vue +1 -1
- package/vue/UiPageHeader.vue +1 -1
- package/vue/UiPopover.vue +1 -1
- package/vue/UiRadio.vue +1 -1
- package/vue/UiRadioGroup.vue +1 -1
- package/vue/UiReel.vue +1 -1
- package/vue/UiScrollArea.vue +1 -1
- package/vue/UiSearchResultRow.vue +1 -1
- package/vue/UiSearchShell.vue +1 -1
- package/vue/UiSection.vue +1 -1
- package/vue/UiSelect.vue +1 -1
- package/vue/UiSeparator.vue +1 -1
- package/vue/UiSidebar.vue +1 -1
- package/vue/UiSpinner.vue +1 -1
- package/vue/UiStack.vue +1 -1
- package/vue/UiStatusMessage.vue +1 -1
- package/vue/UiSwatch.vue +1 -1
- package/vue/UiSwitch.vue +1 -1
- package/vue/UiSwitcher.vue +1 -1
- package/vue/UiTable.vue +1 -1
- package/vue/UiTabs.vue +1 -1
- package/vue/UiText.vue +1 -1
- package/vue/UiTextarea.vue +1 -1
- package/vue/UiToast.vue +1 -1
- package/vue/UiToastRegion.vue +1 -1
- package/vue/UiTooltip.vue +1 -1
- package/vue/UiTopBar.vue +1 -1
- package/vue/UiTree.vue +1 -1
- package/vue/UiTreeItem.vue +1 -1
- package/vue/chunks/UiActionBar.js +1 -1
- package/vue/chunks/UiAffordanceScope.js +1 -1
- package/vue/chunks/UiAvatar.js +1 -1
- package/vue/chunks/UiAvatarGroup.js +1 -1
- package/vue/chunks/UiBadge.js +1 -1
- package/vue/chunks/UiBreadcrumbItem.js +1 -1
- package/vue/chunks/UiBreadcrumbs.js +1 -1
- package/vue/chunks/UiButton.js +1 -1
- package/vue/chunks/UiCallout.js +1 -1
- package/vue/chunks/UiCard.js +1 -1
- package/vue/chunks/UiCheckbox.js +1 -1
- package/vue/chunks/UiCluster.js +1 -1
- package/vue/chunks/UiCombobox.js +1 -1
- package/vue/chunks/UiContainer.js +1 -1
- package/vue/chunks/UiContextMenu.js +1 -1
- package/vue/chunks/UiCover.js +1 -1
- package/vue/chunks/UiDescriptionItem.js +1 -1
- package/vue/chunks/UiDescriptionList.js +1 -1
- package/vue/chunks/UiDialog.js +1 -1
- package/vue/chunks/UiDisclosure.js +1 -1
- package/vue/chunks/UiEditable.js +1 -1
- package/vue/chunks/UiEditorInsertTableGrid.js +1 -1
- package/vue/chunks/UiEditorMentionMenu.js +1 -1
- package/vue/chunks/UiEditorMentionMenuItem.js +1 -1
- package/vue/chunks/UiEditorSlashMenu.js +1 -1
- package/vue/chunks/UiEditorSlashMenuGroup.js +1 -1
- package/vue/chunks/UiEditorSlashMenuItem.js +1 -1
- package/vue/chunks/UiEditorSurface.js +1 -1
- package/vue/chunks/UiEditorTableContextMenu.js +1 -1
- package/vue/chunks/UiEditorTableOverlay.js +1 -1
- package/vue/chunks/UiEditorTableToolbar.js +1 -1
- package/vue/chunks/UiEditorToolbar.js +1 -1
- package/vue/chunks/UiFloatingActionButton.js +1 -1
- package/vue/chunks/UiFormField.js +1 -1
- package/vue/chunks/UiGrid.js +1 -1
- package/vue/chunks/UiIcon.js +1 -1
- package/vue/chunks/UiIconButton.js +1 -1
- package/vue/chunks/UiImage.js +1 -1
- package/vue/chunks/UiInput.js +1 -1
- package/vue/chunks/UiInputGroup.js +1 -1
- package/vue/chunks/UiList.js +1 -1
- package/vue/chunks/UiListItem.js +1 -1
- package/vue/chunks/UiListbox.js +1 -1
- package/vue/chunks/UiMenu.js +1 -1
- package/vue/chunks/UiMenuGroup.js +1 -1
- package/vue/chunks/UiMenuItem.js +1 -1
- package/vue/chunks/UiMeter.js +1 -1
- package/vue/chunks/UiNavItem.js +1 -1
- package/vue/chunks/UiPageHeader.js +1 -1
- package/vue/chunks/UiPopover.js +1 -1
- package/vue/chunks/UiRadio.js +1 -1
- package/vue/chunks/UiRadioGroup.js +1 -1
- package/vue/chunks/UiReel.js +1 -1
- package/vue/chunks/UiScrollArea.js +1 -1
- package/vue/chunks/UiSearchResultRow.js +1 -1
- package/vue/chunks/UiSearchShell.js +1 -1
- package/vue/chunks/UiSection.js +1 -1
- package/vue/chunks/UiSelect.js +1 -1
- package/vue/chunks/UiSeparator.js +1 -1
- package/vue/chunks/UiSidebar.js +1 -1
- package/vue/chunks/UiSpinner.js +1 -1
- package/vue/chunks/UiStack.js +1 -1
- package/vue/chunks/UiStatusMessage.js +1 -1
- package/vue/chunks/UiSwatch.js +1 -1
- package/vue/chunks/UiSwitch.js +1 -1
- package/vue/chunks/UiSwitcher.js +1 -1
- package/vue/chunks/UiTable.js +1 -1
- package/vue/chunks/UiTabs.js +1 -1
- package/vue/chunks/UiText.js +1 -1
- package/vue/chunks/UiTextarea.js +1 -1
- package/vue/chunks/UiToast.js +1 -1
- package/vue/chunks/UiToastRegion.js +1 -1
- package/vue/chunks/UiTooltip.js +1 -1
- package/vue/chunks/UiTopBar.js +1 -1
- package/vue/chunks/UiTree.js +1 -1
- package/vue/chunks/UiTreeItem.js +1 -1
- package/vue/chunks/_plugin-vue_export-helper.js +42 -10
- package/vue/components.css +20 -20
- package/vue/editor/index.js +189 -85
- package/vue/host.ts +83 -30
package/vue/editor/index.js
CHANGED
|
@@ -1224,7 +1224,7 @@ function createImageUploads(options) {
|
|
|
1224
1224
|
};
|
|
1225
1225
|
}
|
|
1226
1226
|
//#endregion
|
|
1227
|
-
//#region ../../node_modules/.pnpm/@nextwebwg+html-next@1.0.0-alpha.
|
|
1227
|
+
//#region ../../node_modules/.pnpm/@nextwebwg+html-next@1.0.0-alpha.55/node_modules/@nextwebwg/html-next/dist/requests.js
|
|
1228
1228
|
/**
|
|
1229
1229
|
* Requests: behavior a component asks its consumer for, answered through a native event's
|
|
1230
1230
|
* `respondWith` (https://nextwebwg.org/declarative-components/javascript#requests).
|
|
@@ -1240,7 +1240,12 @@ var port = (event) => {
|
|
|
1240
1240
|
if (found === void 0) ports.set(event, found = {});
|
|
1241
1241
|
return found;
|
|
1242
1242
|
};
|
|
1243
|
-
/**
|
|
1243
|
+
/**
|
|
1244
|
+
* A request as its responders receive it: the nearest one answers with `respondWith`. Its static
|
|
1245
|
+
* `respond`, `request` and `hasResponder` are how code without a `host` takes part
|
|
1246
|
+
* (https://nextwebwg.org/declarative-components/javascript#outside-a-controller). They never read
|
|
1247
|
+
* `this`, so `const { respond, request, hasResponder } = RequestEvent` works.
|
|
1248
|
+
*/
|
|
1244
1249
|
var RequestEvent = class extends CustomEvent {
|
|
1245
1250
|
/** Aborts when the asker no longer needs the answer, or its component disconnects. */
|
|
1246
1251
|
signal;
|
|
@@ -1264,71 +1269,135 @@ var RequestEvent = class extends CustomEvent {
|
|
|
1264
1269
|
reportError(error);
|
|
1265
1270
|
}
|
|
1266
1271
|
}
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
answer
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1272
|
+
/**
|
|
1273
|
+
* Answers `name` requests that reach `target` with `answer`, records it as a known responder, then
|
|
1274
|
+
* announces it so a component whose request went unanswered can ask again. Returns a function that
|
|
1275
|
+
* removes it.
|
|
1276
|
+
*/
|
|
1277
|
+
static respond(target, name, answer) {
|
|
1278
|
+
const listener = (event) => {
|
|
1279
|
+
if ("respondWith" in event) answerRequest(event, answer);
|
|
1280
|
+
};
|
|
1281
|
+
target.addEventListener(name, listener);
|
|
1282
|
+
const forget = knownResponder(target, name);
|
|
1283
|
+
target.dispatchEvent(new CustomEvent("responder", {
|
|
1284
|
+
bubbles: true,
|
|
1285
|
+
detail: { name }
|
|
1286
|
+
}));
|
|
1287
|
+
return () => {
|
|
1288
|
+
target.removeEventListener(name, listener);
|
|
1289
|
+
forget();
|
|
1290
|
+
};
|
|
1278
1291
|
}
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1292
|
+
/**
|
|
1293
|
+
* Asks `name` at `target` with the request steps `host.request` uses, with no declaration to check
|
|
1294
|
+
* the detail or the answer against, no connection signal, and nothing remembered for late responders.
|
|
1295
|
+
*/
|
|
1296
|
+
static request(target, name, detail, options) {
|
|
1297
|
+
return dispatchRequest(target, target.nodeType ? target : null, name, detail ?? null, options?.signal ?? new AbortController().signal, options?.progress);
|
|
1298
|
+
}
|
|
1299
|
+
/** Whether a known responder for `name` is on the path a request from `target` takes, now. */
|
|
1300
|
+
static hasResponder(target, name) {
|
|
1301
|
+
return knownCount(target, name) > 0;
|
|
1286
1302
|
}
|
|
1287
1303
|
};
|
|
1288
|
-
/**
|
|
1289
|
-
|
|
1290
|
-
const
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1304
|
+
/** Answers a request event with a responder function, as `RequestEvent.respond` and framework function props do. */
|
|
1305
|
+
function answerRequest(event, responder) {
|
|
1306
|
+
const request = event;
|
|
1307
|
+
request.respondWith(responder(request.detail, {
|
|
1308
|
+
signal: request.signal,
|
|
1309
|
+
progress: (loaded, total) => request.progress(loaded, total)
|
|
1310
|
+
}));
|
|
1311
|
+
}
|
|
1312
|
+
var runtimeKey = Symbol.for("@nextwebwg/html-next.runtime.v1");
|
|
1313
|
+
var documentRecord = (document) => document[runtimeKey] ??= {};
|
|
1314
|
+
/** A target's document: a node's owner, a window's document, or a target outside the DOM itself. */
|
|
1315
|
+
var recordOf = (target) => documentRecord(target.nodeType === 9 ? target : target.ownerDocument ?? target.document ?? target);
|
|
1316
|
+
var requestState = (record) => record.requests ??= { g: /* @__PURE__ */ new WeakMap() };
|
|
1317
|
+
/**
|
|
1318
|
+
* Records a responder for `name` on `target` that `hasResponder` can see, until the returned function
|
|
1319
|
+
* runs. `own` counts the entries a controller's `host.on` adds on its own root, which its own
|
|
1320
|
+
* `host.hasResponder` does not count.
|
|
1321
|
+
*/
|
|
1322
|
+
function knownResponder(target, name, own) {
|
|
1323
|
+
const record = recordOf(target);
|
|
1324
|
+
const known = record.k ??= /* @__PURE__ */ new WeakMap();
|
|
1325
|
+
const names = known.get(target) ?? known.set(target, []).get(target);
|
|
1326
|
+
const change = (add) => {
|
|
1327
|
+
for (const list of own === void 0 ? [names] : [names, own]) if (add) list.push(name);
|
|
1328
|
+
else list.splice(list.indexOf(name), 1);
|
|
1329
|
+
record.w?.forEach((changed) => changed(name));
|
|
1330
|
+
};
|
|
1331
|
+
change(true);
|
|
1332
|
+
let held = true;
|
|
1333
|
+
return () => {
|
|
1334
|
+
if (held) {
|
|
1335
|
+
held = false;
|
|
1336
|
+
change(false);
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
}
|
|
1340
|
+
/** The next object on a composed event's path: an assigned slot, a parent, a shadow host, the window. */
|
|
1341
|
+
var parentOf = (node) => node.nodeType === 9 ? node.defaultView : node.nodeType === 11 ? node.host : node.nodeType ? node.assignedSlot ?? node.parentNode : null;
|
|
1342
|
+
/** How many of `names` are `name`. */
|
|
1343
|
+
var countOf = (names, name) => names?.filter((known) => known === name).length ?? 0;
|
|
1344
|
+
/** How many known responders for `name` are on the path a request from `target` takes. */
|
|
1345
|
+
function knownCount(target, name) {
|
|
1346
|
+
const known = recordOf(target).k;
|
|
1347
|
+
let count = 0;
|
|
1348
|
+
if (known !== void 0) for (let node = target; node; node = parentOf(node)) count += countOf(known.get(node), name);
|
|
1349
|
+
return count;
|
|
1350
|
+
}
|
|
1351
|
+
/** Settles with `value`, or rejects with the signal's reason when it aborts first; a late value is discarded. */
|
|
1352
|
+
function settle(value, signal) {
|
|
1353
|
+
return new Promise((resolve, reject) => {
|
|
1354
|
+
const abort = () => reject(signal.reason);
|
|
1355
|
+
if (signal.aborted) abort();
|
|
1356
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
1357
|
+
Promise.resolve(value).then((result) => {
|
|
1358
|
+
signal.removeEventListener("abort", abort);
|
|
1359
|
+
resolve(result);
|
|
1360
|
+
}, (error) => {
|
|
1361
|
+
signal.removeEventListener("abort", abort);
|
|
1362
|
+
reject(error);
|
|
1363
|
+
});
|
|
1299
1364
|
});
|
|
1300
|
-
}
|
|
1365
|
+
}
|
|
1301
1366
|
/**
|
|
1302
|
-
*
|
|
1303
|
-
*
|
|
1304
|
-
*
|
|
1305
|
-
* answer given as a promise is returned as a promise.
|
|
1306
|
-
*
|
|
1307
|
-
* @contract Settles `null` when no listener answers during the dispatch, or when the answer is `null`.
|
|
1308
|
-
* @failure Throws when the signal has already aborted. A promised answer rejects with the signal's
|
|
1309
|
-
* reason when it aborts before the answer arrives, and with the answer's own rejection.
|
|
1367
|
+
* The request steps every asker shares: wait for the controllers of components at `from` and around
|
|
1368
|
+
* it, dispatch the `RequestEvent` at `target`, and settle with the answer, or `null` when nobody
|
|
1369
|
+
* answered. `answered` hears, during the dispatch, whether anyone did.
|
|
1310
1370
|
*/
|
|
1311
|
-
function
|
|
1312
|
-
const signal = options.signal ?? new AbortController().signal;
|
|
1371
|
+
async function dispatchRequest(target, from, name, detail, signal, progress, answered) {
|
|
1313
1372
|
signal.throwIfAborted();
|
|
1314
|
-
const
|
|
1315
|
-
|
|
1373
|
+
const state = requestState(recordOf(target));
|
|
1374
|
+
for (;;) {
|
|
1375
|
+
const waits = [];
|
|
1376
|
+
for (let node = from; node !== null; node = node.parentNode ?? node.host ?? null) {
|
|
1377
|
+
const gate = state.g.get(node);
|
|
1378
|
+
if (gate !== void 0) waits.push(gate);
|
|
1379
|
+
}
|
|
1380
|
+
if (waits.length === 0) break;
|
|
1381
|
+
await settle(Promise.all(waits), signal);
|
|
1382
|
+
}
|
|
1383
|
+
const event = new RequestEvent(name, {
|
|
1384
|
+
detail,
|
|
1316
1385
|
signal,
|
|
1317
1386
|
bubbles: true,
|
|
1318
1387
|
composed: true
|
|
1319
1388
|
});
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
return
|
|
1389
|
+
const recorded = port(event);
|
|
1390
|
+
recorded.p = progress;
|
|
1391
|
+
target.dispatchEvent(event);
|
|
1392
|
+
answered?.(recorded.a !== void 0);
|
|
1393
|
+
try {
|
|
1394
|
+
return recorded.a === void 0 ? null : await settle(recorded.a[0], signal);
|
|
1395
|
+
} finally {
|
|
1396
|
+
recorded.p = void 0;
|
|
1326
1397
|
}
|
|
1327
|
-
return settle(answer, signal).then((value) => value ?? null).finally(() => {
|
|
1328
|
-
event.report = void 0;
|
|
1329
|
-
});
|
|
1330
1398
|
}
|
|
1331
|
-
|
|
1399
|
+
//#endregion
|
|
1400
|
+
//#region src/editor/requests.ts
|
|
1332
1401
|
/** Answers a request event with a responder function, as an HTML Next framework function prop does. */
|
|
1333
1402
|
function respondWithFunction(event, responder) {
|
|
1334
1403
|
const request = event;
|
|
@@ -1338,8 +1407,8 @@ function respondWithFunction(event, responder) {
|
|
|
1338
1407
|
}));
|
|
1339
1408
|
}
|
|
1340
1409
|
/**
|
|
1341
|
-
* Calls `callback` with the request name when a responder announces itself, as
|
|
1342
|
-
* `respond()` does, on `root`, one of its ancestors, or the document.
|
|
1410
|
+
* Calls `callback` with the request name when a responder announces itself, as
|
|
1411
|
+
* `RequestEvent.respond()` does, on `root`, one of its ancestors, or the document.
|
|
1343
1412
|
*
|
|
1344
1413
|
* @lifecycle Listens on the document until the returned function is called.
|
|
1345
1414
|
*/
|
|
@@ -1810,6 +1879,45 @@ function selectionActionDetail(state, id) {
|
|
|
1810
1879
|
after: doc.textBetween(to, Math.min(doc.content.size, to + CONTEXT), "\n")
|
|
1811
1880
|
};
|
|
1812
1881
|
}
|
|
1882
|
+
/** Whether a viewport this wide gets the editing dock rather than floating tools. */
|
|
1883
|
+
var usesMobileDock = (viewportWidth) => viewportWidth <= 767;
|
|
1884
|
+
/**
|
|
1885
|
+
* Where the dock sits: across the visual viewport, against its bottom edge, so an on-screen keyboard
|
|
1886
|
+
* pushes it up. It never rises above the viewport's top.
|
|
1887
|
+
*/
|
|
1888
|
+
function mobileDockPlacement(viewport, dockHeight) {
|
|
1889
|
+
return {
|
|
1890
|
+
left: viewport.left,
|
|
1891
|
+
top: Math.max(viewport.top, viewport.bottom - dockHeight),
|
|
1892
|
+
width: viewport.width
|
|
1893
|
+
};
|
|
1894
|
+
}
|
|
1895
|
+
/** Calls `onChange` with the new mode whenever it changes. */
|
|
1896
|
+
function createMobileDock(onChange) {
|
|
1897
|
+
let mode = "formatting";
|
|
1898
|
+
let formattingChosen = false;
|
|
1899
|
+
const set = (next) => {
|
|
1900
|
+
if (next === mode) return;
|
|
1901
|
+
mode = next;
|
|
1902
|
+
onChange(mode);
|
|
1903
|
+
};
|
|
1904
|
+
return {
|
|
1905
|
+
get mode() {
|
|
1906
|
+
return mode;
|
|
1907
|
+
},
|
|
1908
|
+
tableActive() {
|
|
1909
|
+
if (!formattingChosen) set("table");
|
|
1910
|
+
},
|
|
1911
|
+
showFormatting() {
|
|
1912
|
+
formattingChosen = true;
|
|
1913
|
+
set("formatting");
|
|
1914
|
+
},
|
|
1915
|
+
tableInactive() {
|
|
1916
|
+
formattingChosen = false;
|
|
1917
|
+
set("formatting");
|
|
1918
|
+
}
|
|
1919
|
+
};
|
|
1920
|
+
}
|
|
1813
1921
|
//#endregion
|
|
1814
1922
|
//#region src/editor/extensions/relative-links.ts
|
|
1815
1923
|
/** Keep other origins and non-web schemes intact; same-origin links retain path, query, and fragment. */
|
|
@@ -3508,7 +3616,7 @@ var LoomaEditor = defineComponent({
|
|
|
3508
3616
|
});
|
|
3509
3617
|
const tablePickerOpen = ref(false);
|
|
3510
3618
|
const mobileToolbarStyle = ref({});
|
|
3511
|
-
const mobile = ref(typeof window !== "undefined" && window.innerWidth
|
|
3619
|
+
const mobile = ref(typeof window !== "undefined" && usesMobileDock(window.innerWidth));
|
|
3512
3620
|
const editorFocused = ref(false);
|
|
3513
3621
|
let formatting;
|
|
3514
3622
|
let formattingPopup = null;
|
|
@@ -3520,10 +3628,12 @@ var LoomaEditor = defineComponent({
|
|
|
3520
3628
|
const formattingActive = () => formatting?.active() ?? false;
|
|
3521
3629
|
const editorStateVersion = ref(0);
|
|
3522
3630
|
const mobileToolbarMode = ref("formatting");
|
|
3631
|
+
const mobileDock = createMobileDock((mode) => {
|
|
3632
|
+
mobileToolbarMode.value = mode;
|
|
3633
|
+
});
|
|
3523
3634
|
let dragLeaveTimer = null;
|
|
3524
3635
|
let tableResizeActive = false;
|
|
3525
3636
|
let tableInteractionActive = false;
|
|
3526
|
-
let mobileTableControlsDismissed = false;
|
|
3527
3637
|
let hoveredTableCell = null;
|
|
3528
3638
|
let overlayTableElement = null;
|
|
3529
3639
|
let tablePointerFrame = null;
|
|
@@ -3573,16 +3683,17 @@ var LoomaEditor = defineComponent({
|
|
|
3573
3683
|
chipEditing?.close();
|
|
3574
3684
|
if (focusChip) element?.focus();
|
|
3575
3685
|
};
|
|
3576
|
-
const
|
|
3686
|
+
const responderVersion = ref(0);
|
|
3577
3687
|
const answers = (name) => {
|
|
3688
|
+
responderVersion.value;
|
|
3578
3689
|
const prop = EDITOR_REQUESTS[name];
|
|
3579
|
-
return typeof props[prop] === "function" || attrs[`on${prop[0].toUpperCase()}${prop.slice(1)}`] != null ||
|
|
3690
|
+
return typeof props[prop] === "function" || attrs[`on${prop[0].toUpperCase()}${prop.slice(1)}`] != null || root.value !== null && RequestEvent.hasResponder(root.value, name);
|
|
3580
3691
|
};
|
|
3581
3692
|
const connection = new AbortController();
|
|
3582
3693
|
const ask = (name, detail, options = {}) => {
|
|
3583
|
-
if (!root.value || connection.signal.aborted) return null;
|
|
3694
|
+
if (!root.value || connection.signal.aborted) return Promise.resolve(null);
|
|
3584
3695
|
const signal = options.signal ? AbortSignal.any([options.signal, connection.signal]) : connection.signal;
|
|
3585
|
-
return
|
|
3696
|
+
return RequestEvent.request(root.value, name, detail, {
|
|
3586
3697
|
...options,
|
|
3587
3698
|
signal
|
|
3588
3699
|
});
|
|
@@ -3596,10 +3707,12 @@ var LoomaEditor = defineComponent({
|
|
|
3596
3707
|
};
|
|
3597
3708
|
const askThen = (name, detail, apply) => {
|
|
3598
3709
|
const answer = askLatest(name, detail);
|
|
3599
|
-
if (!(answer instanceof Promise)) return apply(answer);
|
|
3600
3710
|
const controller = latest.get(name);
|
|
3601
|
-
|
|
3602
|
-
|
|
3711
|
+
const current = () => controller === latest.get(name) && !connection.signal.aborted;
|
|
3712
|
+
answer.then((value) => {
|
|
3713
|
+
if (current()) apply(value);
|
|
3714
|
+
}, (error) => {
|
|
3715
|
+
if (!current()) return;
|
|
3603
3716
|
reportError(error);
|
|
3604
3717
|
apply(null);
|
|
3605
3718
|
});
|
|
@@ -3794,14 +3907,7 @@ var LoomaEditor = defineComponent({
|
|
|
3794
3907
|
chipEditing = chips;
|
|
3795
3908
|
const imageUploads = createImageUploads({
|
|
3796
3909
|
editor: session.editor,
|
|
3797
|
-
upload: () =>
|
|
3798
|
-
const image = await ask("image-upload", { file }, init);
|
|
3799
|
-
if (image && !found.has("image-upload")) {
|
|
3800
|
-
found.add("image-upload");
|
|
3801
|
-
checkResponders();
|
|
3802
|
-
}
|
|
3803
|
-
return image;
|
|
3804
|
-
},
|
|
3910
|
+
upload: () => (file, init) => ask("image-upload", { file }, init),
|
|
3805
3911
|
onError: (error, file) => emit("uploadError", error, file)
|
|
3806
3912
|
});
|
|
3807
3913
|
imageUploads.subscribe(() => {
|
|
@@ -3838,9 +3944,10 @@ var LoomaEditor = defineComponent({
|
|
|
3838
3944
|
}, { capture: true });
|
|
3839
3945
|
stopAnnouncements = onResponderAnnounced(element, (name) => {
|
|
3840
3946
|
if (!(name in EDITOR_REQUESTS)) return;
|
|
3841
|
-
|
|
3947
|
+
responderVersion.value += 1;
|
|
3842
3948
|
checkResponders();
|
|
3843
3949
|
});
|
|
3950
|
+
responderVersion.value += 1;
|
|
3844
3951
|
responders = new Set(EDITOR_REQUEST_NAMES.filter(answers));
|
|
3845
3952
|
askExtensions();
|
|
3846
3953
|
askSlashCommands();
|
|
@@ -3993,22 +4100,20 @@ var LoomaEditor = defineComponent({
|
|
|
3993
4100
|
tableUi.geometry = null;
|
|
3994
4101
|
tableUi.capabilities = { ...EMPTY_CAPABILITIES };
|
|
3995
4102
|
overlayTableElement = null;
|
|
3996
|
-
|
|
3997
|
-
mobileToolbarMode.value = "formatting";
|
|
4103
|
+
mobileDock.tableInactive();
|
|
3998
4104
|
};
|
|
3999
4105
|
const updateMobileViewport = () => {
|
|
4000
|
-
mobile.value = window.innerWidth
|
|
4106
|
+
mobile.value = usesMobileDock(window.innerWidth);
|
|
4001
4107
|
if (!mobile.value) {
|
|
4002
4108
|
mobileToolbarStyle.value = {};
|
|
4003
4109
|
return;
|
|
4004
4110
|
}
|
|
4005
4111
|
nextTick(() => {
|
|
4006
|
-
const
|
|
4007
|
-
const toolbarHeight = mobileToolbarShell.value?.getBoundingClientRect().height || 56;
|
|
4112
|
+
const placement = mobileDockPlacement(getVisualViewportRect(window), mobileToolbarShell.value?.getBoundingClientRect().height || 56);
|
|
4008
4113
|
mobileToolbarStyle.value = {
|
|
4009
|
-
left: `${
|
|
4010
|
-
top: `${
|
|
4011
|
-
width: `${
|
|
4114
|
+
left: `${placement.left}px`,
|
|
4115
|
+
top: `${placement.top}px`,
|
|
4116
|
+
width: `${placement.width}px`
|
|
4012
4117
|
};
|
|
4013
4118
|
});
|
|
4014
4119
|
};
|
|
@@ -4098,7 +4203,7 @@ var LoomaEditor = defineComponent({
|
|
|
4098
4203
|
}
|
|
4099
4204
|
const selectedTableIsActive = state.active && selectedTable === table;
|
|
4100
4205
|
overlayTableElement = table;
|
|
4101
|
-
if (selectedTableIsActive
|
|
4206
|
+
if (selectedTableIsActive) mobileDock.tableActive();
|
|
4102
4207
|
const rect = table.getBoundingClientRect();
|
|
4103
4208
|
const maxToolbarWidth = Math.min(420, window.innerWidth - 24);
|
|
4104
4209
|
const toolbarLeft = Math.min(Math.max(12, rect.left + (rect.width - maxToolbarWidth) / 2), Math.max(12, window.innerWidth - maxToolbarWidth - 12));
|
|
@@ -4853,8 +4958,7 @@ var LoomaEditor = defineComponent({
|
|
|
4853
4958
|
type: "button",
|
|
4854
4959
|
"aria-label": "Formatting tools",
|
|
4855
4960
|
onClick: () => {
|
|
4856
|
-
|
|
4857
|
-
mobileToolbarMode.value = "formatting";
|
|
4961
|
+
mobileDock.showFormatting();
|
|
4858
4962
|
editor.value?.commands.focus();
|
|
4859
4963
|
nextTick(updateMobileViewport);
|
|
4860
4964
|
}
|
package/vue/host.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Generated by HTML Next 1.0.0-alpha.
|
|
1
|
+
// Generated by HTML Next 1.0.0-alpha.55 for Vue 3.5. Do not edit.
|
|
2
2
|
import {
|
|
3
3
|
computed,
|
|
4
4
|
createTextVNode,
|
|
@@ -206,6 +206,8 @@ const requestStateKey = Symbol.for('@nextwebwg/html-next.runtime.v1')
|
|
|
206
206
|
type DocumentRecord = {
|
|
207
207
|
requests?: { readonly g: WeakMap<Node, Promise<void>> }
|
|
208
208
|
relay?: (from: Node, name: string) => void
|
|
209
|
+
k?: WeakMap<EventTarget, string[]>
|
|
210
|
+
w?: Set<(name: string) => void>
|
|
209
211
|
}
|
|
210
212
|
const documentRecord = (root: Element): DocumentRecord =>
|
|
211
213
|
(root.ownerDocument as unknown as Record<symbol, DocumentRecord>)[requestStateKey] ??= {}
|
|
@@ -229,6 +231,28 @@ function relayResponders(root: Element, name: string): void {
|
|
|
229
231
|
documentRecord(root).relay?.(root, name)
|
|
230
232
|
}
|
|
231
233
|
|
|
234
|
+
/** Records a responder hasResponder can see on root until the returned function runs; own lists its controller's. */
|
|
235
|
+
function knownResponder(root: Element, name: string, own?: string[]): () => void {
|
|
236
|
+
const record = documentRecord(root)
|
|
237
|
+
const known = record.k ??= new WeakMap()
|
|
238
|
+
const names = known.get(root) ?? known.set(root, []).get(root)!
|
|
239
|
+
const change = (add: boolean): void => {
|
|
240
|
+
for (const list of own === undefined ? [names] : [names, own]) {
|
|
241
|
+
if (add) list.push(name)
|
|
242
|
+
else list.splice(list.indexOf(name), 1)
|
|
243
|
+
}
|
|
244
|
+
record.w?.forEach((changed) => changed(name))
|
|
245
|
+
}
|
|
246
|
+
change(true)
|
|
247
|
+
let held = true
|
|
248
|
+
return () => {
|
|
249
|
+
if (held) {
|
|
250
|
+
held = false
|
|
251
|
+
change(false)
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
232
256
|
/** For a component that asks: a responder announcement reaches its controller only as the relay to its root, which does not bubble. */
|
|
233
257
|
function hostListener(type: string, callback: (event: Event) => unknown): (event: Event) => void {
|
|
234
258
|
return (event) => {
|
|
@@ -538,14 +562,16 @@ export interface ComponentHostOptions {
|
|
|
538
562
|
/** Each named declared script, which a controller reads as `host.scripts`. */
|
|
539
563
|
readonly scripts?: Readonly<Record<string, unknown>>
|
|
540
564
|
readonly acceptsState?: (name: string, keys: readonly string[], value: unknown) => boolean
|
|
541
|
-
/** Asks one of the component's declared requests. */
|
|
542
|
-
request
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
565
|
+
/** Asks one of the component's declared requests; its `has` builds `host.hasResponder`. */
|
|
566
|
+
readonly request?:
|
|
567
|
+
& ((
|
|
568
|
+
root: Element,
|
|
569
|
+
connection: AbortSignal,
|
|
570
|
+
name: string,
|
|
571
|
+
detail?: unknown,
|
|
572
|
+
options?: any,
|
|
573
|
+
) => Promise<unknown>)
|
|
574
|
+
& { readonly has?: (host: any, own: string[]) => (name: string) => boolean }
|
|
549
575
|
/** Each declared request's responder, from its function prop or event form, read when the request arrives. */
|
|
550
576
|
readonly responders?: Readonly<Record<string, () => ((event: Event) => void) | undefined>>
|
|
551
577
|
}
|
|
@@ -632,20 +658,30 @@ export function useComponentHost(
|
|
|
632
658
|
const stops: Array<() => void> = []
|
|
633
659
|
const connected = shallowRef(false)
|
|
634
660
|
const pauses = new Map<() => void, () => void>()
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
661
|
+
// A subscription's known responder (k), and for a request's function prop or event form whether one is set (r).
|
|
662
|
+
const subscriptions = new Set<{
|
|
663
|
+
type: string
|
|
664
|
+
callback: (event: Event) => void | (() => void)
|
|
665
|
+
target?: Element | undefined
|
|
666
|
+
cleanup?: void | (() => void)
|
|
667
|
+
k?: (() => void) | undefined
|
|
668
|
+
r?: () => boolean
|
|
669
|
+
}>()
|
|
643
670
|
type Subscription = typeof subscriptions extends Set<infer S> ? S : never
|
|
671
|
+
// How many known responders the controller's host.on keeps on its own root, by name.
|
|
672
|
+
const own: string[] = []
|
|
673
|
+
const track = (entry: Subscription): void => {
|
|
674
|
+
entry.k?.()
|
|
675
|
+
entry.k = entry.target === undefined || entry.r?.() === false
|
|
676
|
+
? undefined
|
|
677
|
+
: knownResponder(entry.target, entry.type, entry.r ? undefined : own)
|
|
678
|
+
}
|
|
644
679
|
const activate = (entry: Subscription): void => {
|
|
645
680
|
if (entry.type === 'connect') entry.cleanup = entry.callback(new Event('connect'))
|
|
646
681
|
else if (entry.type !== 'disconnect') {
|
|
647
682
|
entry.target = root.value ?? undefined
|
|
648
683
|
entry.target?.addEventListener(entry.type, entry.callback as EventListener)
|
|
684
|
+
track(entry)
|
|
649
685
|
// A responder registered after a request went unanswered tells the asker to ask again.
|
|
650
686
|
if (entry.target !== undefined) relayResponders(entry.target, entry.type)
|
|
651
687
|
}
|
|
@@ -653,6 +689,7 @@ export function useComponentHost(
|
|
|
653
689
|
const deactivate = (entry: Subscription, disconnecting: boolean): void => {
|
|
654
690
|
entry.target?.removeEventListener(entry.type, entry.callback as EventListener)
|
|
655
691
|
entry.target = undefined
|
|
692
|
+
track(entry)
|
|
656
693
|
const cleanup = entry.cleanup
|
|
657
694
|
entry.cleanup = undefined
|
|
658
695
|
cleanup?.()
|
|
@@ -704,17 +741,7 @@ export function useComponentHost(
|
|
|
704
741
|
}, options.controllerSource?.definition ?? '<component>'),
|
|
705
742
|
scripts: options.scripts ?? Object.freeze({}),
|
|
706
743
|
on(type: string, callback: (event: Event) => void | (() => void)): () => void {
|
|
707
|
-
|
|
708
|
-
type,
|
|
709
|
-
callback: type === 'connect' || type === 'disconnect' || options.request === undefined
|
|
710
|
-
? callback
|
|
711
|
-
: hostListener(type, callback),
|
|
712
|
-
}
|
|
713
|
-
subscriptions.add(entry)
|
|
714
|
-
if (connected.value) activate(entry)
|
|
715
|
-
return () => {
|
|
716
|
-
if (subscriptions.delete(entry)) deactivate(entry, false)
|
|
717
|
-
}
|
|
744
|
+
return listen(type, callback)
|
|
718
745
|
},
|
|
719
746
|
props: Object.freeze(propHandles),
|
|
720
747
|
refs: Object.defineProperties(
|
|
@@ -787,13 +814,39 @@ export function useComponentHost(
|
|
|
787
814
|
),
|
|
788
815
|
}),
|
|
789
816
|
}
|
|
817
|
+
function listen(
|
|
818
|
+
type: string,
|
|
819
|
+
callback: (event: Event) => void | (() => void),
|
|
820
|
+
set?: () => boolean,
|
|
821
|
+
): () => void {
|
|
822
|
+
const entry: Subscription = {
|
|
823
|
+
type,
|
|
824
|
+
callback: type === 'connect' || type === 'disconnect' || options.request === undefined
|
|
825
|
+
? callback
|
|
826
|
+
: hostListener(type, callback),
|
|
827
|
+
}
|
|
828
|
+
if (set !== undefined) entry.r = set
|
|
829
|
+
subscriptions.add(entry)
|
|
830
|
+
if (connected.value) activate(entry)
|
|
831
|
+
return () => {
|
|
832
|
+
if (subscriptions.delete(entry)) deactivate(entry, false)
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
if (options.request?.has !== undefined) {
|
|
836
|
+
Object.assign(host, { hasResponder: options.request.has(host, own) })
|
|
837
|
+
}
|
|
790
838
|
const requests = requestConnection()
|
|
791
839
|
// Each request's responder listens on the root from its first connection, before the controller runs.
|
|
792
840
|
const responders = Object.entries(options.responders ?? {})
|
|
793
|
-
for (const [name, read] of responders)
|
|
794
|
-
|
|
841
|
+
for (const [name, read] of responders) {
|
|
842
|
+
listen(name, (event) =>
|
|
843
|
+
read()?.(event), () =>
|
|
844
|
+
read() !== undefined)
|
|
845
|
+
}
|
|
846
|
+
// A function prop or event form set later is a known responder, and relays for its request, as a late host.on does.
|
|
795
847
|
if (responders.length > 0) {
|
|
796
848
|
watch(() => responders.map(([, read]) => read() !== undefined), (now, before) => {
|
|
849
|
+
for (const entry of subscriptions) if (entry.r !== undefined) track(entry)
|
|
797
850
|
const element = root.value
|
|
798
851
|
if (element === null || !connected.value) return
|
|
799
852
|
now.forEach((set, index) => {
|