@apollohg/react-native-rich-text-editor 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +160 -0
- package/README.md +259 -0
- package/RUST-STANDARD-LIBRARY-NOTICES.html +8266 -0
- package/ReactNativeProseEditor.podspec +59 -0
- package/THIRD_PARTY_NOTICES.md +31155 -0
- package/android/build.gradle +188 -0
- package/android/consumer-rules.pro +18 -0
- package/android/expo/build.gradle +17 -0
- package/android/src/debug/java/com/apollohg/editor/viewer/PreparedProseDrawInstrumentation.kt +7 -0
- package/android/src/main/assets/editor-icons/MaterialIcons.json +2236 -0
- package/android/src/main/assets/editor-icons/MaterialIcons.ttf +0 -0
- package/android/src/main/java/com/apollohg/editor/AndroidApiCompat.kt +19 -0
- package/android/src/main/java/com/apollohg/editor/AndroidCollaborationTransport.kt +860 -0
- package/android/src/main/java/com/apollohg/editor/CaretGeometry.kt +91 -0
- package/android/src/main/java/com/apollohg/editor/CodeHighlighting.kt +141 -0
- package/android/src/main/java/com/apollohg/editor/DecodedBitmapBudget.kt +250 -0
- package/android/src/main/java/com/apollohg/editor/EditorAddons.kt +133 -0
- package/android/src/main/java/com/apollohg/editor/EditorBlockSpacing.kt +51 -0
- package/android/src/main/java/com/apollohg/editor/EditorBoxDrawable.kt +16 -0
- package/android/src/main/java/com/apollohg/editor/EditorBoxDrawing.kt +234 -0
- package/android/src/main/java/com/apollohg/editor/EditorCheckboxSpan.kt +87 -0
- package/android/src/main/java/com/apollohg/editor/EditorCodeHighlighting.kt +120 -0
- package/android/src/main/java/com/apollohg/editor/EditorDecorationLayer.java +18 -0
- package/android/src/main/java/com/apollohg/editor/EditorDocumentLayout.kt +626 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditText.kt +1042 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextAnnotations.kt +191 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextCaret.kt +100 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextClipboard.kt +101 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextComposition.kt +220 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextConfiguration.kt +316 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextCorrection.kt +303 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextDeferredUpdates.kt +327 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextDeletion.kt +258 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextDiagnostics.kt +83 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextDragDrop.kt +67 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextExternalComposition.kt +357 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextHardwareInput.kt +277 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextImages.kt +280 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextInputLifecycle.kt +183 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextInputPreparation.kt +79 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextInputTraits.kt +384 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextLayout.kt +100 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextNativeMutation.kt +243 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextPlaceholder.kt +154 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextRenderPatch.kt +347 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextRendering.kt +313 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextRustCommands.kt +281 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextSelection.kt +352 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextState.kt +113 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextTaskMarkers.kt +92 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextTextCommit.kt +327 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextToolbar.kt +84 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextUpdates.kt +245 -0
- package/android/src/main/java/com/apollohg/editor/EditorGlyphHeightCursorDrawable.kt +42 -0
- package/android/src/main/java/com/apollohg/editor/EditorHeightBehavior.kt +13 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputConnection.kt +923 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputCoordinates.kt +191 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputCorrection.kt +107 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputCursorGeometry.kt +128 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputSnapshots.kt +134 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputSurroundingDeletion.kt +321 -0
- package/android/src/main/java/com/apollohg/editor/EditorKeyboardToolbarView.kt +851 -0
- package/android/src/main/java/com/apollohg/editor/EditorMentionStyle.kt +192 -0
- package/android/src/main/java/com/apollohg/editor/EditorReconciliationWatcher.kt +46 -0
- package/android/src/main/java/com/apollohg/editor/EditorStyleSheet.kt +303 -0
- package/android/src/main/java/com/apollohg/editor/EditorStyleSheetSpans.kt +253 -0
- package/android/src/main/java/com/apollohg/editor/EditorSurfaceInputConnection.kt +67 -0
- package/android/src/main/java/com/apollohg/editor/EditorTextDecorationDrawing.kt +143 -0
- package/android/src/main/java/com/apollohg/editor/EditorTextSurface.kt +712 -0
- package/android/src/main/java/com/apollohg/editor/EditorTextSurfaceDragDrop.kt +94 -0
- package/android/src/main/java/com/apollohg/editor/EditorTextSurfaceInteraction.kt +708 -0
- package/android/src/main/java/com/apollohg/editor/EditorTheme.kt +650 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2Adapter.kt +912 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2AdapterMutations.kt +402 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2AdapterRendering.kt +123 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2AdapterSelection.kt +203 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2Backend.kt +120 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2Driver.kt +87 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2Registry.kt +97 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2RenderValidation.kt +409 -0
- package/android/src/main/java/com/apollohg/editor/ExpoAutoGrowStyleSizePublisher.kt +34 -0
- package/android/src/main/java/com/apollohg/editor/ImageResizeOverlayView.kt +266 -0
- package/android/src/main/java/com/apollohg/editor/ImeTextCoordinateMapper.kt +102 -0
- package/android/src/main/java/com/apollohg/editor/KeyboardToolbarImeAnimationController.kt +101 -0
- package/android/src/main/java/com/apollohg/editor/MentionSuggestionChipView.kt +234 -0
- package/android/src/main/java/com/apollohg/editor/NativeCollaborationTransportRegistry.kt +493 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoView.kt +813 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewAtoms.kt +68 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewBinding.kt +126 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewDiagnostics.kt +208 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewErrors.kt +146 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewEvents.kt +150 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewExternalComposition.kt +39 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewFocus.kt +176 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewLifecycle.kt +302 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewMentions.kt +259 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewNativeActions.kt +179 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewOutsideTap.kt +214 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewPendingUpdates.kt +376 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewProperties.kt +234 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewPropertyRetries.kt +197 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewToolbar.kt +285 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewTypes.kt +28 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewUpdates.kt +271 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorModule.kt +687 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorOutsideTapDispatcher.kt +380 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorV2Numbers.kt +45 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorViewRegistry.kt +372 -0
- package/android/src/main/java/com/apollohg/editor/NativeImagePipeline.kt +22 -0
- package/android/src/main/java/com/apollohg/editor/NativeToolbar.kt +193 -0
- package/android/src/main/java/com/apollohg/editor/NativeToolbarIcons.kt +177 -0
- package/android/src/main/java/com/apollohg/editor/NativeToolbarItem.kt +274 -0
- package/android/src/main/java/com/apollohg/editor/OkHttpCollaborationSocket.kt +102 -0
- package/android/src/main/java/com/apollohg/editor/OrderedListMarkerFormatter.kt +130 -0
- package/android/src/main/java/com/apollohg/editor/PointerTransparentView.java +18 -0
- package/android/src/main/java/com/apollohg/editor/PositionBridge.kt +128 -0
- package/android/src/main/java/com/apollohg/editor/ProseViewerView.kt +854 -0
- package/android/src/main/java/com/apollohg/editor/RemoteSelectionOverlayView.kt +314 -0
- package/android/src/main/java/com/apollohg/editor/RenderBlockSpans.kt +314 -0
- package/android/src/main/java/com/apollohg/editor/RenderBridge.kt +224 -0
- package/android/src/main/java/com/apollohg/editor/RenderBridgeBlockStyles.kt +407 -0
- package/android/src/main/java/com/apollohg/editor/RenderBridgeElements.kt +544 -0
- package/android/src/main/java/com/apollohg/editor/RenderBridgeInlineAndAtoms.kt +631 -0
- package/android/src/main/java/com/apollohg/editor/RenderBridgeParagraphs.kt +215 -0
- package/android/src/main/java/com/apollohg/editor/RenderImageDecoder.kt +748 -0
- package/android/src/main/java/com/apollohg/editor/RenderImageLoader.kt +900 -0
- package/android/src/main/java/com/apollohg/editor/RenderLayoutConstants.kt +117 -0
- package/android/src/main/java/com/apollohg/editor/RenderMediaSpans.kt +337 -0
- package/android/src/main/java/com/apollohg/editor/RenderParagraphSpans.kt +182 -0
- package/android/src/main/java/com/apollohg/editor/RichTextEditorView.kt +951 -0
- package/android/src/main/java/com/apollohg/editor/SharedNativeImagePipeline.kt +78 -0
- package/android/src/main/java/com/apollohg/editor/UniffiEditorV2Backend.kt +261 -0
- package/android/src/main/java/com/apollohg/editor/viewer/AndroidProseLayoutEngine.kt +1656 -0
- package/android/src/main/java/com/apollohg/editor/viewer/FabricAttachmentSidecars.kt +80 -0
- package/android/src/main/java/com/apollohg/editor/viewer/FabricLeaseHandleBridge.kt +59 -0
- package/android/src/main/java/com/apollohg/editor/viewer/FallbackSelectionGeometry.kt +450 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseDrawingView.kt +678 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseInstrumentation.kt +608 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayout.kt +186 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayoutCache.kt +393 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayoutRegistry.kt +828 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseTheme.kt +316 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseViewerManager.kt +900 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseViewerPackage.kt +16 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedViewerAtoms.kt +89 -0
- package/android/src/main/java/com/apollohg/editor/viewer/ViewerCodeHighlighting.kt +91 -0
- package/android/src/main/java/com/apollohg/editor/viewer/ViewerDocument.kt +453 -0
- package/android/src/main/java/com/apollohg/editor/viewer/ViewerFontEnvironment.kt +282 -0
- package/android/src/main/java/com/apollohg/editor/viewer/ViewerImagePipeline.kt +460 -0
- package/android/src/main/jni/CMakeLists.txt +85 -0
- package/android/src/main/jni/PreparedProseViewerMeasurementsManager.cpp +334 -0
- package/android/src/main/jni/ReactNativeProseEditorSpec.h +17 -0
- package/android/src/main/jni/reactnativeproseeditor.h +6 -0
- package/android/src/main/res/values/attrs.xml +6 -0
- package/android/src/release/java/com/apollohg/editor/viewer/PreparedProseDrawInstrumentation.kt +9 -0
- package/app.plugin.js +62 -0
- package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseMeasurementsManager.h +62 -0
- package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerComponentDescriptor.h +30 -0
- package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerShadowNode.cpp +192 -0
- package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerShadowNode.h +46 -0
- package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerState.h +145 -0
- package/dist/AtomHost.d.ts +17 -0
- package/dist/AtomHost.js +135 -0
- package/dist/DefaultAtomChip.d.ts +2 -0
- package/dist/DefaultAtomChip.js +22 -0
- package/dist/EditorAddon.d.ts +32 -0
- package/dist/EditorAddon.js +29 -0
- package/dist/EditorAddonNormalization.d.ts +6 -0
- package/dist/EditorAddonNormalization.js +48 -0
- package/dist/EditorMentionThemeNormalization.d.ts +8 -0
- package/dist/EditorMentionThemeNormalization.js +22 -0
- package/dist/EditorMentionThemeValidation.d.ts +12 -0
- package/dist/EditorMentionThemeValidation.js +95 -0
- package/dist/EditorStyleSheet.d.ts +4 -0
- package/dist/EditorStyleSheet.js +10 -0
- package/dist/EditorStyleSheetNormalization.d.ts +3 -0
- package/dist/EditorStyleSheetNormalization.js +226 -0
- package/dist/EditorStyleSheetTypes.d.ts +151 -0
- package/dist/EditorStyleSheetTypes.js +2 -0
- package/dist/EditorTheme.d.ts +117 -0
- package/dist/EditorTheme.js +41 -0
- package/dist/EditorToolbar.d.ts +4 -0
- package/dist/EditorToolbar.js +17 -0
- package/dist/EditorToolbarComponent.d.ts +13 -0
- package/dist/EditorToolbarComponent.js +24 -0
- package/dist/EditorToolbarItems.d.ts +9 -0
- package/dist/EditorToolbarItems.js +58 -0
- package/dist/EditorToolbarRegistry.d.ts +59 -0
- package/dist/EditorToolbarRegistry.js +175 -0
- package/dist/EditorToolbarTypes.d.ts +273 -0
- package/dist/EditorToolbarTypes.js +2 -0
- package/dist/EditorToolbarVisuals.d.ts +154 -0
- package/dist/EditorToolbarVisuals.js +228 -0
- package/dist/EditorUpdateRevision.d.ts +8 -0
- package/dist/EditorUpdateRevision.js +22 -0
- package/dist/ExternalTextComposition.d.ts +45 -0
- package/dist/ExternalTextComposition.js +537 -0
- package/dist/ImageLoadingPolicy.d.ts +54 -0
- package/dist/ImageLoadingPolicy.js +60 -0
- package/dist/NativeEditorBoundaryError.d.ts +111 -0
- package/dist/NativeEditorBoundaryError.js +268 -0
- package/dist/NativeEditorBridge.d.ts +9 -0
- package/dist/NativeEditorBridge.js +37 -0
- package/dist/NativeEditorCollaborationTransport.d.ts +154 -0
- package/dist/NativeEditorCollaborationTransport.js +275 -0
- package/dist/NativeEditorCreateConfig.d.ts +16 -0
- package/dist/NativeEditorCreateConfig.js +249 -0
- package/dist/NativeEditorCreateJson.d.ts +76 -0
- package/dist/NativeEditorCreateJson.js +474 -0
- package/dist/NativeEditorCreateValidation.d.ts +32 -0
- package/dist/NativeEditorCreateValidation.js +150 -0
- package/dist/NativeEditorDocumentBridge.d.ts +72 -0
- package/dist/NativeEditorDocumentBridge.js +305 -0
- package/dist/NativeEditorDocumentHandle.d.ts +70 -0
- package/dist/NativeEditorDocumentHandle.js +89 -0
- package/dist/NativeEditorLocalAwareness.d.ts +34 -0
- package/dist/NativeEditorLocalAwareness.js +153 -0
- package/dist/NativeEditorNativeModule.d.ts +48 -0
- package/dist/NativeEditorNativeModule.js +34 -0
- package/dist/NativeEditorRenderNormalization.d.ts +22 -0
- package/dist/NativeEditorRenderNormalization.js +274 -0
- package/dist/NativeEditorResultNormalization.d.ts +108 -0
- package/dist/NativeEditorResultNormalization.js +400 -0
- package/dist/NativeEditorTypes.d.ts +318 -0
- package/dist/NativeEditorTypes.js +15 -0
- package/dist/NativeEditorV2Decimal.d.ts +5 -0
- package/dist/NativeEditorV2Decimal.js +18 -0
- package/dist/NativeProseViewer.d.ts +122 -0
- package/dist/NativeProseViewer.js +130 -0
- package/dist/NativeRichTextEditor.d.ts +3 -0
- package/dist/NativeRichTextEditor.js +6 -0
- package/dist/ResourceLimits.d.ts +100 -0
- package/dist/ResourceLimits.js +80 -0
- package/dist/RichTextEditor.d.ts +4 -0
- package/dist/RichTextEditor.js +25 -0
- package/dist/RichTextEditorNativeTypes.d.ts +122 -0
- package/dist/RichTextEditorNativeTypes.js +2 -0
- package/dist/RichTextEditorNativeView.d.ts +12 -0
- package/dist/RichTextEditorNativeView.js +15 -0
- package/dist/RichTextEditorSerialization.d.ts +53 -0
- package/dist/RichTextEditorSerialization.js +283 -0
- package/dist/RichTextEditorTypes.d.ts +281 -0
- package/dist/RichTextEditorTypes.js +2 -0
- package/dist/ViewerConfiguration.d.ts +22 -0
- package/dist/ViewerConfiguration.js +6 -0
- package/dist/YjsCollaboration.d.ts +146 -0
- package/dist/YjsCollaboration.js +496 -0
- package/dist/addons.d.ts +193 -0
- package/dist/addons.js +122 -0
- package/dist/atomConstants.d.ts +3 -0
- package/dist/atomConstants.js +6 -0
- package/dist/atomInstances.d.ts +35 -0
- package/dist/atomInstances.js +79 -0
- package/dist/atomPolicy.d.ts +4 -0
- package/dist/atomPolicy.js +47 -0
- package/dist/atomUpdates.d.ts +2 -0
- package/dist/atomUpdates.js +38 -0
- package/dist/atoms.d.ts +92 -0
- package/dist/atoms.js +222 -0
- package/dist/attributeValidation.d.ts +4 -0
- package/dist/attributeValidation.js +97 -0
- package/dist/contentExpression.d.ts +6 -0
- package/dist/contentExpression.js +335 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +78 -0
- package/dist/listMarkers.d.ts +15 -0
- package/dist/listMarkers.js +21 -0
- package/dist/schemaDefinition.d.ts +143 -0
- package/dist/schemaDefinition.js +206 -0
- package/dist/schemaDocument.d.ts +17 -0
- package/dist/schemaDocument.js +69 -0
- package/dist/schemaDocumentConstruction.d.ts +5 -0
- package/dist/schemaDocumentConstruction.js +125 -0
- package/dist/schemaNormalization.d.ts +29 -0
- package/dist/schemaNormalization.js +313 -0
- package/dist/schemaPresets.d.ts +68 -0
- package/dist/schemaPresets.js +198 -0
- package/dist/schemaResolution.d.ts +9 -0
- package/dist/schemaResolution.js +211 -0
- package/dist/schemas.d.ts +5 -0
- package/dist/schemas.js +28 -0
- package/dist/specs/PreparedProseViewerNativeComponent.d.ts +37 -0
- package/dist/specs/PreparedProseViewerNativeComponent.js +6 -0
- package/dist/useEditorToolbarInteractions.d.ts +12 -0
- package/dist/useEditorToolbarInteractions.js +218 -0
- package/dist/useEditorToolbarItems.d.ts +8 -0
- package/dist/useEditorToolbarItems.js +280 -0
- package/dist/useEditorToolbarPresentation.d.ts +4 -0
- package/dist/useEditorToolbarPresentation.js +203 -0
- package/dist/useEditorToolbarState.d.ts +63 -0
- package/dist/useEditorToolbarState.js +108 -0
- package/dist/useFocusPreservingFrames.d.ts +17 -0
- package/dist/useFocusPreservingFrames.js +108 -0
- package/dist/useNativeEditor.d.ts +66 -0
- package/dist/useNativeEditor.js +370 -0
- package/dist/useRichTextEditorCommands.d.ts +21 -0
- package/dist/useRichTextEditorCommands.js +299 -0
- package/dist/useRichTextEditorEvents.d.ts +18 -0
- package/dist/useRichTextEditorEvents.js +216 -0
- package/dist/useRichTextEditorMentions.d.ts +11 -0
- package/dist/useRichTextEditorMentions.js +316 -0
- package/dist/useRichTextEditorPresentation.d.ts +5 -0
- package/dist/useRichTextEditorPresentation.js +178 -0
- package/dist/useRichTextEditorState.d.ts +180 -0
- package/dist/useRichTextEditorState.js +405 -0
- package/dist/useRichTextEditorUpdates.d.ts +10 -0
- package/dist/useRichTextEditorUpdates.js +308 -0
- package/dist/useViewerAtoms.d.ts +38 -0
- package/dist/useViewerAtoms.js +288 -0
- package/expo-module.config.json +13 -0
- package/ios/EditorAddons.swift +354 -0
- package/ios/EditorCodeHighlighting.swift +184 -0
- package/ios/EditorCore.xcframework/Info.plist +44 -0
- package/ios/EditorCore.xcframework/ios-arm64/libeditor_core.a +0 -0
- package/ios/EditorCore.xcframework/ios-arm64_x86_64-simulator/libeditor_core.a +0 -0
- package/ios/EditorInteractionOverlays.swift +697 -0
- package/ios/EditorLayoutManager.swift +971 -0
- package/ios/EditorNodeTypes.swift +37 -0
- package/ios/EditorStyleSheet.swift +461 -0
- package/ios/EditorTextView+AttributedPatch.swift +305 -0
- package/ios/EditorTextView+Binding.swift +61 -0
- package/ios/EditorTextView+Caret.swift +333 -0
- package/ios/EditorTextView+Commands.swift +203 -0
- package/ios/EditorTextView+Delegate.swift +65 -0
- package/ios/EditorTextView+Diagnostics.swift +225 -0
- package/ios/EditorTextView+DragDrop.swift +290 -0
- package/ios/EditorTextView+ExternalComposition.swift +364 -0
- package/ios/EditorTextView+Images.swift +354 -0
- package/ios/EditorTextView+InputTraits.swift +200 -0
- package/ios/EditorTextView+KeyboardInput.swift +318 -0
- package/ios/EditorTextView+Layout.swift +245 -0
- package/ios/EditorTextView+MarkedText.swift +267 -0
- package/ios/EditorTextView+NativeInputLifecycle.swift +372 -0
- package/ios/EditorTextView+NativeMutation.swift +471 -0
- package/ios/EditorTextView+Reconciliation.swift +97 -0
- package/ios/EditorTextView+RenderPatch.swift +573 -0
- package/ios/EditorTextView+Rendering.swift +539 -0
- package/ios/EditorTextView+Selection.swift +542 -0
- package/ios/EditorTextView.swift +953 -0
- package/ios/EditorTheme.swift +626 -0
- package/ios/EditorV2Adapter+Commands.swift +204 -0
- package/ios/EditorV2Adapter+Envelope.swift +238 -0
- package/ios/EditorV2Adapter+Mutation.swift +392 -0
- package/ios/EditorV2Adapter+Registry.swift +185 -0
- package/ios/EditorV2Adapter+RenderState.swift +360 -0
- package/ios/EditorV2Adapter+RenderValidation.swift +420 -0
- package/ios/EditorV2Adapter+Selection.swift +329 -0
- package/ios/EditorV2Adapter+TextCommands.swift +430 -0
- package/ios/EditorV2Adapter.swift +376 -0
- package/ios/EditorV2Shadow.swift +353 -0
- package/ios/Generated_editor_core.swift +2378 -0
- package/ios/NativeCodeHighlighting.swift +159 -0
- package/ios/NativeCollaborationSocket.swift +144 -0
- package/ios/NativeCollaborationTransport+Protocol.swift +258 -0
- package/ios/NativeCollaborationTransport+Socket.swift +379 -0
- package/ios/NativeCollaborationTransport+Validation.swift +103 -0
- package/ios/NativeCollaborationTransport.swift +322 -0
- package/ios/NativeCollaborationTransportRegistry.swift +521 -0
- package/ios/NativeEditorExpoView+AccessoryRetry.swift +219 -0
- package/ios/NativeEditorExpoView+Binding.swift +268 -0
- package/ios/NativeEditorExpoView+Diagnostics.swift +66 -0
- package/ios/NativeEditorExpoView+Events.swift +131 -0
- package/ios/NativeEditorExpoView+Focus.swift +169 -0
- package/ios/NativeEditorExpoView+MentionRetry.swift +288 -0
- package/ios/NativeEditorExpoView+Mentions.swift +288 -0
- package/ios/NativeEditorExpoView+Properties.swift +300 -0
- package/ios/NativeEditorExpoView+Toolbar.swift +86 -0
- package/ios/NativeEditorExpoView+Updates.swift +312 -0
- package/ios/NativeEditorExpoView.swift +349 -0
- package/ios/NativeEditorModule.swift +856 -0
- package/ios/NativeEditorViewRegistry.swift +226 -0
- package/ios/NativeToolbar+ButtonStyle.swift +214 -0
- package/ios/NativeToolbar+Buttons.swift +228 -0
- package/ios/NativeToolbar+Diagnostics.swift +114 -0
- package/ios/NativeToolbar+Menu.swift +101 -0
- package/ios/NativeToolbar+Models.swift +519 -0
- package/ios/NativeToolbar+Placeholder.swift +39 -0
- package/ios/NativeToolbar.swift +612 -0
- package/ios/OrderedListMarkerFormatter.swift +103 -0
- package/ios/PositionBridge.swift +596 -0
- package/ios/ProseViewerView.swift +462 -0
- package/ios/RenderBridge+Atoms.swift +288 -0
- package/ios/RenderBridge+Attachments.swift +246 -0
- package/ios/RenderBridge+BlockBoundaries.swift +313 -0
- package/ios/RenderBridge+Style.swift +343 -0
- package/ios/RenderBridge.swift +704 -0
- package/ios/RichTextEditorView.swift +930 -0
- package/ios/SharedNativeImagePipeline+Cache.swift +189 -0
- package/ios/SharedNativeImagePipeline+Transport.swift +328 -0
- package/ios/SharedNativeImagePipeline.swift +533 -0
- package/ios/Viewer/CoreTextProseLayoutEngine+AttributedText.swift +436 -0
- package/ios/Viewer/CoreTextProseLayoutEngine+Models.swift +322 -0
- package/ios/Viewer/CoreTextProseLayoutEngine.swift +635 -0
- package/ios/Viewer/Fabric/PREPPreparedProseViewerComponentView.h +4 -0
- package/ios/Viewer/Fabric/PREPPreparedProseViewerComponentView.mm +767 -0
- package/ios/Viewer/Fabric/PreparedProseMeasurementsManager.mm +118 -0
- package/ios/Viewer/NativeSVGImageDecoder.h +9 -0
- package/ios/Viewer/NativeSVGImageDecoder.mm +106 -0
- package/ios/Viewer/NativeSVGPreflight.h +11 -0
- package/ios/Viewer/NativeSVGPreflight.mm +219 -0
- package/ios/Viewer/PreparedProseDrawingView.swift +639 -0
- package/ios/Viewer/PreparedProseInstrumentation.swift +387 -0
- package/ios/Viewer/PreparedProseLayout.swift +326 -0
- package/ios/Viewer/PreparedProseLayoutCache.swift +766 -0
- package/ios/Viewer/PreparedProseLayoutRegistry+Artifacts.swift +377 -0
- package/ios/Viewer/PreparedProseLayoutRegistry+Fabric.swift +582 -0
- package/ios/Viewer/PreparedProseLayoutRegistry+FabricOwnership.swift +128 -0
- package/ios/Viewer/PreparedProseLayoutRegistry.swift +381 -0
- package/ios/Viewer/ViewerDocument.swift +575 -0
- package/ios/Viewer/ViewerFontEnvironment.swift +283 -0
- package/ios/Viewer/ViewerImagePipeline.swift +478 -0
- package/ios/editor_coreFFI/editor_coreFFI.h +1023 -0
- package/ios/editor_coreFFI/module.modulemap +7 -0
- package/package.json +151 -0
- package/react-native.config.js +17 -0
- package/rust/android/arm64-v8a/libeditor_core.so +0 -0
- package/rust/android/armeabi-v7a/libeditor_core.so +0 -0
- package/rust/android/x86/libeditor_core.so +0 -0
- package/rust/android/x86_64/libeditor_core.so +0 -0
- package/rust/bindings/kotlin/uniffi/editor_core/editor_core.kt +3146 -0
- package/src/AtomHost.tsx +180 -0
- package/src/DefaultAtomChip.tsx +27 -0
- package/src/EditorAddon.ts +65 -0
- package/src/EditorAddonNormalization.ts +49 -0
- package/src/EditorMentionThemeNormalization.ts +25 -0
- package/src/EditorMentionThemeValidation.ts +133 -0
- package/src/EditorStyleSheet.ts +9 -0
- package/src/EditorStyleSheetNormalization.ts +219 -0
- package/src/EditorStyleSheetTypes.ts +189 -0
- package/src/EditorTheme.ts +196 -0
- package/src/EditorToolbar.tsx +31 -0
- package/src/EditorToolbarComponent.tsx +23 -0
- package/src/EditorToolbarItems.tsx +64 -0
- package/src/EditorToolbarRegistry.tsx +254 -0
- package/src/EditorToolbarTypes.tsx +322 -0
- package/src/EditorToolbarVisuals.tsx +270 -0
- package/src/EditorUpdateRevision.ts +26 -0
- package/src/ExternalTextComposition.ts +658 -0
- package/src/ImageLoadingPolicy.ts +125 -0
- package/src/NativeEditorBoundaryError.ts +345 -0
- package/src/NativeEditorBridge.ts +93 -0
- package/src/NativeEditorCollaborationTransport.ts +493 -0
- package/src/NativeEditorCreateConfig.ts +326 -0
- package/src/NativeEditorCreateJson.ts +579 -0
- package/src/NativeEditorCreateValidation.ts +178 -0
- package/src/NativeEditorDocumentBridge.ts +485 -0
- package/src/NativeEditorDocumentHandle.ts +168 -0
- package/src/NativeEditorLocalAwareness.ts +168 -0
- package/src/NativeEditorNativeModule.ts +97 -0
- package/src/NativeEditorRenderNormalization.ts +320 -0
- package/src/NativeEditorResultNormalization.ts +469 -0
- package/src/NativeEditorTypes.ts +366 -0
- package/src/NativeEditorV2Decimal.ts +13 -0
- package/src/NativeProseViewer.tsx +356 -0
- package/src/NativeRichTextEditor.tsx +33 -0
- package/src/ResourceLimits.ts +187 -0
- package/src/RichTextEditor.tsx +27 -0
- package/src/RichTextEditorNativeTypes.tsx +144 -0
- package/src/RichTextEditorNativeView.tsx +21 -0
- package/src/RichTextEditorSerialization.tsx +381 -0
- package/src/RichTextEditorTypes.tsx +327 -0
- package/src/ViewerConfiguration.ts +23 -0
- package/src/YjsCollaboration.ts +692 -0
- package/src/addons.ts +311 -0
- package/src/atomConstants.ts +3 -0
- package/src/atomInstances.ts +123 -0
- package/src/atomPolicy.ts +47 -0
- package/src/atomUpdates.ts +52 -0
- package/src/atoms.ts +379 -0
- package/src/attributeValidation.ts +116 -0
- package/src/contentExpression.ts +338 -0
- package/src/index.ts +295 -0
- package/src/listMarkers.ts +18 -0
- package/src/schemaDefinition.ts +395 -0
- package/src/schemaDocument.ts +92 -0
- package/src/schemaDocumentConstruction.ts +148 -0
- package/src/schemaNormalization.ts +367 -0
- package/src/schemaPresets.ts +250 -0
- package/src/schemaResolution.ts +242 -0
- package/src/schemas.ts +43 -0
- package/src/specs/PreparedProseViewerNativeComponent.ts +40 -0
- package/src/useEditorToolbarInteractions.tsx +329 -0
- package/src/useEditorToolbarItems.tsx +390 -0
- package/src/useEditorToolbarPresentation.tsx +483 -0
- package/src/useEditorToolbarState.tsx +172 -0
- package/src/useFocusPreservingFrames.ts +171 -0
- package/src/useNativeEditor.ts +534 -0
- package/src/useRichTextEditorCommands.tsx +478 -0
- package/src/useRichTextEditorEvents.tsx +342 -0
- package/src/useRichTextEditorMentions.tsx +441 -0
- package/src/useRichTextEditorPresentation.tsx +563 -0
- package/src/useRichTextEditorState.tsx +620 -0
- package/src/useRichTextEditorUpdates.tsx +403 -0
- package/src/useViewerAtoms.tsx +427 -0
package/dist/atoms.js
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defineAtomNode = defineAtomNode;
|
|
4
|
+
exports.withAtomsSchema = withAtomsSchema;
|
|
5
|
+
exports.serializeEditorAtoms = serializeEditorAtoms;
|
|
6
|
+
const attributeValidation_1 = require("./attributeValidation");
|
|
7
|
+
const atomConstants_1 = require("./atomConstants");
|
|
8
|
+
const atomPolicy_1 = require("./atomPolicy");
|
|
9
|
+
function isAtomComponent(value) {
|
|
10
|
+
if (typeof value === 'function')
|
|
11
|
+
return true;
|
|
12
|
+
if (value == null || typeof value !== 'object' || !('$$typeof' in value))
|
|
13
|
+
return false;
|
|
14
|
+
return (value.$$typeof === Symbol.for('react.memo') ||
|
|
15
|
+
value.$$typeof === Symbol.for('react.forward_ref') ||
|
|
16
|
+
value.$$typeof === Symbol.for('react.lazy'));
|
|
17
|
+
}
|
|
18
|
+
function isSafeTag(tag) {
|
|
19
|
+
return atomPolicy_1.ATOM_HTML_IDENTIFIER.test(tag) && !atomPolicy_1.ATOM_HTML_DENIED_TAGS.has(tag);
|
|
20
|
+
}
|
|
21
|
+
function isSafeAttr(name) {
|
|
22
|
+
return (atomPolicy_1.ATOM_HTML_IDENTIFIER.test(name) &&
|
|
23
|
+
!name.startsWith('on') &&
|
|
24
|
+
!atomPolicy_1.ATOM_HTML_DENIED_ATTRS.has(name));
|
|
25
|
+
}
|
|
26
|
+
function stringRecord(value, label) {
|
|
27
|
+
if (value == null || typeof value !== 'object' || Array.isArray(value)) {
|
|
28
|
+
throw new Error(`${label} must be an object`);
|
|
29
|
+
}
|
|
30
|
+
const result = {};
|
|
31
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
32
|
+
if (typeof entry !== 'string') {
|
|
33
|
+
throw new Error(`${label} '${key}' must be a string`);
|
|
34
|
+
}
|
|
35
|
+
result[key] = entry;
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
function kebabCase(value) {
|
|
40
|
+
return value
|
|
41
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1-$2')
|
|
42
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
43
|
+
.replace(/_/g, '-')
|
|
44
|
+
.toLowerCase();
|
|
45
|
+
}
|
|
46
|
+
function normalizedHtmlRules(config) {
|
|
47
|
+
if (config.html == null || typeof config.html !== 'object' || Array.isArray(config.html)) {
|
|
48
|
+
throw new Error(`atom '${config.name}' requires HTML rules`);
|
|
49
|
+
}
|
|
50
|
+
const raw = config.html;
|
|
51
|
+
if (Object.keys(raw).some((key) => !['tag', 'staticAttrs', 'attrMap'].includes(key))) {
|
|
52
|
+
throw new Error(`atom '${config.name}' has an unknown HTML rule field`);
|
|
53
|
+
}
|
|
54
|
+
if (typeof raw.tag !== 'string' || !isSafeTag(raw.tag)) {
|
|
55
|
+
throw new Error(`atom '${config.name}' has an invalid HTML tag '${String(raw.tag)}'`);
|
|
56
|
+
}
|
|
57
|
+
const staticAttrs = stringRecord(raw.staticAttrs, `atom '${config.name}' staticAttrs`);
|
|
58
|
+
if (Object.keys(staticAttrs).length === 0) {
|
|
59
|
+
throw new Error(`atom '${config.name}' requires a static attribute discriminator`);
|
|
60
|
+
}
|
|
61
|
+
for (const name of Object.keys(staticAttrs)) {
|
|
62
|
+
if (!isSafeAttr(name)) {
|
|
63
|
+
throw new Error(`atom '${config.name}' has an invalid HTML attribute '${name}'`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const attrs = config.attrs ?? {};
|
|
67
|
+
const attrMap = raw.attrMap == null
|
|
68
|
+
? Object.fromEntries(Object.keys(attrs).map((name) => [name, `data-${kebabCase(name)}`]))
|
|
69
|
+
: stringRecord(raw.attrMap, `atom '${config.name}' attrMap`);
|
|
70
|
+
for (const name of Object.keys(attrMap)) {
|
|
71
|
+
if (!Object.prototype.hasOwnProperty.call(attrs, name)) {
|
|
72
|
+
throw new Error(`atom '${config.name}' maps undeclared attribute '${name}'`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
for (const name of Object.keys(attrs)) {
|
|
76
|
+
if (!Object.prototype.hasOwnProperty.call(attrMap, name)) {
|
|
77
|
+
throw new Error(`atom '${config.name}' attrMap is missing '${name}'`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const targets = new Set();
|
|
81
|
+
for (const target of Object.values(attrMap)) {
|
|
82
|
+
if (!isSafeAttr(target)) {
|
|
83
|
+
throw new Error(`atom '${config.name}' has an invalid HTML attribute '${target}'`);
|
|
84
|
+
}
|
|
85
|
+
if (targets.has(target)) {
|
|
86
|
+
throw new Error(`atom '${config.name}' repeats HTML attribute '${target}'`);
|
|
87
|
+
}
|
|
88
|
+
if (Object.prototype.hasOwnProperty.call(staticAttrs, target)) {
|
|
89
|
+
throw new Error(`atom '${config.name}' collides on HTML attribute '${target}'`);
|
|
90
|
+
}
|
|
91
|
+
targets.add(target);
|
|
92
|
+
}
|
|
93
|
+
return { tag: raw.tag, staticAttrs, attrMap };
|
|
94
|
+
}
|
|
95
|
+
function defineAtomNode(config) {
|
|
96
|
+
if (config == null || typeof config !== 'object') {
|
|
97
|
+
throw new Error('atom config must be an object');
|
|
98
|
+
}
|
|
99
|
+
if (typeof config.name !== 'string' || config.name.length === 0) {
|
|
100
|
+
throw new Error('atom name must be a non-empty string');
|
|
101
|
+
}
|
|
102
|
+
if (atomPolicy_1.RESERVED_WIRE_NODE_TYPES.has(config.name)) {
|
|
103
|
+
throw new Error(`atom name '${config.name}' is reserved`);
|
|
104
|
+
}
|
|
105
|
+
if (!isAtomComponent(config.component)) {
|
|
106
|
+
throw new Error(`atom '${config.name}' requires a component`);
|
|
107
|
+
}
|
|
108
|
+
if (config.estimatedHeight != null &&
|
|
109
|
+
(!Number.isFinite(config.estimatedHeight) || config.estimatedHeight < 0)) {
|
|
110
|
+
throw new Error(`atom '${config.name}' estimatedHeight must be non-negative`);
|
|
111
|
+
}
|
|
112
|
+
if ('allowUndeclaredAttrs' in config) {
|
|
113
|
+
throw new Error(`atom '${config.name}' cannot allow undeclared attributes`);
|
|
114
|
+
}
|
|
115
|
+
if (config.attrs != null && (typeof config.attrs !== 'object' || Array.isArray(config.attrs))) {
|
|
116
|
+
throw new Error(`atom '${config.name}' attrs must be an object`);
|
|
117
|
+
}
|
|
118
|
+
for (const [name, spec] of Object.entries(config.attrs ?? {}))
|
|
119
|
+
(0, attributeValidation_1.validateAttributeSpec)(spec, name);
|
|
120
|
+
if (config.idAttribute !== undefined && config.attrs?.[config.idAttribute]?.type !== 'string')
|
|
121
|
+
throw new Error(`atom '${config.name}' identifier attribute must declare type string`);
|
|
122
|
+
const html = normalizedHtmlRules(config);
|
|
123
|
+
const nodeSpec = {
|
|
124
|
+
name: config.name,
|
|
125
|
+
content: '',
|
|
126
|
+
group: 'block',
|
|
127
|
+
role: 'block',
|
|
128
|
+
isVoid: true,
|
|
129
|
+
...(config.attrs == null ? {} : { attrs: config.attrs }),
|
|
130
|
+
html,
|
|
131
|
+
};
|
|
132
|
+
return {
|
|
133
|
+
name: config.name,
|
|
134
|
+
...(config.attrs == null ? {} : { attrs: config.attrs }),
|
|
135
|
+
html,
|
|
136
|
+
component: config.component,
|
|
137
|
+
...(config.idAttribute === undefined ? {} : { idAttribute: config.idAttribute }),
|
|
138
|
+
estimatedHeight: config.estimatedHeight ?? atomConstants_1.DEFAULT_ATOM_CHIP_HEIGHT,
|
|
139
|
+
nodeSpec,
|
|
140
|
+
buildFragmentJson(attrs, descriptor) {
|
|
141
|
+
(0, attributeValidation_1.validateAttributes)(attrs ?? {}, config.attrs ?? {});
|
|
142
|
+
return {
|
|
143
|
+
type: descriptor?.documentNodeName ?? 'doc',
|
|
144
|
+
content: [
|
|
145
|
+
{
|
|
146
|
+
type: config.name,
|
|
147
|
+
...(attrs == null ? {} : { attrs }),
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
};
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function schemaValuesEqual(left, right) {
|
|
155
|
+
if (Object.is(left, right))
|
|
156
|
+
return true;
|
|
157
|
+
if (left == null || right == null || typeof left !== 'object' || typeof right !== 'object') {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
161
|
+
return (Array.isArray(left) &&
|
|
162
|
+
Array.isArray(right) &&
|
|
163
|
+
left.length === right.length &&
|
|
164
|
+
left.every((value, index) => schemaValuesEqual(value, right[index])));
|
|
165
|
+
}
|
|
166
|
+
const leftRecord = left;
|
|
167
|
+
const rightRecord = right;
|
|
168
|
+
const leftKeys = Object.keys(leftRecord).sort();
|
|
169
|
+
const rightKeys = Object.keys(rightRecord).sort();
|
|
170
|
+
return (leftKeys.length === rightKeys.length &&
|
|
171
|
+
leftKeys.every((key, index) => key === rightKeys[index] && schemaValuesEqual(leftRecord[key], rightRecord[key])));
|
|
172
|
+
}
|
|
173
|
+
function assertUnambiguousHtmlRules(nodes) {
|
|
174
|
+
const ruled = nodes.filter((node) => node.html != null);
|
|
175
|
+
for (let rightIndex = 1; rightIndex < ruled.length; rightIndex += 1) {
|
|
176
|
+
const right = ruled[rightIndex];
|
|
177
|
+
for (let leftIndex = 0; leftIndex < rightIndex; leftIndex += 1) {
|
|
178
|
+
const left = ruled[leftIndex];
|
|
179
|
+
if (left.html?.tag !== right.html?.tag)
|
|
180
|
+
continue;
|
|
181
|
+
const leftStatic = left.html?.staticAttrs ?? {};
|
|
182
|
+
const rightStatic = right.html?.staticAttrs ?? {};
|
|
183
|
+
const conflicts = Object.entries(leftStatic).some(([name, value]) => Object.prototype.hasOwnProperty.call(rightStatic, name) &&
|
|
184
|
+
rightStatic[name] !== value);
|
|
185
|
+
if (!conflicts) {
|
|
186
|
+
throw new Error(`ambiguous atom HTML rules for '${left.name}' and '${right.name}'`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function withAtomsSchema(schema, atoms) {
|
|
192
|
+
const nodes = [...schema.nodes];
|
|
193
|
+
let changed = false;
|
|
194
|
+
for (const atom of atoms) {
|
|
195
|
+
const existing = nodes.find((node) => node.name === atom.name);
|
|
196
|
+
if (existing != null) {
|
|
197
|
+
if (!schemaValuesEqual(existing, atom.nodeSpec)) {
|
|
198
|
+
throw new Error(`schema already declares conflicting node '${atom.name}'`);
|
|
199
|
+
}
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
nodes.push(atom.nodeSpec);
|
|
203
|
+
changed = true;
|
|
204
|
+
}
|
|
205
|
+
assertUnambiguousHtmlRules(nodes);
|
|
206
|
+
return changed ? { ...schema, nodes } : schema;
|
|
207
|
+
}
|
|
208
|
+
function serializeEditorAtoms(atoms) {
|
|
209
|
+
if (atoms == null || atoms.length === 0)
|
|
210
|
+
return undefined;
|
|
211
|
+
const serialized = {
|
|
212
|
+
nodeTypes: [],
|
|
213
|
+
estimatedHeights: {},
|
|
214
|
+
};
|
|
215
|
+
for (const atom of atoms) {
|
|
216
|
+
if (Object.prototype.hasOwnProperty.call(serialized.estimatedHeights, atom.name))
|
|
217
|
+
continue;
|
|
218
|
+
serialized.nodeTypes.push(atom.name);
|
|
219
|
+
serialized.estimatedHeights[atom.name] = atom.estimatedHeight ?? atomConstants_1.DEFAULT_ATOM_CHIP_HEIGHT;
|
|
220
|
+
}
|
|
221
|
+
return JSON.stringify(serialized);
|
|
222
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AttrSpec } from './schemas';
|
|
2
|
+
export declare function validateAttribute(value: unknown, spec: AttrSpec, name: string): void;
|
|
3
|
+
export declare function validateAttributeSpec(spec: AttrSpec, name: string): void;
|
|
4
|
+
export declare function validateAttributes(attrs: Record<string, unknown>, specs: Record<string, AttrSpec>): void;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateAttribute = validateAttribute;
|
|
4
|
+
exports.validateAttributeSpec = validateAttributeSpec;
|
|
5
|
+
exports.validateAttributes = validateAttributes;
|
|
6
|
+
function jsonType(value) {
|
|
7
|
+
return Array.isArray(value) ? 'array' : value === null ? 'null' : typeof value;
|
|
8
|
+
}
|
|
9
|
+
function validateJson(value, ancestors = new Set()) {
|
|
10
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean')
|
|
11
|
+
return;
|
|
12
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
13
|
+
return;
|
|
14
|
+
if (typeof value !== 'object' || ancestors.has(value) || ancestors.size > 128)
|
|
15
|
+
throw new Error('Attribute values must be finite, acyclic JSON.');
|
|
16
|
+
if (!Array.isArray(value) &&
|
|
17
|
+
Object.getPrototypeOf(value) !== Object.prototype &&
|
|
18
|
+
Object.getPrototypeOf(value) !== null)
|
|
19
|
+
throw new Error('Attribute values must be plain JSON objects.');
|
|
20
|
+
ancestors.add(value);
|
|
21
|
+
const entries = Array.isArray(value) ? value : Object.values(value);
|
|
22
|
+
for (let index = 0; index < entries.length; index += 1)
|
|
23
|
+
validateJson(entries[index], ancestors);
|
|
24
|
+
ancestors.delete(value);
|
|
25
|
+
}
|
|
26
|
+
function equal(left, right) {
|
|
27
|
+
if (left === right)
|
|
28
|
+
return true;
|
|
29
|
+
if (left == null || right == null || typeof left !== 'object' || typeof right !== 'object')
|
|
30
|
+
return false;
|
|
31
|
+
if (Array.isArray(left) !== Array.isArray(right))
|
|
32
|
+
return false;
|
|
33
|
+
const a = Object.keys(left), b = Object.keys(right);
|
|
34
|
+
return (a.length === b.length &&
|
|
35
|
+
a.every((key) => Object.prototype.hasOwnProperty.call(right, key) &&
|
|
36
|
+
equal(left[key], right[key])));
|
|
37
|
+
}
|
|
38
|
+
function validateAttribute(value, spec, name) {
|
|
39
|
+
validateJson(value);
|
|
40
|
+
const type = jsonType(value);
|
|
41
|
+
if ((spec.type != null && type !== spec.type) || (type === 'number' && !Number.isFinite(value)))
|
|
42
|
+
throw new Error(`invalid attribute '${name}': expected ${spec.type ?? 'finite number'}`);
|
|
43
|
+
if (spec.enum != null && !spec.enum.some((entry) => equal(entry, value)))
|
|
44
|
+
throw new Error(`invalid attribute '${name}': outside enum`);
|
|
45
|
+
const size = typeof value === 'number'
|
|
46
|
+
? value
|
|
47
|
+
: typeof value === 'string'
|
|
48
|
+
? [...value].length
|
|
49
|
+
: Array.isArray(value)
|
|
50
|
+
? value.length
|
|
51
|
+
: undefined;
|
|
52
|
+
if ((spec.min != null && (size == null || size < spec.min)) ||
|
|
53
|
+
(spec.max != null && (size == null || size > spec.max)))
|
|
54
|
+
throw new Error(`invalid attribute '${name}': outside bounds`);
|
|
55
|
+
}
|
|
56
|
+
function validateAttributeSpec(spec, name) {
|
|
57
|
+
if (spec == null || typeof spec !== 'object' || Array.isArray(spec))
|
|
58
|
+
throw new Error(`invalid attribute '${name}' declaration`);
|
|
59
|
+
if (Object.keys(spec).some((key) => !['default', 'type', 'enum', 'min', 'max'].includes(key)))
|
|
60
|
+
throw new Error(`invalid attribute '${name}' declaration field`);
|
|
61
|
+
if (spec.type !== undefined &&
|
|
62
|
+
!['string', 'number', 'boolean', 'object', 'array'].includes(spec.type))
|
|
63
|
+
throw new Error(`invalid attribute '${name}' type`);
|
|
64
|
+
if (spec.min !== undefined || spec.max !== undefined) {
|
|
65
|
+
if (!['number', 'string', 'array'].includes(spec.type ?? '') ||
|
|
66
|
+
(spec.min !== undefined && !Number.isFinite(spec.min)) ||
|
|
67
|
+
(spec.max !== undefined && !Number.isFinite(spec.max)) ||
|
|
68
|
+
(spec.min !== undefined && spec.max !== undefined && spec.min > spec.max))
|
|
69
|
+
throw new Error(`invalid attribute '${name}' bounds`);
|
|
70
|
+
if (spec.type !== 'number' &&
|
|
71
|
+
[spec.min, spec.max].some((bound) => bound !== undefined && (!Number.isInteger(bound) || bound < 0)))
|
|
72
|
+
throw new Error(`invalid attribute '${name}' length bounds`);
|
|
73
|
+
}
|
|
74
|
+
if (spec.enum !== undefined) {
|
|
75
|
+
if (!Array.isArray(spec.enum) || spec.enum.length === 0)
|
|
76
|
+
throw new Error(`invalid attribute '${name}' enum`);
|
|
77
|
+
if (new Set(spec.enum.map(jsonType)).size !== 1)
|
|
78
|
+
throw new Error(`invalid attribute '${name}': enum values must share one JSON type`);
|
|
79
|
+
for (const entry of spec.enum)
|
|
80
|
+
validateAttribute(entry, { ...spec, enum: undefined }, name);
|
|
81
|
+
}
|
|
82
|
+
if (spec.default !== undefined)
|
|
83
|
+
validateAttribute(spec.default, spec, name);
|
|
84
|
+
}
|
|
85
|
+
function validateAttributes(attrs, specs) {
|
|
86
|
+
for (const name of Object.keys(attrs))
|
|
87
|
+
if (!Object.prototype.hasOwnProperty.call(specs, name))
|
|
88
|
+
throw new Error(`undeclared attribute '${name}'`);
|
|
89
|
+
for (const [name, spec] of Object.entries(specs)) {
|
|
90
|
+
const value = Object.prototype.hasOwnProperty.call(attrs, name)
|
|
91
|
+
? attrs[name]
|
|
92
|
+
: spec.default;
|
|
93
|
+
if (value === undefined)
|
|
94
|
+
throw new Error(`required attribute '${name}' missing`);
|
|
95
|
+
validateAttribute(value, spec, name);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const CONTENT_EXPRESSION_MAX_DEPTH = 128;
|
|
2
|
+
export declare const DEFAULT_CONTENT_MAX_NODES = 10000;
|
|
3
|
+
/** Return every referenced node/group symbol, or null for an invalid expression. */
|
|
4
|
+
export declare function contentExpressionSymbols(content: string): string[] | null;
|
|
5
|
+
export declare function acceptingContentSymbols(content: string, existingChildTypes?: readonly string[], symbolMatches?: (childType: string, symbol: string) => boolean): string[];
|
|
6
|
+
export declare function minimalContentMatch<T>(content: string, choose: (symbol: string) => T | undefined, consumeWork?: () => boolean): T[] | undefined;
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_CONTENT_MAX_NODES = exports.CONTENT_EXPRESSION_MAX_DEPTH = void 0;
|
|
4
|
+
exports.contentExpressionSymbols = contentExpressionSymbols;
|
|
5
|
+
exports.acceptingContentSymbols = acceptingContentSymbols;
|
|
6
|
+
exports.minimalContentMatch = minimalContentMatch;
|
|
7
|
+
exports.CONTENT_EXPRESSION_MAX_DEPTH = 128;
|
|
8
|
+
exports.DEFAULT_CONTENT_MAX_NODES = 10000;
|
|
9
|
+
const MAX_AUTOMATON_STATES = 10000;
|
|
10
|
+
const MAX_REPETITION_BOUND = 10000;
|
|
11
|
+
function collectExpressionSymbols(expression, symbols) {
|
|
12
|
+
if (expression.kind === 'symbol') {
|
|
13
|
+
symbols.add(expression.symbol);
|
|
14
|
+
}
|
|
15
|
+
else if (expression.kind !== 'empty') {
|
|
16
|
+
if (expression.kind === 'repeat')
|
|
17
|
+
collectExpressionSymbols(expression.expression, symbols);
|
|
18
|
+
else
|
|
19
|
+
for (const nested of expression.expressions)
|
|
20
|
+
collectExpressionSymbols(nested, symbols);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Return every referenced node/group symbol, or null for an invalid expression. */
|
|
24
|
+
function contentExpressionSymbols(content) {
|
|
25
|
+
try {
|
|
26
|
+
const expression = new ContentExpressionParser(content).parse();
|
|
27
|
+
const compiler = new ContentExpressionCompiler();
|
|
28
|
+
compiler.compile(expression);
|
|
29
|
+
const symbols = new Set();
|
|
30
|
+
collectExpressionSymbols(expression, symbols);
|
|
31
|
+
return [...symbols];
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
class ContentExpressionParser {
|
|
38
|
+
constructor(source) {
|
|
39
|
+
this.source = source;
|
|
40
|
+
this.position = 0;
|
|
41
|
+
this.depth = 0;
|
|
42
|
+
}
|
|
43
|
+
parse() {
|
|
44
|
+
if (this.source.trim() === '')
|
|
45
|
+
return { kind: 'empty' };
|
|
46
|
+
const expression = this.parseAlternation();
|
|
47
|
+
this.skipWhitespace();
|
|
48
|
+
if (!this.atEnd())
|
|
49
|
+
throw new Error(`unexpected '${this.peek()}'`);
|
|
50
|
+
return expression;
|
|
51
|
+
}
|
|
52
|
+
parseAlternation() {
|
|
53
|
+
const expressions = [this.parseSequence()];
|
|
54
|
+
while (true) {
|
|
55
|
+
this.skipWhitespace();
|
|
56
|
+
if (!this.consume('|'))
|
|
57
|
+
break;
|
|
58
|
+
this.skipWhitespace();
|
|
59
|
+
if (this.atEnd() || this.peek() === ')' || this.peek() === '|') {
|
|
60
|
+
throw new Error("missing expression after '|'");
|
|
61
|
+
}
|
|
62
|
+
expressions.push(this.parseSequence());
|
|
63
|
+
}
|
|
64
|
+
return expressions.length === 1 ? expressions[0] : { kind: 'alternation', expressions };
|
|
65
|
+
}
|
|
66
|
+
parseSequence() {
|
|
67
|
+
const expressions = [];
|
|
68
|
+
while (true) {
|
|
69
|
+
this.skipWhitespace();
|
|
70
|
+
if (this.atEnd() || this.peek() === ')' || this.peek() === '|')
|
|
71
|
+
break;
|
|
72
|
+
expressions.push(this.parseRepeated());
|
|
73
|
+
}
|
|
74
|
+
if (expressions.length === 0)
|
|
75
|
+
throw new Error('expected expression');
|
|
76
|
+
return expressions.length === 1 ? expressions[0] : { kind: 'sequence', expressions };
|
|
77
|
+
}
|
|
78
|
+
parseRepeated() {
|
|
79
|
+
const atom = this.parseAtom();
|
|
80
|
+
this.skipWhitespace();
|
|
81
|
+
let expression = atom;
|
|
82
|
+
if (this.consume('?'))
|
|
83
|
+
expression = { kind: 'repeat', expression: atom, min: 0, max: 1 };
|
|
84
|
+
else if (this.consume('*'))
|
|
85
|
+
expression = { kind: 'repeat', expression: atom, min: 0, max: null };
|
|
86
|
+
else if (this.consume('+'))
|
|
87
|
+
expression = { kind: 'repeat', expression: atom, min: 1, max: null };
|
|
88
|
+
else if (this.consume('{'))
|
|
89
|
+
expression = this.parseRange(atom);
|
|
90
|
+
this.skipWhitespace();
|
|
91
|
+
if (['?', '*', '+', '{'].includes(this.peek() ?? '')) {
|
|
92
|
+
throw new Error('multiple quantifiers');
|
|
93
|
+
}
|
|
94
|
+
return expression;
|
|
95
|
+
}
|
|
96
|
+
parseAtom() {
|
|
97
|
+
this.skipWhitespace();
|
|
98
|
+
if (this.consume('(')) {
|
|
99
|
+
if (this.depth >= exports.CONTENT_EXPRESSION_MAX_DEPTH)
|
|
100
|
+
throw new Error('expression nesting too deep');
|
|
101
|
+
this.depth += 1;
|
|
102
|
+
try {
|
|
103
|
+
this.skipWhitespace();
|
|
104
|
+
if (this.peek() === ')')
|
|
105
|
+
throw new Error('empty group');
|
|
106
|
+
const expression = this.parseAlternation();
|
|
107
|
+
this.skipWhitespace();
|
|
108
|
+
if (!this.consume(')'))
|
|
109
|
+
throw new Error("missing ')'");
|
|
110
|
+
return expression;
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
this.depth -= 1;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const start = this.position;
|
|
117
|
+
while (this.peek() != null && /[A-Za-z0-9_-]/.test(this.peek()))
|
|
118
|
+
this.position += 1;
|
|
119
|
+
if (start === this.position)
|
|
120
|
+
throw new Error('expected node or group name');
|
|
121
|
+
return { kind: 'symbol', symbol: this.source.slice(start, this.position) };
|
|
122
|
+
}
|
|
123
|
+
parseRange(expression) {
|
|
124
|
+
const min = this.parseNumber();
|
|
125
|
+
let max;
|
|
126
|
+
if (this.consume('}'))
|
|
127
|
+
max = min;
|
|
128
|
+
else {
|
|
129
|
+
if (!this.consume(','))
|
|
130
|
+
throw new Error("expected ',' or '}'");
|
|
131
|
+
if (this.consume('}'))
|
|
132
|
+
max = null;
|
|
133
|
+
else {
|
|
134
|
+
max = this.parseNumber();
|
|
135
|
+
if (!this.consume('}'))
|
|
136
|
+
throw new Error("expected '}'");
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (max != null && max < min)
|
|
140
|
+
throw new Error('range maximum is smaller than minimum');
|
|
141
|
+
if ((max ?? min) > MAX_REPETITION_BOUND)
|
|
142
|
+
throw new Error('repetition bound too large');
|
|
143
|
+
return { kind: 'repeat', expression, min, max };
|
|
144
|
+
}
|
|
145
|
+
parseNumber() {
|
|
146
|
+
const start = this.position;
|
|
147
|
+
while (this.peek() != null && /[0-9]/.test(this.peek()))
|
|
148
|
+
this.position += 1;
|
|
149
|
+
if (start === this.position)
|
|
150
|
+
throw new Error('expected number');
|
|
151
|
+
const value = Number(this.source.slice(start, this.position));
|
|
152
|
+
if (!Number.isSafeInteger(value) || value > 4294967295)
|
|
153
|
+
throw new Error('invalid count');
|
|
154
|
+
return value;
|
|
155
|
+
}
|
|
156
|
+
skipWhitespace() {
|
|
157
|
+
while (this.peek() != null && /\s/.test(this.peek()))
|
|
158
|
+
this.position += 1;
|
|
159
|
+
}
|
|
160
|
+
peek() {
|
|
161
|
+
return this.source[this.position];
|
|
162
|
+
}
|
|
163
|
+
consume(character) {
|
|
164
|
+
if (this.peek() !== character)
|
|
165
|
+
return false;
|
|
166
|
+
this.position += 1;
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
atEnd() {
|
|
170
|
+
return this.position === this.source.length;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
class ContentExpressionCompiler {
|
|
174
|
+
constructor() {
|
|
175
|
+
this.states = [];
|
|
176
|
+
}
|
|
177
|
+
compile(expression, depth = 0) {
|
|
178
|
+
if (depth > exports.CONTENT_EXPRESSION_MAX_DEPTH)
|
|
179
|
+
throw new Error('expression nesting too deep');
|
|
180
|
+
if (expression.kind === 'empty') {
|
|
181
|
+
const start = this.state();
|
|
182
|
+
const end = this.state();
|
|
183
|
+
this.states[start].epsilon.push(end);
|
|
184
|
+
return [start, end];
|
|
185
|
+
}
|
|
186
|
+
if (expression.kind === 'symbol') {
|
|
187
|
+
const start = this.state();
|
|
188
|
+
const end = this.state();
|
|
189
|
+
this.states[start].transitions.push({ symbol: expression.symbol, target: end });
|
|
190
|
+
return [start, end];
|
|
191
|
+
}
|
|
192
|
+
if (expression.kind === 'sequence') {
|
|
193
|
+
const start = this.state();
|
|
194
|
+
let tail = start;
|
|
195
|
+
for (const nested of expression.expressions) {
|
|
196
|
+
const [nestedStart, nestedEnd] = this.compile(nested, depth + 1);
|
|
197
|
+
this.states[tail].epsilon.push(nestedStart);
|
|
198
|
+
tail = nestedEnd;
|
|
199
|
+
}
|
|
200
|
+
return [start, tail];
|
|
201
|
+
}
|
|
202
|
+
if (expression.kind === 'alternation') {
|
|
203
|
+
const start = this.state();
|
|
204
|
+
const end = this.state();
|
|
205
|
+
for (const nested of expression.expressions) {
|
|
206
|
+
const [nestedStart, nestedEnd] = this.compile(nested, depth + 1);
|
|
207
|
+
this.states[start].epsilon.push(nestedStart);
|
|
208
|
+
this.states[nestedEnd].epsilon.push(end);
|
|
209
|
+
}
|
|
210
|
+
return [start, end];
|
|
211
|
+
}
|
|
212
|
+
return this.compileRepeat(expression.expression, expression.min, expression.max, depth + 1);
|
|
213
|
+
}
|
|
214
|
+
compileRepeat(expression, min, max, depth) {
|
|
215
|
+
const start = this.state();
|
|
216
|
+
const end = this.state();
|
|
217
|
+
let tail = start;
|
|
218
|
+
for (let count = 0; count < min; count += 1) {
|
|
219
|
+
const [itemStart, itemEnd] = this.compile(expression, depth);
|
|
220
|
+
this.states[tail].epsilon.push(itemStart);
|
|
221
|
+
tail = itemEnd;
|
|
222
|
+
}
|
|
223
|
+
if (max == null) {
|
|
224
|
+
this.states[tail].epsilon.push(end);
|
|
225
|
+
const [itemStart, itemEnd] = this.compile(expression, depth);
|
|
226
|
+
this.states[tail].epsilon.push(itemStart);
|
|
227
|
+
this.states[itemEnd].epsilon.push(tail);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
for (let count = min; count < max; count += 1) {
|
|
231
|
+
this.states[tail].epsilon.push(end);
|
|
232
|
+
const [itemStart, itemEnd] = this.compile(expression, depth);
|
|
233
|
+
this.states[tail].epsilon.push(itemStart);
|
|
234
|
+
tail = itemEnd;
|
|
235
|
+
}
|
|
236
|
+
this.states[tail].epsilon.push(end);
|
|
237
|
+
}
|
|
238
|
+
return [start, end];
|
|
239
|
+
}
|
|
240
|
+
state() {
|
|
241
|
+
if (this.states.length >= MAX_AUTOMATON_STATES)
|
|
242
|
+
throw new Error('too many automaton states');
|
|
243
|
+
this.states.push({ epsilon: [], transitions: [] });
|
|
244
|
+
return this.states.length - 1;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function epsilonClosure(states, initial) {
|
|
248
|
+
const result = new Set();
|
|
249
|
+
const pending = [...initial];
|
|
250
|
+
while (pending.length > 0) {
|
|
251
|
+
const state = pending.pop();
|
|
252
|
+
if (result.has(state))
|
|
253
|
+
continue;
|
|
254
|
+
result.add(state);
|
|
255
|
+
pending.push(...states[state].epsilon);
|
|
256
|
+
}
|
|
257
|
+
return result;
|
|
258
|
+
}
|
|
259
|
+
function acceptingContentSymbols(content, existingChildTypes = [], symbolMatches = (child, symbol) => child === symbol) {
|
|
260
|
+
try {
|
|
261
|
+
const expression = new ContentExpressionParser(content).parse();
|
|
262
|
+
const compiler = new ContentExpressionCompiler();
|
|
263
|
+
const [start] = compiler.compile(expression);
|
|
264
|
+
let current = epsilonClosure(compiler.states, [start]);
|
|
265
|
+
for (const childType of existingChildTypes) {
|
|
266
|
+
const next = new Set();
|
|
267
|
+
for (const state of current) {
|
|
268
|
+
for (const transition of compiler.states[state].transitions) {
|
|
269
|
+
if (symbolMatches(childType, transition.symbol))
|
|
270
|
+
next.add(transition.target);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
current = epsilonClosure(compiler.states, next);
|
|
274
|
+
}
|
|
275
|
+
const symbols = new Set();
|
|
276
|
+
for (const state of current) {
|
|
277
|
+
for (const transition of compiler.states[state].transitions) {
|
|
278
|
+
symbols.add(transition.symbol);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return [...symbols].sort();
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
return [];
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function minimalContentMatch(content, choose, consumeWork = () => true) {
|
|
288
|
+
try {
|
|
289
|
+
const expression = new ContentExpressionParser(content).parse();
|
|
290
|
+
const compiler = new ContentExpressionCompiler();
|
|
291
|
+
const [start, accept] = compiler.compile(expression);
|
|
292
|
+
let current = new Map([[start, undefined]]);
|
|
293
|
+
const visited = new Set();
|
|
294
|
+
while (current.size > 0) {
|
|
295
|
+
const closure = new Map();
|
|
296
|
+
const pending = [...current.entries()];
|
|
297
|
+
while (pending.length > 0) {
|
|
298
|
+
if (!consumeWork())
|
|
299
|
+
return undefined;
|
|
300
|
+
const [state, path] = pending.pop();
|
|
301
|
+
if (closure.has(state))
|
|
302
|
+
continue;
|
|
303
|
+
closure.set(state, path);
|
|
304
|
+
for (const target of compiler.states[state].epsilon)
|
|
305
|
+
pending.push([target, path]);
|
|
306
|
+
}
|
|
307
|
+
const accepted = closure.get(accept);
|
|
308
|
+
if (closure.has(accept)) {
|
|
309
|
+
const result = [];
|
|
310
|
+
for (let path = accepted; path; path = path.previous)
|
|
311
|
+
result.push(path.value);
|
|
312
|
+
return result.reverse();
|
|
313
|
+
}
|
|
314
|
+
const next = new Map();
|
|
315
|
+
for (const [state, path] of closure) {
|
|
316
|
+
if (visited.has(state))
|
|
317
|
+
continue;
|
|
318
|
+
visited.add(state);
|
|
319
|
+
for (const transition of compiler.states[state].transitions) {
|
|
320
|
+
if (!consumeWork())
|
|
321
|
+
return undefined;
|
|
322
|
+
const value = choose(transition.symbol);
|
|
323
|
+
if (value !== undefined && !next.has(transition.target)) {
|
|
324
|
+
next.set(transition.target, { value, previous: path });
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
current = next;
|
|
329
|
+
}
|
|
330
|
+
return undefined;
|
|
331
|
+
}
|
|
332
|
+
catch {
|
|
333
|
+
return undefined;
|
|
334
|
+
}
|
|
335
|
+
}
|