@brightspot/ui 3.0.1-cms-ui-migration.2 → 3.0.1-cms-ui-migration.4
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/README.md +56 -37
- package/dist/custom-elements.json +1807 -1807
- package/dist/storybook/assets/{ActionBar.stories-hJ_5cm-P.js → ActionBar.stories-BZAVK1QG.js} +1 -1
- package/dist/storybook/assets/{ActionItem.stories-Bjx2803w.js → ActionItem.stories-BqiWvlWi.js} +1 -1
- package/dist/storybook/assets/{Avatar.stories-Cj0YgZ6f.js → Avatar.stories-DkdB6hd_.js} +1 -1
- package/dist/storybook/assets/{AvatarGroup.stories-Lh_sQFCU.js → AvatarGroup.stories-DODqaIix.js} +1 -1
- package/dist/storybook/assets/{Badge.stories-BL7RUibx.js → Badge.stories-DZoum08S.js} +1 -1
- package/dist/storybook/assets/{Button-BPHNcxqK.js → Button-BkmBgNO-.js} +1 -1
- package/dist/storybook/assets/{Button.stories-CAYO4gdU.js → Button.stories-BFhCL2dp.js} +1 -1
- package/dist/storybook/assets/{ButtonGroup.stories-Cd13Us5K.js → ButtonGroup.stories-DlTGTvkq.js} +1 -1
- package/dist/storybook/assets/{Celebrate.stories-D_KE3Qze.js → Celebrate.stories-m4d4zTEz.js} +1 -1
- package/dist/storybook/assets/{Checkbox.stories-Aj1xgZVn.js → Checkbox.stories-Y253YeU7.js} +1 -1
- package/dist/storybook/assets/{CircularProgress.stories-BecV_v6d.js → CircularProgress.stories-6BD8uV5G.js} +1 -1
- package/dist/storybook/assets/{ClipboardMixin.stories-DU-WiZ2f.js → ClipboardMixin.stories-BkH66rIU.js} +1 -1
- package/dist/storybook/assets/{Color-6BZIO3FS-BYl4KZZn.js → Color-6BZIO3FS-iG0OjPBU.js} +1 -1
- package/dist/storybook/assets/{Colors.stories-BMUVUy2q.js → Colors.stories-BxiyQnEg.js} +1 -1
- package/dist/storybook/assets/{CombinedEffects.stories-FHcPKFm6.js → CombinedEffects.stories-Bs3U7qRl.js} +1 -1
- package/dist/storybook/assets/{ComponentStatesMixin-EMUnfT5y.js → ComponentStatesMixin-DampYb5c.js} +1 -1
- package/dist/storybook/assets/{ComponentStatesMixin.stories-SXq0kzS9.js → ComponentStatesMixin.stories-CZ2OW7as.js} +1 -1
- package/dist/storybook/assets/{CopyToClipboard.stories-u43lhvcI.js → CopyToClipboard.stories-CdlghjaE.js} +1 -1
- package/dist/storybook/assets/{Debounce.stories-BdCn5qgO.js → Debounce.stories-CymT8PnT.js} +1 -1
- package/dist/storybook/assets/{DocsRenderer-LL677BLK-DxiEJ_jx.js → DocsRenderer-LL677BLK-dqHCo-GE.js} +3 -3
- package/dist/storybook/assets/{Dropdown.stories-BWSRwjIF.js → Dropdown.stories-B6JwKg-I.js} +1 -1
- package/dist/storybook/assets/{EmptyState.stories-BpobeZL5.js → EmptyState.stories-Bk229lPH.js} +1 -1
- package/dist/storybook/assets/{Events.stories-CP5kMzpr.js → Events.stories-C8-k9cx8.js} +1 -1
- package/dist/storybook/assets/{Heading.stories-CbJD-oTB.js → Heading.stories-DIdnAQRG.js} +1 -1
- package/dist/storybook/assets/{HueRipple.stories-BOABJ7zw.js → HueRipple.stories-B1gXAEaH.js} +1 -1
- package/dist/storybook/assets/{Icon.stories-CWlUHL4j.js → Icon.stories--1VJ0_yt.js} +1 -1
- package/dist/storybook/assets/{IconButton.stories-BWBs-OLT.js → IconButton.stories-CS2rEIir.js} +1 -1
- package/dist/storybook/assets/{LinearProgress.stories-LZ0GZoxF.js → LinearProgress.stories-Bx0CQQls.js} +1 -1
- package/dist/storybook/assets/{Pagination.stories-CbLaR3P9.js → Pagination.stories-B4AogTXB.js} +1 -1
- package/dist/storybook/assets/{Popover.stories-JHrWqYZw.js → Popover.stories-BR88DPgU.js} +1 -1
- package/dist/storybook/assets/{ReadyMixin-B1H2a9x8.js → ReadyMixin-n6qZO39Y.js} +1 -1
- package/dist/storybook/assets/{RovingTabindexMixin.stories-UMHpYG73.js → RovingTabindexMixin.stories-1xTJSMSv.js} +1 -1
- package/dist/storybook/assets/{Rtc.stories-VQtNSlls.js → Rtc.stories-Rt0A_rUZ.js} +1 -1
- package/dist/storybook/assets/{ScrollShadow.stories-CYdi8Tgp.js → ScrollShadow.stories-CjLdJyYu.js} +1 -1
- package/dist/storybook/assets/{Switch.stories-D8F2hZCf.js → Switch.stories-CF8wO4v2.js} +1 -1
- package/dist/storybook/assets/{Tab.stories-wgBP0lTj.js → Tab.stories-C8XNshog.js} +1 -1
- package/dist/storybook/assets/{Tabs.stories-C00rr5sf.js → Tabs.stories-B01l4rQx.js} +1 -1
- package/dist/storybook/assets/{Throttle.stories-BhQEfJbS.js → Throttle.stories-Bpi0K5j9.js} +1 -1
- package/dist/storybook/assets/{Tooltip.stories-CGoZ5qTn.js → Tooltip.stories-BC4zMiZ1.js} +1 -1
- package/dist/storybook/assets/{Upload.stories-B3K-HAXw.js → Upload.stories-2pWv_fZ1.js} +1 -1
- package/dist/storybook/assets/{UploadItem.stories-71ArSoUh.js → UploadItem.stories-aLeAUM7y.js} +1 -1
- package/dist/storybook/assets/{Welcome.stories-CihlfFXS.js → Welcome.stories-DJV83eb7.js} +1 -1
- package/dist/storybook/assets/{Widget.stories-1u4KbiJM.js → Widget.stories-Cz0i2o6L.js} +1 -1
- package/dist/storybook/assets/{WithTooltip-65CFNBJE-B3Jitxw9.js → WithTooltip-65CFNBJE-D8QwVYG8.js} +1 -1
- package/dist/storybook/assets/{blocks-C1HaXuQB.js → blocks-BFmpEZRy.js} +5 -5
- package/dist/storybook/assets/{formatter-EIJCOSYU-Dy9Lt9fs.js → formatter-EIJCOSYU-CdwdJOPy.js} +1 -1
- package/dist/storybook/assets/if-defined-gbJXriW-.js +1 -0
- package/dist/storybook/assets/{iframe-Dx6IxWXF.js → iframe-CyssRDCd.js} +4 -4
- package/dist/storybook/assets/{index-OrjedSVh.js → index-B82i8dhg.js} +1 -1
- package/dist/storybook/assets/{onFind-YTqjw6W0.js → onFind-BFI1uIxr.js} +1 -1
- package/dist/storybook/assets/{onFind.stories-DEvwTrmx.js → onFind.stories-zZjQs_Gn.js} +1 -1
- package/dist/storybook/assets/{onRemove.stories-D5mO-Lin.js → onRemove.stories-pFBwAIex.js} +1 -1
- package/dist/storybook/assets/{onVisible.stories-C3Rcz0Eb.js → onVisible.stories-5dErOVRq.js} +1 -1
- package/dist/storybook/assets/{style-map-CiMHry7H.js → style-map-D0EcLEWO.js} +1 -1
- package/dist/storybook/assets/{syntaxhighlighter-ED5Y7EFY-DIZnuhb2.js → syntaxhighlighter-ED5Y7EFY--2h_dVga.js} +1 -1
- package/dist/storybook/iframe.html +1 -1
- package/dist/storybook/project.json +1 -1
- package/package.json +16 -2
- package/src/legacy/tool-ui/src/AnalyticsWidget.css +1 -1
- package/src/legacy/tool-ui/src/Board.css +1 -1
- package/src/legacy/tool-ui/src/BulkUpload.css +1 -1
- package/src/legacy/tool-ui/src/ComboInput.css +1 -1
- package/src/legacy/tool-ui/src/Compat.css +5 -5
- package/src/legacy/tool-ui/src/ContentEditDrawer.css +1 -1
- package/src/legacy/tool-ui/src/Dialog.css +1 -1
- package/src/legacy/tool-ui/src/FormFilter.css +1 -1
- package/src/legacy/tool-ui/src/Icon/index.css +1 -1
- package/src/legacy/tool-ui/src/ImageEditor.css +1 -1
- package/src/legacy/tool-ui/src/Incompatible.css +2 -2
- package/src/legacy/tool-ui/src/LinkCarousel.css +1 -1
- package/src/legacy/tool-ui/src/Page.css +1 -1
- package/src/legacy/tool-ui/src/RepeatableContentInputGroup.css +1 -1
- package/src/legacy/tool-ui/src/RichText.css +1 -1
- package/src/legacy/tool-ui/src/SearchWidget.css +2 -2
- package/src/legacy/tool-ui/src/SearchWidgetAdvanced.css +1 -1
- package/src/legacy/tool-ui/src/Widget.css +1 -1
- package/src/legacy/tool-ui/src/main/webapp/dist/v5.5e5d7f655e174ddd85f5.css +5 -0
- package/dist/storybook/assets/if-defined-CA2KmTqA.js +0 -1
- package/docs/adr/0001-retire-cms-ui-package-fold-under-src-legacy.md +0 -78
- package/docs/adr/0002-yarn-workspaces-preserve-cms-ui-deps.md +0 -130
- package/docs/adr/0003-bundle-equivalence-as-fold-acceptance-criterion.md +0 -286
- package/src/legacy/tool-ui/src/main/resources/settings.properties +0 -1
- package/src/legacy/tool-ui/src/main/webapp/WEB-INF/web.xml +0 -81
- package/src/legacy/tool-ui/src/main/webapp/dist/v5.5e3fdf0f0b20b4e3c170.css +0 -5
- package/src/legacy/tool-ui/src/main/webapp/script/bsp-uploader.js +0 -170
- package/src/legacy/tool-ui/src/main/webapp/script/bsp-utils.js +0 -393
- package/src/legacy/tool-ui/src/main/webapp/script/content/layout-element.js +0 -141
- package/src/legacy/tool-ui/src/main/webapp/script/input/query.js +0 -78
- package/src/legacy/tool-ui/src/main/webapp/script/input/workflow.js +0 -718
- package/src/legacy/tool-ui/src/main/webapp/script/jquery.extra.js +0 -633
- package/src/legacy/tool-ui/src/main/webapp/script/v3/Dropbox.js +0 -18
- package/src/legacy/tool-ui/src/main/webapp/script/v3/EditFieldUpdate.js +0 -406
- package/src/legacy/tool-ui/src/main/webapp/script/v3/EditFieldUpdateCache.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/script/v3/Notification.js +0 -151
- package/src/legacy/tool-ui/src/main/webapp/script/v3/content/edit.js +0 -194
- package/src/legacy/tool-ui/src/main/webapp/script/v3/content/state.js +0 -785
- package/src/legacy/tool-ui/src/main/webapp/script/v3/csrf.js +0 -35
- package/src/legacy/tool-ui/src/main/webapp/script/v3/dashboard.js +0 -65
- package/src/legacy/tool-ui/src/main/webapp/script/v3/input/dataTransfer.js +0 -129
- package/src/legacy/tool-ui/src/main/webapp/script/v3/input/file.js +0 -433
- package/src/legacy/tool-ui/src/main/webapp/script/v3/input/object.js +0 -743
- package/src/legacy/tool-ui/src/main/webapp/script/v3/input/read-only.js +0 -17
- package/src/legacy/tool-ui/src/main/webapp/script/v3/jquery.frame.js +0 -478
- package/src/legacy/tool-ui/src/main/webapp/script/v3/jquery.repeatable.js +0 -2406
- package/src/legacy/tool-ui/src/main/webapp/script/v3/plugin/popup.d.ts +0 -2
- package/src/legacy/tool-ui/src/main/webapp/script/v3/plugin/popup.js +0 -446
- package/src/legacy/tool-ui/src/main/webapp/script/v3/search-filters.js +0 -62
- package/src/legacy/tool-ui/src/main/webapp/script/v3/search.js +0 -53
- package/src/legacy/tool-ui/src/main/webapp/script/v3.js +0 -1049
- package/src/legacy/tool-ui/src/main/webapp/v4/Admin.js +0 -16
- package/src/legacy/tool-ui/src/main/webapp/v4/AutoExpand.js +0 -84
- package/src/legacy/tool-ui/src/main/webapp/v4/AutoSubmit.js +0 -68
- package/src/legacy/tool-ui/src/main/webapp/v4/Bridge.js +0 -536
- package/src/legacy/tool-ui/src/main/webapp/v4/CheckboxInput.js +0 -22
- package/src/legacy/tool-ui/src/main/webapp/v4/ColorInput.js +0 -5
- package/src/legacy/tool-ui/src/main/webapp/v4/ColorInputSpectrum.js +0 -107
- package/src/legacy/tool-ui/src/main/webapp/v4/ComboInput.js +0 -1491
- package/src/legacy/tool-ui/src/main/webapp/v4/CommunityWidget.js +0 -29
- package/src/legacy/tool-ui/src/main/webapp/v4/ContentEdit.js +0 -2427
- package/src/legacy/tool-ui/src/main/webapp/v4/ContentLock.js +0 -470
- package/src/legacy/tool-ui/src/main/webapp/v4/ContentReporting.js +0 -32
- package/src/legacy/tool-ui/src/main/webapp/v4/DataTable.js +0 -31
- package/src/legacy/tool-ui/src/main/webapp/v4/DateStringField.js +0 -485
- package/src/legacy/tool-ui/src/main/webapp/v4/Entry.js +0 -264
- package/src/legacy/tool-ui/src/main/webapp/v4/ExternalItemAuth.js +0 -16
- package/src/legacy/tool-ui/src/main/webapp/v4/Form.js +0 -31
- package/src/legacy/tool-ui/src/main/webapp/v4/Hierarchy.js +0 -100
- package/src/legacy/tool-ui/src/main/webapp/v4/Icon.ts +0 -49
- package/src/legacy/tool-ui/src/main/webapp/v4/ImageEditor.js +0 -2403
- package/src/legacy/tool-ui/src/main/webapp/v4/ImageEditorBundle.js +0 -5
- package/src/legacy/tool-ui/src/main/webapp/v4/LinkCarousel.js +0 -40
- package/src/legacy/tool-ui/src/main/webapp/v4/LinkList.js +0 -14
- package/src/legacy/tool-ui/src/main/webapp/v4/LinkTable.js +0 -123
- package/src/legacy/tool-ui/src/main/webapp/v4/Location.js +0 -19
- package/src/legacy/tool-ui/src/main/webapp/v4/LocationMap.js +0 -148
- package/src/legacy/tool-ui/src/main/webapp/v4/LookingGlass.js +0 -24
- package/src/legacy/tool-ui/src/main/webapp/v4/Message.js +0 -14
- package/src/legacy/tool-ui/src/main/webapp/v4/NumberBar.js +0 -32
- package/src/legacy/tool-ui/src/main/webapp/v4/Page.js +0 -890
- package/src/legacy/tool-ui/src/main/webapp/v4/Preview.js +0 -758
- package/src/legacy/tool-ui/src/main/webapp/v4/PreviewEditor.js +0 -86
- package/src/legacy/tool-ui/src/main/webapp/v4/PreviewOverlay.js +0 -1005
- package/src/legacy/tool-ui/src/main/webapp/v4/PubSub.js +0 -47
- package/src/legacy/tool-ui/src/main/webapp/v4/QueryField.js +0 -211
- package/src/legacy/tool-ui/src/main/webapp/v4/RegionMap.js +0 -215
- package/src/legacy/tool-ui/src/main/webapp/v4/RepeatableContentInputGroup.js +0 -160
- package/src/legacy/tool-ui/src/main/webapp/v4/RichTextEditor.js +0 -154
- package/src/legacy/tool-ui/src/main/webapp/v4/SearchFields.js +0 -281
- package/src/legacy/tool-ui/src/main/webapp/v4/SearchResult.js +0 -255
- package/src/legacy/tool-ui/src/main/webapp/v4/SharePreview.js +0 -56
- package/src/legacy/tool-ui/src/main/webapp/v4/Sortable.js +0 -874
- package/src/legacy/tool-ui/src/main/webapp/v4/StyleEmbeddedContent.js +0 -100
- package/src/legacy/tool-ui/src/main/webapp/v4/StyleguidePresets.js +0 -357
- package/src/legacy/tool-ui/src/main/webapp/v4/TabContainer.js +0 -360
- package/src/legacy/tool-ui/src/main/webapp/v4/Taxonomy.js +0 -27
- package/src/legacy/tool-ui/src/main/webapp/v4/ThemeBundleEditor.js +0 -224
- package/src/legacy/tool-ui/src/main/webapp/v4/TimedContent.js +0 -147
- package/src/legacy/tool-ui/src/main/webapp/v4/TimedContentBundle.js +0 -8
- package/src/legacy/tool-ui/src/main/webapp/v4/VideoEditor.js +0 -2417
- package/src/legacy/tool-ui/src/main/webapp/v4/VideoEditorBundle.js +0 -8
- package/src/legacy/tool-ui/src/main/webapp/v4/ViewMirror.js +0 -52
- package/src/legacy/tool-ui/src/main/webapp/v4/ViewPreview.d.ts +0 -13
- package/src/legacy/tool-ui/src/main/webapp/v4/ViewPreview.js +0 -177
- package/src/legacy/tool-ui/src/main/webapp/v4/Widget.js +0 -90
- package/src/legacy/tool-ui/src/main/webapp/v4/__mocks__/fileMock.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/__mocks__/styleMock.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/__mocks__/textArea.mock.js +0 -20
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/globals.js +0 -770
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/ProseMirror.test.js +0 -16
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/index.html +0 -54
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/comment_manager/CommentManager.test.js +0 -29
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/comment_manager/index.html +0 -35
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/custom_keyboard/CustomKeyboard.js +0 -42
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/custom_keyboard/index.html +0 -37
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/enhancement_manager/EnhancementManager.test.js +0 -288
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/enhancement_manager/block.html +0 -38
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/enhancement_manager/inline.html +0 -38
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/enhancement_manager/no-popups.html +0 -38
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/list_manager/ListManager.js +0 -257
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/list_manager/index.html +0 -38
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/menubar/hierarchal.html +0 -33
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/menubar/index.html +0 -33
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/menubar/menubar.test.js +0 -195
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/menubar/small.html +0 -34
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/menubar/tags.html +0 -34
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/placeholder_manager/PlaceholderManager.test.js +0 -134
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/placeholder_manager/has-editable-placeholder.html +0 -32
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/placeholder_manager/has-text.html +0 -34
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/placeholder_manager/index.html +0 -31
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/table_manager/TableManager.test.js +0 -63
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/table_manager/existing.html +0 -48
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/track_manager/TrackManager.test.js +0 -291
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/track_manager/existing.html +0 -39
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/track_manager/insert.html +0 -37
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/Sortable.test.js +0 -105
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/ProseMirror.test.js +0 -41
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/codemirror-shim.test.js +0 -72
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/plugins/collab_manager/CollabManager.test.js +0 -46
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/plugins/enhancement_manager/EnhancementManager.test.js +0 -84
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/plugins/list_manager/ListManager.test.js +0 -54
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/plugins/menubar/menubar.test.js +0 -183
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/plugins/spellcheck/SpellCheck.test.js +0 -45
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/settings/BSSerializer.test.js +0 -346
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/settings/menuItemsBuilder.test.js +0 -226
- package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/utilities.test.js +0 -118
- package/src/legacy/tool-ui/src/main/webapp/v4/appetizeio/Appetizeio.js +0 -5
- package/src/legacy/tool-ui/src/main/webapp/v4/appetizeio/AppetizeioEmbedded.js +0 -113
- package/src/legacy/tool-ui/src/main/webapp/v4/compat/Fetch.js +0 -16
- package/src/legacy/tool-ui/src/main/webapp/v4/compat/jquery.js +0 -32
- package/src/legacy/tool-ui/src/main/webapp/v4/compat/requirejs.js +0 -13
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/Tether.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/TetherLayout.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/closest.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/create.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/find.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/findAll.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/ifClick.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/ifMatches.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/ifUnmodified.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/index.js +0 -5
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/insertBefore.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/insertFirst.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/insertLast.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/onFind.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/onFindOnce.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/onRTEReady.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/onRemove.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/onVisible.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/previousUntil.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/dom/resolveIconCompat.js +0 -40
- package/src/legacy/tool-ui/src/main/webapp/v4/rtc/Socket.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/rtc/index.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/ProseMirror.js +0 -909
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/README.md +0 -68
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/codemirror-shim.d.ts +0 -8
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/codemirror-shim.js +0 -274
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/collab-workflow.jpeg +0 -0
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/interchangeable.ts +0 -250
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/mention.js +0 -90
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/PluginProvider.js +0 -124
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/README.md +0 -46
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/ai_inline_manager/AIInlineManager.ts +0 -124
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/ai_inline_manager/views/AIInlineView.ts +0 -1019
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/ai_manager/AiManager.ts +0 -199
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/collab_manager/CollabManager.js +0 -339
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/collab_manager/views/AvatarView.js +0 -96
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/comment_manager/CommentManager.js +0 -348
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/custom_keyboard/CustomKeyboard.js +0 -110
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/custom_keyboard/README.md +0 -29
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/EnhancementManager.js +0 -428
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/README.md +0 -63
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/commands.js +0 -690
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/constants.js +0 -12
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/enhancement-creation.jpeg +0 -0
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/index.js +0 -15
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/rte-flow.jpeg +0 -0
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/views/ActionButtonView.js +0 -86
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/views/BlockSubmenuView.js +0 -60
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/views/EnhancementView.js +0 -208
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/views/PreviewView.js +0 -102
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/views/SubmenuView.js +0 -365
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/find_replace_manager/FindReplaceManager.js +0 -239
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/find_replace_manager/views/FindView.js +0 -604
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/fullscreen_manager/FullscreenManager.js +0 -57
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/fullscreen_manager/README.md +0 -26
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/fullscreen_manager/commands.js +0 -16
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/fullscreen_manager/index.js +0 -4
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/fullscreen_manager/views/FullscreenView.js +0 -474
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/html_editor_manager/htmlEditorManager.js +0 -66
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/html_editor_manager/views/HtmlEditorView.js +0 -97
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/list_manager/ListManager.js +0 -342
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/list_manager/README.md +0 -50
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/list_manager/commands.js +0 -207
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/list_manager/constants.js +0 -26
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/list_manager/index.js +0 -4
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/menubar/Menubar.js +0 -485
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/menubar/README.md +0 -40
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/menubar/views/MenuView.js +0 -842
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/paste_manager/PasteManager.js +0 -368
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/placeholder_manager/PlaceHolderManager.js +0 -128
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/raw_text_manager/README.md +0 -13
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/raw_text_manager/RawTextManager.js +0 -96
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/spellcheck/index.js +0 -3
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/spellcheck/spellcheck-plugin.js +0 -280
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/spellcheck/spellcheck-service.js +0 -94
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/table_manager/TableManager.js +0 -57
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/table_manager/commands.js +0 -97
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/table_manager/views/TableSizerView.js +0 -88
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/table_manager/views/TableView.js +0 -613
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/track_manager/README.md +0 -13
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/track_manager/TrackManager.js +0 -905
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/BSSerializer.js +0 -819
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/README.md +0 -80
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/commands.js +0 -98
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/constants.d.ts +0 -84
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/constants.js +0 -87
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/index.js +0 -13
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/keymapBuilder.js +0 -223
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/menuItemsBuilder.js +0 -559
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/schemaBuilder.js +0 -1281
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/utilities.d.ts +0 -4
- package/src/legacy/tool-ui/src/main/webapp/v4/rte/utilities.js +0 -359
- package/src/legacy/tool-ui/src/main/webapp/v4/theme/ColorRotator.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/util/debounce.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/util/getComponentKey.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/util/noise.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/util/repaint.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/util/storage.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/util/throttle.js +0 -1
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/AssignmentContent.js +0 -33
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/AssignmentDeskDashboard.js +0 -217
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/AssociatedContentWidget.js +0 -7
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/BulkUpload.js +0 -19
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/Calendar.js +0 -7
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/ClosableWindow.js +0 -13
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/PitchAssignments.js +0 -25
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/PitchContent.js +0 -33
- package/src/legacy/tool-ui/src/main/webapp/v4/widget/Revisions.js +0 -61
package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/ai_inline_manager/views/AIInlineView.ts
DELETED
|
@@ -1,1019 +0,0 @@
|
|
|
1
|
-
import { getPluginState } from '../../../utilities'
|
|
2
|
-
import { html, render, TemplateResult } from 'lit-html'
|
|
3
|
-
import { DOMParser as ProseDOMParser, Schema } from 'prosemirror-model'
|
|
4
|
-
import { EditorView } from 'prosemirror-view'
|
|
5
|
-
import { getLegacyHTMLTextForProsemirror } from '../../../codemirror-shim'
|
|
6
|
-
import create from '../../../../../../../dom/create'
|
|
7
|
-
import moment from 'moment'
|
|
8
|
-
import Cookies from 'js-cookie'
|
|
9
|
-
import DOMPurify from 'dompurify'
|
|
10
|
-
|
|
11
|
-
if (!window.BRIGHTSPOT?.ui.cms.enableV5UI) {
|
|
12
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
13
|
-
// @ts-ignore
|
|
14
|
-
await import('./AIInline.less')
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const BASE_CLASS = 'ProseMirrorAIInline-container'
|
|
18
|
-
const PROMPT_PLACEHOLDER = window.RTE_PROMPT_PLACEHOLDER
|
|
19
|
-
const PROMPT_PREFIX = window.RTE_PROMPT_PREFIX
|
|
20
|
-
const PROMPT_RETRY = window.RTE_PROMPT_RETRY
|
|
21
|
-
const WORKING_ON_IT_TEXT = window.RTE_WORKING_ON_IT
|
|
22
|
-
const ACCEPT_BUTTON_TEXT = window.RTE_ACCEPT
|
|
23
|
-
const DISCARD_BUTTON_TEXT = window.RTE_DISCARD
|
|
24
|
-
const TRY_AGAIN_BUTTON_TEXT = window.RTE_TRY_AGAIN
|
|
25
|
-
const COLLAPSED_CLASS = 'collapsed'
|
|
26
|
-
const CHAT_PAGE_RESPONSES_PATH = (
|
|
27
|
-
window.BRIGHTSPOT?.web?.pagePaths as Record<string, string>
|
|
28
|
-
)?.['com.psddev.ai.chat.ChatPageResponses']
|
|
29
|
-
const PROMPT_SUGGESTIONS_PATH = (
|
|
30
|
-
window.BRIGHTSPOT?.web?.pagePaths as Record<string, string>
|
|
31
|
-
)?.['com.psddev.ai.chat.PromptPage']
|
|
32
|
-
|
|
33
|
-
interface CompliantTagNameMap extends Map<string, string> {
|
|
34
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
35
|
-
[key: string]: any
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* AI Inline widget for the ProseMirror RTE editor.
|
|
40
|
-
* Provides AI-powered text suggestions and editing functionality.
|
|
41
|
-
*/
|
|
42
|
-
class AIInlineView {
|
|
43
|
-
private focused = false
|
|
44
|
-
private isLoading = false
|
|
45
|
-
private retry = false
|
|
46
|
-
private suggestionsFetched = false
|
|
47
|
-
private readonly editorView: EditorView
|
|
48
|
-
private readonly myKey: string
|
|
49
|
-
private readonly userLabel: string
|
|
50
|
-
private readonly userId: string
|
|
51
|
-
private readonly compliantTagNameMap: CompliantTagNameMap
|
|
52
|
-
private readonly dom: HTMLDivElement
|
|
53
|
-
private readonly field: string
|
|
54
|
-
private readonly textArea: HTMLTextAreaElement | null
|
|
55
|
-
private readonly loadingOverlay: HTMLDivElement
|
|
56
|
-
private readonly loadingPromptEle: HTMLDivElement | null
|
|
57
|
-
private readonly objectId?: string
|
|
58
|
-
private readonly typeId?: string
|
|
59
|
-
private readonly contentState?: string
|
|
60
|
-
private inputEle?: HTMLInputElement
|
|
61
|
-
private submitButtonEle?: HTMLButtonElement
|
|
62
|
-
private acceptRejectContainerEle?: HTMLDivElement
|
|
63
|
-
private suggestionsContainer: HTMLElement | null = null
|
|
64
|
-
private sendTrackingEvent?: (interaction: string) => void
|
|
65
|
-
private chatId?: string
|
|
66
|
-
private responseId?: string
|
|
67
|
-
private lastPrompt?: string
|
|
68
|
-
private lastSelectedContent?: string
|
|
69
|
-
private lastSelectionFrom?: number
|
|
70
|
-
private lastSelectionTo?: number
|
|
71
|
-
|
|
72
|
-
constructor(
|
|
73
|
-
editorView: EditorView,
|
|
74
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
75
|
-
myKey: any,
|
|
76
|
-
userLabel: string,
|
|
77
|
-
userId: string,
|
|
78
|
-
compliantTagNameMap: CompliantTagNameMap,
|
|
79
|
-
) {
|
|
80
|
-
this.editorView = editorView
|
|
81
|
-
this.myKey = myKey
|
|
82
|
-
this.userLabel = userLabel
|
|
83
|
-
this.userId = userId
|
|
84
|
-
this.compliantTagNameMap = compliantTagNameMap
|
|
85
|
-
|
|
86
|
-
const editorDom = this.editorView.dom
|
|
87
|
-
const contentForm =
|
|
88
|
-
editorDom.parentElement?.closest<HTMLElement>('.ContentEdit')
|
|
89
|
-
const cig = editorDom.closest<HTMLElement>('.CIG')
|
|
90
|
-
const cigRowParent = editorDom.closest<HTMLElement>('.CIG-row')
|
|
91
|
-
|
|
92
|
-
this.objectId = cig?.dataset?.objectId
|
|
93
|
-
this.typeId = contentForm?.dataset?.typeId
|
|
94
|
-
this.field = cigRowParent?.dataset?.field || ''
|
|
95
|
-
this.contentState = contentForm?.querySelector<HTMLInputElement>(
|
|
96
|
-
`input[name="${contentForm?.dataset?.contentId}/oldValues"]`,
|
|
97
|
-
)?.value
|
|
98
|
-
this.textArea = cigRowParent?.querySelector('textarea') || null
|
|
99
|
-
|
|
100
|
-
this.dom = create('div', {
|
|
101
|
-
class: `${BASE_CLASS} ${COLLAPSED_CLASS}`,
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
render(this.template(), this.dom)
|
|
105
|
-
|
|
106
|
-
this.inputEle =
|
|
107
|
-
this.dom.querySelector<HTMLInputElement>(
|
|
108
|
-
`input.${BASE_CLASS}-inputContainer-input`,
|
|
109
|
-
) ?? undefined
|
|
110
|
-
|
|
111
|
-
// Create loading overlay as a sibling element (not inside the container)
|
|
112
|
-
this.loadingOverlay = create(
|
|
113
|
-
'div',
|
|
114
|
-
{ class: 'ProseMirrorAIInline-loadingOverlay' },
|
|
115
|
-
[
|
|
116
|
-
create('div', { class: 'ProseMirrorAIInline-loadingOverlay-prompt' }),
|
|
117
|
-
create('div', { class: 'ProseMirrorAIInline-loadingOverlay-spinner' }, [
|
|
118
|
-
create('div', {
|
|
119
|
-
class: 'ProseMirrorAIInline-loadingOverlay-spinner-icon',
|
|
120
|
-
}),
|
|
121
|
-
create(
|
|
122
|
-
'div',
|
|
123
|
-
{ class: 'ProseMirrorAIInline-loadingOverlay-spinner-text' },
|
|
124
|
-
WORKING_ON_IT_TEXT,
|
|
125
|
-
),
|
|
126
|
-
]),
|
|
127
|
-
],
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
this.loadingPromptEle = this.loadingOverlay.querySelector<HTMLDivElement>(
|
|
131
|
-
'.ProseMirrorAIInline-loadingOverlay-prompt',
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
this.submitButtonEle =
|
|
135
|
-
this.dom.querySelector<HTMLButtonElement>(
|
|
136
|
-
`button.${BASE_CLASS}-inputContainer-submitButton`,
|
|
137
|
-
) ?? undefined
|
|
138
|
-
|
|
139
|
-
// Create the accept/reject container imperatively (not in lit-html template)
|
|
140
|
-
// so it persists across re-renders when attached to the toolbar button
|
|
141
|
-
this.acceptRejectContainerEle = this.createAcceptRejectContainer()
|
|
142
|
-
|
|
143
|
-
this.inputEle?.addEventListener('focus', (evt: Event) => {
|
|
144
|
-
evt.preventDefault()
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
// We want to keep the top of the AI Inline Editing widget
|
|
148
|
-
// anchored to the bottom of the toolbar, but the toolbar
|
|
149
|
-
// contracts and expands when our editorView contracts and
|
|
150
|
-
// expands (e.g. user toggles preview pane), so this will
|
|
151
|
-
// ensure the top of the widget remains anchored by letting us
|
|
152
|
-
// know when the editorView has implicitly resized itself.
|
|
153
|
-
const ro = new ResizeObserver(() => {
|
|
154
|
-
this.render()
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
ro.observe(this.editorView.dom)
|
|
158
|
-
|
|
159
|
-
this.render()
|
|
160
|
-
this.initTracking()
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Our AI Inline widget markup.
|
|
165
|
-
*/
|
|
166
|
-
private template = (): TemplateResult => html`
|
|
167
|
-
<div class="${BASE_CLASS}-inputContainer">
|
|
168
|
-
<input
|
|
169
|
-
class="${BASE_CLASS}-inputContainer-input"
|
|
170
|
-
type="text"
|
|
171
|
-
data-hide-word-count="true"
|
|
172
|
-
placeholder="${PROMPT_PLACEHOLDER}"
|
|
173
|
-
@keydown=${(e: KeyboardEvent) => {
|
|
174
|
-
if (e.key === 'Enter') {
|
|
175
|
-
e.preventDefault()
|
|
176
|
-
this.sendTrackingEvent?.('submit inline prompt')
|
|
177
|
-
this.submitSuggestion(
|
|
178
|
-
this.editorView,
|
|
179
|
-
this.editorView.state.schema,
|
|
180
|
-
this.inputEle?.value,
|
|
181
|
-
)
|
|
182
|
-
}
|
|
183
|
-
}}
|
|
184
|
-
/>
|
|
185
|
-
<button
|
|
186
|
-
type="button"
|
|
187
|
-
class="${BASE_CLASS}-inputContainer-submitButton"
|
|
188
|
-
aria-label=${window.BRIGHTSPOT?.ai?.submitSuggestion}
|
|
189
|
-
title=${window.BRIGHTSPOT?.ai?.submitSuggestion}
|
|
190
|
-
@click=${() => {
|
|
191
|
-
if (this.isLoading) {
|
|
192
|
-
this.cancelSuggestion()
|
|
193
|
-
} else {
|
|
194
|
-
this.sendTrackingEvent?.('submit inline prompt')
|
|
195
|
-
this.submitSuggestion(
|
|
196
|
-
this.editorView,
|
|
197
|
-
this.editorView.state.schema,
|
|
198
|
-
this.inputEle?.value,
|
|
199
|
-
)
|
|
200
|
-
}
|
|
201
|
-
}}
|
|
202
|
-
></button>
|
|
203
|
-
</div>
|
|
204
|
-
`
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Creates the accept/reject container element imperatively.
|
|
208
|
-
* This is done outside of lit-html so it persists across re-renders.
|
|
209
|
-
*/
|
|
210
|
-
private createAcceptRejectContainer(): HTMLDivElement {
|
|
211
|
-
const acceptButton = create('button', {}, [
|
|
212
|
-
create('span', { class: `${BASE_CLASS}-actions-accept-icon` }),
|
|
213
|
-
ACCEPT_BUTTON_TEXT,
|
|
214
|
-
])
|
|
215
|
-
acceptButton.addEventListener('click', this.handleAccept)
|
|
216
|
-
|
|
217
|
-
const discardButton = create('button', {}, [
|
|
218
|
-
create('span', { class: `${BASE_CLASS}-actions-rejectAll-icon` }),
|
|
219
|
-
DISCARD_BUTTON_TEXT,
|
|
220
|
-
])
|
|
221
|
-
discardButton.addEventListener('click', this.handleDiscard)
|
|
222
|
-
|
|
223
|
-
const tryAgainButton = create('button', {}, [
|
|
224
|
-
create('span', { class: `${BASE_CLASS}-actions-tryAgain-icon` }),
|
|
225
|
-
TRY_AGAIN_BUTTON_TEXT,
|
|
226
|
-
])
|
|
227
|
-
tryAgainButton.addEventListener('click', this.handleTryAgain)
|
|
228
|
-
|
|
229
|
-
const container = create(
|
|
230
|
-
'div',
|
|
231
|
-
{
|
|
232
|
-
class: `${BASE_CLASS}-acceptRejectContainer`,
|
|
233
|
-
hidden: '',
|
|
234
|
-
},
|
|
235
|
-
[
|
|
236
|
-
create('ul', { class: `${BASE_CLASS}-actions`, role: 'menu' }, [
|
|
237
|
-
create(
|
|
238
|
-
'li',
|
|
239
|
-
{
|
|
240
|
-
class: `${BASE_CLASS}-actions-accept ProseMirrorToolbar-action`,
|
|
241
|
-
role: 'menuitem',
|
|
242
|
-
},
|
|
243
|
-
[acceptButton],
|
|
244
|
-
),
|
|
245
|
-
create(
|
|
246
|
-
'li',
|
|
247
|
-
{
|
|
248
|
-
class: `${BASE_CLASS}-actions-rejectAll ProseMirrorToolbar-action`,
|
|
249
|
-
role: 'menuitem',
|
|
250
|
-
},
|
|
251
|
-
[discardButton],
|
|
252
|
-
),
|
|
253
|
-
create(
|
|
254
|
-
'li',
|
|
255
|
-
{
|
|
256
|
-
class: `${BASE_CLASS}-actions-tryAgain ProseMirrorToolbar-action`,
|
|
257
|
-
role: 'menuitem',
|
|
258
|
-
},
|
|
259
|
-
[tryAgainButton],
|
|
260
|
-
),
|
|
261
|
-
]),
|
|
262
|
-
],
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
// Stop click events from propagating to the toolbar button (which would toggle AI inline off)
|
|
266
|
-
container.addEventListener('click', (evt: Event) => {
|
|
267
|
-
evt.stopPropagation()
|
|
268
|
-
})
|
|
269
|
-
|
|
270
|
-
return container
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* Hides the accept/reject container and resets the input field.
|
|
275
|
-
*/
|
|
276
|
-
private hideAcceptRejectContainer(): void {
|
|
277
|
-
if (this.inputEle) {
|
|
278
|
-
this.inputEle.value = ''
|
|
279
|
-
this.inputEle.placeholder = PROMPT_PLACEHOLDER
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if (this.acceptRejectContainerEle) {
|
|
283
|
-
this.acceptRejectContainerEle.setAttribute('hidden', '')
|
|
284
|
-
}
|
|
285
|
-
this.dom.classList.remove('has-suggestions')
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Shows the accept/reject container, recreating and reattaching if needed.
|
|
290
|
-
*/
|
|
291
|
-
private showAcceptRejectContainer(): void {
|
|
292
|
-
// Recreate the container if it was removed from the DOM (e.g., toolbar re-render)
|
|
293
|
-
if (!this.acceptRejectContainerEle?.isConnected) {
|
|
294
|
-
this.acceptRejectContainerEle = this.createAcceptRejectContainer()
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Attach to AI inline toolbar button if not already attached
|
|
298
|
-
if (
|
|
299
|
-
!this.acceptRejectContainerEle.parentElement?.matches(
|
|
300
|
-
"[data-rte-style='rte2-toolbar-ai-inline']",
|
|
301
|
-
)
|
|
302
|
-
) {
|
|
303
|
-
const aiInlineButton = this.editorView.dom
|
|
304
|
-
.closest('.ProseMirrorContainer')
|
|
305
|
-
?.querySelector("[data-rte-style='rte2-toolbar-ai-inline']")
|
|
306
|
-
aiInlineButton?.appendChild(this.acceptRejectContainerEle)
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
this.attachAcceptRejectTracking(this.acceptRejectContainerEle)
|
|
310
|
-
this.acceptRejectContainerEle.removeAttribute('hidden')
|
|
311
|
-
this.dom.classList.add('has-suggestions')
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Accepts the suggested text by removing deleted content and keeping inserted content.
|
|
316
|
-
*/
|
|
317
|
-
private handleAccept = (evt: Event): void => {
|
|
318
|
-
evt.preventDefault()
|
|
319
|
-
|
|
320
|
-
const { state, dispatch } = this.editorView
|
|
321
|
-
const { tr, schema } = state
|
|
322
|
-
|
|
323
|
-
// Find and delete content marked for deletion
|
|
324
|
-
let startPosDel: number | null = null
|
|
325
|
-
let endPosDel: number | null = null
|
|
326
|
-
tr.doc.descendants((node, pos) => {
|
|
327
|
-
node.marks.forEach((mark) => {
|
|
328
|
-
if (mark.type === schema.marks.aiInlineDel) {
|
|
329
|
-
if (startPosDel === null) {
|
|
330
|
-
startPosDel = pos > 0 ? pos - 1 : pos
|
|
331
|
-
}
|
|
332
|
-
endPosDel = pos + node.nodeSize
|
|
333
|
-
}
|
|
334
|
-
})
|
|
335
|
-
})
|
|
336
|
-
|
|
337
|
-
if (startPosDel !== null && endPosDel !== null) {
|
|
338
|
-
tr.delete(startPosDel, endPosDel)
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
// Remove insertion marks from the kept text
|
|
342
|
-
tr.doc.descendants((node, pos) => {
|
|
343
|
-
node.marks.forEach((mark) => {
|
|
344
|
-
if (mark.type === schema.marks.aiInlineIns) {
|
|
345
|
-
tr.removeMark(pos, pos + node.nodeSize, schema.marks.aiInlineIns)
|
|
346
|
-
}
|
|
347
|
-
})
|
|
348
|
-
})
|
|
349
|
-
|
|
350
|
-
this.hideAcceptRejectContainer()
|
|
351
|
-
dispatch(tr)
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/**
|
|
355
|
-
* Rejects the suggested text by removing inserted content and keeping original content.
|
|
356
|
-
*/
|
|
357
|
-
private handleDiscard = (evt: Event): void => {
|
|
358
|
-
evt.preventDefault()
|
|
359
|
-
|
|
360
|
-
const { state, dispatch } = this.editorView
|
|
361
|
-
const { tr, schema } = state
|
|
362
|
-
|
|
363
|
-
// Find and delete inserted content
|
|
364
|
-
let startPosIns: number | null = null
|
|
365
|
-
let endPosIns: number | null = null
|
|
366
|
-
tr.doc.descendants((node, pos) => {
|
|
367
|
-
node.marks.forEach((mark) => {
|
|
368
|
-
if (mark.type === schema.marks.aiInlineIns) {
|
|
369
|
-
if (startPosIns === null) {
|
|
370
|
-
startPosIns = pos > 0 ? pos - 1 : pos
|
|
371
|
-
}
|
|
372
|
-
endPosIns = pos + node.nodeSize
|
|
373
|
-
if (endPosIns < tr.doc.content.size) {
|
|
374
|
-
endPosIns += 1
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
})
|
|
378
|
-
})
|
|
379
|
-
|
|
380
|
-
if (startPosIns !== null && endPosIns !== null) {
|
|
381
|
-
tr.delete(startPosIns, endPosIns)
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
// Remove deletion marks from the kept text
|
|
385
|
-
tr.doc.descendants((node, pos) => {
|
|
386
|
-
node.marks.forEach((mark) => {
|
|
387
|
-
if (mark.type === schema.marks.aiInlineDel) {
|
|
388
|
-
tr.removeMark(pos, pos + node.nodeSize, schema.marks.aiInlineDel)
|
|
389
|
-
}
|
|
390
|
-
})
|
|
391
|
-
})
|
|
392
|
-
|
|
393
|
-
this.hideAcceptRejectContainer()
|
|
394
|
-
dispatch(tr)
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* Discards current suggestion and retries with the last prompt.
|
|
399
|
-
*/
|
|
400
|
-
private handleTryAgain = (evt: Event): void => {
|
|
401
|
-
evt.preventDefault()
|
|
402
|
-
|
|
403
|
-
const { state, dispatch } = this.editorView
|
|
404
|
-
const { tr, schema } = state
|
|
405
|
-
|
|
406
|
-
// Find and delete inserted content
|
|
407
|
-
let startPosIns: number | null = null
|
|
408
|
-
let endPosIns: number | null = null
|
|
409
|
-
tr.doc.descendants((node, pos) => {
|
|
410
|
-
node.marks.forEach((mark) => {
|
|
411
|
-
if (mark.type === schema.marks.aiInlineIns) {
|
|
412
|
-
if (startPosIns === null) {
|
|
413
|
-
startPosIns = pos > 0 ? pos - 1 : pos
|
|
414
|
-
}
|
|
415
|
-
endPosIns = pos + node.nodeSize
|
|
416
|
-
if (endPosIns < tr.doc.content.size) {
|
|
417
|
-
endPosIns += 1
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
})
|
|
421
|
-
})
|
|
422
|
-
|
|
423
|
-
if (startPosIns !== null && endPosIns !== null) {
|
|
424
|
-
tr.delete(startPosIns, endPosIns)
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
// Remove deletion marks but keep the text
|
|
428
|
-
tr.doc.descendants((node, pos) => {
|
|
429
|
-
node.marks.forEach((mark) => {
|
|
430
|
-
if (mark.type === schema.marks.aiInlineDel) {
|
|
431
|
-
tr.removeMark(pos, pos + node.nodeSize, schema.marks.aiInlineDel)
|
|
432
|
-
}
|
|
433
|
-
})
|
|
434
|
-
})
|
|
435
|
-
|
|
436
|
-
// Hide the accept/reject container (but don't reset input)
|
|
437
|
-
if (this.acceptRejectContainerEle) {
|
|
438
|
-
this.acceptRejectContainerEle.setAttribute('hidden', '')
|
|
439
|
-
}
|
|
440
|
-
this.dom.classList.remove('has-suggestions')
|
|
441
|
-
|
|
442
|
-
this.retry = true
|
|
443
|
-
dispatch(tr)
|
|
444
|
-
|
|
445
|
-
// Re-run the last prompt
|
|
446
|
-
if (this.lastPrompt) {
|
|
447
|
-
this.submitSuggestion(
|
|
448
|
-
this.editorView,
|
|
449
|
-
this.editorView.state.schema,
|
|
450
|
-
this.lastPrompt,
|
|
451
|
-
)
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
/**
|
|
456
|
-
* Fetches and displays prompt suggestions automatically
|
|
457
|
-
*/
|
|
458
|
-
private fetchPromptSuggestions = (): void => {
|
|
459
|
-
const query = new URLSearchParams({
|
|
460
|
-
id: this.objectId || '',
|
|
461
|
-
typeId: this.typeId || '',
|
|
462
|
-
field: this.field,
|
|
463
|
-
})
|
|
464
|
-
|
|
465
|
-
const url = PROMPT_SUGGESTIONS_PATH + '?' + query
|
|
466
|
-
fetch(url, {
|
|
467
|
-
method: 'GET',
|
|
468
|
-
})
|
|
469
|
-
.then((response) => {
|
|
470
|
-
if (!response.ok) {
|
|
471
|
-
throw new Error('Network response was not ok: ' + response.statusText)
|
|
472
|
-
}
|
|
473
|
-
return response.text()
|
|
474
|
-
})
|
|
475
|
-
.then((suggestionsHTML) => {
|
|
476
|
-
const suggestionsDom = new DOMParser().parseFromString(
|
|
477
|
-
suggestionsHTML,
|
|
478
|
-
'text/html',
|
|
479
|
-
)
|
|
480
|
-
|
|
481
|
-
// Get the suggestions container from the parsed HTML
|
|
482
|
-
this.suggestionsContainer = suggestionsDom.querySelector(
|
|
483
|
-
'.ProseMirrorAIInline-container-suggestions-dropdown',
|
|
484
|
-
)
|
|
485
|
-
if (!this.suggestionsContainer) {
|
|
486
|
-
console.error('Suggestions container not found in response')
|
|
487
|
-
return
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
// Append the suggestions container to the AI Inline container (this.dom)
|
|
491
|
-
this.dom.appendChild(this.suggestionsContainer)
|
|
492
|
-
// Make suggestions always visible
|
|
493
|
-
this.suggestionsContainer.removeAttribute('hidden')
|
|
494
|
-
|
|
495
|
-
const suggestionsList = this.suggestionsContainer.querySelector(
|
|
496
|
-
'.ProseMirrorAIInline-container-suggestions-list',
|
|
497
|
-
)
|
|
498
|
-
|
|
499
|
-
if (suggestionsList) {
|
|
500
|
-
// Add click handlers to each suggestion button
|
|
501
|
-
suggestionsList
|
|
502
|
-
.querySelectorAll<HTMLButtonElement>(
|
|
503
|
-
'.ProseMirrorAIInline-container-suggestions-list-item:not(.is-empty) button[data-prompt]',
|
|
504
|
-
)
|
|
505
|
-
.forEach((button) => {
|
|
506
|
-
button.addEventListener('click', () => {
|
|
507
|
-
this.sendTrackingEvent?.('click inline prompt suggestion')
|
|
508
|
-
this.submitSuggestion(
|
|
509
|
-
this.editorView,
|
|
510
|
-
this.editorView.state.schema,
|
|
511
|
-
button.dataset.prompt,
|
|
512
|
-
)
|
|
513
|
-
})
|
|
514
|
-
})
|
|
515
|
-
}
|
|
516
|
-
})
|
|
517
|
-
.catch((error) => {
|
|
518
|
-
console.error('Fetch error: ', error)
|
|
519
|
-
})
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
/**
|
|
523
|
-
* Handles the suggestion button click event.
|
|
524
|
-
*/
|
|
525
|
-
private async submitSuggestion(
|
|
526
|
-
view: EditorView,
|
|
527
|
-
schema: Schema,
|
|
528
|
-
prompt?: string,
|
|
529
|
-
): Promise<void> {
|
|
530
|
-
if (!prompt) return
|
|
531
|
-
|
|
532
|
-
// Store the prompt for "Try Again" functionality
|
|
533
|
-
this.lastPrompt = prompt
|
|
534
|
-
|
|
535
|
-
this.isLoading = true
|
|
536
|
-
this.dom.classList.add('is-loading')
|
|
537
|
-
|
|
538
|
-
// Insert loading overlay after the container if not already in DOM
|
|
539
|
-
if (this.loadingOverlay && !this.loadingOverlay.parentElement) {
|
|
540
|
-
this.dom.insertAdjacentElement('afterend', this.loadingOverlay)
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
this.loadingOverlay?.classList.add('is-loading')
|
|
544
|
-
if (this.loadingPromptEle) {
|
|
545
|
-
this.loadingPromptEle.textContent = prompt
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
// Capture retry state at the start (before it gets reset)
|
|
549
|
-
const isRetry = this.retry
|
|
550
|
-
|
|
551
|
-
// Store selection positions on first submission, reuse on retry
|
|
552
|
-
let from: number
|
|
553
|
-
let to: number
|
|
554
|
-
let selectedContent: string
|
|
555
|
-
|
|
556
|
-
if (
|
|
557
|
-
isRetry &&
|
|
558
|
-
this.lastSelectedContent !== undefined &&
|
|
559
|
-
this.lastSelectionFrom !== undefined &&
|
|
560
|
-
this.lastSelectionTo !== undefined
|
|
561
|
-
) {
|
|
562
|
-
// Reuse stored values on retry
|
|
563
|
-
selectedContent = this.lastSelectedContent
|
|
564
|
-
from = this.lastSelectionFrom
|
|
565
|
-
to = this.lastSelectionTo
|
|
566
|
-
} else {
|
|
567
|
-
// Store values on first submission
|
|
568
|
-
const state = view.state
|
|
569
|
-
const selection = state.selection
|
|
570
|
-
from = selection.from
|
|
571
|
-
to = selection.to
|
|
572
|
-
const slice = state.doc.slice(from, to)
|
|
573
|
-
selectedContent = slice.content.textBetween(0, slice.content.size)
|
|
574
|
-
|
|
575
|
-
this.lastSelectedContent = selectedContent
|
|
576
|
-
this.lastSelectionFrom = from
|
|
577
|
-
this.lastSelectionTo = to
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
// Build full prompt once
|
|
581
|
-
let fullPrompt = PROMPT_PREFIX + prompt + ' | ' + selectedContent
|
|
582
|
-
|
|
583
|
-
// Add retry prefix if applicable
|
|
584
|
-
if (this.retry) {
|
|
585
|
-
fullPrompt = PROMPT_RETRY + fullPrompt
|
|
586
|
-
this.retry = false
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
const query = new URLSearchParams({
|
|
590
|
-
id: this.objectId || '',
|
|
591
|
-
typeId: this.typeId || '',
|
|
592
|
-
field: this.field,
|
|
593
|
-
state: this.contentState || '',
|
|
594
|
-
prompt: fullPrompt,
|
|
595
|
-
})
|
|
596
|
-
|
|
597
|
-
this.disableInput(true)
|
|
598
|
-
|
|
599
|
-
// Update UI to show loading state
|
|
600
|
-
const inputElement = this.inputEle
|
|
601
|
-
const originalPlaceholder = inputElement?.placeholder || ''
|
|
602
|
-
const originalValue = inputElement?.value || ''
|
|
603
|
-
|
|
604
|
-
if (inputElement) {
|
|
605
|
-
inputElement.value = ''
|
|
606
|
-
inputElement.placeholder = WORKING_ON_IT_TEXT
|
|
607
|
-
}
|
|
608
|
-
this.submitButtonEle?.classList.add('is-loading')
|
|
609
|
-
|
|
610
|
-
const tempDiv = create('div')
|
|
611
|
-
|
|
612
|
-
try {
|
|
613
|
-
// Make a single request and wait for complete response (no polling needed)
|
|
614
|
-
const response = await fetch(CHAT_PAGE_RESPONSES_PATH, {
|
|
615
|
-
method: 'POST',
|
|
616
|
-
credentials: 'include',
|
|
617
|
-
body: query,
|
|
618
|
-
headers: {
|
|
619
|
-
'Brightspot-CSRF': Cookies.get('bsp.csrf') || '',
|
|
620
|
-
},
|
|
621
|
-
})
|
|
622
|
-
|
|
623
|
-
const text = await response.text()
|
|
624
|
-
|
|
625
|
-
const rteTagNames = new Set(
|
|
626
|
-
((window.RICH_TEXT_ELEMENTS as Array<{ tag: string }>) || []).map((e) =>
|
|
627
|
-
e.tag.toLowerCase(),
|
|
628
|
-
),
|
|
629
|
-
)
|
|
630
|
-
|
|
631
|
-
tempDiv.innerHTML = DOMPurify.sanitize(text, {
|
|
632
|
-
CUSTOM_ELEMENT_HANDLING: {
|
|
633
|
-
tagNameCheck: (tagName: string) =>
|
|
634
|
-
rteTagNames.has(tagName.toLowerCase()), // Allow all registered RichTextElement custom elements
|
|
635
|
-
attributeNameCheck: () => true, // Allow all attributes on custom elements (class, id, label, data-*, etc.)
|
|
636
|
-
allowCustomizedBuiltInElements: true,
|
|
637
|
-
},
|
|
638
|
-
ADD_ATTR: ['link-data', 'data-cms-id', 'data-cms-href'], // Allow Brightspot-specific attributes on standard elements
|
|
639
|
-
})
|
|
640
|
-
} catch (error) {
|
|
641
|
-
console.error('Error fetching AI suggestion:', error)
|
|
642
|
-
this.disableInput(false)
|
|
643
|
-
this.isLoading = false
|
|
644
|
-
return
|
|
645
|
-
} finally {
|
|
646
|
-
// Always restore UI state
|
|
647
|
-
this.submitButtonEle?.classList.remove('is-loading')
|
|
648
|
-
this.dom.classList.remove('is-loading')
|
|
649
|
-
this.loadingOverlay?.classList.remove('is-loading')
|
|
650
|
-
if (inputElement) {
|
|
651
|
-
inputElement.value = originalValue
|
|
652
|
-
inputElement.placeholder = originalPlaceholder
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
// Set the chatId once
|
|
657
|
-
if (!this.chatId) {
|
|
658
|
-
this.chatId =
|
|
659
|
-
tempDiv.querySelector<HTMLElement>('.chatData')?.dataset.chatId
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
// If loading is false, the suggestion was cancelled
|
|
663
|
-
if (!this.isLoading) {
|
|
664
|
-
this.disableInput(false)
|
|
665
|
-
return
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
const responses = tempDiv.querySelectorAll('.AIChat-responseText')
|
|
669
|
-
|
|
670
|
-
if (responses.length > 0) {
|
|
671
|
-
// Get the most recent response
|
|
672
|
-
const recentResponse = responses[responses.length - 1]
|
|
673
|
-
const response = recentResponse?.innerHTML || ''
|
|
674
|
-
this.responseId =
|
|
675
|
-
recentResponse?.closest<HTMLElement>(
|
|
676
|
-
'.AIChat-response',
|
|
677
|
-
)?.dataset.responseId
|
|
678
|
-
|
|
679
|
-
const domFragment = create('div')
|
|
680
|
-
domFragment.innerHTML = getLegacyHTMLTextForProsemirror(
|
|
681
|
-
response,
|
|
682
|
-
view.state.schema,
|
|
683
|
-
this.compliantTagNameMap,
|
|
684
|
-
true,
|
|
685
|
-
)
|
|
686
|
-
|
|
687
|
-
const parsedSlice = ProseDOMParser.fromSchema(schema).parseSlice(
|
|
688
|
-
domFragment,
|
|
689
|
-
{
|
|
690
|
-
preserveWhitespace: 'full',
|
|
691
|
-
},
|
|
692
|
-
)
|
|
693
|
-
|
|
694
|
-
// Create transaction from current state (important for retry after document changes)
|
|
695
|
-
const tr = view.state.tr
|
|
696
|
-
const docSize = view.state.doc.content.size
|
|
697
|
-
|
|
698
|
-
// Clamp positions to valid document range (important for retry after document changes)
|
|
699
|
-
const clampedFrom = Math.min(from, docSize)
|
|
700
|
-
const clampedTo = Math.min(to, docSize)
|
|
701
|
-
|
|
702
|
-
try {
|
|
703
|
-
// Add aiInlineDel mark to the to be replaced text
|
|
704
|
-
tr.addMark(clampedFrom, clampedTo, schema.marks.aiInlineDel.create())
|
|
705
|
-
|
|
706
|
-
// Insert the response after the current selection
|
|
707
|
-
tr.replace(clampedTo, clampedTo, parsedSlice)
|
|
708
|
-
|
|
709
|
-
// Add aiInlineIns mark to the suggested text
|
|
710
|
-
const insertEnd = tr.mapping.map(clampedTo)
|
|
711
|
-
tr.addMark(clampedTo, insertEnd, schema.marks.aiInlineIns.create())
|
|
712
|
-
|
|
713
|
-
this.trackAiUsage(this.textArea, this.chatId, this.responseId)
|
|
714
|
-
|
|
715
|
-
this.disableInput(false)
|
|
716
|
-
this.isLoading = false
|
|
717
|
-
|
|
718
|
-
view.dispatch(tr)
|
|
719
|
-
|
|
720
|
-
// Add AI highlighting in a separate transaction by finding nodes with aiInlineIns
|
|
721
|
-
const time = moment().format('MM/D/YYYY h:mm:ss A')
|
|
722
|
-
const aiMark = schema.marks.ai.create({
|
|
723
|
-
'data-user-label': this.userLabel,
|
|
724
|
-
'data-time': time,
|
|
725
|
-
'data-user-id': this.userId,
|
|
726
|
-
'data-response-id': this.responseId,
|
|
727
|
-
'data-chat-id': this.chatId,
|
|
728
|
-
title: `${this.userLabel}: ${time}`,
|
|
729
|
-
})
|
|
730
|
-
|
|
731
|
-
// Document state after all changes have been made
|
|
732
|
-
const tr2 = view.state.tr
|
|
733
|
-
view.state.doc.descendants((node, pos) => {
|
|
734
|
-
if (node.marks.some((m) => m.type === schema.marks.aiInlineIns)) {
|
|
735
|
-
tr2.addMark(pos, pos + node.nodeSize, aiMark)
|
|
736
|
-
}
|
|
737
|
-
})
|
|
738
|
-
|
|
739
|
-
if (tr2.steps.length > 0) {
|
|
740
|
-
view.dispatch(tr2)
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
this.showAcceptRejectContainer()
|
|
744
|
-
} catch (err) {
|
|
745
|
-
console.error('Error creating/dispatching transaction:', err)
|
|
746
|
-
this.disableInput(false)
|
|
747
|
-
this.isLoading = false
|
|
748
|
-
}
|
|
749
|
-
} else {
|
|
750
|
-
// No responses received, re-enable inputs
|
|
751
|
-
this.disableInput(false)
|
|
752
|
-
this.isLoading = false
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
// Disable input and buttons while suggestion is active
|
|
757
|
-
private cancelSuggestion = async (): Promise<void> => {
|
|
758
|
-
this.isLoading = false
|
|
759
|
-
|
|
760
|
-
const query = new URLSearchParams({
|
|
761
|
-
id: this.objectId || '',
|
|
762
|
-
typeId: this.typeId || '',
|
|
763
|
-
field: this.field,
|
|
764
|
-
state: this.contentState || '',
|
|
765
|
-
action: 'cancel',
|
|
766
|
-
})
|
|
767
|
-
|
|
768
|
-
await fetch(CHAT_PAGE_RESPONSES_PATH, {
|
|
769
|
-
method: 'POST',
|
|
770
|
-
credentials: 'include',
|
|
771
|
-
body: query,
|
|
772
|
-
headers: {
|
|
773
|
-
'Brightspot-CSRF': Cookies.get('bsp.csrf') || '',
|
|
774
|
-
},
|
|
775
|
-
})
|
|
776
|
-
|
|
777
|
-
this.dom.classList.remove('is-loading')
|
|
778
|
-
if (this.loadingOverlay) {
|
|
779
|
-
this.loadingOverlay.classList.remove('is-loading')
|
|
780
|
-
}
|
|
781
|
-
if (this.submitButtonEle) {
|
|
782
|
-
this.submitButtonEle.classList.remove('is-loading')
|
|
783
|
-
}
|
|
784
|
-
if (this.inputEle) {
|
|
785
|
-
this.inputEle.placeholder = PROMPT_PLACEHOLDER
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
this.disableInput(false)
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
// Log the fact that AI Chat was activated on a particular field.
|
|
792
|
-
private trackAiUsage = (
|
|
793
|
-
textarea: HTMLTextAreaElement | null,
|
|
794
|
-
chatId: string | undefined,
|
|
795
|
-
responseId: string | undefined,
|
|
796
|
-
): void => {
|
|
797
|
-
if (textarea && chatId && responseId) {
|
|
798
|
-
// Find the main object's ID
|
|
799
|
-
const contentEditForm = document.querySelector<HTMLFormElement>(
|
|
800
|
-
'form.ContentEdit[data-content-id]',
|
|
801
|
-
)
|
|
802
|
-
|
|
803
|
-
if (!contentEditForm) return
|
|
804
|
-
|
|
805
|
-
let objectId: string
|
|
806
|
-
if (contentEditForm.classList.contains('is-draft')) {
|
|
807
|
-
objectId = contentEditForm.dataset.revisionId || ''
|
|
808
|
-
} else {
|
|
809
|
-
objectId = contentEditForm.dataset.contentId || ''
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
// Find the field's full internal name path
|
|
813
|
-
let fieldName = ''
|
|
814
|
-
let parents = this.getParents(textarea, '.inputContainer')
|
|
815
|
-
parents = parents.reverse()
|
|
816
|
-
for (const parent of parents) {
|
|
817
|
-
if (parent instanceof HTMLElement) {
|
|
818
|
-
fieldName = fieldName.concat(parent.dataset.name + '*')
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
if (objectId && fieldName) {
|
|
823
|
-
// Add hidden input to page that BE can interpret
|
|
824
|
-
const hiddenInput = create('input', {
|
|
825
|
-
type: 'hidden',
|
|
826
|
-
name: objectId + '/aiGeneratedField|' + fieldName,
|
|
827
|
-
value: chatId,
|
|
828
|
-
})
|
|
829
|
-
|
|
830
|
-
const prePublish = contentEditForm.querySelector<HTMLElement>(
|
|
831
|
-
'div.PrePublish[data-prepublish]',
|
|
832
|
-
)
|
|
833
|
-
if (prePublish) {
|
|
834
|
-
prePublish
|
|
835
|
-
.querySelector<HTMLFormElement>('form.PrePublishForm')
|
|
836
|
-
?.prepend(hiddenInput)
|
|
837
|
-
} else {
|
|
838
|
-
contentEditForm.prepend(hiddenInput)
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
// Notify BE to mark this response as being used
|
|
842
|
-
const baseUrl = (
|
|
843
|
-
window.BRIGHTSPOT?.web?.pagePaths as Record<string, string>
|
|
844
|
-
)['com.psddev.ai.cms.tracking.FlagUsedResponsePage']
|
|
845
|
-
const params = new URLSearchParams({
|
|
846
|
-
chatId: chatId,
|
|
847
|
-
responseId: responseId,
|
|
848
|
-
})
|
|
849
|
-
const url = `${baseUrl}?${params}`
|
|
850
|
-
|
|
851
|
-
fetch(url, {
|
|
852
|
-
method: 'get',
|
|
853
|
-
})
|
|
854
|
-
.then((response) => {
|
|
855
|
-
if (!response.ok) {
|
|
856
|
-
throw new Error(
|
|
857
|
-
'Network response was not ok: ' + response.statusText,
|
|
858
|
-
)
|
|
859
|
-
}
|
|
860
|
-
return response.text()
|
|
861
|
-
})
|
|
862
|
-
.catch((error) => {
|
|
863
|
-
console.error('Fetch error: ', error)
|
|
864
|
-
})
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
private disableInput = (disable: boolean): void => {
|
|
870
|
-
if (this.inputEle) {
|
|
871
|
-
this.inputEle.disabled = disable
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
// Disable/enable suggestion buttons
|
|
875
|
-
if (this.suggestionsContainer) {
|
|
876
|
-
const suggestionButtons =
|
|
877
|
-
this.suggestionsContainer.querySelectorAll<HTMLButtonElement>(
|
|
878
|
-
'.ProseMirrorAIInline-container-suggestions-list-item:not(.is-empty) button[data-prompt]',
|
|
879
|
-
)
|
|
880
|
-
suggestionButtons.forEach((button) => {
|
|
881
|
-
button.disabled = disable
|
|
882
|
-
if (disable) {
|
|
883
|
-
button.classList.add('is-disabled')
|
|
884
|
-
} else {
|
|
885
|
-
button.classList.remove('is-disabled')
|
|
886
|
-
}
|
|
887
|
-
})
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
private getParents = (elem: Element, selector: string): Element[] => {
|
|
892
|
-
// Set up a parent array
|
|
893
|
-
const parents: Element[] = []
|
|
894
|
-
|
|
895
|
-
// Push each parent element to the array
|
|
896
|
-
for (
|
|
897
|
-
;
|
|
898
|
-
elem && elem !== document.documentElement;
|
|
899
|
-
elem = <Element>elem.parentNode
|
|
900
|
-
) {
|
|
901
|
-
if (selector) {
|
|
902
|
-
if (elem.matches(selector)) {
|
|
903
|
-
parents.push(elem)
|
|
904
|
-
}
|
|
905
|
-
continue
|
|
906
|
-
}
|
|
907
|
-
parents.push(elem)
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
// Return our parent array
|
|
911
|
-
return parents
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
/**
|
|
915
|
-
* Renders the AI Inline by displaying it if our plugin state
|
|
916
|
-
* has an active state. Also anchors the top of the widget to the bottom
|
|
917
|
-
* of the toolbar, whose height expands and contracts with the UI.
|
|
918
|
-
*/
|
|
919
|
-
private render(): void {
|
|
920
|
-
const pluginState = getPluginState(this.editorView, this.myKey)
|
|
921
|
-
const aiInlineEnabled = pluginState
|
|
922
|
-
?.get('activeStates')
|
|
923
|
-
?.get('toggleAIInline')
|
|
924
|
-
|
|
925
|
-
// Check if there are nodes with meta aiInlineDel or aiInlineIns in the doc
|
|
926
|
-
let aiInlineNodeFound = false
|
|
927
|
-
const { doc } = this.editorView.state
|
|
928
|
-
doc.descendants((node) => {
|
|
929
|
-
if (
|
|
930
|
-
node?.type?.name &&
|
|
931
|
-
(node.marks || []).some(
|
|
932
|
-
(mark) =>
|
|
933
|
-
mark.attrs &&
|
|
934
|
-
(mark.attrs.aiInlineDel ||
|
|
935
|
-
mark.attrs.aiInlineIns ||
|
|
936
|
-
mark.type?.name === 'aiInlineDel' ||
|
|
937
|
-
mark.type?.name === 'aiInlineIns'),
|
|
938
|
-
)
|
|
939
|
-
) {
|
|
940
|
-
aiInlineNodeFound = true
|
|
941
|
-
return false
|
|
942
|
-
}
|
|
943
|
-
return true
|
|
944
|
-
})
|
|
945
|
-
|
|
946
|
-
if (aiInlineEnabled) {
|
|
947
|
-
this.dom.classList.remove(COLLAPSED_CLASS)
|
|
948
|
-
if (!this.focused) {
|
|
949
|
-
this.inputEle?.focus()
|
|
950
|
-
this.focused = true
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
// Load suggestions on first open
|
|
954
|
-
if (!this.suggestionsFetched) {
|
|
955
|
-
this.suggestionsFetched = true
|
|
956
|
-
this.fetchPromptSuggestions()
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
if (aiInlineNodeFound) {
|
|
960
|
-
this.showAcceptRejectContainer()
|
|
961
|
-
}
|
|
962
|
-
} else {
|
|
963
|
-
this.dom.classList.add(COLLAPSED_CLASS)
|
|
964
|
-
this.focused = false
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
update(): void {
|
|
969
|
-
this.render()
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
// Tracking: The standard trackingManager.track() pattern relies on onFind to
|
|
973
|
-
// discover elements, but ProseMirror containers are excluded from onFind's observation
|
|
974
|
-
// scope. Instead, we call trackingManager.sendData() directly with manual click listeners.
|
|
975
|
-
private async initTracking(): Promise<void> {
|
|
976
|
-
const analytics = await import(
|
|
977
|
-
/* webpackIgnore: true */ 'bsp-tracking'
|
|
978
|
-
).catch(() => null)
|
|
979
|
-
if (!analytics) return
|
|
980
|
-
|
|
981
|
-
const { trackingManager } = analytics
|
|
982
|
-
this.sendTrackingEvent = (interaction: string) => {
|
|
983
|
-
trackingManager?.sendData('click', {
|
|
984
|
-
feature: 'ai_create',
|
|
985
|
-
interaction: interaction,
|
|
986
|
-
})
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
this.editorView.dom
|
|
990
|
-
.closest('.ProseMirrorContainer')
|
|
991
|
-
?.querySelector('a.rte2-toolbar-ai-inline')
|
|
992
|
-
?.addEventListener('click', () =>
|
|
993
|
-
this.sendTrackingEvent?.('click AI inline (rte toolbar)'),
|
|
994
|
-
)
|
|
995
|
-
|
|
996
|
-
// Attach to existing accept/reject container (if already created)
|
|
997
|
-
this.attachAcceptRejectTracking(this.acceptRejectContainerEle)
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
private attachAcceptRejectTracking(container?: HTMLElement): void {
|
|
1001
|
-
if (!container || !this.sendTrackingEvent) return
|
|
1002
|
-
if (container.dataset.trackingAttached) return
|
|
1003
|
-
container.dataset.trackingAttached = 'true'
|
|
1004
|
-
|
|
1005
|
-
container
|
|
1006
|
-
.querySelector(`.${BASE_CLASS}-actions-accept button`)
|
|
1007
|
-
?.addEventListener('click', () =>
|
|
1008
|
-
this.sendTrackingEvent?.('accept inline response'),
|
|
1009
|
-
)
|
|
1010
|
-
|
|
1011
|
-
container
|
|
1012
|
-
.querySelector(`.${BASE_CLASS}-actions-rejectAll button`)
|
|
1013
|
-
?.addEventListener('click', () =>
|
|
1014
|
-
this.sendTrackingEvent?.('reject inline response'),
|
|
1015
|
-
)
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
export { AIInlineView }
|