@astryxdesign/core 0.6.2 → 0.6.3-canary.0899f21
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/CHANGELOG.md +81 -0
- package/dist/BottomSheet/BottomSheet.d.ts +1 -1
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +3 -1
- package/dist/BottomSheet/BottomSheetPanel.d.ts +7 -5
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +56 -19
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +13 -28
- package/dist/Chat/ChatComposer.d.ts.map +1 -1
- package/dist/Chat/ChatComposer.js +10 -5
- package/dist/Chat/ChatComposerDrawer.d.ts +19 -5
- package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
- package/dist/Chat/ChatComposerDrawer.js +48 -23
- package/dist/Chat/ChatComposerInput.d.ts +11 -3
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +63 -16
- package/dist/Chat/ChatDictationButton.d.ts +3 -2
- package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
- package/dist/Chat/ChatDictationButton.js +6 -4
- package/dist/Chat/ChatLayout.d.ts +19 -0
- package/dist/Chat/ChatLayout.d.ts.map +1 -1
- package/dist/Chat/ChatLayout.js +19 -0
- package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
- package/dist/Chat/ChatLayoutScrollButton.js +44 -34
- package/dist/Chat/ChatMessageBubble.d.ts +2 -0
- package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
- package/dist/Chat/ChatMessageBubble.js +5 -3
- package/dist/Chat/ChatMessageList.d.ts +2 -1
- package/dist/Chat/ChatMessageList.d.ts.map +1 -1
- package/dist/Chat/ChatMessageList.js +4 -3
- package/dist/Chat/ChatMessageMetadata.d.ts +5 -4
- package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
- package/dist/Chat/ChatMessageMetadata.js +12 -9
- package/dist/Chat/ChatSendButton.js +1 -1
- package/dist/Chat/index.d.ts +1 -1
- package/dist/Chat/index.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +12 -2
- package/dist/Citation/Citation.d.ts +1 -1
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +3 -2
- package/dist/CodeBlock/highlightRanges.d.ts.map +1 -1
- package/dist/CodeBlock/highlightRanges.js +14 -3
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +6 -1
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +1 -1
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +1 -1
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +4 -4
- package/dist/DateInput/NativeDateField.d.ts.map +1 -1
- package/dist/DateInput/NativeDateField.js +16 -16
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +2 -2
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +4 -4
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +8 -8
- package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
- package/dist/DateTimeInput/TouchDateTimeField.js +4 -4
- package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +9 -3
- package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -1
- package/dist/DateTimeInput/nativePickerSegmentStyles.js +3 -3
- package/dist/Dialog/DialogHeader.d.ts +8 -1
- package/dist/Dialog/DialogHeader.d.ts.map +1 -1
- package/dist/Dialog/DialogHeader.js +13 -4
- package/dist/Field/InputClearButton.d.ts +4 -2
- package/dist/Field/InputClearButton.d.ts.map +1 -1
- package/dist/Field/InputClearButton.js +4 -2
- package/dist/Field/PanelSearchInput.d.ts.map +1 -1
- package/dist/Field/PanelSearchInput.js +1 -1
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +7 -7
- package/dist/Icon/Icon.d.ts +6 -31
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +8 -71
- package/dist/Icon/IconDefaultSizeContext.d.ts +4 -0
- package/dist/Icon/IconDefaultSizeContext.d.ts.map +1 -0
- package/dist/Icon/IconDefaultSizeContext.js +18 -0
- package/dist/Icon/IconSize.stylex.d.ts +65 -0
- package/dist/Icon/IconSize.stylex.d.ts.map +1 -0
- package/dist/Icon/IconSize.stylex.js +75 -0
- package/dist/Item/Item.d.ts +1 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +4 -3
- package/dist/Kbd/Kbd.d.ts +5 -3
- package/dist/Kbd/Kbd.d.ts.map +1 -1
- package/dist/Kbd/Kbd.js +36 -42
- package/dist/Link/Link.d.ts.map +1 -1
- package/dist/Link/Link.js +6 -2
- package/dist/Link/useLinkComponent.d.ts +5 -15
- package/dist/Link/useLinkComponent.d.ts.map +1 -1
- package/dist/Link/useLinkComponent.js +34 -51
- package/dist/List/List.d.ts +19 -1
- package/dist/List/List.d.ts.map +1 -1
- package/dist/List/List.js +9 -2
- package/dist/List/ListContext.d.ts +1 -0
- package/dist/List/ListContext.d.ts.map +1 -1
- package/dist/List/ListContext.js +2 -1
- package/dist/List/ListItem.d.ts +1 -1
- package/dist/List/ListItem.d.ts.map +1 -1
- package/dist/List/ListItem.js +9 -2
- package/dist/Markdown/Markdown.d.ts +8 -2
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.fr23.bench.d.ts +2 -0
- package/dist/Markdown/Markdown.fr23.bench.d.ts.map +1 -0
- package/dist/Markdown/Markdown.fr23.bench.js +150 -0
- package/dist/Markdown/Markdown.fr23.sampling.d.ts +2 -0
- package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -0
- package/dist/Markdown/Markdown.fr23.sampling.js +43 -0
- package/dist/Markdown/Markdown.js +262 -109
- package/dist/Markdown/ast.d.ts +162 -0
- package/dist/Markdown/ast.d.ts.map +1 -0
- package/dist/Markdown/ast.js +74 -0
- package/dist/Markdown/index.d.ts +5 -3
- package/dist/Markdown/index.d.ts.map +1 -1
- package/dist/Markdown/index.js +3 -2
- package/dist/Markdown/parser/index.d.ts +10 -0
- package/dist/Markdown/parser/index.d.ts.map +1 -0
- package/dist/Markdown/parser/index.js +10 -0
- package/dist/Markdown/parser.d.ts +126 -58
- package/dist/Markdown/parser.d.ts.map +1 -1
- package/dist/Markdown/parser.js +716 -167
- package/dist/Markdown/plugins/frontmatter.d.ts +32 -0
- package/dist/Markdown/plugins/frontmatter.d.ts.map +1 -0
- package/dist/Markdown/plugins/frontmatter.js +132 -0
- package/dist/Markdown/plugins/index.d.ts +17 -0
- package/dist/Markdown/plugins/index.d.ts.map +1 -0
- package/dist/Markdown/plugins/index.js +14 -0
- package/dist/Markdown/plugins/protocol.d.ts +191 -0
- package/dist/Markdown/plugins/protocol.d.ts.map +1 -0
- package/dist/Markdown/plugins/protocol.js +957 -0
- package/dist/Markdown/plugins/semanticFence.d.ts +36 -0
- package/dist/Markdown/plugins/semanticFence.d.ts.map +1 -0
- package/dist/Markdown/plugins/semanticFence.js +213 -0
- package/dist/Markdown/plugins/softBreaks.d.ts +3 -0
- package/dist/Markdown/plugins/softBreaks.d.ts.map +1 -0
- package/dist/Markdown/plugins/softBreaks.js +172 -0
- package/dist/Markdown/plugins/sourceDecoration.d.ts +76 -0
- package/dist/Markdown/plugins/sourceDecoration.d.ts.map +1 -0
- package/dist/Markdown/plugins/sourceDecoration.js +393 -0
- package/dist/Markdown/plugins/textTransform.d.ts +30 -0
- package/dist/Markdown/plugins/textTransform.d.ts.map +1 -0
- package/dist/Markdown/plugins/textTransform.js +374 -0
- package/dist/Markdown/remark.d.ts +196 -0
- package/dist/Markdown/remark.d.ts.map +1 -0
- package/dist/Markdown/remark.js +1062 -0
- package/dist/Markdown/url.d.ts +6 -0
- package/dist/Markdown/url.d.ts.map +1 -0
- package/dist/Markdown/url.js +31 -0
- package/dist/Markdown/utils.d.ts +4 -2
- package/dist/Markdown/utils.d.ts.map +1 -1
- package/dist/Markdown/utils.js +2 -1
- package/dist/MetadataList/MetadataList.js +3 -3
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +4 -4
- package/dist/Outline/index.d.ts +1 -0
- package/dist/Outline/index.d.ts.map +1 -1
- package/dist/Outline/parseOutlineFromMarkdown.d.ts +7 -1
- package/dist/Outline/parseOutlineFromMarkdown.d.ts.map +1 -1
- package/dist/Outline/parseOutlineFromMarkdown.js +14 -8
- package/dist/Outline/useOutlineFromMarkdown.d.ts +3 -1
- package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
- package/dist/Outline/useOutlineFromMarkdown.js +8 -3
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchEditPopover.js +46 -30
- package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchValueEditor.js +5 -0
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +36 -31
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +13 -1
- package/dist/ScrollableArea/ScrollableArea.d.ts +1 -0
- package/dist/ScrollableArea/ScrollableArea.d.ts.map +1 -1
- package/dist/ScrollableArea/ScrollableArea.js +1 -0
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +5 -5
- package/dist/Selector/Selector.d.ts +9 -7
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +16 -7
- package/dist/SideNav/SideNav.d.ts +2 -1
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +9 -3
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +28 -12
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +23 -7
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +11 -0
- package/dist/TabList/Tab.d.ts +1 -1
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +20 -7
- package/dist/Table/Table.d.ts +1 -0
- package/dist/Table/Table.d.ts.map +1 -1
- package/dist/Table/Table.js +29 -13
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +1 -1
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +2 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +4 -4
- package/dist/Timer/Timer.d.ts +49 -0
- package/dist/Timer/Timer.d.ts.map +1 -0
- package/dist/Timer/Timer.js +158 -0
- package/dist/Timer/index.d.ts +9 -0
- package/dist/Timer/index.d.ts.map +1 -0
- package/dist/Timer/index.js +10 -0
- package/dist/ToggleButton/ToggleButton.d.ts +9 -6
- package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
- package/dist/ToggleButton/ToggleButton.js +15 -27
- package/dist/TopNav/TopNavMenu.d.ts +1 -1
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +3 -2
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +3 -0
- package/dist/TreeList/TreeListItem.d.ts +6 -1
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +12 -2
- package/dist/TreeList/TreeListTypes.d.ts +8 -1
- package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +16 -7
- package/dist/astryx.css +27 -11
- package/dist/hooks/scrollKeyboardDelegation.d.ts +3 -0
- package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -0
- package/dist/hooks/scrollKeyboardDelegation.js +146 -0
- package/dist/hooks/useClickableContainer.d.ts +10 -1
- package/dist/hooks/useClickableContainer.d.ts.map +1 -1
- package/dist/hooks/useClickableContainer.js +15 -4
- package/dist/hooks/useScrollableArea.d.ts +6 -2
- package/dist/hooks/useScrollableArea.d.ts.map +1 -1
- package/dist/hooks/useScrollableArea.js +17 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/theme/declarationBoundary.d.ts +17 -0
- package/dist/theme/declarationBoundary.d.ts.map +1 -0
- package/dist/theme/declarationBoundary.js +343 -0
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +4 -0
- package/dist/theme/generateThemeRules.d.ts +13 -7
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +140 -34
- package/dist/utils/interactionOverlay.stylex.d.ts +8 -0
- package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
- package/dist/utils/interactionOverlay.stylex.js +9 -0
- package/dist/utils/safeUrl.d.ts +11 -0
- package/dist/utils/safeUrl.d.ts.map +1 -0
- package/dist/utils/safeUrl.js +78 -0
- package/locales/af-ZA.json +530 -1
- package/locales/ar-SA.json +490 -1
- package/locales/ca-ES.json +514 -1
- package/locales/cs-CZ.json +498 -1
- package/locales/da-DK.json +522 -1
- package/locales/de-DE.json +522 -1
- package/locales/el-GR.json +498 -1
- package/locales/es-ES.json +510 -1
- package/locales/fi-FI.json +498 -1
- package/locales/fr-FR.json +534 -1
- package/locales/he-IL.json +498 -1
- package/locales/hu-HU.json +498 -1
- package/locales/it-IT.json +510 -1
- package/locales/ja-JP.json +490 -1
- package/locales/ko-KR.json +498 -1
- package/locales/nl-NL.json +534 -1
- package/locales/no-NO.json +510 -1
- package/locales/pl-PL.json +506 -1
- package/locales/pt-BR.json +506 -1
- package/locales/pt-PT.json +506 -1
- package/locales/ro-RO.json +506 -1
- package/locales/ru-RU.json +498 -1
- package/locales/sr-SP.json +498 -1
- package/locales/sv-SE.json +502 -1
- package/locales/tr-TR.json +498 -1
- package/locales/uk-UA.json +498 -1
- package/locales/vi-VN.json +502 -1
- package/locales/zh-CN.json +490 -1
- package/locales/zh-TW.json +490 -1
- package/package.json +24 -4
- package/src/BottomSheet/BottomSheet.doc.mjs +8 -1
- package/src/BottomSheet/BottomSheet.spec.md +46 -20
- package/src/BottomSheet/BottomSheet.test.tsx +6 -3
- package/src/BottomSheet/BottomSheet.tsx +3 -1
- package/src/BottomSheet/BottomSheetKeyboard.test.tsx +195 -0
- package/src/BottomSheet/BottomSheetPanel.test.tsx +11 -1
- package/src/BottomSheet/BottomSheetPanel.tsx +49 -16
- package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +344 -0
- package/src/Button/Button.doc.mjs +5 -5
- package/src/Button/Button.tsx +15 -13
- package/src/Button/__tests__/Button.a11y.chromium.spec.ts +17 -1
- package/src/Button/__tests__/Button.a11y.known-failures.ts +0 -29
- package/src/Button/__tests__/Button.a11y.renders.tsx +9 -2
- package/src/Button/__tests__/Button.a11y.states.ts +9 -0
- package/src/Chat/ChatComposer.doc.mjs +14 -0
- package/src/Chat/ChatComposer.spec.md +230 -0
- package/src/Chat/ChatComposer.test.tsx +57 -0
- package/src/Chat/ChatComposer.tsx +21 -9
- package/src/Chat/ChatComposerDrawer.doc.mjs +63 -5
- package/src/Chat/ChatComposerDrawer.spec.md +267 -0
- package/src/Chat/ChatComposerDrawer.test.tsx +81 -12
- package/src/Chat/ChatComposerDrawer.tsx +38 -9
- package/src/Chat/ChatComposerInput.doc.mjs +114 -26
- package/src/Chat/ChatComposerInput.spec.md +185 -0
- package/src/Chat/ChatComposerInput.test.tsx +113 -3
- package/src/Chat/ChatComposerInput.tsx +78 -13
- package/src/Chat/ChatComposerTokenElement.spec.md +152 -0
- package/src/Chat/ChatComposerTokenElement.test.tsx +85 -0
- package/src/Chat/ChatDictationButton.doc.mjs +3 -3
- package/src/Chat/ChatDictationButton.spec.md +160 -0
- package/src/Chat/ChatDictationButton.test.tsx +92 -27
- package/src/Chat/ChatDictationButton.tsx +8 -6
- package/src/Chat/ChatLayout.doc.mjs +12 -4
- package/src/Chat/ChatLayout.spec.md +271 -0
- package/src/Chat/ChatLayout.test.tsx +28 -0
- package/src/Chat/ChatLayout.tsx +19 -0
- package/src/Chat/ChatLayoutScrollButton.spec.md +338 -0
- package/src/Chat/ChatLayoutScrollButton.test.tsx +31 -0
- package/src/Chat/ChatLayoutScrollButton.tsx +31 -14
- package/src/Chat/ChatMessageBubble.doc.mjs +28 -15
- package/src/Chat/ChatMessageBubble.spec.md +263 -0
- package/src/Chat/ChatMessageBubble.test.tsx +93 -0
- package/src/Chat/ChatMessageBubble.tsx +8 -3
- package/src/Chat/ChatMessageList.spec.md +222 -0
- package/src/Chat/ChatMessageList.test.tsx +64 -2
- package/src/Chat/ChatMessageList.tsx +4 -3
- package/src/Chat/ChatMessageMetadata.doc.mjs +57 -3
- package/src/Chat/ChatMessageMetadata.spec.md +220 -0
- package/src/Chat/ChatMessageMetadata.test.tsx +34 -0
- package/src/Chat/ChatMessageMetadata.tsx +13 -13
- package/src/Chat/ChatSendButton.test.tsx +1 -4
- package/src/Chat/ChatSendButton.tsx +1 -1
- package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +514 -0
- package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +740 -0
- package/src/Chat/__tests__/ChatMessageBubble.a11y.chromium.spec.ts +457 -0
- package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.test.ts +91 -0
- package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.ts +91 -0
- package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +456 -0
- package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +413 -0
- package/src/Chat/index.ts +1 -0
- package/src/CheckboxInput/CheckboxInput.doc.mjs +11 -0
- package/src/CheckboxInput/CheckboxInput.test.tsx +34 -0
- package/src/CheckboxInput/CheckboxInput.tsx +21 -1
- package/src/Citation/Citation.doc.mjs +2 -2
- package/src/Citation/Citation.test.tsx +17 -0
- package/src/Citation/Citation.tsx +4 -2
- package/src/ClickableCard/ClickableCard.doc.mjs +2 -2
- package/src/ClickableCard/ClickableCard.test.tsx +102 -5
- package/src/CodeBlock/highlightRanges.test.ts +143 -1
- package/src/CodeBlock/highlightRanges.ts +15 -5
- package/src/Collapsible/Collapsible.doc.mjs +11 -0
- package/src/Collapsible/Collapsible.test.tsx +21 -0
- package/src/Collapsible/Collapsible.tsx +5 -0
- package/src/CommandPalette/CommandPaletteInput.tsx +6 -1
- package/src/ComplexSelector/ComplexSelector.tsx +6 -1
- package/src/DateInput/DateInput.tsx +6 -1
- package/src/DateInput/NativeDateField.tsx +24 -8
- package/src/DateInput/TouchDateField.tsx +6 -2
- package/src/DateRangeInput/DateRangeInput.tsx +6 -1
- package/src/DateTimeInput/DateTimeInput.tsx +6 -1
- package/src/DateTimeInput/TouchDateTimeField.tsx +6 -1
- package/src/DateTimeInput/nativePickerSegmentStyles.ts +24 -8
- package/src/Dialog/Dialog.doc.mjs +2 -0
- package/src/Dialog/DialogHeader.doc.mjs +22 -0
- package/src/Dialog/DialogHeader.test.tsx +167 -3
- package/src/Dialog/DialogHeader.tsx +37 -6
- package/src/Dialog/modules/DialogHeader.spec.md +101 -42
- package/src/DropdownMenu/DropdownMenu.test.tsx +5 -2
- package/src/Field/InputClearButton.test.tsx +17 -3
- package/src/Field/InputClearButton.tsx +5 -2
- package/src/Field/PanelSearchInput.tsx +5 -2
- package/src/FieldStatus/__tests__/StatusMessage.a11y.states.ts +1 -1
- package/src/FileInput/FileInput.tsx +11 -2
- package/src/Icon/Icon.doc.mjs +7 -5
- package/src/Icon/Icon.spec.md +81 -40
- package/src/Icon/Icon.test.tsx +6 -3
- package/src/Icon/Icon.tsx +20 -68
- package/src/Icon/IconDefaultSizeContext.ts +23 -0
- package/src/Icon/IconSize.stylex.ts +70 -0
- package/src/IconButton/IconButton.doc.mjs +3 -3
- package/src/IconButton/IconButton.test.tsx +40 -0
- package/src/Item/Item.doc.mjs +6 -2
- package/src/Item/Item.tsx +9 -3
- package/src/Kbd/Kbd.doc.mjs +3 -3
- package/src/Kbd/Kbd.test.tsx +57 -1
- package/src/Kbd/Kbd.tsx +57 -37
- package/src/Layout/LayoutFooter.doc.mjs +17 -0
- package/src/Link/Link.doc.mjs +17 -4
- package/src/Link/Link.test.tsx +24 -0
- package/src/Link/Link.tsx +5 -0
- package/src/Link/LinkProvider.doc.mjs +2 -2
- package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +261 -0
- package/src/Link/useLinkComponent.test.tsx +333 -0
- package/src/Link/useLinkComponent.ts +29 -57
- package/src/List/List.doc.mjs +6 -0
- package/src/List/List.spec.md +200 -0
- package/src/List/List.test.tsx +117 -1
- package/src/List/List.tsx +22 -2
- package/src/List/ListContext.tsx +3 -1
- package/src/List/ListItem.doc.mjs +2 -2
- package/src/List/ListItem.source-build.test.mjs +41 -0
- package/src/List/ListItem.tsx +26 -2
- package/src/Markdown/Markdown.doc.mjs +300 -2
- package/src/Markdown/Markdown.fr23.bench.ts +174 -0
- package/src/Markdown/Markdown.fr23.perf.test.ts +249 -0
- package/src/Markdown/Markdown.fr23.sampling.ts +49 -0
- package/src/Markdown/Markdown.helpers.perf.test.ts +489 -0
- package/src/Markdown/Markdown.public.test.ts +130 -3
- package/src/Markdown/Markdown.renderBoundary.test.tsx +72 -0
- package/src/Markdown/Markdown.spec.md +203 -45
- package/src/Markdown/Markdown.test.tsx +63 -0
- package/src/Markdown/Markdown.tsx +414 -135
- package/src/Markdown/ast.test.ts +307 -0
- package/src/Markdown/ast.ts +337 -0
- package/src/Markdown/incremental.test.ts +12 -0
- package/src/Markdown/index.ts +37 -1
- package/src/Markdown/modules/remark.spec.md +269 -0
- package/src/Markdown/modules/softBreaks.spec.md +137 -0
- package/src/Markdown/parser/index.ts +64 -0
- package/src/Markdown/parser.public.test.ts +103 -0
- package/src/Markdown/parser.test.ts +20 -0
- package/src/Markdown/parser.ts +1180 -235
- package/src/Markdown/plugins/frontmatter.test.tsx +125 -0
- package/src/Markdown/plugins/frontmatter.ts +198 -0
- package/src/Markdown/plugins/index.ts +54 -0
- package/src/Markdown/plugins/protocol.test.tsx +1022 -0
- package/src/Markdown/plugins/protocol.ts +1618 -0
- package/src/Markdown/plugins/semanticFence.test.tsx +546 -0
- package/src/Markdown/plugins/semanticFence.ts +424 -0
- package/src/Markdown/plugins/softBreaks.test.tsx +172 -0
- package/src/Markdown/plugins/softBreaks.ts +169 -0
- package/src/Markdown/plugins/sourceDecoration.test.tsx +799 -0
- package/src/Markdown/plugins/sourceDecoration.ts +539 -0
- package/src/Markdown/plugins/textTransform.test.ts +467 -0
- package/src/Markdown/plugins/textTransform.ts +554 -0
- package/src/Markdown/remark.test.tsx +1877 -0
- package/src/Markdown/remark.ts +1574 -0
- package/src/Markdown/url.ts +36 -0
- package/src/Markdown/utils.ts +13 -1
- package/src/MetadataList/MetadataList.test.tsx +4 -2
- package/src/MetadataList/MetadataList.tsx +3 -3
- package/src/MultiSelector/MultiSelector.test.tsx +1 -35
- package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +128 -0
- package/src/NumberInput/NumberInput.tsx +6 -1
- package/src/Outline/Outline.doc.mjs +7 -5
- package/src/Outline/Outline.spec.md +1 -1
- package/src/Outline/index.ts +1 -0
- package/src/Outline/modules/parseOutlineFromMarkdown.spec.md +142 -0
- package/src/Outline/parseOutlineFromMarkdown.ts +40 -10
- package/src/Outline/useOutlineFromMarkdown.ts +15 -3
- package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
- package/src/PowerSearch/PowerSearchEditPopover.test.tsx +150 -1
- package/src/PowerSearch/PowerSearchEditPopover.tsx +51 -28
- package/src/PowerSearch/PowerSearchValueEditor.test.tsx +51 -0
- package/src/PowerSearch/PowerSearchValueEditor.tsx +4 -0
- package/src/ProgressBar/ProgressBar.test.tsx +29 -11
- package/src/ProgressBar/ProgressBar.tsx +59 -72
- package/src/RadioList/RadioList.doc.mjs +11 -0
- package/src/RadioList/RadioList.test.tsx +32 -0
- package/src/RadioList/RadioListItem.tsx +25 -1
- package/src/ScrollableArea/ScrollableArea.tsx +1 -0
- package/src/ScrollableArea/modules/useScrollableArea.spec.md +50 -22
- package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
- package/src/SegmentedControl/SegmentedControl.test.tsx +31 -0
- package/src/SegmentedControl/SegmentedControlItem.tsx +6 -9
- package/src/Selector/Selector.doc.mjs +2 -2
- package/src/Selector/Selector.spec.md +51 -49
- package/src/Selector/Selector.test.tsx +61 -55
- package/src/Selector/Selector.tsx +34 -15
- package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +130 -0
- package/src/Selector/__tests__/Listbox.a11y.dom.ts +38 -0
- package/src/Selector/__tests__/Listbox.a11y.inventory.test.ts +63 -0
- package/src/Selector/__tests__/Listbox.a11y.known-failures.ts +37 -0
- package/src/Selector/__tests__/Listbox.a11y.states.ts +232 -0
- package/src/Selector/__tests__/Selector.a11y.chromium.spec.ts +45 -0
- package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +121 -0
- package/src/SideNav/SideNav.doc.mjs +1 -1
- package/src/SideNav/SideNav.test.tsx +10 -0
- package/src/SideNav/SideNav.tsx +14 -2
- package/src/Slider/Slider.doc.mjs +17 -3
- package/src/Slider/Slider.test.tsx +221 -0
- package/src/Slider/Slider.tsx +40 -9
- package/src/Spinner/Spinner.test.tsx +4 -0
- package/src/Spinner/Spinner.tsx +31 -18
- package/src/Switch/Switch.doc.mjs +11 -0
- package/src/Switch/Switch.test.tsx +16 -0
- package/src/Switch/Switch.tsx +28 -0
- package/src/TabList/Tab.tsx +35 -7
- package/src/TabList/TabList.doc.mjs +11 -0
- package/src/TabList/TabList.spec.md +204 -0
- package/src/TabList/TabList.test.tsx +66 -0
- package/src/TabList/__tests__/Tabs.a11y.known-failures.ts +1 -34
- package/src/Table/Table.doc.mjs +1 -1
- package/src/Table/Table.spec.md +54 -40
- package/src/Table/Table.test.tsx +83 -10
- package/src/Table/Table.tsx +30 -22
- package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +137 -0
- package/src/TextArea/TextArea.tsx +6 -1
- package/src/TextInput/TextInput.test.tsx +20 -1
- package/src/TextInput/TextInput.tsx +6 -1
- package/src/TimeInput/TimeInput.tsx +6 -1
- package/src/Timer/Timer.doc.mjs +183 -0
- package/src/Timer/Timer.spec.md +215 -0
- package/src/Timer/Timer.test.tsx +302 -0
- package/src/Timer/Timer.tsx +258 -0
- package/src/Timer/index.ts +11 -0
- package/src/ToggleButton/ToggleButton.doc.mjs +3 -3
- package/src/ToggleButton/ToggleButton.test.tsx +299 -4
- package/src/ToggleButton/ToggleButton.tsx +26 -33
- package/src/ToggleButton/ToggleButtonGroup.doc.mjs +3 -3
- package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +209 -0
- package/src/Token/Token.doc.mjs +2 -2
- package/src/Tokenizer/Tokenizer.spec.md +142 -75
- package/src/TopNav/TopNavMenu.doc.mjs +2 -2
- package/src/TopNav/TopNavMenu.test.tsx +30 -0
- package/src/TopNav/TopNavMenu.tsx +7 -2
- package/src/TreeList/TreeList.doc.mjs +3 -3
- package/src/TreeList/TreeList.spec.md +123 -75
- package/src/TreeList/TreeList.test.tsx +29 -0
- package/src/TreeList/TreeList.tsx +3 -0
- package/src/TreeList/TreeListItem.tsx +15 -1
- package/src/TreeList/TreeListTypes.ts +11 -1
- package/src/Typeahead/BaseTypeahead.spec.md +4 -3
- package/src/Typeahead/BaseTypeahead.tsx +21 -7
- package/src/Typeahead/Typeahead.test.tsx +53 -0
- package/src/__tests__/PressedState.a11y.chromium.spec.ts +813 -0
- package/src/__tests__/pressState.ts +93 -0
- package/src/hooks/scrollKeyboardDelegation.test.ts +155 -0
- package/src/hooks/scrollKeyboardDelegation.ts +233 -0
- package/src/hooks/useClickableContainer.test.tsx +236 -0
- package/src/hooks/useClickableContainer.ts +20 -4
- package/src/hooks/useScrollableArea.doc.mjs +15 -3
- package/src/hooks/useScrollableArea.test.tsx +59 -1
- package/src/hooks/useScrollableArea.ts +34 -10
- package/src/index.ts +3 -0
- package/src/inputFontFloor.test.ts +106 -0
- package/src/tailwind-theme.css +0 -6
- package/src/theme/Theme.test.tsx +32 -0
- package/src/theme/declarationBoundary.test.ts +126 -0
- package/src/theme/declarationBoundary.ts +347 -0
- package/src/theme/derivedVarRegistry.test.ts +7 -0
- package/src/theme/derivedVarRegistry.ts +1 -0
- package/src/theme/generateThemeRules.test.ts +526 -1
- package/src/theme/generateThemeRules.ts +228 -50
- package/src/theme/tokenValueCompat.test.ts +4 -1
- package/src/utils/interactionOverlay.stylex.ts +20 -0
- package/src/utils/safeUrl.test.ts +88 -0
- package/src/utils/safeUrl.ts +85 -0
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file textTransform.ts
|
|
5
|
+
* @input Regex selectors and replacement callbacks for eligible Markdown prose
|
|
6
|
+
* @output Immutable Markdown transforms with protected-context traversal
|
|
7
|
+
* @position Optional helper layer compiled onto the core transform protocol
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {
|
|
11
|
+
MarkdownAstBlockContent,
|
|
12
|
+
MarkdownAstListItem,
|
|
13
|
+
MarkdownAstPhrasingContent,
|
|
14
|
+
MarkdownAstTableCell,
|
|
15
|
+
MarkdownAstTableRow,
|
|
16
|
+
} from '../ast';
|
|
17
|
+
import {
|
|
18
|
+
getMarkdownHelperOwnership,
|
|
19
|
+
adoptMarkdownHelperNode,
|
|
20
|
+
adoptMarkdownHelperNodes,
|
|
21
|
+
markMarkdownTransformClaim,
|
|
22
|
+
markMarkdownTransformTrusted,
|
|
23
|
+
type MarkdownExtensionNode,
|
|
24
|
+
type MarkdownHelperOwnership,
|
|
25
|
+
type MarkdownTransform,
|
|
26
|
+
} from './protocol';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Ownership for a transform invoked outside Core's pipeline. It owns no
|
|
30
|
+
* plugin name and no renderer, so a callback's extension node is rejected
|
|
31
|
+
* while ordinary phrasing still works.
|
|
32
|
+
*/
|
|
33
|
+
const UNOWNED: MarkdownHelperOwnership = Object.freeze({
|
|
34
|
+
pluginName: '\u0000unowned',
|
|
35
|
+
hasRenderer: () => false,
|
|
36
|
+
sourceUnchanged: false,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export interface MarkdownTextTransformContext {
|
|
40
|
+
readonly parentType:
|
|
41
|
+
'heading' | 'paragraph' | 'strong' | 'emphasis' | 'delete' | 'tableCell';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface MarkdownTextTransformOptions<
|
|
45
|
+
Node extends MarkdownExtensionNode = never,
|
|
46
|
+
> {
|
|
47
|
+
/** Global expression matched against eligible built-in prose only. */
|
|
48
|
+
readonly pattern: RegExp;
|
|
49
|
+
/**
|
|
50
|
+
* Literal substrings such that source containing an eligible match contains
|
|
51
|
+
* at least one. Core uses them to skip the transform without walking the AST
|
|
52
|
+
* when none are present. Omit this optimization when no conservative literal
|
|
53
|
+
* exists; the helper will inspect eligible prose on every run. This fast path
|
|
54
|
+
* is also disabled for case-insensitive patterns so JavaScript case folding
|
|
55
|
+
* remains exact.
|
|
56
|
+
*/
|
|
57
|
+
readonly requiredSubstrings?: readonly [string, ...string[]];
|
|
58
|
+
/** Optionally decline or extend a regex claim. */
|
|
59
|
+
readonly getEndIndex?: (
|
|
60
|
+
text: string,
|
|
61
|
+
match: RegExpExecArray,
|
|
62
|
+
) => number | false;
|
|
63
|
+
replace(
|
|
64
|
+
match: RegExpExecArray,
|
|
65
|
+
context: MarkdownTextTransformContext,
|
|
66
|
+
):
|
|
67
|
+
| MarkdownAstPhrasingContent<Node>
|
|
68
|
+
| ReadonlyArray<MarkdownAstPhrasingContent<Node>>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Replacement nodes already placed in a document by this helper.
|
|
73
|
+
*
|
|
74
|
+
* A callback that builds a node per match hands over a fresh object, and
|
|
75
|
+
* that object can go straight into the tree — copying it would allocate a
|
|
76
|
+
* second one for nothing, and it is validated and frozen on the way in
|
|
77
|
+
* either way. A callback that returns the SAME object for several matches
|
|
78
|
+
* is the case that needs a copy: one object cannot occupy two positions in
|
|
79
|
+
* a tree, and a node already frozen into an earlier position must not be
|
|
80
|
+
* reused for a later one. Weak, so remembering a node never keeps it alive.
|
|
81
|
+
*/
|
|
82
|
+
const adoptedReplacements = new WeakSet<object>();
|
|
83
|
+
|
|
84
|
+
/** One reusable expression per transform invocation. */
|
|
85
|
+
interface Scanner {
|
|
86
|
+
readonly pattern: RegExp;
|
|
87
|
+
busy: boolean;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
type AnyExtension = MarkdownExtensionNode;
|
|
91
|
+
type Phrasing = MarkdownAstPhrasingContent<AnyExtension>;
|
|
92
|
+
type Block = MarkdownAstBlockContent<AnyExtension>;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Copies a caller's node away from them. The cycle-tracking map is allocated
|
|
96
|
+
* only once a nested object actually appears: the overwhelmingly common
|
|
97
|
+
* replacement is a flat node of primitives, and this runs once per match.
|
|
98
|
+
*/
|
|
99
|
+
function cloneReplacement<T>(value: T, seen?: Map<object, unknown>): T {
|
|
100
|
+
if (value == null || typeof value !== 'object') {
|
|
101
|
+
return value;
|
|
102
|
+
}
|
|
103
|
+
const cached = seen?.get(value);
|
|
104
|
+
if (cached != null) {
|
|
105
|
+
return cached as T;
|
|
106
|
+
}
|
|
107
|
+
if (Array.isArray(value)) {
|
|
108
|
+
const clone: unknown[] = [];
|
|
109
|
+
seen ??= new Map<object, unknown>();
|
|
110
|
+
seen.set(value, clone);
|
|
111
|
+
for (const item of value) {
|
|
112
|
+
clone.push(cloneReplacement(item, seen));
|
|
113
|
+
}
|
|
114
|
+
return clone as T;
|
|
115
|
+
}
|
|
116
|
+
if (Object.getPrototypeOf(value) !== Object.prototype) {
|
|
117
|
+
return value;
|
|
118
|
+
}
|
|
119
|
+
const clone: Record<string, unknown> = {};
|
|
120
|
+
let tracked = seen;
|
|
121
|
+
for (const key in value) {
|
|
122
|
+
const nested = (value as Record<string, unknown>)[key];
|
|
123
|
+
if (nested != null && typeof nested === 'object') {
|
|
124
|
+
if (tracked === undefined) {
|
|
125
|
+
tracked = new Map<object, unknown>();
|
|
126
|
+
tracked.set(value, clone);
|
|
127
|
+
}
|
|
128
|
+
clone[key] = cloneReplacement(nested, tracked);
|
|
129
|
+
} else {
|
|
130
|
+
clone[key] = nested;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return clone as T;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function advanceStringIndex(
|
|
137
|
+
value: string,
|
|
138
|
+
index: number,
|
|
139
|
+
unicode: boolean,
|
|
140
|
+
): number {
|
|
141
|
+
if (!unicode || index >= value.length) {
|
|
142
|
+
return index + 1;
|
|
143
|
+
}
|
|
144
|
+
const first = value.charCodeAt(index);
|
|
145
|
+
if (first < 0xd800 || first > 0xdbff || index + 1 >= value.length) {
|
|
146
|
+
return index + 1;
|
|
147
|
+
}
|
|
148
|
+
const second = value.charCodeAt(index + 1);
|
|
149
|
+
return second >= 0xdc00 && second <= 0xdfff ? index + 2 : index + 1;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function replaceTextNode<Node extends MarkdownExtensionNode>(
|
|
153
|
+
value: string,
|
|
154
|
+
options: MarkdownTextTransformOptions<Node>,
|
|
155
|
+
parentType: MarkdownTextTransformContext['parentType'],
|
|
156
|
+
ownership: MarkdownHelperOwnership,
|
|
157
|
+
scanner: Scanner,
|
|
158
|
+
): ReadonlyArray<Phrasing> | null {
|
|
159
|
+
// The conservative substring hint decides per text node, not just per
|
|
160
|
+
// document: source without one cannot contain an eligible match, so most
|
|
161
|
+
// prose is skipped before any scanning happens.
|
|
162
|
+
// Disabled for case-insensitive patterns, exactly as the document-level
|
|
163
|
+
// claim is, so JavaScript case folding stays the only authority.
|
|
164
|
+
const required = options.pattern.ignoreCase
|
|
165
|
+
? undefined
|
|
166
|
+
: options.requiredSubstrings;
|
|
167
|
+
if (required != null && !required.some(hint => value.includes(hint))) {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
// One expression per transform invocation rather than one per text node.
|
|
171
|
+
// A `replace` callback that re-enters this helper gets its own, so a
|
|
172
|
+
// nested scan can never disturb the outer one's `lastIndex`.
|
|
173
|
+
const pattern = scanner.busy
|
|
174
|
+
? new RegExp(options.pattern.source, options.pattern.flags)
|
|
175
|
+
: scanner.pattern;
|
|
176
|
+
const reentrant = pattern !== scanner.pattern;
|
|
177
|
+
if (!reentrant) {
|
|
178
|
+
scanner.busy = true;
|
|
179
|
+
}
|
|
180
|
+
pattern.lastIndex = 0;
|
|
181
|
+
const output: Phrasing[] = [];
|
|
182
|
+
let cursor = 0;
|
|
183
|
+
let changed = false;
|
|
184
|
+
let match: RegExpExecArray | null;
|
|
185
|
+
|
|
186
|
+
while ((match = pattern.exec(value)) != null) {
|
|
187
|
+
const start = match.index;
|
|
188
|
+
const defaultEnd = start + match[0].length;
|
|
189
|
+
const resolvedEnd = options.getEndIndex?.(value, match) ?? defaultEnd;
|
|
190
|
+
if (resolvedEnd === false) {
|
|
191
|
+
if (match[0].length === 0) {
|
|
192
|
+
pattern.lastIndex = advanceStringIndex(
|
|
193
|
+
value,
|
|
194
|
+
pattern.lastIndex,
|
|
195
|
+
pattern.unicode || pattern.flags.includes('v'),
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (
|
|
201
|
+
!Number.isInteger(resolvedEnd) ||
|
|
202
|
+
resolvedEnd < defaultEnd ||
|
|
203
|
+
resolvedEnd < start ||
|
|
204
|
+
resolvedEnd > value.length
|
|
205
|
+
) {
|
|
206
|
+
throw new TypeError(
|
|
207
|
+
'Markdown text transform returned an invalid end index',
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
if (start < cursor) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (start > cursor) {
|
|
214
|
+
output.push({type: 'text', value: value.slice(cursor, start)});
|
|
215
|
+
}
|
|
216
|
+
const replacement = options.replace(match, {parentType});
|
|
217
|
+
// The callback's nodes are the only untrusted structure this helper can
|
|
218
|
+
// introduce. Each one is checked here under the same rules Core applies
|
|
219
|
+
// to newly-introduced nodes — representable data, no authored
|
|
220
|
+
// provenance, no foreign extension ownership, no cycles — and frozen,
|
|
221
|
+
// so the tree this transform returns needs no further checking. A node
|
|
222
|
+
// the callback has handed over before is copied first; a fresh one is
|
|
223
|
+
// adopted as it stands.
|
|
224
|
+
if (Array.isArray(replacement)) {
|
|
225
|
+
const adopted: Phrasing[] = [];
|
|
226
|
+
for (const replacementNode of replacement) {
|
|
227
|
+
adopted.push(
|
|
228
|
+
adoptedReplacements.has(replacementNode)
|
|
229
|
+
? cloneReplacement(replacementNode)
|
|
230
|
+
: replacementNode,
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
adoptMarkdownHelperNodes(adopted, ownership);
|
|
234
|
+
for (const node of adopted) {
|
|
235
|
+
adoptedReplacements.add(node);
|
|
236
|
+
}
|
|
237
|
+
output.push(...adopted);
|
|
238
|
+
} else {
|
|
239
|
+
// One node is the overwhelmingly common reply, and it is worth its
|
|
240
|
+
// own path: wrapping it in an array to share the loop above would
|
|
241
|
+
// allocate twice per match, which on a large document is the
|
|
242
|
+
// helper's dominant garbage.
|
|
243
|
+
const single = replacement as Phrasing;
|
|
244
|
+
const adopted = adoptedReplacements.has(single)
|
|
245
|
+
? cloneReplacement(single)
|
|
246
|
+
: single;
|
|
247
|
+
adoptMarkdownHelperNode(adopted, ownership);
|
|
248
|
+
adoptedReplacements.add(adopted);
|
|
249
|
+
output.push(adopted);
|
|
250
|
+
}
|
|
251
|
+
cursor = resolvedEnd;
|
|
252
|
+
pattern.lastIndex =
|
|
253
|
+
resolvedEnd === start
|
|
254
|
+
? advanceStringIndex(
|
|
255
|
+
value,
|
|
256
|
+
pattern.lastIndex,
|
|
257
|
+
pattern.unicode || pattern.flags.includes('v'),
|
|
258
|
+
)
|
|
259
|
+
: Math.max(pattern.lastIndex, resolvedEnd);
|
|
260
|
+
changed = true;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (!reentrant) {
|
|
264
|
+
scanner.busy = false;
|
|
265
|
+
}
|
|
266
|
+
if (!changed) {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
if (cursor < value.length) {
|
|
270
|
+
output.push({type: 'text', value: value.slice(cursor)});
|
|
271
|
+
}
|
|
272
|
+
return output;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function transformPhrasing<Node extends MarkdownExtensionNode>(
|
|
276
|
+
children: ReadonlyArray<Phrasing>,
|
|
277
|
+
options: MarkdownTextTransformOptions<Node>,
|
|
278
|
+
parentType: MarkdownTextTransformContext['parentType'],
|
|
279
|
+
ownership: MarkdownHelperOwnership,
|
|
280
|
+
scanner: Scanner,
|
|
281
|
+
): ReadonlyArray<Phrasing> {
|
|
282
|
+
// Lazy rebuild: unchanged phrasing is returned as-is, so prose with no
|
|
283
|
+
// match costs one walk and no allocation. Only the first change copies.
|
|
284
|
+
let next: Phrasing[] | undefined;
|
|
285
|
+
for (let index = 0; index < children.length; index++) {
|
|
286
|
+
const node = children[index];
|
|
287
|
+
if (node.type === 'text') {
|
|
288
|
+
const replaced = replaceTextNode(
|
|
289
|
+
node.value,
|
|
290
|
+
options,
|
|
291
|
+
parentType,
|
|
292
|
+
ownership,
|
|
293
|
+
scanner,
|
|
294
|
+
);
|
|
295
|
+
if (replaced == null) {
|
|
296
|
+
next?.push(node);
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
next ??= children.slice(0, index);
|
|
300
|
+
for (const replacement of replaced) {
|
|
301
|
+
next.push(replacement);
|
|
302
|
+
}
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
if (
|
|
306
|
+
node.type === 'strong' ||
|
|
307
|
+
node.type === 'emphasis' ||
|
|
308
|
+
node.type === 'delete'
|
|
309
|
+
) {
|
|
310
|
+
const nested = transformPhrasing(
|
|
311
|
+
node.children,
|
|
312
|
+
options,
|
|
313
|
+
node.type,
|
|
314
|
+
ownership,
|
|
315
|
+
scanner,
|
|
316
|
+
);
|
|
317
|
+
if (nested === node.children) {
|
|
318
|
+
next?.push(node);
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
next ??= children.slice(0, index);
|
|
322
|
+
next.push({...node, children: nested});
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
// Links, images, code, math, citations, breaks, and accepted extension
|
|
326
|
+
// syntax are protected contexts owned by their existing semantics.
|
|
327
|
+
next?.push(node);
|
|
328
|
+
}
|
|
329
|
+
return next ?? children;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function blockMayContainRequiredSource<Node extends MarkdownExtensionNode>(
|
|
333
|
+
block: Block,
|
|
334
|
+
source: string | undefined,
|
|
335
|
+
options: MarkdownTextTransformOptions<Node>,
|
|
336
|
+
): boolean {
|
|
337
|
+
const required = options.requiredSubstrings;
|
|
338
|
+
if (source === undefined || required === undefined) {
|
|
339
|
+
return true;
|
|
340
|
+
}
|
|
341
|
+
const start = block.position?.start.offset;
|
|
342
|
+
const end = block.position?.end.offset;
|
|
343
|
+
if (typeof start !== 'number' || typeof end !== 'number') {
|
|
344
|
+
return true;
|
|
345
|
+
}
|
|
346
|
+
for (const hint of required) {
|
|
347
|
+
const match = source.indexOf(hint, start);
|
|
348
|
+
if (match >= 0 && match < end) {
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function transformBlocks<Node extends MarkdownExtensionNode>(
|
|
356
|
+
blocks: ReadonlyArray<Block>,
|
|
357
|
+
options: MarkdownTextTransformOptions<Node>,
|
|
358
|
+
ownership: MarkdownHelperOwnership,
|
|
359
|
+
scanner: Scanner,
|
|
360
|
+
source: string | undefined,
|
|
361
|
+
): ReadonlyArray<Block> {
|
|
362
|
+
// Lazy rebuild, matching transformPhrasing: a block list with no match is
|
|
363
|
+
// returned unchanged and allocates nothing.
|
|
364
|
+
let next: Block[] | undefined;
|
|
365
|
+
for (let index = 0; index < blocks.length; index++) {
|
|
366
|
+
const block = blocks[index];
|
|
367
|
+
if (!blockMayContainRequiredSource(block, source, options)) {
|
|
368
|
+
next?.push(block);
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
let replacement: Block;
|
|
372
|
+
switch (block.type) {
|
|
373
|
+
case 'heading':
|
|
374
|
+
case 'paragraph': {
|
|
375
|
+
const children = transformPhrasing(
|
|
376
|
+
block.children,
|
|
377
|
+
options,
|
|
378
|
+
block.type,
|
|
379
|
+
ownership,
|
|
380
|
+
scanner,
|
|
381
|
+
);
|
|
382
|
+
replacement =
|
|
383
|
+
children === block.children ? block : {...block, children};
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
case 'blockquote': {
|
|
387
|
+
const children = transformBlocks(
|
|
388
|
+
block.children,
|
|
389
|
+
options,
|
|
390
|
+
ownership,
|
|
391
|
+
scanner,
|
|
392
|
+
source,
|
|
393
|
+
);
|
|
394
|
+
replacement =
|
|
395
|
+
children === block.children ? block : {...block, children};
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
case 'list': {
|
|
399
|
+
let items: MarkdownAstListItem<AnyExtension>[] | undefined;
|
|
400
|
+
for (
|
|
401
|
+
let item_index = 0;
|
|
402
|
+
item_index < block.children.length;
|
|
403
|
+
item_index++
|
|
404
|
+
) {
|
|
405
|
+
const item = block.children[item_index];
|
|
406
|
+
const itemChildren = transformBlocks(
|
|
407
|
+
item.children,
|
|
408
|
+
options,
|
|
409
|
+
ownership,
|
|
410
|
+
scanner,
|
|
411
|
+
source,
|
|
412
|
+
);
|
|
413
|
+
if (itemChildren === item.children) {
|
|
414
|
+
items?.push(item);
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
items ??= block.children.slice(0, item_index);
|
|
418
|
+
items.push({...item, children: itemChildren});
|
|
419
|
+
}
|
|
420
|
+
replacement = items == null ? block : {...block, children: items};
|
|
421
|
+
break;
|
|
422
|
+
}
|
|
423
|
+
case 'table': {
|
|
424
|
+
let rows: MarkdownAstTableRow<AnyExtension>[] | undefined;
|
|
425
|
+
for (
|
|
426
|
+
let row_index = 0;
|
|
427
|
+
row_index < block.children.length;
|
|
428
|
+
row_index++
|
|
429
|
+
) {
|
|
430
|
+
const row = block.children[row_index];
|
|
431
|
+
let cells: MarkdownAstTableCell<AnyExtension>[] | undefined;
|
|
432
|
+
for (
|
|
433
|
+
let cell_index = 0;
|
|
434
|
+
cell_index < row.children.length;
|
|
435
|
+
cell_index++
|
|
436
|
+
) {
|
|
437
|
+
const cell = row.children[cell_index];
|
|
438
|
+
const cellChildren = transformPhrasing(
|
|
439
|
+
cell.children,
|
|
440
|
+
options,
|
|
441
|
+
'tableCell',
|
|
442
|
+
ownership,
|
|
443
|
+
scanner,
|
|
444
|
+
);
|
|
445
|
+
if (cellChildren === cell.children) {
|
|
446
|
+
cells?.push(cell);
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
cells ??= row.children.slice(0, cell_index);
|
|
450
|
+
cells.push({...cell, children: cellChildren});
|
|
451
|
+
}
|
|
452
|
+
if (cells == null) {
|
|
453
|
+
rows?.push(row);
|
|
454
|
+
continue;
|
|
455
|
+
}
|
|
456
|
+
rows ??= block.children.slice(0, row_index);
|
|
457
|
+
rows.push({...row, children: cells});
|
|
458
|
+
}
|
|
459
|
+
replacement = rows == null ? block : {...block, children: rows};
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
case 'code':
|
|
463
|
+
case 'math':
|
|
464
|
+
case 'image':
|
|
465
|
+
case 'thematicBreak':
|
|
466
|
+
case 'extension':
|
|
467
|
+
replacement = block;
|
|
468
|
+
break;
|
|
469
|
+
}
|
|
470
|
+
if (next === undefined && replacement !== block) {
|
|
471
|
+
next = blocks.slice(0, index);
|
|
472
|
+
}
|
|
473
|
+
next?.push(replacement);
|
|
474
|
+
}
|
|
475
|
+
return next ?? blocks;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
export function createMarkdownTextTransform(
|
|
479
|
+
options: MarkdownTextTransformOptions<never>,
|
|
480
|
+
): MarkdownTransform<never>;
|
|
481
|
+
export function createMarkdownTextTransform<Node extends MarkdownExtensionNode>(
|
|
482
|
+
options: MarkdownTextTransformOptions<Node>,
|
|
483
|
+
): MarkdownTransform<Node>;
|
|
484
|
+
export function createMarkdownTextTransform(
|
|
485
|
+
options: MarkdownTextTransformOptions<MarkdownExtensionNode>,
|
|
486
|
+
): MarkdownTransform<MarkdownExtensionNode> {
|
|
487
|
+
if (!options.pattern.global) {
|
|
488
|
+
throw new TypeError(
|
|
489
|
+
'Markdown text transform patterns must use the global flag',
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
if (
|
|
493
|
+
options.requiredSubstrings != null &&
|
|
494
|
+
(!Array.isArray(options.requiredSubstrings) ||
|
|
495
|
+
options.requiredSubstrings.length === 0 ||
|
|
496
|
+
options.requiredSubstrings.some(
|
|
497
|
+
value => typeof value !== 'string' || value === '',
|
|
498
|
+
))
|
|
499
|
+
) {
|
|
500
|
+
throw new TypeError(
|
|
501
|
+
'Markdown text transform requiredSubstrings must be non-empty strings',
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
const requiredSubstrings =
|
|
505
|
+
options.requiredSubstrings == null
|
|
506
|
+
? undefined
|
|
507
|
+
: (Object.freeze([...options.requiredSubstrings]) as readonly [
|
|
508
|
+
string,
|
|
509
|
+
...string[],
|
|
510
|
+
]);
|
|
511
|
+
const normalizedOptions: MarkdownTextTransformOptions<MarkdownExtensionNode> =
|
|
512
|
+
Object.freeze({
|
|
513
|
+
pattern: new RegExp(options.pattern.source, options.pattern.flags),
|
|
514
|
+
requiredSubstrings,
|
|
515
|
+
getEndIndex: options.getEndIndex,
|
|
516
|
+
replace: options.replace,
|
|
517
|
+
});
|
|
518
|
+
const transform: MarkdownTransform<MarkdownExtensionNode> = (
|
|
519
|
+
root,
|
|
520
|
+
context,
|
|
521
|
+
) => {
|
|
522
|
+
const ownership = getMarkdownHelperOwnership(context) ?? UNOWNED;
|
|
523
|
+
const children = transformBlocks(
|
|
524
|
+
root.children,
|
|
525
|
+
normalizedOptions,
|
|
526
|
+
ownership,
|
|
527
|
+
{
|
|
528
|
+
pattern: new RegExp(
|
|
529
|
+
normalizedOptions.pattern.source,
|
|
530
|
+
normalizedOptions.pattern.flags,
|
|
531
|
+
),
|
|
532
|
+
busy: false,
|
|
533
|
+
},
|
|
534
|
+
ownership.sourceUnchanged &&
|
|
535
|
+
requiredSubstrings != null &&
|
|
536
|
+
!normalizedOptions.pattern.ignoreCase
|
|
537
|
+
? context.source
|
|
538
|
+
: undefined,
|
|
539
|
+
);
|
|
540
|
+
return children === root.children ? root : {...root, children};
|
|
541
|
+
};
|
|
542
|
+
// Every node this helper returns is either one Core already validated or
|
|
543
|
+
// one `replaceTextNode` just validated against the same rules, so Core may
|
|
544
|
+
// run it on the trusted path.
|
|
545
|
+
const trusted = markMarkdownTransformTrusted(
|
|
546
|
+
transform as MarkdownTransform<never>,
|
|
547
|
+
) as MarkdownTransform<MarkdownExtensionNode>;
|
|
548
|
+
if (requiredSubstrings == null || options.pattern.ignoreCase) {
|
|
549
|
+
return trusted;
|
|
550
|
+
}
|
|
551
|
+
return markMarkdownTransformClaim(trusted, source =>
|
|
552
|
+
requiredSubstrings.some(required => source.includes(required)),
|
|
553
|
+
);
|
|
554
|
+
}
|