@brightspot/ui 3.0.1-cms-ui-migration.2 → 3.0.1-cms-ui-migration.3

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.
Files changed (297) hide show
  1. package/README.md +54 -35
  2. package/dist/custom-elements.json +1924 -1924
  3. package/dist/storybook/assets/{ActionBar.stories-hJ_5cm-P.js → ActionBar.stories-CSxtZl7v.js} +1 -1
  4. package/dist/storybook/assets/{ActionItem.stories-Bjx2803w.js → ActionItem.stories-BWcMRMP3.js} +1 -1
  5. package/dist/storybook/assets/{Avatar.stories-Cj0YgZ6f.js → Avatar.stories-CYTUGXzH.js} +1 -1
  6. package/dist/storybook/assets/{AvatarGroup.stories-Lh_sQFCU.js → AvatarGroup.stories-CSYBYo_5.js} +1 -1
  7. package/dist/storybook/assets/{Badge.stories-BL7RUibx.js → Badge.stories-LuF4BuVr.js} +1 -1
  8. package/dist/storybook/assets/{Button-BPHNcxqK.js → Button-CrXCMxHb.js} +1 -1
  9. package/dist/storybook/assets/{Button.stories-CAYO4gdU.js → Button.stories-JVwxdrdM.js} +1 -1
  10. package/dist/storybook/assets/{ButtonGroup.stories-Cd13Us5K.js → ButtonGroup.stories-qtq64a1H.js} +1 -1
  11. package/dist/storybook/assets/{Celebrate.stories-D_KE3Qze.js → Celebrate.stories-DjTtaSd6.js} +1 -1
  12. package/dist/storybook/assets/{Checkbox.stories-Aj1xgZVn.js → Checkbox.stories-v1Pr5mL6.js} +1 -1
  13. package/dist/storybook/assets/{CircularProgress.stories-BecV_v6d.js → CircularProgress.stories-DkV7PJ4D.js} +1 -1
  14. package/dist/storybook/assets/{ClipboardMixin.stories-DU-WiZ2f.js → ClipboardMixin.stories-Dh5c7uSM.js} +1 -1
  15. package/dist/storybook/assets/{Color-6BZIO3FS-BYl4KZZn.js → Color-6BZIO3FS-B1gcREt6.js} +1 -1
  16. package/dist/storybook/assets/{Colors.stories-BMUVUy2q.js → Colors.stories-DnubtRqn.js} +1 -1
  17. package/dist/storybook/assets/{CombinedEffects.stories-FHcPKFm6.js → CombinedEffects.stories-By6akSve.js} +1 -1
  18. package/dist/storybook/assets/{ComponentStatesMixin-EMUnfT5y.js → ComponentStatesMixin-CPLGv3h-.js} +1 -1
  19. package/dist/storybook/assets/{ComponentStatesMixin.stories-SXq0kzS9.js → ComponentStatesMixin.stories-CiQ_lyhm.js} +1 -1
  20. package/dist/storybook/assets/{CopyToClipboard.stories-u43lhvcI.js → CopyToClipboard.stories-cJ7rl3mj.js} +1 -1
  21. package/dist/storybook/assets/{Debounce.stories-BdCn5qgO.js → Debounce.stories-Bw-goobU.js} +1 -1
  22. package/dist/storybook/assets/{DocsRenderer-LL677BLK-DxiEJ_jx.js → DocsRenderer-LL677BLK-CNW57dGQ.js} +3 -3
  23. package/dist/storybook/assets/{Dropdown.stories-BWSRwjIF.js → Dropdown.stories-CwC3HXXd.js} +1 -1
  24. package/dist/storybook/assets/{EmptyState.stories-BpobeZL5.js → EmptyState.stories-BUEJwuhP.js} +1 -1
  25. package/dist/storybook/assets/{Events.stories-CP5kMzpr.js → Events.stories-D1mf9buv.js} +1 -1
  26. package/dist/storybook/assets/{Heading.stories-CbJD-oTB.js → Heading.stories-DO906G4P.js} +1 -1
  27. package/dist/storybook/assets/{HueRipple.stories-BOABJ7zw.js → HueRipple.stories-BOySRSZB.js} +1 -1
  28. package/dist/storybook/assets/{Icon.stories-CWlUHL4j.js → Icon.stories-BsqgTbdG.js} +1 -1
  29. package/dist/storybook/assets/{IconButton.stories-BWBs-OLT.js → IconButton.stories-aza1AAKk.js} +1 -1
  30. package/dist/storybook/assets/{LinearProgress.stories-LZ0GZoxF.js → LinearProgress.stories-CDYmiiex.js} +1 -1
  31. package/dist/storybook/assets/{Pagination.stories-CbLaR3P9.js → Pagination.stories-LXB-x7YB.js} +1 -1
  32. package/dist/storybook/assets/{Popover.stories-JHrWqYZw.js → Popover.stories-DY1HesPJ.js} +1 -1
  33. package/dist/storybook/assets/{ReadyMixin-B1H2a9x8.js → ReadyMixin-DmOC67IJ.js} +1 -1
  34. package/dist/storybook/assets/{RovingTabindexMixin.stories-UMHpYG73.js → RovingTabindexMixin.stories-BWy0Rq8d.js} +1 -1
  35. package/dist/storybook/assets/{Rtc.stories-VQtNSlls.js → Rtc.stories-DrmdqqbI.js} +1 -1
  36. package/dist/storybook/assets/{ScrollShadow.stories-CYdi8Tgp.js → ScrollShadow.stories-DiKFPazh.js} +1 -1
  37. package/dist/storybook/assets/{Switch.stories-D8F2hZCf.js → Switch.stories-BgFnw8_z.js} +1 -1
  38. package/dist/storybook/assets/{Tab.stories-wgBP0lTj.js → Tab.stories-c2wLMooF.js} +1 -1
  39. package/dist/storybook/assets/{Tabs.stories-C00rr5sf.js → Tabs.stories-CjH8seNP.js} +1 -1
  40. package/dist/storybook/assets/{Throttle.stories-BhQEfJbS.js → Throttle.stories-CXysc_QE.js} +1 -1
  41. package/dist/storybook/assets/{Tooltip.stories-CGoZ5qTn.js → Tooltip.stories-6qzyByPm.js} +1 -1
  42. package/dist/storybook/assets/{Upload.stories-B3K-HAXw.js → Upload.stories-BLxykydQ.js} +1 -1
  43. package/dist/storybook/assets/{UploadItem.stories-71ArSoUh.js → UploadItem.stories-CcfcqdJW.js} +1 -1
  44. package/dist/storybook/assets/{Welcome.stories-CihlfFXS.js → Welcome.stories-CzYS_3fH.js} +1 -1
  45. package/dist/storybook/assets/{Widget.stories-1u4KbiJM.js → Widget.stories-Du7T4LAI.js} +1 -1
  46. package/dist/storybook/assets/{WithTooltip-65CFNBJE-B3Jitxw9.js → WithTooltip-65CFNBJE-D4LfXdYt.js} +1 -1
  47. package/dist/storybook/assets/{blocks-C1HaXuQB.js → blocks-DR3fGePu.js} +5 -5
  48. package/dist/storybook/assets/{formatter-EIJCOSYU-Dy9Lt9fs.js → formatter-EIJCOSYU-Cf01216O.js} +1 -1
  49. package/dist/storybook/assets/if-defined-DaMmbcIU.js +1 -0
  50. package/dist/storybook/assets/{iframe-Dx6IxWXF.js → iframe-CQArUhO8.js} +4 -4
  51. package/dist/storybook/assets/{index-OrjedSVh.js → index-B1uI_67G.js} +1 -1
  52. package/dist/storybook/assets/{onFind-YTqjw6W0.js → onFind-BpFkN2Rh.js} +1 -1
  53. package/dist/storybook/assets/{onFind.stories-DEvwTrmx.js → onFind.stories-Cxdeg69X.js} +1 -1
  54. package/dist/storybook/assets/{onRemove.stories-D5mO-Lin.js → onRemove.stories-BHEWpNrE.js} +1 -1
  55. package/dist/storybook/assets/{onVisible.stories-C3Rcz0Eb.js → onVisible.stories-DFJ3S_ZS.js} +1 -1
  56. package/dist/storybook/assets/{style-map-CiMHry7H.js → style-map-DJ83UC3V.js} +1 -1
  57. package/dist/storybook/assets/{syntaxhighlighter-ED5Y7EFY-DIZnuhb2.js → syntaxhighlighter-ED5Y7EFY-zYN83mxK.js} +1 -1
  58. package/dist/storybook/iframe.html +1 -1
  59. package/dist/storybook/project.json +1 -1
  60. package/package.json +16 -2
  61. package/dist/storybook/assets/if-defined-CA2KmTqA.js +0 -1
  62. package/src/legacy/tool-ui/src/main/resources/settings.properties +0 -1
  63. package/src/legacy/tool-ui/src/main/webapp/WEB-INF/web.xml +0 -81
  64. package/src/legacy/tool-ui/src/main/webapp/script/bsp-uploader.js +0 -170
  65. package/src/legacy/tool-ui/src/main/webapp/script/bsp-utils.js +0 -393
  66. package/src/legacy/tool-ui/src/main/webapp/script/content/layout-element.js +0 -141
  67. package/src/legacy/tool-ui/src/main/webapp/script/input/query.js +0 -78
  68. package/src/legacy/tool-ui/src/main/webapp/script/input/workflow.js +0 -718
  69. package/src/legacy/tool-ui/src/main/webapp/script/jquery.extra.js +0 -633
  70. package/src/legacy/tool-ui/src/main/webapp/script/v3/Dropbox.js +0 -18
  71. package/src/legacy/tool-ui/src/main/webapp/script/v3/EditFieldUpdate.js +0 -406
  72. package/src/legacy/tool-ui/src/main/webapp/script/v3/EditFieldUpdateCache.js +0 -1
  73. package/src/legacy/tool-ui/src/main/webapp/script/v3/Notification.js +0 -151
  74. package/src/legacy/tool-ui/src/main/webapp/script/v3/content/edit.js +0 -194
  75. package/src/legacy/tool-ui/src/main/webapp/script/v3/content/state.js +0 -785
  76. package/src/legacy/tool-ui/src/main/webapp/script/v3/csrf.js +0 -35
  77. package/src/legacy/tool-ui/src/main/webapp/script/v3/dashboard.js +0 -65
  78. package/src/legacy/tool-ui/src/main/webapp/script/v3/input/dataTransfer.js +0 -129
  79. package/src/legacy/tool-ui/src/main/webapp/script/v3/input/file.js +0 -433
  80. package/src/legacy/tool-ui/src/main/webapp/script/v3/input/object.js +0 -743
  81. package/src/legacy/tool-ui/src/main/webapp/script/v3/input/read-only.js +0 -17
  82. package/src/legacy/tool-ui/src/main/webapp/script/v3/jquery.frame.js +0 -478
  83. package/src/legacy/tool-ui/src/main/webapp/script/v3/jquery.repeatable.js +0 -2406
  84. package/src/legacy/tool-ui/src/main/webapp/script/v3/plugin/popup.d.ts +0 -2
  85. package/src/legacy/tool-ui/src/main/webapp/script/v3/plugin/popup.js +0 -446
  86. package/src/legacy/tool-ui/src/main/webapp/script/v3/search-filters.js +0 -62
  87. package/src/legacy/tool-ui/src/main/webapp/script/v3/search.js +0 -53
  88. package/src/legacy/tool-ui/src/main/webapp/script/v3.js +0 -1049
  89. package/src/legacy/tool-ui/src/main/webapp/v4/Admin.js +0 -16
  90. package/src/legacy/tool-ui/src/main/webapp/v4/AutoExpand.js +0 -84
  91. package/src/legacy/tool-ui/src/main/webapp/v4/AutoSubmit.js +0 -68
  92. package/src/legacy/tool-ui/src/main/webapp/v4/Bridge.js +0 -536
  93. package/src/legacy/tool-ui/src/main/webapp/v4/CheckboxInput.js +0 -22
  94. package/src/legacy/tool-ui/src/main/webapp/v4/ColorInput.js +0 -5
  95. package/src/legacy/tool-ui/src/main/webapp/v4/ColorInputSpectrum.js +0 -107
  96. package/src/legacy/tool-ui/src/main/webapp/v4/ComboInput.js +0 -1491
  97. package/src/legacy/tool-ui/src/main/webapp/v4/CommunityWidget.js +0 -29
  98. package/src/legacy/tool-ui/src/main/webapp/v4/ContentEdit.js +0 -2427
  99. package/src/legacy/tool-ui/src/main/webapp/v4/ContentLock.js +0 -470
  100. package/src/legacy/tool-ui/src/main/webapp/v4/ContentReporting.js +0 -32
  101. package/src/legacy/tool-ui/src/main/webapp/v4/DataTable.js +0 -31
  102. package/src/legacy/tool-ui/src/main/webapp/v4/DateStringField.js +0 -485
  103. package/src/legacy/tool-ui/src/main/webapp/v4/Entry.js +0 -264
  104. package/src/legacy/tool-ui/src/main/webapp/v4/ExternalItemAuth.js +0 -16
  105. package/src/legacy/tool-ui/src/main/webapp/v4/Form.js +0 -31
  106. package/src/legacy/tool-ui/src/main/webapp/v4/Hierarchy.js +0 -100
  107. package/src/legacy/tool-ui/src/main/webapp/v4/Icon.ts +0 -49
  108. package/src/legacy/tool-ui/src/main/webapp/v4/ImageEditor.js +0 -2403
  109. package/src/legacy/tool-ui/src/main/webapp/v4/ImageEditorBundle.js +0 -5
  110. package/src/legacy/tool-ui/src/main/webapp/v4/LinkCarousel.js +0 -40
  111. package/src/legacy/tool-ui/src/main/webapp/v4/LinkList.js +0 -14
  112. package/src/legacy/tool-ui/src/main/webapp/v4/LinkTable.js +0 -123
  113. package/src/legacy/tool-ui/src/main/webapp/v4/Location.js +0 -19
  114. package/src/legacy/tool-ui/src/main/webapp/v4/LocationMap.js +0 -148
  115. package/src/legacy/tool-ui/src/main/webapp/v4/LookingGlass.js +0 -24
  116. package/src/legacy/tool-ui/src/main/webapp/v4/Message.js +0 -14
  117. package/src/legacy/tool-ui/src/main/webapp/v4/NumberBar.js +0 -32
  118. package/src/legacy/tool-ui/src/main/webapp/v4/Page.js +0 -890
  119. package/src/legacy/tool-ui/src/main/webapp/v4/Preview.js +0 -758
  120. package/src/legacy/tool-ui/src/main/webapp/v4/PreviewEditor.js +0 -86
  121. package/src/legacy/tool-ui/src/main/webapp/v4/PreviewOverlay.js +0 -1005
  122. package/src/legacy/tool-ui/src/main/webapp/v4/PubSub.js +0 -47
  123. package/src/legacy/tool-ui/src/main/webapp/v4/QueryField.js +0 -211
  124. package/src/legacy/tool-ui/src/main/webapp/v4/RegionMap.js +0 -215
  125. package/src/legacy/tool-ui/src/main/webapp/v4/RepeatableContentInputGroup.js +0 -160
  126. package/src/legacy/tool-ui/src/main/webapp/v4/RichTextEditor.js +0 -154
  127. package/src/legacy/tool-ui/src/main/webapp/v4/SearchFields.js +0 -281
  128. package/src/legacy/tool-ui/src/main/webapp/v4/SearchResult.js +0 -255
  129. package/src/legacy/tool-ui/src/main/webapp/v4/SharePreview.js +0 -56
  130. package/src/legacy/tool-ui/src/main/webapp/v4/Sortable.js +0 -874
  131. package/src/legacy/tool-ui/src/main/webapp/v4/StyleEmbeddedContent.js +0 -100
  132. package/src/legacy/tool-ui/src/main/webapp/v4/StyleguidePresets.js +0 -357
  133. package/src/legacy/tool-ui/src/main/webapp/v4/TabContainer.js +0 -360
  134. package/src/legacy/tool-ui/src/main/webapp/v4/Taxonomy.js +0 -27
  135. package/src/legacy/tool-ui/src/main/webapp/v4/ThemeBundleEditor.js +0 -224
  136. package/src/legacy/tool-ui/src/main/webapp/v4/TimedContent.js +0 -147
  137. package/src/legacy/tool-ui/src/main/webapp/v4/TimedContentBundle.js +0 -8
  138. package/src/legacy/tool-ui/src/main/webapp/v4/VideoEditor.js +0 -2417
  139. package/src/legacy/tool-ui/src/main/webapp/v4/VideoEditorBundle.js +0 -8
  140. package/src/legacy/tool-ui/src/main/webapp/v4/ViewMirror.js +0 -52
  141. package/src/legacy/tool-ui/src/main/webapp/v4/ViewPreview.d.ts +0 -13
  142. package/src/legacy/tool-ui/src/main/webapp/v4/ViewPreview.js +0 -177
  143. package/src/legacy/tool-ui/src/main/webapp/v4/Widget.js +0 -90
  144. package/src/legacy/tool-ui/src/main/webapp/v4/__mocks__/fileMock.js +0 -1
  145. package/src/legacy/tool-ui/src/main/webapp/v4/__mocks__/styleMock.js +0 -1
  146. package/src/legacy/tool-ui/src/main/webapp/v4/__mocks__/textArea.mock.js +0 -20
  147. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/globals.js +0 -770
  148. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/ProseMirror.test.js +0 -16
  149. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/index.html +0 -54
  150. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/comment_manager/CommentManager.test.js +0 -29
  151. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/comment_manager/index.html +0 -35
  152. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/custom_keyboard/CustomKeyboard.js +0 -42
  153. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/custom_keyboard/index.html +0 -37
  154. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/enhancement_manager/EnhancementManager.test.js +0 -288
  155. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/enhancement_manager/block.html +0 -38
  156. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/enhancement_manager/inline.html +0 -38
  157. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/enhancement_manager/no-popups.html +0 -38
  158. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/list_manager/ListManager.js +0 -257
  159. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/list_manager/index.html +0 -38
  160. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/menubar/hierarchal.html +0 -33
  161. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/menubar/index.html +0 -33
  162. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/menubar/menubar.test.js +0 -195
  163. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/menubar/small.html +0 -34
  164. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/menubar/tags.html +0 -34
  165. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/placeholder_manager/PlaceholderManager.test.js +0 -134
  166. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/placeholder_manager/has-editable-placeholder.html +0 -32
  167. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/placeholder_manager/has-text.html +0 -34
  168. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/placeholder_manager/index.html +0 -31
  169. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/table_manager/TableManager.test.js +0 -63
  170. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/table_manager/existing.html +0 -48
  171. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/track_manager/TrackManager.test.js +0 -291
  172. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/track_manager/existing.html +0 -39
  173. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/integration/rte/plugins/track_manager/insert.html +0 -37
  174. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/Sortable.test.js +0 -105
  175. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/ProseMirror.test.js +0 -41
  176. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/codemirror-shim.test.js +0 -72
  177. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/plugins/collab_manager/CollabManager.test.js +0 -46
  178. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/plugins/enhancement_manager/EnhancementManager.test.js +0 -84
  179. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/plugins/list_manager/ListManager.test.js +0 -54
  180. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/plugins/menubar/menubar.test.js +0 -183
  181. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/plugins/spellcheck/SpellCheck.test.js +0 -45
  182. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/settings/BSSerializer.test.js +0 -346
  183. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/settings/menuItemsBuilder.test.js +0 -226
  184. package/src/legacy/tool-ui/src/main/webapp/v4/__tests__/unit/rte/utilities.test.js +0 -118
  185. package/src/legacy/tool-ui/src/main/webapp/v4/appetizeio/Appetizeio.js +0 -5
  186. package/src/legacy/tool-ui/src/main/webapp/v4/appetizeio/AppetizeioEmbedded.js +0 -113
  187. package/src/legacy/tool-ui/src/main/webapp/v4/compat/Fetch.js +0 -16
  188. package/src/legacy/tool-ui/src/main/webapp/v4/compat/jquery.js +0 -32
  189. package/src/legacy/tool-ui/src/main/webapp/v4/compat/requirejs.js +0 -13
  190. package/src/legacy/tool-ui/src/main/webapp/v4/dom/Tether.js +0 -1
  191. package/src/legacy/tool-ui/src/main/webapp/v4/dom/TetherLayout.js +0 -1
  192. package/src/legacy/tool-ui/src/main/webapp/v4/dom/closest.js +0 -1
  193. package/src/legacy/tool-ui/src/main/webapp/v4/dom/create.js +0 -1
  194. package/src/legacy/tool-ui/src/main/webapp/v4/dom/find.js +0 -1
  195. package/src/legacy/tool-ui/src/main/webapp/v4/dom/findAll.js +0 -1
  196. package/src/legacy/tool-ui/src/main/webapp/v4/dom/ifClick.js +0 -1
  197. package/src/legacy/tool-ui/src/main/webapp/v4/dom/ifMatches.js +0 -1
  198. package/src/legacy/tool-ui/src/main/webapp/v4/dom/ifUnmodified.js +0 -1
  199. package/src/legacy/tool-ui/src/main/webapp/v4/dom/index.js +0 -5
  200. package/src/legacy/tool-ui/src/main/webapp/v4/dom/insertBefore.js +0 -1
  201. package/src/legacy/tool-ui/src/main/webapp/v4/dom/insertFirst.js +0 -1
  202. package/src/legacy/tool-ui/src/main/webapp/v4/dom/insertLast.js +0 -1
  203. package/src/legacy/tool-ui/src/main/webapp/v4/dom/onFind.js +0 -1
  204. package/src/legacy/tool-ui/src/main/webapp/v4/dom/onFindOnce.js +0 -1
  205. package/src/legacy/tool-ui/src/main/webapp/v4/dom/onRTEReady.js +0 -1
  206. package/src/legacy/tool-ui/src/main/webapp/v4/dom/onRemove.js +0 -1
  207. package/src/legacy/tool-ui/src/main/webapp/v4/dom/onVisible.js +0 -1
  208. package/src/legacy/tool-ui/src/main/webapp/v4/dom/previousUntil.js +0 -1
  209. package/src/legacy/tool-ui/src/main/webapp/v4/dom/resolveIconCompat.js +0 -40
  210. package/src/legacy/tool-ui/src/main/webapp/v4/rtc/Socket.js +0 -1
  211. package/src/legacy/tool-ui/src/main/webapp/v4/rtc/index.js +0 -1
  212. package/src/legacy/tool-ui/src/main/webapp/v4/rte/ProseMirror.js +0 -909
  213. package/src/legacy/tool-ui/src/main/webapp/v4/rte/README.md +0 -68
  214. package/src/legacy/tool-ui/src/main/webapp/v4/rte/codemirror-shim.d.ts +0 -8
  215. package/src/legacy/tool-ui/src/main/webapp/v4/rte/codemirror-shim.js +0 -274
  216. package/src/legacy/tool-ui/src/main/webapp/v4/rte/collab-workflow.jpeg +0 -0
  217. package/src/legacy/tool-ui/src/main/webapp/v4/rte/interchangeable.ts +0 -250
  218. package/src/legacy/tool-ui/src/main/webapp/v4/rte/mention.js +0 -90
  219. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/PluginProvider.js +0 -124
  220. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/README.md +0 -46
  221. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/ai_inline_manager/AIInlineManager.ts +0 -124
  222. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/ai_inline_manager/views/AIInlineView.ts +0 -1019
  223. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/ai_manager/AiManager.ts +0 -199
  224. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/collab_manager/CollabManager.js +0 -339
  225. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/collab_manager/views/AvatarView.js +0 -96
  226. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/comment_manager/CommentManager.js +0 -348
  227. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/custom_keyboard/CustomKeyboard.js +0 -110
  228. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/custom_keyboard/README.md +0 -29
  229. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/EnhancementManager.js +0 -428
  230. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/README.md +0 -63
  231. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/commands.js +0 -690
  232. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/constants.js +0 -12
  233. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/enhancement-creation.jpeg +0 -0
  234. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/index.js +0 -15
  235. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/rte-flow.jpeg +0 -0
  236. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/views/ActionButtonView.js +0 -86
  237. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/views/BlockSubmenuView.js +0 -60
  238. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/views/EnhancementView.js +0 -208
  239. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/views/PreviewView.js +0 -102
  240. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/enhancement_manager/views/SubmenuView.js +0 -365
  241. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/find_replace_manager/FindReplaceManager.js +0 -239
  242. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/find_replace_manager/views/FindView.js +0 -604
  243. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/fullscreen_manager/FullscreenManager.js +0 -57
  244. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/fullscreen_manager/README.md +0 -26
  245. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/fullscreen_manager/commands.js +0 -16
  246. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/fullscreen_manager/index.js +0 -4
  247. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/fullscreen_manager/views/FullscreenView.js +0 -474
  248. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/html_editor_manager/htmlEditorManager.js +0 -66
  249. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/html_editor_manager/views/HtmlEditorView.js +0 -97
  250. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/list_manager/ListManager.js +0 -342
  251. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/list_manager/README.md +0 -50
  252. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/list_manager/commands.js +0 -207
  253. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/list_manager/constants.js +0 -26
  254. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/list_manager/index.js +0 -4
  255. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/menubar/Menubar.js +0 -485
  256. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/menubar/README.md +0 -40
  257. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/menubar/views/MenuView.js +0 -842
  258. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/paste_manager/PasteManager.js +0 -368
  259. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/placeholder_manager/PlaceHolderManager.js +0 -128
  260. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/raw_text_manager/README.md +0 -13
  261. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/raw_text_manager/RawTextManager.js +0 -96
  262. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/spellcheck/index.js +0 -3
  263. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/spellcheck/spellcheck-plugin.js +0 -280
  264. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/spellcheck/spellcheck-service.js +0 -94
  265. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/table_manager/TableManager.js +0 -57
  266. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/table_manager/commands.js +0 -97
  267. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/table_manager/views/TableSizerView.js +0 -88
  268. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/table_manager/views/TableView.js +0 -613
  269. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/track_manager/README.md +0 -13
  270. package/src/legacy/tool-ui/src/main/webapp/v4/rte/plugins/track_manager/TrackManager.js +0 -905
  271. package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/BSSerializer.js +0 -819
  272. package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/README.md +0 -80
  273. package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/commands.js +0 -98
  274. package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/constants.d.ts +0 -84
  275. package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/constants.js +0 -87
  276. package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/index.js +0 -13
  277. package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/keymapBuilder.js +0 -223
  278. package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/menuItemsBuilder.js +0 -559
  279. package/src/legacy/tool-ui/src/main/webapp/v4/rte/settings/schemaBuilder.js +0 -1281
  280. package/src/legacy/tool-ui/src/main/webapp/v4/rte/utilities.d.ts +0 -4
  281. package/src/legacy/tool-ui/src/main/webapp/v4/rte/utilities.js +0 -359
  282. package/src/legacy/tool-ui/src/main/webapp/v4/theme/ColorRotator.js +0 -1
  283. package/src/legacy/tool-ui/src/main/webapp/v4/util/debounce.js +0 -1
  284. package/src/legacy/tool-ui/src/main/webapp/v4/util/getComponentKey.js +0 -1
  285. package/src/legacy/tool-ui/src/main/webapp/v4/util/noise.js +0 -1
  286. package/src/legacy/tool-ui/src/main/webapp/v4/util/repaint.js +0 -1
  287. package/src/legacy/tool-ui/src/main/webapp/v4/util/storage.js +0 -1
  288. package/src/legacy/tool-ui/src/main/webapp/v4/util/throttle.js +0 -1
  289. package/src/legacy/tool-ui/src/main/webapp/v4/widget/AssignmentContent.js +0 -33
  290. package/src/legacy/tool-ui/src/main/webapp/v4/widget/AssignmentDeskDashboard.js +0 -217
  291. package/src/legacy/tool-ui/src/main/webapp/v4/widget/AssociatedContentWidget.js +0 -7
  292. package/src/legacy/tool-ui/src/main/webapp/v4/widget/BulkUpload.js +0 -19
  293. package/src/legacy/tool-ui/src/main/webapp/v4/widget/Calendar.js +0 -7
  294. package/src/legacy/tool-ui/src/main/webapp/v4/widget/ClosableWindow.js +0 -13
  295. package/src/legacy/tool-ui/src/main/webapp/v4/widget/PitchAssignments.js +0 -25
  296. package/src/legacy/tool-ui/src/main/webapp/v4/widget/PitchContent.js +0 -33
  297. package/src/legacy/tool-ui/src/main/webapp/v4/widget/Revisions.js +0 -61
@@ -1,2406 +0,0 @@
1
- /***
2
-
3
- Repeatable Inputs
4
- -----------------
5
-
6
- For the purposes of this code, there are three types of repeatables:
7
-
8
- * object = an input that can be repeated (but not collapsed/uncollapsed)
9
-
10
- * form = multiple inputs can be repeated (and collapsed/uncollapsed)
11
-
12
- * preview = a slideshow, which will have grid view and gallery view
13
-
14
- * single = A single input is used instead of an add more button.
15
- This is used only when the addButtonText option is set to an empty string
16
- and there is a single template and a single input
17
- If user presses enter on the input, then a new input is created so the user can add more keywords.
18
-
19
- The types have the following things in common:
20
-
21
- * They can have a template (or multiple templates) to add new items.
22
- An "add item" button is included for each template.
23
-
24
- * A remove button is added next to each item item (or in the case of single input,
25
- the remove button might be styled to overlay the input).
26
-
27
- How removing / restoring works
28
- ------------------------------
29
-
30
- When user clicks the "remove" button, the item is not actually removed from the page,
31
- instead a "toBeRemoved" class is added so the item can be styled to indicate it will be removed,
32
- the inputs are all set to be disabled so they will not be sent to the backend, and the remove
33
- button is changed to a restore button.
34
-
35
- When user clicks the "restore" button, the "toBeRemoved" class is removed, the inputs
36
- are no longer disabled, and the restore button is changed to a remove button.
37
-
38
- HTML for repeatables
39
- --------------------
40
-
41
- The HTML within the repeatable element must conform to these standards:
42
-
43
- * It must contain a list (UL or OL) where each item within the list is
44
- a repeatable input
45
-
46
- * Within the list there should be a template. The template can be one of the list items
47
- with classname li.template or a script element with type="text/template".
48
-
49
- Acceptable variation for previewable items
50
- -------------------------------------------
51
- * The first visible `editable-view` <div> under view switcher will decide the default editing view for previewable items;
52
- * By default, new items are inserted to the end of list;
53
- set global variable 'repeatableInsertFront' to be true to let new *previewable* items inserted to the beginning of the list.
54
-
55
- ==================================================
56
- ***/
57
-
58
- import create from '../../v4/dom/create'
59
- import ColorRotator from '../../v4/theme/ColorRotator'
60
- import scrollIntoView from 'scroll-into-view'
61
- import { tabbable } from 'tabbable'
62
- ;(function ($, win, undef) {
63
- var $win = $(win)
64
- const tooltips = window.BRIGHTSPOT?.ui.tooltips
65
-
66
- // Counter to use to make sure the browser doesn't cache ajax requests
67
- var cacheNonce = 0
68
-
69
- // Defaults to use for repeatables
70
- var repeatableDefaults = {
71
- addButtonText: 'Add',
72
- removeButtonText: 'Remove',
73
- restoreButtonText: 'Restore',
74
- sortableOptions: {
75
- delay: 300,
76
- },
77
- }
78
-
79
- // Create the jquery plugin .repeatable() (using plugin2)
80
- $.plugin2('repeatable', {
81
- /**
82
- * Default options used by plugin2
83
- */
84
- _defaultOptions: repeatableDefaults,
85
-
86
- /**
87
- * Function called by plugin2 when a new element is added to the page.
88
- *
89
- * ??? - it appears that a second parameter "options" is supported here,
90
- * but we don't seem to be using that
91
- *
92
- * @param {Element} container
93
- * The repeatable element that was added to the page.
94
- */
95
- _create: function (container) {
96
- var plugin = this
97
- var $container = $(container)
98
- var options = plugin.option()
99
- var repeatable
100
-
101
- // Create a copy of the repeatableUtility object
102
- // This uses prototypal inheritance so we're not actually copying the entire object
103
- // It allows each repeatable instance to have its own object that saves state
104
- repeatable = Object.create(repeatableUtility)
105
-
106
- // Initialize the repeatable utility to get things started
107
- repeatable.init($container, options)
108
- $container.data('repeatable', repeatable)
109
-
110
- // ARIA support
111
- // The content selector element comes from object.js so wait for its insertion and
112
- // movement of items in the list.
113
- const list = container.querySelector(':scope > ol, ul')
114
- const label =
115
- container.closest('.CIG-row')?.querySelector('.CIG-label label')
116
- ?.textContent || ''
117
-
118
- if (list) {
119
- const observer = new MutationObserver((records) => {
120
- records.forEach((record) => {
121
- if (
122
- Array.from(record.addedNodes).some((n) => n.nodeName === 'A') ||
123
- record.target.nodeName === 'OL'
124
- ) {
125
- list.querySelectorAll(':scope > li').forEach((item, i) => {
126
- const index = ++i
127
- item.querySelectorAll(':scope > a, select').forEach((child) => {
128
- const rowFieldName =
129
- child.closest('.CIG-row')?.dataset.fieldName
130
- const rowDisplayName =
131
- child.closest('.CIG-row')?.dataset.fieldDisplayName
132
- const childTitle = child.title
133
-
134
- const ariaLabel = childTitle
135
- ? `${childTitle} `
136
- : `${
137
- rowDisplayName
138
- ? rowDisplayName
139
- : rowFieldName
140
- ? rowFieldName
141
- : label
142
- } ${index}`
143
-
144
- child.setAttribute('aria-label', ariaLabel)
145
- })
146
- })
147
- }
148
- })
149
- })
150
- observer.observe(container, {
151
- childList: true,
152
- subtree: true,
153
- })
154
-
155
- if (list.classList?.contains('RTI-list')) {
156
- list.querySelectorAll(':scope > li').forEach((item, i) => {
157
- const index = ++i
158
- item.querySelectorAll(':scope > a, input').forEach((child) => {
159
- const rowFieldName = child.closest('.CIG-row')?.dataset.fieldName
160
- const rowDisplayName =
161
- child.closest('.CIG-row')?.dataset.fieldDisplayName
162
- const childTitle = child.title
163
-
164
- const ariaLabel = childTitle
165
- ? `${childTitle} `
166
- : `${
167
- rowDisplayName
168
- ? rowDisplayName
169
- : rowFieldName
170
- ? rowFieldName
171
- : label
172
- } ${index}`
173
-
174
- child.setAttribute('aria-label', ariaLabel)
175
- })
176
- })
177
- }
178
- }
179
-
180
- // Set starting point for additions.
181
- if (
182
- container.previousElementSibling?.nodeName === 'OL' ||
183
- container.previousElementSibling?.nodeName === 'UL'
184
- ) {
185
- repeatable.ariaIndex = container.previousElementSibling.children.length
186
- }
187
- },
188
-
189
- /**
190
- * Function to add a new item after bulk file upload.
191
- * This is called by by some code delivered by the back-end.
192
- *
193
- * @param {Function} callback
194
- * Function to call after the item has been added.
195
- * Refer to repeatableUtility.addItem
196
- */
197
- add: function (callback, noFocus) {
198
- var plugin = this
199
-
200
- // In this case, the plugin is called on the add button
201
- var $caller = plugin.$caller
202
-
203
- // Not a great way to do this, but leaving this for now.
204
- // The callback function modifies the template to insert actual values,
205
- // then triggers a change event
206
- $caller.closest('.addButton').trigger('click', [callback, noFocus])
207
-
208
- return $caller
209
- },
210
- })
211
-
212
- /**
213
- * Object to initialize and control repeatable inputs.
214
- *
215
- * This object should not be used directly, instead create a new object for each
216
- * repeatable using Object.create and prototypal inheritance.
217
- * After creating the new object, call the .init() function.
218
- *
219
- * @example
220
- * myRepeatable = Object.create(repeatableUtility);
221
- * myRepeatable.init(element, options);
222
- */
223
- var repeatableUtility = {
224
- /**
225
- * Default options
226
- */
227
- defaults: repeatableDefaults,
228
-
229
- /**
230
- * Regex to check if data-preview-field is a method.
231
- */
232
- methodRegex: '^get[A-Z]+|^is[A-Z]+|^has[A-Z]+',
233
-
234
- ariaIndex: 0,
235
-
236
- /**
237
- * Initialize the object and set up the user interface.
238
- *
239
- * @param {Element|jQuery object|jQuery selector} element
240
- * The element that contains the repeatable HTML.
241
- *
242
- * @param {Object} [options]
243
- */
244
- init: function (element, options) {
245
- var self = this
246
- self.cr = new ColorRotator()
247
-
248
- // Save the element for later use
249
- self.$element = $(element).first()
250
-
251
- // Set up a place to save other dom elements for later use
252
- self.dom = {}
253
-
254
- // Override the default options
255
- self.options = $.extend(true, {}, self.defaults, options)
256
-
257
- self.initializingCount = 0
258
-
259
- // Get the various things we will need from the DOM
260
- self.initDOM()
261
-
262
- // Set up the event-input-disable functionality
263
- self.initInputDisable()
264
-
265
- // Determine which type of repeatable we are dealing with
266
- self.initMode()
267
-
268
- // Initialize collection item weights if needed
269
- self.modeWeightedInit()
270
-
271
- // For each item initialize it
272
- var $items = self.dom.$list.find('> li')
273
-
274
- $items.each(function () {
275
- self.initItem(this)
276
-
277
- if (self.modeIsPreview()) {
278
- self.itemLoad(this).then(() => {
279
- self.initPreview(this)
280
- })
281
- }
282
- })
283
-
284
- if ($items.length === 0 && self.dom.$viewSwitcher) {
285
- self.dom.$viewSwitcher.hide()
286
- }
287
-
288
- // Create the "Add Item" button(s)
289
- self.initAddButton()
290
- self.initViewSwitcher()
291
-
292
- self.isInitialized = true
293
- },
294
-
295
- /**
296
- * Get various things we will need from the DOM and save for later.
297
- */
298
- initDOM: function () {
299
- var self = this
300
- var $list
301
- var $templates = $()
302
-
303
- // Find the list of inputs (must be in a UL or OL)
304
- $list = self.$element.find('> ul, > ol').first()
305
- self.dom.$list = $list // save for later use
306
-
307
- // Templates can be in an LI or a SCRIPT element
308
- $list
309
- .find('> li.template, > template, > script[type="text/template"]')
310
- .each(function () {
311
- var $template = $(this)
312
-
313
- if ($template.is('li.template')) {
314
- $templates = $templates.add($template)
315
- } else if ($template.is('template')) {
316
- $templates = $templates.add($template[0].content.cloneNode(true))
317
- } else {
318
- $templates = $templates.add($($template.text()))
319
- }
320
-
321
- // Remove the template from the page
322
- $template.remove()
323
- })
324
-
325
- // Save form for later use
326
- self.dom.$form = self.dom.$list.closest('form')
327
-
328
- // Save templates for later use
329
- self.dom.$templates = $templates
330
- },
331
-
332
- /**
333
- * Set up the event-input-disable functionality.
334
- * ??? need more info on how this works
335
- */
336
- initInputDisable: function () {
337
- var self = this
338
-
339
- // Mark the input as something that can be locked or disabled
340
- self.$element.addClass('event-input-disable')
341
-
342
- // If the "input-disable" event is triggered, then add or remove a class
343
- self.$element.bind('input-disable', function (event, disable) {
344
- $(event.target)
345
- .closest('.inputContainer')
346
- .toggleClass('state-disabled', disable)
347
- })
348
- },
349
-
350
- /**
351
- * Determine which type of repeatable we are dealing with:
352
- * Sets the "mode" property to one of the following:
353
- * form, single, preview
354
- *
355
- * Note that initDOM() must be called before this is called.
356
- *
357
- * Also see the following functions:
358
- * modeIsPreview(), modeIsSingle(), ...
359
- */
360
- initMode: function () {
361
- var self = this
362
- var $templateInputs
363
-
364
- self.mode = 'form'
365
-
366
- // Set to object mode if we are in a repeatableObjectId
367
- if (
368
- self.$element.hasClass('repeatableObjectId') ||
369
- self.$element.hasClass('repeatableDropdown')
370
- ) {
371
- self.mode = 'object'
372
- }
373
-
374
- // Set to single input mode if there is no add button text,
375
- // and if there is a single template with a single input
376
- $templateInputs = self.dom.$templates
377
- .find(':input')
378
- .not(':input[name$=".toggle"]')
379
- if (
380
- !self.options.addButtonText &&
381
- self.dom.$templates.length === 1 &&
382
- $templateInputs.length === 1
383
- ) {
384
- self.mode = 'single'
385
- return
386
- }
387
-
388
- // Set to preview mode
389
- if (self.$element.hasClass('repeatableForm-previewable')) {
390
- self.mode = 'preview'
391
- self.isError = self.$element[0].querySelector('.message-error')
392
- if (!window.GALLERY_LIST_VIEW_UI && !self.isError) {
393
- self.$element.addClass('is-gridView')
394
- }
395
- return
396
- }
397
-
398
- if (self.$element.hasClass('repeatableForm-weighted')) {
399
- self.mode = 'weighted'
400
- }
401
- },
402
-
403
- /**
404
- * Initialize the "Add Item" controls.
405
- *
406
- * There is a single container for the add item controls,
407
- * and within it can be mutiple add buttons (one for each template).
408
- *
409
- * The text of the add button is defined by a data attribute on the template
410
- * and the addButtonText options.
411
- */
412
- initAddButton: function () {
413
- var self = this
414
- var $addButtonContainer
415
- var $addButtonSelect
416
- var tooManyButtons
417
-
418
- // Create the Add Item container
419
- // -- Initialize single input mode if necessary
420
- // -- Create an add button for each template
421
- // -- Set up click event on the add button
422
-
423
- // Create a container where all the "Add Item" buttons will be displayed
424
- // First check to see if there is already a div to place them,
425
- // if not create a new div at the bottom.
426
- $addButtonContainer = self.$element.find('.addButtonContainer')
427
- if (!$addButtonContainer.length) {
428
- $addButtonContainer = $('<div/>', {
429
- class: 'addButtonContainer',
430
- }).appendTo(self.$element)
431
- }
432
-
433
- // Save the add button container for later use
434
- // (in single mode we will add more to it)
435
- self.dom.$addButtonContainer = $addButtonContainer
436
-
437
- // If we are in single input mode then we'll do some extra stuff
438
- self.modeSingleInitAddButton()
439
-
440
- // Create an "Add Item" link for each template we found,
441
- // or if there are too many links create a dropdown
442
-
443
- tooManyButtons = Boolean(self.dom.$templates.length >= 2)
444
-
445
- if (tooManyButtons) {
446
- // Create a dropdown to list the available add buttons
447
- var $addButtonSelectContainer = $('<span/>', {
448
- class: 'addButtonSelectContainer',
449
- }).appendTo($addButtonContainer)
450
-
451
- $addButtonSelect = $('<select/>', {
452
- class: 'addButtonSelect',
453
- 'aria-label': 'Type',
454
- 'data-searchable': true,
455
- placeholder:
456
- self.dom.$templates.first().attr('data-add') || tooltips.add,
457
- on: {
458
- change: function () {
459
- // Get the selected option
460
- var $selected = $addButtonSelect.find(':selected')
461
-
462
- // Get a link to the add button for that option, and click it.
463
- // The "addButton" data is saved on the OPTION element.
464
- var $button = $selected.data('addButton')
465
- if ($button) {
466
- // Note: normally I wouldn't simulate a click on the button;
467
- // however, there is other pre-existing code that requires that
468
- // add button to be there, so we will continue creating the button
469
- // and hide it if we have too many buttons to show.
470
- $button.click()
471
- }
472
-
473
- $addButtonSelect.val('')
474
- $addButtonSelectContainer
475
- .find('.dropDown-label')
476
- .trigger('dropDown-update')
477
- $addButtonSelect.blur()
478
- },
479
- },
480
- }).appendTo($addButtonSelectContainer)
481
-
482
- $addButtonSelect.append(
483
- $('<option/>', {
484
- value: '',
485
- }),
486
- )
487
-
488
- self.dom.$list[0]
489
- .getAttributeNames()
490
- .filter((name) => name.startsWith('aria-'))
491
- .forEach((name) => {
492
- $addButtonSelect.attr(name, self.dom.$list[0].getAttribute(name))
493
- })
494
- }
495
-
496
- self.dom.$templates.each(function () {
497
- var $template = $(this)
498
- var itemType =
499
- $template.attr('data-type') ||
500
- $template.attr('data-type-label') ||
501
- $template.attr('data-item-fallback') ||
502
- ''
503
- var ariaLabel =
504
- window.BRIGHTSPOT?.ui.tooltips.add +
505
- ' ' +
506
- self.dom.$addButtonContainer
507
- .closest('.CIG-row')
508
- .find('label')
509
- .text() || ''
510
- var $addButton
511
- var addButtonText
512
-
513
- // Check if itemType should be URL
514
- if ($template[0]?.firstChild?.classList?.contains('widget-urlsItem')) {
515
- itemType = $template[0]?.firstChild?.getAttribute('data-type')
516
- }
517
-
518
- // Determine which text to use for the add button
519
- addButtonText = itemType
520
- if (self.options.addButtonText) {
521
- addButtonText =
522
- ($template.attr('data-add') || tooltips.add) + ' ' + addButtonText
523
- if ($template.attr('data-type')) {
524
- ariaLabel = addButtonText
525
- }
526
- }
527
-
528
- // Add an element for the "Add Button" control
529
- $addButton = $('<a/>', {
530
- class: 'addButton',
531
- 'aria-label': ariaLabel,
532
- role: 'button',
533
- href: '#',
534
- text: addButtonText,
535
- 'data-sortable-item-type': $template.attr('data-sortable-item-type'),
536
-
537
- // Save the template on the add button control so when user
538
- // clicks it we will know which template to add
539
- // 'data-addButtonTemplate': $template
540
- })
541
- .on('click keypress', function (event, customCallback, noFocus) {
542
- if (event.type === 'keypress' && event.key !== 'Enter') {
543
- return
544
- }
545
- ++self.initializingCount
546
-
547
- // The click event for the add button supports an
548
- // optional callback function that will be called after
549
- // the new item is added.
550
- // Add the new item based on this template
551
- self.addItem($template, customCallback, noFocus)
552
-
553
- return false
554
- })
555
- .toggle(!tooManyButtons) // Hide button if there are too many buttons
556
- .appendTo($addButtonContainer)
557
-
558
- self.dom.$list[0]
559
- .getAttributeNames()
560
- .filter((name) => name.startsWith('aria-') && name !== 'aria-label')
561
- .forEach((name) => {
562
- $addButton.attr(name, self.dom.$list[0].getAttribute(name))
563
- })
564
-
565
- if (tooManyButtons) {
566
- $('<option/>', {
567
- value: itemType,
568
- text: itemType,
569
- data: {
570
- // Save the add button in a data attribute,
571
- // so later when user selects this item we know which
572
- // add button should be clicked
573
- addButton: $addButton,
574
- },
575
- }).appendTo($addButtonSelect)
576
- }
577
- })
578
- },
579
-
580
- /**
581
- * Initialize an item. This should be called for each list item on the page,
582
- * plus it should be called for any new item added to the page.
583
- *
584
- * @param {Element|jQuery object|jQuery selector} element
585
- * The LI element that contains the item HTML.
586
- */
587
- initItem: function (element) {
588
- var self = this
589
- var $item = $(element)
590
-
591
- // Set form for dynamic previews if we need it by checking the first item init.
592
- // This will delegate the preview to use the data-dynamic-preview
593
- // attribute that is updated during a contentState ajax call.
594
- if (
595
- self.modeIsPreview() &&
596
- $item.index() === 0 &&
597
- !self.isDynamicPreview
598
- ) {
599
- var previewField = $item.attr('data-preview-field')
600
- if (previewField) {
601
- var checkFields = previewField.split('/')
602
- for (var i = 0; i < checkFields.length; i++) {
603
- if (checkFields[i].match(self.methodRegex)) {
604
- self.isDynamicPreview = true
605
- break
606
- }
607
- }
608
- }
609
- }
610
-
611
- // Create item weight for the item if necessary,
612
- // and set up other stuff for mode=weighted
613
- self.modeWeightedInitItem($item)
614
-
615
- // Create a the label for the item if necessary.
616
- // The label acts as a toggle to show and hide the item,
617
- // plus it can load the content of the item from a URL
618
- self.initItemLabel($item)
619
-
620
- // Collapse the item unless it has an error message within it
621
- // Do not collapse "preview" or "object" mode
622
- if (
623
- $item.find('.message-error').length === 0 &&
624
- $item.find('> .layouts').length === 0 &&
625
- !$item.hasClass('expanded') &&
626
- !self.modeIsObject()
627
- ) {
628
- if (
629
- !window.GALLERY_LIST_VIEW_UI &&
630
- self.modeIsPreview() &&
631
- !self.isError
632
- ) {
633
- $item.addClass('is-gridItem')
634
- }
635
- self.itemCollapse($item)
636
- }
637
-
638
- // An input with ".toggle" in the name will be checked
639
- // to tell the backend that it should be saved, but the checkbox will not actually
640
- // be shown to the user, so we hid it here
641
- $item.find(':input[name$=".toggle"]').hide()
642
-
643
- // Create progress UI if necessary
644
- self.initCollectionItemProgress($item)
645
-
646
- // Create toggle UI if necessary
647
- self.initCollectionItemToggle($item)
648
-
649
- const $itemLiveRegion = $('<span/>', {
650
- class: 'screen-reader-only',
651
- 'aria-live': 'polite',
652
- })
653
- $item.append($itemLiveRegion)
654
-
655
- // Add the remove control to the item
656
- self.initItemRemove($item)
657
- },
658
-
659
- initPreview: function (item) {
660
- const previewField = item.dataset.previewField?.split('/')
661
-
662
- if (previewField && previewField.length < 3) {
663
- const field = item.querySelector(
664
- `:scope > .objectInputs > .inputContainer[data-field="${previewField[0]}"]`,
665
- )
666
-
667
- if (field) {
668
- field.classList.add('RCIG-previewField')
669
- return
670
- }
671
- }
672
-
673
- // If the preview is via methods on backend there won't be an associated HTML
674
- // input so insert an Image for display whose click brings user to List view.
675
- const $item = $(item)
676
- const $objectInputs = $item.find('.objectInputs')
677
-
678
- if ($objectInputs.length === 0) {
679
- return
680
- }
681
-
682
- const self = this
683
- const preview = create('img')
684
-
685
- item.appendChild(
686
- create(
687
- 'a',
688
- {
689
- className: 'RCIG-preview',
690
- onclick: self.handleExpandClick.bind(self, $item),
691
- },
692
- preview,
693
- ),
694
- )
695
-
696
- const updatePreview = () => {
697
- preview.src = item.dataset.preview || ''
698
- }
699
-
700
- updatePreview()
701
- $item.on('change', updatePreview)
702
- },
703
-
704
- handleExpandClick: function ($item) {
705
- let select = this.$element[0].querySelector(
706
- '.repeatablePreviewControls select',
707
- )
708
- select.selectedIndex = 1
709
- if (select.dispatchEvent(new Event('change'))) {
710
- this.itemToggle($item)
711
- $item[0].scrollIntoView()
712
- }
713
- },
714
-
715
- /**
716
- * Initialize the label for an item.
717
- *
718
- * @param {Element|jQuery object} element
719
- * The item (LI element).
720
- */
721
- initItemLabel: function (element) {
722
- var self = this
723
- var $item = $(element)
724
- var type = $item.attr('data-type')
725
- var label = $item.attr('data-label-html') || $item.attr('data-label')
726
- var $label
727
- var $existingLabel
728
- var labelHtml
729
-
730
- // Do not add a label if there is no data-type attribute
731
- if (!type) {
732
- return
733
- }
734
-
735
- // The text for the label will be the data type such as "Slideshow Slide"
736
- // And if a data-label attribute was provided append it after a colon such as "Slideshow Slide: My Slide"
737
- labelHtml = type
738
- if (label) {
739
- labelHtml += ': ' + label
740
- }
741
-
742
- $label = $('<div/>', {
743
- class: 'repeatableLabel',
744
- tabindex: '0',
745
- html: labelHtml,
746
-
747
- // Set up some parameters so the label text will dynamically update based on the input field
748
- 'data-object-id': $item
749
- .find('> input[type="hidden"][name$=".id"]')
750
- .val(),
751
- })
752
- .on('click', function (e) {
753
- if (
754
- $item[0].matches('.is-removing') ||
755
- $item[0].hasAttribute('data-empty')
756
- )
757
- return
758
- if (!self.itemIsGridView($item)) {
759
- self.itemToggle($item)
760
- } else {
761
- self.handleExpandClick($item)
762
- }
763
- })
764
- .keydown(function (event) {
765
- if (event.key === 'Enter' || event.key === ' ') {
766
- if ($item[0].matches('.is-removing')) return
767
- event.preventDefault()
768
- $label.trigger('click')
769
- }
770
- })
771
-
772
- if (!$item.attr('data-disable-dynamic-html')) {
773
- $label.attr(
774
- 'data-dynamic-html',
775
- '${toolPageContext.getObjectLabel(content.state.getType())}: ${toolPageContext.createObjectLabelHtml(content)}', // eslint-disable-line no-template-curly-in-string
776
- )
777
- }
778
-
779
- // If there was already a label on the page remove the repeatableLabel class
780
- // so it doesn't conflict with the new label we are creating,
781
- // then add this existing label to the new label we are creating.
782
- $existingLabel = $item.find(' > .repeatableLabel')
783
- if ($existingLabel.length) {
784
- $existingLabel.removeClass('repeatableLabel').appendTo($label)
785
-
786
- // Just in case the label has any inputs, make sure clicks on the input do not bubble up
787
- // to the label and make it toggle the item
788
- $label.find(':input').click(function (e) {
789
- e.stopPropagation()
790
- })
791
- }
792
-
793
- // Add our label to item at the top
794
- $item.prepend($label)
795
- },
796
-
797
- /**
798
- * Initialize the remove button for an individiual item.
799
- *
800
- * @param {Element|jQuery object} item
801
- * The item (LI element).
802
- */
803
- initItemRemove: function (item) {
804
- var self = this
805
- var $item = $(item)
806
- var $label
807
- var $itemLiveRegion = $item.find('.screen-reader-only')
808
-
809
- let inputAriaLabel = ''
810
- const cigRow = $item.closest('.CIG-row')
811
- if (cigRow.length) {
812
- inputAriaLabel = cigRow.find('.CIG-label label').first().text()
813
- }
814
-
815
- // Add the remove button to the item
816
- var $remove = $('<button/>', {
817
- class: 'removeButton',
818
- type: 'button',
819
- 'aria-label': `${tooltips.remove} ${inputAriaLabel}`,
820
- title: `${tooltips.remove} ${inputAriaLabel}`,
821
- text: self.options.removeButtonText,
822
- }).on('click', function (event) {
823
- self.removeItemToggle($item)
824
-
825
- if ($item.hasClass('is-removing')) {
826
- this.title = `${tooltips.restore} ${inputAriaLabel}`
827
- this.setAttribute(
828
- 'aria-label',
829
- `${tooltips.restore} ${inputAriaLabel}`,
830
- )
831
- $itemLiveRegion.text(tooltips?.removedItem)
832
- } else {
833
- this.title = `${tooltips.remove} ${inputAriaLabel}`
834
- this.setAttribute(
835
- 'aria-label',
836
- `${tooltips.remove} ${inputAriaLabel}`,
837
- )
838
- $itemLiveRegion.text(tooltips?.restoredItem)
839
- }
840
- })
841
-
842
- $label = $item.find('.repeatableLabel')
843
-
844
- if ($label && $label[0]) {
845
- $remove.insertAfter($label)
846
- } else {
847
- $remove.appendTo($item)
848
- }
849
- },
850
-
851
- // Note: Repeatable with progress is not supported in V5 UI.
852
- /**
853
- * Conditionally initializes the progress information for an individual item.
854
- *
855
- * @param {Element|jquery object} item
856
- * the item (LI element).
857
- */
858
- initCollectionItemProgress: function (item) {
859
- var $item = $(item)
860
- var progressFieldValue = $item.attr('data-progress-field-value')
861
-
862
- if (!progressFieldValue) {
863
- return
864
- }
865
-
866
- $('<div>', {
867
- class: 'repeatableLabel-progress',
868
- })
869
- .append(
870
- $('<div>', {
871
- class: 'repeatableLabel-progressBar',
872
- }).append(
873
- $('<div>', {
874
- class: 'repeatableLabel-progressFill',
875
- style: 'width: ' + progressFieldValue + '%',
876
- }),
877
- ),
878
- )
879
- .prepend(
880
- $('<div>', {
881
- class: 'repeatableLabel-progressLabel',
882
- text: progressFieldValue + '% of Target',
883
- }),
884
- )
885
- .appendTo($item)
886
- },
887
-
888
- // Note: Repeatable with toggle is not supported in V5 UI.
889
- /**
890
- * Conditionally initializes the toggle button for an individual item.
891
- *
892
- * @param {Element|jquery object} item
893
- * the item (LI element).
894
- */
895
- initCollectionItemToggle: function (item) {
896
- var self = this
897
- var $item = $(item)
898
- var toggleField = $item.attr('data-toggle-field')
899
- var toggleFieldValue = $item.attr('data-toggle-field-value')
900
-
901
- if (!toggleField) {
902
- return
903
- }
904
-
905
- // Add the remove button to the item
906
- var id = $item.find('> input[type="hidden"][name$=".id"]').val()
907
-
908
- var input = $('<input/>', {
909
- id: id + '-toggle',
910
- class: 'repeatableLabel-toggle',
911
- type: 'checkbox',
912
- name: id + '/' + toggleField,
913
- value: true,
914
- }).on('change', function (event) {
915
- // Add/remove weight and recalculate
916
- var checked = $(this).is(':checked')
917
- var previouslyChecked = $item.attr('data-toggle-field-value') === 'true'
918
-
919
- if (checked !== previouslyChecked) {
920
- $item.attr('data-toggle-field-value', checked)
921
-
922
- if (
923
- $item.closest('.repeatableForm').hasClass('repeatableForm-weighted')
924
- ) {
925
- if (checked === true) {
926
- self.addCollectionItemWeight($item)
927
- } else {
928
- self.removeCollectionItemWeight($item)
929
- }
930
- }
931
- }
932
- })
933
-
934
- if (toggleFieldValue === 'true') {
935
- input.attr('checked', 'checked')
936
- }
937
-
938
- input.after(
939
- $('<label>', {
940
- for: id + '-toggle',
941
- class: 'repeatableLabel-toggleLabel',
942
- }),
943
- )
944
-
945
- input.appendTo($item)
946
- },
947
-
948
- //= =================================================
949
- // MODE WEIGHTED
950
- //= =================================================
951
-
952
- /**
953
- * Initialize weighted mode
954
- */
955
- modeWeightedInit: function () {
956
- var self = this
957
-
958
- if (!self.modeIsWeighted()) {
959
- return
960
- }
961
-
962
- // Set up a listener for when the user drags and drops an item to change the order,
963
- // so we can adjust the order of weights
964
- self.dom.$list.on('sortable.end', function (event, element) {
965
- var $item = $(element)
966
-
967
- // Find the index for the new position of the element
968
- var newIndex = $item.index()
969
- var oldIndex = $item.data('repeatableIndex')
970
- self.repositionCollectionItemWeight(oldIndex, newIndex)
971
- })
972
-
973
- var $itemWeightsContainer = self.dom.$list
974
- .parent()
975
- .find('.repeatableForm-itemWeights')
976
- self.collectionItemWeightsCalculated =
977
- $itemWeightsContainer.data('calculated')
978
-
979
- // If values are calculated, handle updates from cms-updateContentState event
980
- if (self.collectionItemWeightsCalculated) {
981
- // TODO: Make this functionality generic, using meta tags or hidden fields
982
- self.dom.$form.on(
983
- 'cms-updateContentState',
984
- (function (self) {
985
- return function (event, data) {
986
- var allDiffs = $.extend(
987
- {},
988
- data._differences,
989
- data._hiddenDifferences,
990
- )
991
- if (!allDiffs) {
992
- return
993
- }
994
-
995
- $.each(allDiffs, function (id, fields) {
996
- if (fields.length === 0) {
997
- return
998
- }
999
-
1000
- var $inputs = self.dom.$list.find(
1001
- '.objectInputs[data-object-id="' + id + '"]',
1002
- )
1003
-
1004
- if (!$inputs) {
1005
- return
1006
- }
1007
-
1008
- var $item = $inputs.closest('li')
1009
-
1010
- if (!$item) {
1011
- return
1012
- }
1013
-
1014
- var weightFieldName = $item.attr('data-weight-field')
1015
- if (!weightFieldName) {
1016
- return
1017
- }
1018
-
1019
- var newWeightFieldValue = fields[weightFieldName]
1020
- if (
1021
- newWeightFieldValue &&
1022
- $item.data('weight-field-value') !== newWeightFieldValue
1023
- ) {
1024
- $item.data('weight-field-value', newWeightFieldValue)
1025
- self.updateCollectionItemWeightData(
1026
- $(
1027
- self.dom.$list
1028
- .siblings('.repeatableForm-itemWeights')
1029
- .find('.repeatableForm-itemWeight')
1030
- .get($item.index()),
1031
- ),
1032
- Math.round(newWeightFieldValue * 100),
1033
- )
1034
- self.fixCollectionItemWeights()
1035
- }
1036
-
1037
- var weightMarkersFieldName = $item.attr(
1038
- 'data-weight-markers-field',
1039
- )
1040
- if (!weightMarkersFieldName) {
1041
- return
1042
- }
1043
-
1044
- var newWeightMarkersFieldValue = fields[weightMarkersFieldName]
1045
- if (
1046
- newWeightMarkersFieldValue &&
1047
- $item.data('weight-markers-field-value') !==
1048
- newWeightMarkersFieldValue
1049
- ) {
1050
- $item.data(
1051
- 'weight-markers-field-value',
1052
- newWeightMarkersFieldValue,
1053
- )
1054
- self.setCollectionItemWeightMarkers($item)
1055
- }
1056
- })
1057
- }
1058
- })(self),
1059
- )
1060
- }
1061
-
1062
- self.initCollectionItemWeightResetButton()
1063
- },
1064
-
1065
- /**
1066
- * Conditionally initializes the weighting display for an individual item.
1067
- *
1068
- * @param {Element|jquery object} item
1069
- * the item (LI element).
1070
- */
1071
- modeWeightedInitItem: function (item) {
1072
- var self = this
1073
- var $item = $(item)
1074
-
1075
- var weightFieldName = $item.data('weight-field')
1076
-
1077
- // Only display field weights if all valid types support collection weights
1078
- if (!self.modeIsWeighted() || !weightFieldName) {
1079
- return false
1080
- }
1081
-
1082
- $item.on('click', '> .removeButton', function () {
1083
- var $this = $(this)
1084
- if (
1085
- $this.closest('li').hasClass('is-removing') ||
1086
- $this.closest('li').hasClass('toBeRemoved')
1087
- ) {
1088
- self.removeCollectionItemWeight($item)
1089
- } else {
1090
- self.addCollectionItemWeight($item)
1091
- }
1092
- })
1093
-
1094
- // Save original index so that we can use this in sortable.end handler
1095
- $item.data('repeatableIndex', $item.index())
1096
-
1097
- self.addCollectionItemWeight($item)
1098
- },
1099
-
1100
- /**
1101
- * Adds a weight to the collection for a given item.
1102
- */
1103
- addCollectionItemWeight: function (item) {
1104
- var self = this
1105
- var $item = $(item)
1106
- var color = self.getCollectionItemWeightColor($item)
1107
- var inputName =
1108
- $item.find('> input[type="hidden"][name$=".id"]').val() +
1109
- '/' +
1110
- $item.data('weight-field')
1111
- var $repeatableWeightLabel = $item.find('> .repeatableLabel-weightLabel')
1112
-
1113
- var weightFieldValue
1114
- if ($repeatableWeightLabel.size() === 0) {
1115
- weightFieldValue = $item.attr('data-weight-field-value')
1116
-
1117
- $('<div>', {
1118
- class: 'repeatableLabel-weightLabel',
1119
- })
1120
- .append(
1121
- $('<span>', {
1122
- class: 'repeatableLabel-color',
1123
- style: 'background-color: ' + color,
1124
- }),
1125
- )
1126
- .append(
1127
- $('<input>', {
1128
- type: 'hidden',
1129
- name: inputName,
1130
- value: weightFieldValue,
1131
- }),
1132
- )
1133
- .prependTo($item)
1134
- } else {
1135
- weightFieldValue = $item
1136
- .find('> .repeatableLabel-weightLabel')
1137
- .find('input')
1138
- .val()
1139
- }
1140
-
1141
- // Only add weight and handle if toggle is true or not available
1142
- if ($item.attr('data-toggle-field-value') === 'false') {
1143
- return
1144
- }
1145
-
1146
- var $itemWeight = $('<div>', {
1147
- class: 'repeatableForm-itemWeight',
1148
- style: 'background-color: ' + color + ';',
1149
- 'data-target': inputName,
1150
- 'data-weight': weightFieldValue,
1151
- })
1152
-
1153
- // Filter items that have been toggled off
1154
- var itemIndex = $item
1155
- .parent()
1156
- .children(':not([data-toggle-field-value="false"], .is-removing)')
1157
- .index($item)
1158
-
1159
- var $itemWeightContainer = $item
1160
- .closest('.repeatableForm')
1161
- .find('> .repeatableForm-itemWeights')
1162
- if (itemIndex === 0) {
1163
- $itemWeightContainer.prepend($itemWeight)
1164
- } else {
1165
- $itemWeightContainer
1166
- .children()
1167
- .eq(itemIndex - 1)
1168
- .after($itemWeight)
1169
- }
1170
-
1171
- self.setCollectionItemWeightMarkers($item)
1172
-
1173
- // Avoid creating handles if draggable is false
1174
- if (!self.collectionItemWeightsCalculated) {
1175
- $itemWeight.prepend(self.createCollectionItemWeightHandle($item))
1176
- }
1177
-
1178
- var itemWeightDoubleValue = $itemWeight.attr('data-weight')
1179
-
1180
- // If item has no data-weight attr, it is a new item,
1181
- // and should scale other weights against `baseWeight`
1182
-
1183
- if (self.isInitialized === true || !itemWeightDoubleValue) {
1184
- var newWeightDouble
1185
-
1186
- if (!itemWeightDoubleValue) {
1187
- // new items are added with a weight proportional to the number of items
1188
- newWeightDouble =
1189
- Math.round((1 / $itemWeightContainer.children().size()) * 100) / 100
1190
- } else {
1191
- // if item exists, use existing weight
1192
- newWeightDouble = parseFloat(itemWeightDoubleValue)
1193
- }
1194
-
1195
- var modifier = 1 - newWeightDouble
1196
-
1197
- $($itemWeightContainer.children().not($itemWeight)).each(function () {
1198
- self.updateCollectionItemWeightData(
1199
- $(this),
1200
- Math.floor(modifier * $(this).attr('data-weight') * 100),
1201
- )
1202
- })
1203
-
1204
- self.updateCollectionItemWeightData(
1205
- $itemWeight,
1206
- (newWeightDouble * 100).toFixed(),
1207
- )
1208
- self.fixCollectionItemWeights()
1209
- } else {
1210
- self.updateCollectionItemWeightData(
1211
- $itemWeight,
1212
- (itemWeightDoubleValue * 100).toFixed(),
1213
- )
1214
- }
1215
- },
1216
-
1217
- /**
1218
- * Sets markers to repeatableForm-itemWeight.
1219
- */
1220
- setCollectionItemWeightMarkers: function (item) {
1221
- var self = this
1222
- var $item = $(item)
1223
- var $itemWeight = $(
1224
- self.dom.$list
1225
- .siblings('.repeatableForm-itemWeights')
1226
- .find('.repeatableForm-itemWeight')
1227
- .get($item.index()),
1228
- )
1229
-
1230
- $itemWeight.find('.repeatableForm-itemWeight-marker').remove()
1231
-
1232
- var markerValues = $item.data('weight-markers-field-value')
1233
- if (markerValues) {
1234
- Array.prototype.forEach.call(markerValues, function (markerValue, i) {
1235
- $itemWeight.append(
1236
- $('<div/>', {
1237
- class: 'repeatableForm-itemWeight-marker',
1238
- style: 'left:' + markerValue * 100 + '%;',
1239
- }),
1240
- )
1241
- })
1242
- }
1243
- },
1244
-
1245
- /**
1246
- * Removes a weight to the collection for a given item.
1247
- */
1248
- removeCollectionItemWeight: function (item) {
1249
- var self = this
1250
- var $item = $(item)
1251
-
1252
- var $repeatableForm = self.dom.$list.parent()
1253
- var $itemWeightsContainer = $repeatableForm.find(
1254
- '.repeatableForm-itemWeights',
1255
- )
1256
-
1257
- $itemWeightsContainer
1258
- .find(
1259
- '.repeatableForm-itemWeight[data-target="' +
1260
- $item.find('.repeatableLabel-weightLabel input').attr('name') +
1261
- '"]',
1262
- )
1263
- .remove()
1264
-
1265
- var $itemWeights = $repeatableForm.find('.repeatableForm-itemWeight')
1266
-
1267
- var totalRemainingPercent = 0
1268
- $itemWeights.each(function (i) {
1269
- var $itemWeight = $(this)
1270
- totalRemainingPercent += parseFloat($itemWeight.attr('data-weight'))
1271
- })
1272
-
1273
- $itemWeights.each(function (i) {
1274
- var $itemWeight = $(this)
1275
- var newDouble =
1276
- parseFloat($itemWeight.attr('data-weight')) / totalRemainingPercent
1277
- self.updateCollectionItemWeightData(
1278
- $itemWeight,
1279
- Math.round(newDouble * 100),
1280
- )
1281
- })
1282
-
1283
- self.fixCollectionItemWeights()
1284
- },
1285
-
1286
- repositionCollectionItemWeight: function (oldIndex, newIndex) {
1287
- var self = this
1288
-
1289
- var $weightsContainer = self.dom.$list
1290
- .parent()
1291
- .find('.repeatableForm-itemWeights')
1292
- var $weights = $weightsContainer.children()
1293
- var $weight = $weights.eq(oldIndex)
1294
-
1295
- if (newIndex === 0) {
1296
- $weightsContainer.prepend($weight)
1297
- } else {
1298
- $weights.eq(newIndex).after($weight)
1299
- }
1300
-
1301
- self.dom.$list.children().each(function () {
1302
- var $item = $(this)
1303
- $item.data('repeatableIndex', $item.index())
1304
- })
1305
- },
1306
-
1307
- initCollectionItemWeightResetButton: function () {
1308
- var self = this
1309
-
1310
- if (self.collectionItemWeightsCalculated) {
1311
- return
1312
- }
1313
-
1314
- self.dom.$list.parent().prepend(
1315
- $('<a>', {
1316
- class: 'repeatableForm-weightResetButton',
1317
- text: 'Reset Weights',
1318
- title: tooltips.resetWeights,
1319
- }).on('click', function () {
1320
- self.resetCollectionItemWeights()
1321
- return false
1322
- }),
1323
- )
1324
- },
1325
-
1326
- /**
1327
- * Resets the collection item weights with an even distribution.
1328
- */
1329
- resetCollectionItemWeights: function () {
1330
- var self = this
1331
- var $itemWeights = self.dom.$list
1332
- .parent()
1333
- .find('.repeatableForm-itemWeight')
1334
- var itemWeightsCount = $itemWeights.size()
1335
-
1336
- if (itemWeightsCount <= 0) {
1337
- return false
1338
- }
1339
-
1340
- var weight = Math.floor(100 / itemWeightsCount)
1341
-
1342
- $itemWeights.each(function () {
1343
- self.updateCollectionItemWeightData(this, weight)
1344
- })
1345
-
1346
- self.fixCollectionItemWeights()
1347
- },
1348
-
1349
- /**
1350
- * Prevents rounding errors and sum of weights from exceeding 100%.
1351
- */
1352
- fixCollectionItemWeights: function () {
1353
- var self = this
1354
- var $itemWeights = self.dom.$list
1355
- .parent()
1356
- .find('.repeatableForm-itemWeights > .repeatableForm-itemWeight')
1357
- var totalPercent = 0
1358
-
1359
- $itemWeights.each(function (i) {
1360
- var $itemWeight = $(this)
1361
- var $itemWeightValue = parseFloat($itemWeight.attr('data-weight'))
1362
- var $itemWeightPercent = $itemWeightValue * 100
1363
- totalPercent += $itemWeightPercent
1364
-
1365
- if (i + 1 === $itemWeights.size() && totalPercent !== 100) {
1366
- self.updateCollectionItemWeightData(
1367
- $itemWeight,
1368
- $itemWeightPercent + 100 - totalPercent,
1369
- )
1370
- }
1371
- })
1372
- },
1373
-
1374
- updateCollectionItemWeightData: function (itemWeight, percent) {
1375
- var self = this
1376
- var $itemWeight = $(itemWeight)
1377
- var $repeatableForm = $itemWeight.closest('.repeatableForm')
1378
- var double = percent / 100
1379
-
1380
- $itemWeight.css({ flex: double + ' 1 0%' })
1381
- $itemWeight.attr('data-weight', double)
1382
-
1383
- var liIndex = $repeatableForm
1384
- .find('input[name="' + $itemWeight.attr('data-target') + '"]')
1385
- .closest('li')
1386
- .index()
1387
-
1388
- var $repeatableWeightDisplay = $(
1389
- self.dom.$list.children('li').get(liIndex),
1390
- ).find('.repeatableLabel-weightLabel')
1391
- $repeatableWeightDisplay.attr('data-weight-label', percent + '%')
1392
- $repeatableWeightDisplay.find('input').val(double)
1393
- },
1394
-
1395
- /**
1396
- * Gets a color for an item to represent the item's weight.
1397
- */
1398
- getCollectionItemWeightColor: function (item) {
1399
- var $item = $(item)
1400
- var weightColor = $item.data('weight-color-field-value')
1401
-
1402
- if (weightColor) {
1403
- return weightColor
1404
- }
1405
-
1406
- weightColor = this.cr.getNext()
1407
-
1408
- $item.data('weight-color-field-value', weightColor)
1409
-
1410
- return weightColor
1411
- },
1412
-
1413
- /**
1414
- * Creates an element that handles dragging to
1415
- * change the collection item weight field.
1416
- */
1417
- createCollectionItemWeightHandle: function (item) {
1418
- var self = this
1419
-
1420
- return $('<div>', {
1421
- class: 'repeatableForm-itemWeightHandle',
1422
- mousedown: function (event) {
1423
- event.stopPropagation()
1424
- $.drag(
1425
- this,
1426
- event,
1427
- function (event, data) {
1428
- data.originX = event.clientX
1429
- data.rightElement = $(this).parent()
1430
- data.leftElement = data.rightElement.prev()
1431
-
1432
- data.originalRightWeight = parseFloat(
1433
- data.rightElement.attr('data-weight'),
1434
- )
1435
- data.originalLeftWeight = parseFloat(
1436
- data.leftElement.attr('data-weight'),
1437
- )
1438
-
1439
- data.rightIndex = data.rightElement.index()
1440
- data.leftIndex = data.leftElement.index()
1441
-
1442
- var $listElements = self.dom.$list.children(
1443
- ':not([data-toggle-field-value="false"], .is-removing, .toBeRemoved)',
1444
- )
1445
-
1446
- data.rightLabel = $($listElements.get(data.rightIndex)).find(
1447
- '.repeatableLabel-weightLabel',
1448
- )
1449
- data.leftLabel = $($listElements.get(data.leftIndex)).find(
1450
- '.repeatableLabel-weightLabel',
1451
- )
1452
-
1453
- data.rightInput = data.rightLabel.find('input')
1454
- data.leftInput = data.leftLabel.find('input')
1455
-
1456
- data.totalWidth =
1457
- data.rightElement.outerWidth() + data.leftElement.outerWidth()
1458
- data.totalWeightDouble =
1459
- data.originalRightWeight + data.originalLeftWeight
1460
- },
1461
- function (event, data) {
1462
- var delta = data.originX - event.clientX
1463
- var deltaPercent = Math.round((delta / data.totalWidth) * 100)
1464
- var deltaDouble = deltaPercent / 100
1465
-
1466
- var newLeftWeightDouble =
1467
- Math.round((data.originalLeftWeight - deltaDouble) * 100) / 100
1468
- var newRightWeightDouble =
1469
- Math.round(
1470
- (data.totalWeightDouble - newLeftWeightDouble) * 100,
1471
- ) / 100
1472
-
1473
- if (newLeftWeightDouble < 0) {
1474
- newLeftWeightDouble = 0
1475
- newRightWeightDouble = data.totalWeightDouble
1476
- }
1477
-
1478
- if (newRightWeightDouble < 0) {
1479
- newRightWeightDouble = 0
1480
- newLeftWeightDouble = data.totalWeightDouble
1481
- }
1482
-
1483
- var newLeftWeightPct = Math.max(
1484
- Math.round(newLeftWeightDouble * 100),
1485
- 0,
1486
- )
1487
- var newRightWeightPct = Math.max(
1488
- Math.round(newRightWeightDouble * 100),
1489
- 0,
1490
- )
1491
-
1492
- data.leftElement
1493
- .css({
1494
- flex: newLeftWeightDouble + ' 1 0%',
1495
- })
1496
- .attr('data-weight', newLeftWeightDouble)
1497
-
1498
- data.rightElement
1499
- .css({
1500
- flex: newRightWeightDouble + ' 1 0% ',
1501
- })
1502
- .attr('data-weight', newRightWeightDouble)
1503
-
1504
- // Update input and numerical display
1505
- data.rightLabel.attr('data-weight-label', newRightWeightPct + '%')
1506
- data.leftLabel.attr('data-weight-label', newLeftWeightPct + '%')
1507
-
1508
- data.rightInput.val(newRightWeightDouble)
1509
- data.leftInput.val(newLeftWeightDouble)
1510
- },
1511
- function (event) {
1512
- // do nothing.
1513
- },
1514
- )
1515
- },
1516
- })
1517
- },
1518
-
1519
- /**
1520
- * Add a new item to the list, based from a template.
1521
- *
1522
- * checks on global variable `repeatableInsertFront` and for class `addToTop`
1523
- * to decide if to insert new item to the beginning of the list
1524
- *
1525
- * @param {Element|jQuery object} template
1526
- * The template for the new item.
1527
- *
1528
- * @param {Function} customCallback
1529
- * A function to call after the new item has been added.
1530
- */
1531
- addItem: function (template, customCallback, noFocus) {
1532
- var self = this
1533
- var $template = $(template)
1534
- var $addedItem
1535
- var promise
1536
- var templateUrl
1537
- var $templateInputs
1538
-
1539
- // For single input mode, don't add another item if the input is empty
1540
- if (self.modeIsSingle() && !self.dom.$singleInput.val()) {
1541
- return false
1542
- }
1543
-
1544
- self.$element[0].dispatchEvent(new Event('repeatable.add'))
1545
-
1546
- if (self.dom.$viewSwitcher) {
1547
- self.dom.$viewSwitcher.show()
1548
- }
1549
-
1550
- // Create a copy of the template to use as the new item
1551
- $addedItem = $template.clone()
1552
- $addedItem.removeClass('template')
1553
-
1554
- // If the template contains inputs that end with ".toggle" then
1555
- // start by making them checked to tell the backend it should save this item
1556
- $addedItem.find(':input[name$=".toggle"]').attr('checked', 'checked')
1557
-
1558
- // Determine if we need to AJAX the template onto the page
1559
- // (if the template has no input but has a link)
1560
- templateUrl = $addedItem.find('a').attr('href')
1561
- $templateInputs = $addedItem.find(':input')
1562
- if (templateUrl && $templateInputs.length === 0) {
1563
- // Not sure why, but sending some kind of cache breaker in the data?
1564
- ++cacheNonce
1565
-
1566
- promise = $.ajax({
1567
- cache: false,
1568
- url: templateUrl,
1569
- data: { _nonce: cacheNonce },
1570
- }).always(function (response) {
1571
- // The response will either be the data (on success), or a jqXHR object (on error)
1572
- var content =
1573
- typeof response === 'string' ? response : response.responseText
1574
-
1575
- // Add the loaded content into the new item
1576
- $addedItem.html(content)
1577
- })
1578
- } else {
1579
- // We're not loading any data, so we'll create an already
1580
- // resolved promise to the next step will complete immediately
1581
- promise = $.Deferred().resolve().promise()
1582
- }
1583
-
1584
- ++this.ariaIndex
1585
- $templateInputs.each((i, element) => {
1586
- if (element.hasAttribute('aria-label')) {
1587
- element.setAttribute(
1588
- 'aria-label',
1589
- `${element.getAttribute('aria-label')} ${this.ariaIndex}`,
1590
- )
1591
- }
1592
- })
1593
-
1594
- // Run more code after the item has been loaded
1595
- promise.always(function () {
1596
- if (self.dom.$list.find('.RCIG-replace').length) {
1597
- self.dom.$list.find('.RCIG-replace').after($addedItem)
1598
- } else {
1599
- // Add the item to the page, prepending if `.addToTop` is present
1600
- if (self.dom.$list.parent('.addToTop').length) {
1601
- self.dom.$list.prepend($addedItem)
1602
- } else {
1603
- self.dom.$list.append($addedItem)
1604
- // Scroll to the newly added item.
1605
- if (self.initializingCount > 1) {
1606
- var children = self.dom.$list[0].children
1607
- const targetEl = children[children.length - 1]
1608
- scrollIntoView(targetEl)
1609
- }
1610
- }
1611
- }
1612
-
1613
- // If item has no fields add to list item data attribute to indicate
1614
- if ($addedItem[0].querySelector(':scope > [data-empty]')) {
1615
- $addedItem[0].dataset.empty = ''
1616
- }
1617
-
1618
- // Initialize stuff on the new item
1619
- // If there was a custom callback provided, call it now.
1620
- // This is used for example, in Image Upload.
1621
- // After the image is uploaded a new repeatable item is added,
1622
- // then the callback inserts values into the template.
1623
- if (customCallback) {
1624
- // Call the customcallback funtion, setting "this" to be the element for the new item
1625
- customCallback.call($addedItem[0])
1626
- }
1627
-
1628
- // Note this will collapse the item as well so we will uncollapse it below
1629
- self.initItem($addedItem)
1630
-
1631
- if (self.modeIsPreview()) {
1632
- self.initPreview($addedItem[0])
1633
- }
1634
-
1635
- // Make sure it's not collapsed since it's a new item
1636
- self.itemUncollapse($addedItem)
1637
-
1638
- // For single input mode, when user enters a value into the input,
1639
- // we copy that value into the added item, then clear the value
1640
- // from the original input so the user can enter another value
1641
- if (self.modeIsSingle()) {
1642
- $addedItem
1643
- .find(':input:not([name$=".toggle"])')
1644
- .val(self.dom.$singleInput.val())
1645
- self.dom.$singleInput.val('')
1646
- self.dom.$singleInput.focus()
1647
- }
1648
-
1649
- // Adjust the element ids so they don't conflict
1650
- $addedItem.find('*[id]').attr('id', function (index, attr) {
1651
- var newAttr
1652
-
1653
- self.ariaIndex += 1
1654
-
1655
- newAttr = attr + 'r' + self.ariaIndex
1656
-
1657
- // Also adjust the LABEL elements that are linked to other inputs
1658
- $addedItem.find('*[for="' + attr + '"]').attr('for', newAttr)
1659
-
1660
- // Also adjust the auto-show elements so they show the correct elements
1661
- $addedItem
1662
- .find('*[data-show="#' + attr + '"]')
1663
- .attr('data-show', '#' + newAttr)
1664
-
1665
- return newAttr
1666
- })
1667
-
1668
- // Trigger a custom "create" event for the item
1669
- // So other code can act on this if necessary
1670
- $addedItem.trigger('create')
1671
-
1672
- if ($addedItem[0].parentNode?.matches('.RCIG-list, .RCS-list')) {
1673
- $addedItem[0].classList.add('is-new-item')
1674
- }
1675
-
1676
- // If we are in mode preview, adjust the added item.
1677
- self.modePreviewAddItem($addedItem)
1678
-
1679
- $addedItem.trigger('change')
1680
-
1681
- var currentIndex = $addedItem.index()
1682
-
1683
- if (win.repeatableInsertFront && self.modeIsPreview()) {
1684
- // move added item to the beginning
1685
- self.repositionItem(currentIndex, 0, $addedItem)
1686
- }
1687
-
1688
- // Trigger a resize event for the window
1689
- // Since we have added new content
1690
- $win.resize()
1691
-
1692
- // Insert another option to indexer
1693
- if (self.dom.$indexer) {
1694
- self.dom.$indexer.find('select').append(
1695
- $('<option></option>')
1696
- .val(currentIndex + 1)
1697
- .html(currentIndex + 1),
1698
- )
1699
- }
1700
-
1701
- // Delay the forced click until content state is finished adding data-additional-query attribute to the DOM, when applicable.
1702
- function delayClick(input) {
1703
- const combo = $addedItem[0].querySelector(':scope > .ComboInput')
1704
-
1705
- if (
1706
- combo &&
1707
- (!input.dataset.dynamicPredicate || input.dataset.additionalQuery)
1708
- ) {
1709
- combo.click()
1710
- } else {
1711
- setTimeout(() => delayClick(input), 10)
1712
- }
1713
- }
1714
-
1715
- // A little hacky but should work fine given how onFind is currently implemented.
1716
- if (!self.modeIsSingle() && !noFocus) {
1717
- window.requestAnimationFrame(() => {
1718
- window.requestAnimationFrame(() => {
1719
- const first = tabbable($addedItem[0])[0]
1720
-
1721
- if (first && !first.classList.contains('RCIG-title')) {
1722
- const input = $addedItem[0].querySelector(
1723
- ':scope > input.objectId',
1724
- )
1725
-
1726
- if (input) {
1727
- delayClick(input)
1728
- } else {
1729
- first.focus()
1730
- first.click()
1731
- }
1732
- } else if (first) {
1733
- first.focus()
1734
- }
1735
-
1736
- // Handle UrlsWidget input focus
1737
- const urlsWidgetItem = self.dom.$list[0]?.lastChild
1738
-
1739
- if (
1740
- urlsWidgetItem &&
1741
- urlsWidgetItem.classList.contains('widget-urlsItem')
1742
- ) {
1743
- urlsWidgetItem.querySelector('.widget-urlsItemLabel')?.focus()
1744
- }
1745
- })
1746
- })
1747
- }
1748
- }) // END promise.always()
1749
-
1750
- // Return the promise just in case someone wants to do something after the item is added
1751
- // (but doesn't want to use the callback function)
1752
- return promise
1753
- },
1754
-
1755
- /**
1756
- * Shortcut function to tell if the mode is 'form'
1757
- * @returns {Boolean}
1758
- */
1759
- modeIsObject: function () {
1760
- var self = this
1761
- return self.mode === 'object'
1762
- },
1763
-
1764
- /**
1765
- * Shortcut function to tell if the mode is 'form'
1766
- * @returns {Boolean}
1767
- */
1768
- modeIsForm: function () {
1769
- var self = this
1770
- return self.mode === 'form'
1771
- },
1772
-
1773
- /**
1774
- * Shortcut function to tell if the mode is 'single'
1775
- * @returns {Boolean}
1776
- */
1777
- modeIsSingle: function () {
1778
- var self = this
1779
- return self.mode === 'single'
1780
- },
1781
-
1782
- /**
1783
- * Shortcut function to tell if the mode is 'preview'
1784
- * @returns {Boolean}
1785
- */
1786
- modeIsPreview: function () {
1787
- var self = this
1788
- return self.mode === 'preview'
1789
- },
1790
-
1791
- /**
1792
- * Shortcut function to tell if the mode is 'weighted'
1793
- * @returns {Boolean}
1794
- */
1795
- modeIsWeighted: function () {
1796
- var self = this
1797
- return self.mode === 'weighted'
1798
- },
1799
-
1800
- /**
1801
- * Toggle the display of an item (and load the item if necessary).
1802
- * If the item contains a hidden input with data-form-fields-url attribute,
1803
- * then that means it has not been loaded yet.
1804
- * In that case dynamically load the item the first time the item is toggled.
1805
- *
1806
- * @param {Element|jQuery object} item
1807
- * The list item that should be toggled.
1808
- *
1809
- * @param {Boolean} [collapseFlag]
1810
- * Set to true to force the item to collapse.
1811
- * Set to false to force the item to uncollapse.
1812
- * If undefined then the item will toggle between collapsed and uncollapsed.
1813
- */
1814
- itemToggle: function (item, collapseFlag) {
1815
- var self = this
1816
- var $item = $(item)
1817
- // var deferred
1818
-
1819
- // Call for textareas to redraw.
1820
- if ($item.hasClass('is-collapsed')) {
1821
- $item.find('textarea').each((i, textarea) => {
1822
- textarea.dispatchEvent(new CustomEvent('change', { bubbles: true }))
1823
- })
1824
- }
1825
-
1826
- // Collapse or uncollapse the item
1827
- $item.toggleClass('is-collapsed collapsed', collapseFlag)
1828
- if (!self.itemIsCollapsed($item)) {
1829
- $item.find('> .objectInputs').css('display', '')
1830
- } else if (
1831
- !self.itemIsGridView($item) &&
1832
- !self.itemIsVerticalView($item)
1833
- ) {
1834
- $item.find('> .objectInputs').hide()
1835
- }
1836
-
1837
- if (collapseFlag && $item.hasClass('expanded')) {
1838
- $item.removeClass('expanded')
1839
- }
1840
-
1841
- self.$element[0].dispatchEvent(new Event('repeatable.toggle'))
1842
-
1843
- // Don't do anything if mode=preview
1844
- if (self.modeIsPreview()) {
1845
- return
1846
- }
1847
-
1848
- // Load the item if necessary,
1849
- // or if it's already loaded do some stuff immediately
1850
- if (!self.itemIsCollapsed($item)) {
1851
- self.itemLoad($item).always(function () {
1852
- // Trigger the resize event since we changed the item size
1853
- $item.resize()
1854
-
1855
- // Trigger a change event on the first input within the item
1856
- // so other code can do something if necessary
1857
- const firstInput = $item.find(':input:first')
1858
- if (firstInput.length) {
1859
- firstInput.change()
1860
-
1861
- // The triggered change above adds data-interacted to the inputContainer
1862
- // (via state.js) once it is expanded, but we don't want that in this case
1863
- const inputContainer = firstInput.closest('.inputContainer')
1864
- if (inputContainer.length) {
1865
- inputContainer.removeAttr('data-interacted')
1866
- }
1867
- }
1868
- })
1869
- }
1870
- },
1871
-
1872
- /**
1873
- * Collapse an item.
1874
- *
1875
- * @param {Element|jQuery object} item
1876
- * The list item that should be collapsed.
1877
- */
1878
- itemCollapse: function (item) {
1879
- var self = this
1880
- self.itemToggle(item, true)
1881
- },
1882
-
1883
- /**
1884
- * Uncollapse an item (and load the item if necessary).
1885
- *
1886
- * @param {Element|jQuery object} item
1887
- * The list item that should be uncollapsed.
1888
- */
1889
- itemUncollapse: function (item) {
1890
- var self = this
1891
- self.itemToggle(item, false)
1892
- },
1893
-
1894
- /**
1895
- * Determine if an item is currently collapsed.
1896
- *
1897
- * @param {Element|jQuery object} item
1898
- * The list item to test.
1899
- */
1900
- itemIsCollapsed: function (item) {
1901
- // var self = this
1902
- var $item = $(item)
1903
- return $item.hasClass('is-collapsed') || $item.hasClass('collapsed')
1904
- },
1905
-
1906
- /**
1907
- * Checks an item to determine if it needs to load some dynamic content,
1908
- * and loads it if necessary.
1909
- *
1910
- * @param {Element|jQuery object} item
1911
- * The item to load.
1912
- *
1913
- * @param {Element|jQuery object} [location]
1914
- * Optional location where to append the loaded content.
1915
- * If not specified will append the loaded content to the item.
1916
- *
1917
- * @returns {Promise}
1918
- * Returns a promise that tells you when the item is done loading.
1919
- * You can use this promise even if the item is already on the page
1920
- * and doesn't need to load anything.
1921
- *
1922
- * @example
1923
- * myRepeatable.itemLoad(element).always(function(){ alert('Item is done loading'); });
1924
- */
1925
- itemLoad: function (item, location) {
1926
- var self = this
1927
- var $item = $(item)
1928
- var $location = location ? $(location) : $item
1929
- var $input
1930
- var url
1931
- var data
1932
-
1933
- // In case we do not need to load anything, we'll create a deferred
1934
- // promise that is already resolved
1935
- var promise = $.Deferred().resolve().promise()
1936
-
1937
- if ($item.data('loaded')) {
1938
- return promise
1939
- }
1940
- // Look for a hidden input that has a data-form-fields-url attribute
1941
- // which indicates we need to load the form fields fields for this item.
1942
- // Note after we load the content we will remove data-form-fields-url
1943
- // so it will only be found and loaded once.
1944
- $input = $item.find('> input[data-form-fields-url]')
1945
-
1946
- if ($input.length > 0) {
1947
- $item.addClass('is-loading')
1948
-
1949
- // Get the URL to fetch
1950
- url = $input.attr('data-form-fields-url')
1951
-
1952
- // Get the data to pass to the URL
1953
- data = $input.val()
1954
-
1955
- // remove attr so it won't be loaded again
1956
- $input.removeAttr('data-form-fields-url')
1957
-
1958
- // Fetch the content
1959
- // Override the promise we created by that returned by the ajax call,
1960
- // so we can pass that back and you can take action when the ajax completes
1961
- promise = $.ajax({
1962
- type: 'POST',
1963
- cache: false,
1964
- url: url,
1965
- data: { data: data },
1966
- }).always(function (response) {
1967
- $item.removeClass('is-loading')
1968
-
1969
- // The response will either be the data (on success), or a jqXHR object (on error)
1970
- var content =
1971
- typeof response === 'string' ? response : response.responseText
1972
- var $content = $(content)
1973
-
1974
- // When ajax completes add the content to the page
1975
- $input.next('input[name$=".expanded"]').val('true')
1976
- $content.appendTo($location)
1977
- $item.data('loaded', true)
1978
-
1979
- // If the item has already been removed, mark the new content to be removed as well
1980
- if (self.itemIsRemoved($item)) {
1981
- // Call the removeItem function again and this time
1982
- // it will also mark the newly loaded content to be disabled
1983
- self.removeItem($item)
1984
- }
1985
-
1986
- // Trigger some events so other code can know we have added content
1987
- // and can add more controls to the form we just loaded
1988
- $location.trigger('create')
1989
- $location.trigger('load')
1990
- })
1991
- }
1992
-
1993
- // Return a promise so other events can be triggered after the item is loaded
1994
- return promise
1995
- },
1996
-
1997
- /**
1998
- * Toggle the remove state for an item.
1999
- * When an item is marked for removal we perform the following steps:
2000
- * - Add toBeRemoved class on the item.
2001
- * - Disable all inputs.
2002
- * - Change remove link text.
2003
- *
2004
- * @param {Element|jQuery object} item
2005
- * The item (LI element).
2006
- *
2007
- * @param {Boolean} [removeFlag]
2008
- * Set to true to force the item to be removed.
2009
- * Set to false to force the item to be restored.
2010
- * If undefined then the item will toggle between remove/restore.
2011
- */
2012
- removeItemToggle: function (item, removeFlag) {
2013
- var self = this
2014
- var $item = $(item)
2015
- var $removeButton = $item.find('.removeButton')
2016
- var $searchButton = $item.find('.ContentSelector-search')
2017
- var $editButton = $item.find('.ContentSelector-edit')
2018
- var $inputs
2019
- var $content = $()
2020
-
2021
- // Define the content where we need to disable inputs and mark toBeRemoved
2022
- $content = $content.add($item)
2023
-
2024
- // Find all the input elements except the content summary quick view button
2025
- // within the content so we can disable them
2026
- $inputs = $content.find(':input:not(".ContentSummary-info")')
2027
-
2028
- // If the removeFlag was not specified, determine if it should be true
2029
- // or false, based on the current class of the item
2030
- if (removeFlag === undefined) {
2031
- removeFlag = !$item.is('.is-removing') && !$item.is('.toBeRemoved')
2032
- }
2033
-
2034
- if (removeFlag) {
2035
- // Add the "toBeRemoved" class to the item.
2036
- $content.addClass('is-removing toBeRemoved')
2037
-
2038
- // Disable all the inputs within the item so they will not be sent to the backend
2039
- // when the form is submitted
2040
- $inputs.each(function () {
2041
- const $input = $(this)
2042
-
2043
- // Keep remove button enabled so item can always be restored or removed
2044
- if ($input.is($removeButton) && $input.parent().is($item)) return
2045
-
2046
- if ($input.prop('disabled')) {
2047
- $input.data('already-disabled', true)
2048
- } else {
2049
- $input.prop('disabled', true)
2050
- }
2051
- })
2052
-
2053
- $searchButton.addClass('is-disabled')
2054
- $editButton.addClass('is-disabled')
2055
-
2056
- $item.find('> .objectInputs').hide()
2057
-
2058
- // Change the text in the remove button
2059
- if (self.options.restoreButtonText) {
2060
- $removeButton.text(self.options.restoreButtonText)
2061
- }
2062
-
2063
- self.$element[0].dispatchEvent(new Event('repeatable.remove'))
2064
- } else {
2065
- // Remove the "toBeRemoved" class to the item.
2066
- $content.removeClass('is-removing toBeRemoved')
2067
-
2068
- // Disable all the inputs within the item so they will not be sent to the backend
2069
- // when the form is submitted
2070
- $inputs.each(function () {
2071
- const $input = $(this)
2072
-
2073
- if ($input.data('already-disabled')) {
2074
- $input.removeData('already-disabled')
2075
- } else {
2076
- $input.prop('disabled', false)
2077
- }
2078
- })
2079
-
2080
- $searchButton.removeClass('is-disabled')
2081
- $editButton.removeClass('is-disabled')
2082
-
2083
- $item.find('> .objectInputs').show()
2084
-
2085
- // Change the text in the remove button
2086
- if (self.options.removeButtonText) {
2087
- $removeButton.text(self.options.removeButtonText)
2088
- }
2089
-
2090
- self.$element[0].dispatchEvent(new Event('repeatable.add'))
2091
- }
2092
-
2093
- // Trigger a change event to notify other code
2094
- $item.change()
2095
- },
2096
-
2097
- /**
2098
- * Mark an item to be removed.
2099
- *
2100
- * @param {Element|jQuery object} item
2101
- * The item (LI element).
2102
- */
2103
- removeItem: function (item) {
2104
- var self = this
2105
- self.removeItemToggle(item, true)
2106
- },
2107
-
2108
- /**
2109
- * Immediately removes an item from
2110
- * the DOM. Invoked by objectIdResult.jsp.
2111
- */
2112
- removeItemImmediately: function (item) {
2113
- var self = this
2114
- var $item = $(item)
2115
-
2116
- if (self.modeIsWeighted) {
2117
- self.removeCollectionItemWeight($item)
2118
- }
2119
-
2120
- $item.remove()
2121
- },
2122
-
2123
- /**
2124
- * Unmark an item to be removed (that is, restore the item).
2125
- *
2126
- * @param {Element|jQuery object} item
2127
- * The item (LI element).
2128
- */
2129
- restoreItem: function (item) {
2130
- var self = this
2131
- self.removeItemToggle(item, false)
2132
- },
2133
-
2134
- /**
2135
- * Determine if an item is currently removed.
2136
- *
2137
- * @param {Element|jQuery object} item
2138
- * The item (LI element).
2139
- */
2140
- itemIsRemoved: function (item) {
2141
- // var self = this
2142
- return $(item).hasClass('is-removing') || $(item).hasClass('toBeRemoved')
2143
- },
2144
-
2145
- //= =================================================
2146
- // MODE SINGLE
2147
- //= =================================================
2148
-
2149
- /**
2150
- * Additional initializing for the "Add Item" controls when mode is "single".
2151
- */
2152
- modeSingleInitAddButton: function () {
2153
- var self = this
2154
- var $input
2155
- var $toggle
2156
- var $singleInput
2157
- var $addButtonContainer = self.dom.$addButtonContainer
2158
-
2159
- // Only do this for single input mode
2160
- if (!self.modeIsSingle()) {
2161
- return
2162
- }
2163
-
2164
- // Get the single input from the template, but not the ".toggle" input.
2165
- // We will also clone the $toggle input later
2166
- $toggle = self.dom.$templates.find(':input[name$=".toggle"]')
2167
- $input = self.dom.$templates.find(':input').not($toggle)
2168
-
2169
- // Make a copy of the input
2170
- $singleInput = $input.clone()
2171
-
2172
- // Remove ID if it has it since duplicates not allowed
2173
- $singleInput.removeAttr('id')
2174
-
2175
- // When user presses Enter on the input then simulate a click on Add Item button
2176
- // so another item can be added
2177
- $singleInput.keydown(function (event) {
2178
- // Check for Enter key
2179
- if (event.which === 13) {
2180
- // TODO: instead of triggering a click on the add button
2181
- // we should just call the method that the click button calls
2182
- $addButtonContainer.find('.addButton').trigger('click')
2183
- return false
2184
- }
2185
- })
2186
-
2187
- // Put a toggle input into the add button container
2188
- // So it will tell the back-end that this input should be added
2189
- // ???: this is not checked initially (but is is checked when the new input is added?)
2190
- $('<input/>', {
2191
- name: $toggle.attr('name'),
2192
- type: 'hidden',
2193
- value: $toggle.attr('value'),
2194
- }).appendTo($addButtonContainer)
2195
-
2196
- // Put the copy of the single input into the add button container
2197
- // so user can type into it and create new items
2198
- $singleInput.appendTo($addButtonContainer)
2199
-
2200
- // Save for later use (so we can check if it contains a value)
2201
- self.dom.$singleInput = $singleInput
2202
-
2203
- // TODO: determine how these inputs are duplicated when the add button container is clicked...
2204
- },
2205
-
2206
- /**
2207
- * Reposition an item by index
2208
- */
2209
- repositionItem: function (oldIndex, newIndex, item) {
2210
- var self = this
2211
- var $item = $(item)
2212
- var $items = self.dom.$list.find('li')
2213
-
2214
- if (!$item || newIndex === oldIndex || newIndex > $items.length) {
2215
- return
2216
- }
2217
-
2218
- // Remove active item temporarily
2219
- $item = $item.detach()
2220
-
2221
- // Add active item in the new position
2222
- if (newIndex === 0) {
2223
- // Special case add to the front of the list
2224
- self.dom.$list.prepend($item)
2225
- } else {
2226
- self.dom.$list
2227
- .find('li')
2228
- .eq(newIndex - 1)
2229
- .after($item)
2230
- }
2231
- },
2232
-
2233
- //= =================================================
2234
- // MODE PREVIEW
2235
- //= =================================================
2236
-
2237
- /**
2238
- * After adding a new item, this function cleans it up for mode=preview.
2239
- * Create the thumbnail image for the empty item.
2240
- * The added item will have a complete form, so move the form to the gallery view.
2241
- */
2242
- modePreviewAddItem: function (item) {
2243
- var self = this
2244
- var $item = $(item)
2245
-
2246
- if (!self.modeIsPreview()) {
2247
- return
2248
- }
2249
-
2250
- let $galleryViewState
2251
- const $galleryViewLabel = $(
2252
- '.view-switcher:enabled + .ComboInput .ComboInput-selected',
2253
- ).text()
2254
-
2255
- if ($galleryViewLabel === 'List View') {
2256
- $galleryViewState = 'list'
2257
- if (!window.GALLERY_LIST_VIEW_UI) {
2258
- $item.removeClass('is-gridItem')
2259
- }
2260
- } else if ($galleryViewLabel === 'Grid View') {
2261
- $galleryViewState = 'grid'
2262
- }
2263
-
2264
- self.$galleryViewState = $galleryViewState
2265
-
2266
- $item.addClass('state-new')
2267
- $item.addClass(`is-${$galleryViewState}Item`)
2268
-
2269
- // Applies RCIG-previewField class for styling on initial upload
2270
- let previewField = $item.attr('data-preview-field')
2271
- if (previewField) {
2272
- const index = previewField.indexOf('/')
2273
- if (index > -1) previewField = previewField.substring(0, index)
2274
- $item
2275
- .find(
2276
- `> .objectInputs > .inputContainer[data-field="${previewField}"]`,
2277
- )
2278
- .addClass('RCIG-previewField')
2279
- }
2280
- },
2281
-
2282
- initViewSwitcher: function () {
2283
- var self = this
2284
- var $container = self.$element
2285
- var $viewGrid
2286
- var $viewVertical
2287
- var $viewSwitcher
2288
- var $topButtonContainer
2289
-
2290
- if (!self.modeIsPreview()) {
2291
- return
2292
- }
2293
-
2294
- // Create controls at the top
2295
- $topButtonContainer = $('<div/>', {
2296
- class: 'repeatablePreviewControls',
2297
- }).prependTo($container)
2298
-
2299
- // Create dropdown to switch between grid view and vertical view
2300
- var $gridSelected =
2301
- !window.GALLERY_LIST_VIEW_UI && !self.isError
2302
- ? "selected='selected'"
2303
- : ''
2304
- var $listSelected =
2305
- window.GALLERY_LIST_VIEW_UI || self.isError ? "selected='selected'" : ''
2306
- $viewSwitcher = $(
2307
- '<select class="view-switcher">' +
2308
- `<option class="view-switcher-grid" ${$gridSelected} value="grid">Grid View</option>` +
2309
- `<option class="view-switcher-vertical" ${$listSelected} value="vertical">List View</option>` +
2310
- '</select>',
2311
- ).appendTo($topButtonContainer)
2312
-
2313
- self.dom.$viewSwitcher = $viewSwitcher // Save for later
2314
-
2315
- // The grid view will use the existing UL or OL
2316
- $viewGrid = self.dom.$list
2317
- self.dom.$viewGrid = $viewGrid // save for later
2318
-
2319
- // The vertical view will also use the existing UL or OL as skeleton
2320
- $viewVertical = self.dom.$list
2321
- self.dom.$viewVertical = $viewVertical // save for later
2322
-
2323
- // Switches between vertical and grid views
2324
- $viewSwitcher.change(function () {
2325
- if ($viewSwitcher.find('option[value="grid"]').attr('selected')) {
2326
- $viewSwitcher.find('option[value="grid"]').removeAttr('selected')
2327
- $viewSwitcher
2328
- .find('option[value="vertical"]')
2329
- .attr('selected', 'selected')
2330
- self.modePreviewShowVertical()
2331
- } else {
2332
- $viewSwitcher.find('option[value="vertical"]').removeAttr('selected')
2333
- $viewSwitcher
2334
- .find('option[value="grid"]')
2335
- .attr('selected', 'selected')
2336
- self.modePreviewShowGrid()
2337
- }
2338
- })
2339
- },
2340
-
2341
- /**
2342
- * When in preview mode, show the grid view.
2343
- */
2344
- modePreviewShowGrid: function () {
2345
- var self = this
2346
-
2347
- if (!self.modeIsPreview()) {
2348
- return
2349
- }
2350
-
2351
- self.dom.$viewGrid.show()
2352
- self.dom.$viewVertical.find('> li').removeClass('is-listItem')
2353
- self.dom.$viewGrid.find('> li').addClass('is-gridItem')
2354
- self.$element.addClass('is-gridView')
2355
-
2356
- self.dom.$viewGrid.find('> li').each(function () {
2357
- var $item = $(this)
2358
- self.itemUncollapse($item)
2359
- })
2360
- },
2361
-
2362
- /**
2363
- * When in preview mode, show the vertical view.
2364
- */
2365
- modePreviewShowVertical: function (activeItem) {
2366
- var self = this
2367
-
2368
- if (!self.modeIsPreview()) {
2369
- return
2370
- }
2371
-
2372
- self.dom.$viewVertical.show()
2373
- self.dom.$viewVertical.find('> li').addClass('is-listItem')
2374
- self.dom.$viewGrid.find('> li').removeClass('is-gridItem')
2375
- self.$element.removeClass('is-gridView')
2376
-
2377
- self.dom.$viewVertical.find('> li').each(function () {
2378
- var $item = $(this)
2379
- self.itemCollapse($item)
2380
- })
2381
- },
2382
-
2383
- /**
2384
- * Determine if an item is an vertical view item
2385
- *
2386
- * @param {Element|jQuery object} item
2387
- * The list item to test.
2388
- */
2389
- itemIsVerticalView: function (item) {
2390
- return item && $(item).hasClass('is-listItem')
2391
- },
2392
-
2393
- /**
2394
- * Determine if an item is a grid view item
2395
- *
2396
- * @param {Element|jQuery object} item
2397
- * The list item to test.
2398
- */
2399
- itemIsGridView: function (item) {
2400
- return item && $(item).hasClass('is-gridItem')
2401
- },
2402
- } // END repeatableUtility
2403
- })(jQuery, window)
2404
-
2405
- // Set filename for debugging tools to allow breakpoints even when using a cachebuster
2406
- // # sourceURL=jquery.repeatable.js