@plone/volto 16.0.0-alpha.12 → 16.0.0-alpha.15

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 (244) hide show
  1. package/.eslintrc +7 -2
  2. package/.github/workflows/acceptance.yml +67 -2
  3. package/CHANGELOG.md +39 -0
  4. package/addon-registry.js +33 -4
  5. package/cypress/support/commands.js +304 -2
  6. package/cypress/support/index.js +2 -0
  7. package/cypress/support/volto-slate.js +78 -0
  8. package/locales/ca/LC_MESSAGES/volto.po +62 -11
  9. package/locales/ca.json +1 -1
  10. package/locales/de/LC_MESSAGES/volto.po +67 -25
  11. package/locales/de.json +1 -1
  12. package/locales/en/LC_MESSAGES/volto.po +62 -11
  13. package/locales/en.json +1 -1
  14. package/locales/es/LC_MESSAGES/volto.po +62 -11
  15. package/locales/es.json +1 -1
  16. package/locales/eu/LC_MESSAGES/volto.po +62 -11
  17. package/locales/eu.json +1 -1
  18. package/locales/fr/LC_MESSAGES/volto.po +62 -11
  19. package/locales/fr.json +1 -1
  20. package/locales/it/LC_MESSAGES/volto.po +62 -11
  21. package/locales/it.json +1 -1
  22. package/locales/ja/LC_MESSAGES/volto.po +62 -11
  23. package/locales/ja.json +1 -1
  24. package/locales/nl/LC_MESSAGES/volto.po +62 -11
  25. package/locales/nl.json +1 -1
  26. package/locales/pt/LC_MESSAGES/volto.po +62 -11
  27. package/locales/pt.json +1 -1
  28. package/locales/pt_BR/LC_MESSAGES/volto.po +62 -11
  29. package/locales/pt_BR.json +1 -1
  30. package/locales/ro/LC_MESSAGES/volto.po +62 -11
  31. package/locales/ro.json +1 -1
  32. package/locales/volto.pot +63 -12
  33. package/package.json +9 -1
  34. package/packages/README.md +7 -0
  35. package/packages/volto-slate/.i18n.babel.config.js +1 -0
  36. package/packages/volto-slate/README.md +235 -0
  37. package/packages/volto-slate/build/messages/src/blocks/Table/TableBlockEdit.json +90 -0
  38. package/packages/volto-slate/build/messages/src/blocks/Text/DefaultTextBlockEditor.json +6 -0
  39. package/packages/volto-slate/build/messages/src/blocks/Text/DetachedTextBlockEditor.json +6 -0
  40. package/packages/volto-slate/build/messages/src/blocks/Text/SlashMenu.json +6 -0
  41. package/packages/volto-slate/build/messages/src/editor/plugins/AdvancedLink/index.json +10 -0
  42. package/packages/volto-slate/build/messages/src/editor/plugins/Link/index.json +10 -0
  43. package/packages/volto-slate/build/messages/src/editor/plugins/Table/index.json +30 -0
  44. package/packages/volto-slate/build/messages/src/elementEditor/messages.json +10 -0
  45. package/packages/volto-slate/build/messages/src/widgets/HtmlSlateWidget.json +6 -0
  46. package/packages/volto-slate/build/messages/src/widgets/RichTextWidgetView.json +6 -0
  47. package/packages/volto-slate/locales/de/LC_MESSAGES/volto.po +148 -0
  48. package/packages/volto-slate/locales/en/LC_MESSAGES/volto.po +148 -0
  49. package/packages/volto-slate/locales/volto.pot +182 -0
  50. package/packages/volto-slate/package.json +43 -0
  51. package/packages/volto-slate/src/actions/content.js +30 -0
  52. package/packages/volto-slate/src/actions/index.js +3 -0
  53. package/packages/volto-slate/src/actions/plugins.js +9 -0
  54. package/packages/volto-slate/src/actions/selection.js +22 -0
  55. package/packages/volto-slate/src/blocks/Table/Cell.jsx +87 -0
  56. package/packages/volto-slate/src/blocks/Table/Cell.test.js +54 -0
  57. package/packages/volto-slate/src/blocks/Table/TableBlockEdit.jsx +885 -0
  58. package/packages/volto-slate/src/blocks/Table/TableBlockEdit.test.js +40 -0
  59. package/packages/volto-slate/src/blocks/Table/TableBlockView.jsx +150 -0
  60. package/packages/volto-slate/src/blocks/Table/TableBlockView.test.js +49 -0
  61. package/packages/volto-slate/src/blocks/Table/deconstruct.js +113 -0
  62. package/packages/volto-slate/src/blocks/Table/extensions/normalizeTable.js +5 -0
  63. package/packages/volto-slate/src/blocks/Table/index.js +58 -0
  64. package/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx +300 -0
  65. package/packages/volto-slate/src/blocks/Text/DetachedTextBlockEditor.jsx +75 -0
  66. package/packages/volto-slate/src/blocks/Text/MarkdownIntroduction.jsx +59 -0
  67. package/packages/volto-slate/src/blocks/Text/PluginSidebar.jsx +18 -0
  68. package/packages/volto-slate/src/blocks/Text/ShortcutListing.jsx +28 -0
  69. package/packages/volto-slate/src/blocks/Text/SlashMenu.jsx +164 -0
  70. package/packages/volto-slate/src/blocks/Text/TextBlockEdit.jsx +38 -0
  71. package/packages/volto-slate/src/blocks/Text/TextBlockEdit.test.js +107 -0
  72. package/packages/volto-slate/src/blocks/Text/TextBlockSchema.js +54 -0
  73. package/packages/volto-slate/src/blocks/Text/TextBlockView.jsx +26 -0
  74. package/packages/volto-slate/src/blocks/Text/css/editor.css +18 -0
  75. package/packages/volto-slate/src/blocks/Text/extensions/Readme.md +49 -0
  76. package/packages/volto-slate/src/blocks/Text/extensions/breakList.js +100 -0
  77. package/packages/volto-slate/src/blocks/Text/extensions/index.js +5 -0
  78. package/packages/volto-slate/src/blocks/Text/extensions/insertBreak.js +57 -0
  79. package/packages/volto-slate/src/blocks/Text/extensions/isSelected.js +8 -0
  80. package/packages/volto-slate/src/blocks/Text/extensions/withDeserializers.js +85 -0
  81. package/packages/volto-slate/src/blocks/Text/extensions/withLists.js +5 -0
  82. package/packages/volto-slate/src/blocks/Text/index.js +166 -0
  83. package/packages/volto-slate/src/blocks/Text/keyboard/backspaceInList.js +58 -0
  84. package/packages/volto-slate/src/blocks/Text/keyboard/breakBlocks.js +3 -0
  85. package/packages/volto-slate/src/blocks/Text/keyboard/cancelEsc.js +7 -0
  86. package/packages/volto-slate/src/blocks/Text/keyboard/indentListItems.js +240 -0
  87. package/packages/volto-slate/src/blocks/Text/keyboard/index.js +52 -0
  88. package/packages/volto-slate/src/blocks/Text/keyboard/joinBlocks.js +177 -0
  89. package/packages/volto-slate/src/blocks/Text/keyboard/moveListItems.js +124 -0
  90. package/packages/volto-slate/src/blocks/Text/keyboard/slashMenu.js +16 -0
  91. package/packages/volto-slate/src/blocks/Text/keyboard/softBreak.js +7 -0
  92. package/packages/volto-slate/src/blocks/Text/keyboard/traverseBlocks.js +81 -0
  93. package/packages/volto-slate/src/blocks/Text/keyboard/unwrapEmptyString.js +26 -0
  94. package/packages/volto-slate/src/blocks/Text/schema.js +39 -0
  95. package/packages/volto-slate/src/constants.js +123 -0
  96. package/packages/volto-slate/src/editor/EditorContext.jsx +5 -0
  97. package/packages/volto-slate/src/editor/EditorReference.jsx +22 -0
  98. package/packages/volto-slate/src/editor/SlateEditor.jsx +369 -0
  99. package/packages/volto-slate/src/editor/config.jsx +313 -0
  100. package/packages/volto-slate/src/editor/decorate.js +63 -0
  101. package/packages/volto-slate/src/editor/deserialize.js +203 -0
  102. package/packages/volto-slate/src/editor/extensions/index.js +5 -0
  103. package/packages/volto-slate/src/editor/extensions/insertBreak.js +15 -0
  104. package/packages/volto-slate/src/editor/extensions/insertData.js +135 -0
  105. package/packages/volto-slate/src/editor/extensions/isInline.js +14 -0
  106. package/packages/volto-slate/src/editor/extensions/normalizeNode.js +45 -0
  107. package/packages/volto-slate/src/editor/extensions/withDeserializers.js +15 -0
  108. package/packages/volto-slate/src/editor/extensions/withTestingFeatures.jsx +84 -0
  109. package/packages/volto-slate/src/editor/index.js +14 -0
  110. package/packages/volto-slate/src/editor/less/editor.less +173 -0
  111. package/packages/volto-slate/src/editor/less/globals.less +18 -0
  112. package/packages/volto-slate/src/editor/plugins/AdvancedLink/deserialize.js +90 -0
  113. package/packages/volto-slate/src/editor/plugins/AdvancedLink/extensions.js +32 -0
  114. package/packages/volto-slate/src/editor/plugins/AdvancedLink/index.js +50 -0
  115. package/packages/volto-slate/src/editor/plugins/AdvancedLink/render.jsx +37 -0
  116. package/packages/volto-slate/src/editor/plugins/AdvancedLink/schema.js +114 -0
  117. package/packages/volto-slate/src/editor/plugins/AdvancedLink/styles.less +8 -0
  118. package/packages/volto-slate/src/editor/plugins/Blockquote/index.js +30 -0
  119. package/packages/volto-slate/src/editor/plugins/Callout/index.js +34 -0
  120. package/packages/volto-slate/src/editor/plugins/Image/deconstruct.js +30 -0
  121. package/packages/volto-slate/src/editor/plugins/Image/extensions.js +51 -0
  122. package/packages/volto-slate/src/editor/plugins/Image/index.js +11 -0
  123. package/packages/volto-slate/src/editor/plugins/Image/render.jsx +22 -0
  124. package/packages/volto-slate/src/editor/plugins/Link/extensions.js +53 -0
  125. package/packages/volto-slate/src/editor/plugins/Link/index.js +168 -0
  126. package/packages/volto-slate/src/editor/plugins/Link/render.jsx +46 -0
  127. package/packages/volto-slate/src/editor/plugins/Markdown/constants.js +96 -0
  128. package/packages/volto-slate/src/editor/plugins/Markdown/extensions.js +334 -0
  129. package/packages/volto-slate/src/editor/plugins/Markdown/index.js +28 -0
  130. package/packages/volto-slate/src/editor/plugins/Markdown/utils.js +198 -0
  131. package/packages/volto-slate/src/editor/plugins/Table/TableButton.jsx +142 -0
  132. package/packages/volto-slate/src/editor/plugins/Table/TableCell.jsx +44 -0
  133. package/packages/volto-slate/src/editor/plugins/Table/TableContainer.jsx +37 -0
  134. package/packages/volto-slate/src/editor/plugins/Table/TableSizePicker.jsx +83 -0
  135. package/packages/volto-slate/src/editor/plugins/Table/extensions.js +87 -0
  136. package/packages/volto-slate/src/editor/plugins/Table/index.js +390 -0
  137. package/packages/volto-slate/src/editor/plugins/Table/less/public.less +29 -0
  138. package/packages/volto-slate/src/editor/plugins/Table/less/table.less +28 -0
  139. package/packages/volto-slate/src/editor/plugins/Table/render.jsx +30 -0
  140. package/packages/volto-slate/src/editor/plugins/index.js +17 -0
  141. package/packages/volto-slate/src/editor/render.jsx +155 -0
  142. package/packages/volto-slate/src/editor/ui/BasicToolbar.jsx +11 -0
  143. package/packages/volto-slate/src/editor/ui/BlockButton.jsx +31 -0
  144. package/packages/volto-slate/src/editor/ui/ExpandedToolbar.jsx +18 -0
  145. package/packages/volto-slate/src/editor/ui/Expando.jsx +5 -0
  146. package/packages/volto-slate/src/editor/ui/InlineToolbar.jsx +71 -0
  147. package/packages/volto-slate/src/editor/ui/MarkButton.jsx +23 -0
  148. package/packages/volto-slate/src/editor/ui/MarkElementButton.jsx +30 -0
  149. package/packages/volto-slate/src/editor/ui/Menu.jsx +13 -0
  150. package/packages/volto-slate/src/editor/ui/PositionedToolbar.jsx +30 -0
  151. package/packages/volto-slate/src/editor/ui/Separator.jsx +7 -0
  152. package/packages/volto-slate/src/editor/ui/SlateContextToolbar.jsx +13 -0
  153. package/packages/volto-slate/src/editor/ui/SlateToolbar.jsx +94 -0
  154. package/packages/volto-slate/src/editor/ui/Toolbar.jsx +97 -0
  155. package/packages/volto-slate/src/editor/ui/ToolbarButton.jsx +33 -0
  156. package/packages/volto-slate/src/editor/ui/ToolbarButton.test.js +25 -0
  157. package/packages/volto-slate/src/editor/ui/index.js +14 -0
  158. package/packages/volto-slate/src/elementEditor/ContextButtons.jsx +56 -0
  159. package/packages/volto-slate/src/elementEditor/PluginEditor.jsx +123 -0
  160. package/packages/volto-slate/src/elementEditor/Readme.md +6 -0
  161. package/packages/volto-slate/src/elementEditor/SchemaProvider.jsx +3 -0
  162. package/packages/volto-slate/src/elementEditor/SidebarEditor.jsx +46 -0
  163. package/packages/volto-slate/src/elementEditor/ToolbarButton.jsx +44 -0
  164. package/packages/volto-slate/src/elementEditor/index.js +5 -0
  165. package/packages/volto-slate/src/elementEditor/makeInlineElementPlugin.js +100 -0
  166. package/packages/volto-slate/src/elementEditor/messages.js +14 -0
  167. package/packages/volto-slate/src/elementEditor/utils.js +215 -0
  168. package/packages/volto-slate/src/hooks/index.js +2 -0
  169. package/packages/volto-slate/src/hooks/useEditorContext.js +6 -0
  170. package/packages/volto-slate/src/hooks/useIsomorphicLayoutEffect.js +7 -0
  171. package/packages/volto-slate/src/i18n.js +180 -0
  172. package/packages/volto-slate/src/icons/hashlink.svg +57 -0
  173. package/packages/volto-slate/src/index.js +59 -0
  174. package/packages/volto-slate/src/reducers/content.js +74 -0
  175. package/packages/volto-slate/src/reducers/index.js +3 -0
  176. package/packages/volto-slate/src/reducers/plugins.js +17 -0
  177. package/packages/volto-slate/src/reducers/selection.js +16 -0
  178. package/packages/volto-slate/src/utils/blocks.js +308 -0
  179. package/packages/volto-slate/src/utils/blocks.test.js +138 -0
  180. package/packages/volto-slate/src/utils/editor.js +31 -0
  181. package/packages/volto-slate/src/utils/image.js +25 -0
  182. package/packages/volto-slate/src/utils/index.js +11 -0
  183. package/packages/volto-slate/src/utils/internals.js +46 -0
  184. package/packages/volto-slate/src/utils/lists.js +92 -0
  185. package/packages/volto-slate/src/utils/marks.js +104 -0
  186. package/packages/volto-slate/src/utils/mime-types.js +24 -0
  187. package/packages/volto-slate/src/utils/nodes.js +4 -0
  188. package/packages/volto-slate/src/utils/ops.js +20 -0
  189. package/packages/volto-slate/src/utils/random.js +17 -0
  190. package/packages/volto-slate/src/utils/selection.js +233 -0
  191. package/packages/volto-slate/src/utils/slate-string-utils.js +408 -0
  192. package/packages/volto-slate/src/utils/volto-blocks.js +314 -0
  193. package/packages/volto-slate/src/widgets/ErrorBoundary.jsx +27 -0
  194. package/packages/volto-slate/src/widgets/HtmlSlateWidget.jsx +139 -0
  195. package/packages/volto-slate/src/widgets/ObjectByTypeWidget.jsx +49 -0
  196. package/packages/volto-slate/src/widgets/RichTextWidget.jsx +65 -0
  197. package/packages/volto-slate/src/widgets/RichTextWidgetView.jsx +37 -0
  198. package/packages/volto-slate/src/widgets/style.css +21 -0
  199. package/razzle.config.js +2 -0
  200. package/src/actions/groups/groups.js +28 -13
  201. package/src/actions/users/users.js +41 -5
  202. package/src/actions/users/users.test.js +2 -2
  203. package/src/components/index.js +1 -0
  204. package/src/components/manage/Blocks/Block/Settings.jsx +2 -2
  205. package/src/components/manage/Blocks/Description/Edit.jsx +182 -211
  206. package/src/components/manage/Blocks/Description/Edit.test.jsx +42 -32
  207. package/src/components/manage/Blocks/Description/View.jsx +13 -8
  208. package/src/components/manage/Blocks/Table/Readme.md +5 -0
  209. package/src/components/manage/Blocks/Text/Readme.md +5 -0
  210. package/src/components/manage/Blocks/Title/Edit.jsx +166 -197
  211. package/src/components/manage/Blocks/Title/Edit.test.jsx +42 -32
  212. package/src/components/manage/Blocks/Title/View.jsx +13 -8
  213. package/src/components/manage/Blocks/ToC/Edit.jsx +29 -24
  214. package/src/components/manage/Blocks/ToC/Schema.jsx +43 -11
  215. package/src/components/manage/Blocks/ToC/View.jsx +87 -39
  216. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.jsx +75 -0
  217. package/src/components/manage/Blocks/ToC/variations/HorizontalMenu.jsx +65 -0
  218. package/src/components/manage/Blocks/ToC/variations/index.js +16 -0
  219. package/src/components/manage/Blocks/Video/Body.jsx +13 -11
  220. package/src/components/manage/Blocks/Video/Edit.jsx +3 -1
  221. package/src/components/manage/Blocks/Video/Edit.test.jsx +20 -1
  222. package/src/components/manage/Blocks/Video/VideoSidebar.jsx +38 -205
  223. package/src/components/manage/Blocks/Video/View.jsx +5 -2
  224. package/src/components/manage/Blocks/Video/View.test.jsx +39 -1
  225. package/src/components/manage/Blocks/Video/schema.js +49 -0
  226. package/src/components/manage/Controlpanels/Controlpanels.jsx +9 -0
  227. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.jsx +149 -0
  228. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.test.jsx +62 -0
  229. package/src/components/manage/Controlpanels/Users/UserGroupMembershipListing.jsx +326 -0
  230. package/src/components/manage/Controlpanels/Users/UserGroupMembershipMatrix.jsx +206 -0
  231. package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +8 -3
  232. package/src/components/theme/Unauthorized/Unauthorized.jsx +1 -1
  233. package/src/components/theme/View/DefaultView.jsx +41 -37
  234. package/src/components/theme/View/DefaultView.test.jsx +6 -1
  235. package/src/config/Blocks.jsx +4 -1
  236. package/src/config/index.js +4 -2
  237. package/src/constants/ActionTypes.js +1 -0
  238. package/src/helpers/MessageLabels/MessageLabels.js +32 -0
  239. package/src/reducers/content/content.js +3 -0
  240. package/src/reducers/groups/groups.js +22 -0
  241. package/src/routes.js +5 -0
  242. package/theme/themes/pastanaga/extras/userscontrolpanel.less +125 -0
  243. package/src/components/manage/Blocks/ToC/Edit.test.jsx +0 -59
  244. package/src/components/manage/Blocks/ToC/View.test.jsx +0 -59
package/.eslintrc CHANGED
@@ -32,14 +32,19 @@
32
32
  "settings": {
33
33
  "import/resolver": {
34
34
  "alias": {
35
- "map": [["@plone/volto", "./src"], ["@package", "./src"], ["@root", "./src"]],
35
+ "map": [
36
+ ["@plone/volto", "./src"],
37
+ ["@plone/volto-slate", "./packages/volto-slate/src"],
38
+ ["@package", "./src"],
39
+ ["@root", "./src"]
40
+ ],
36
41
  "extensions": [".js", ".jsx", ".json"]
37
42
  },
38
43
  "babel-plugin-root-import": {
39
44
  "rootPathSuffix": "src"
40
45
  }
41
46
  },
42
- "import/core-modules": [ "load-volto-addons" ]
47
+ "import/core-modules": ["load-volto-addons"]
43
48
  },
44
49
  "globals": {
45
50
  "root": true,
@@ -133,6 +133,72 @@ jobs:
133
133
  name: cypress-videos
134
134
  path: cypress/videos
135
135
 
136
+ corevoltoslate:
137
+ runs-on: ubuntu-latest
138
+ name: Core Volto Slate
139
+ timeout-minutes: 45
140
+ strategy:
141
+ matrix:
142
+ node-version: [14.x, 16.x]
143
+ steps:
144
+ - uses: actions/checkout@v2
145
+
146
+ # node setup
147
+ - name: Use Node.js ${{ matrix.node-version }}
148
+ uses: actions/setup-node@v1
149
+ with:
150
+ node-version: ${{ matrix.node-version }}
151
+
152
+ # node cache
153
+ - name: Get yarn cache directory path
154
+ id: yarn-cache-dir-path
155
+ run: echo "::set-output name=dir::$(yarn cache dir)"
156
+ - uses: actions/cache@v1
157
+ id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
158
+ with:
159
+ path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
160
+ key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
161
+ restore-keys: |
162
+ ${{ runner.os }}-yarn-
163
+
164
+ ## node install
165
+ - run: yarn --frozen-lockfile
166
+
167
+ - name: Cypress acceptance tests
168
+ uses: cypress-io/github-action@v2
169
+ env:
170
+ BABEL_ENV: production
171
+ CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
172
+ CYPRESS_RETRIES: 2
173
+ # Recommended: pass the GitHub token lets this action correctly
174
+ # determine the unique run id necessary to re-run the checks
175
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
176
+ with:
177
+ record: true
178
+ parallel: false # Since they run on different node versions, we can't parallel
179
+ browser: chrome
180
+ # headless: true
181
+ group: Core Volto Slate ${{ matrix.node-version }}
182
+ config: integrationFolder=cypress/tests
183
+ spec: cypress/tests/core/volto-slate/**/*.js
184
+ start: |
185
+ make start-test-acceptance-server
186
+ make start-test-acceptance-frontend
187
+ wait-on: 'npx wait-on --httpTimeout 20000 http-get://localhost:55001/plone http://localhost:3000'
188
+
189
+ # Upload Cypress screenshots
190
+ - uses: actions/upload-artifact@v1
191
+ if: failure()
192
+ with:
193
+ name: cypress-screenshots
194
+ path: cypress/screenshots
195
+ # Upload Cypress videos
196
+ - uses: actions/upload-artifact@v1
197
+ if: failure()
198
+ with:
199
+ name: cypress-videos
200
+ path: cypress/videos
201
+
136
202
  core6:
137
203
  runs-on: ubuntu-latest
138
204
  name: Core Basic - Plone 6
@@ -505,7 +571,6 @@ jobs:
505
571
  make start-test-acceptance-frontend-workingcopy
506
572
  wait-on: 'npx wait-on --httpTimeout 20000 http-get://localhost:55001/plone http://localhost:3000'
507
573
 
508
-
509
574
  # Upload Cypress screenshots
510
575
  - uses: actions/upload-artifact@v1
511
576
  if: failure()
@@ -557,7 +622,7 @@ jobs:
557
622
 
558
623
  # Generator own tests
559
624
  - name: Generator tests
560
- run: yarn && yarn test
625
+ run: yarn && yarn test
561
626
  working-directory: ${{env.generator-directory}}
562
627
 
563
628
  # install Yeoman and the generator
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # Change Log
2
2
 
3
+ ## 16.0.0-alpha.15 (2022-07-21)
4
+
5
+ ### Breaking
6
+
7
+ - Integrate volto-state add-on. @tiberiuichim @razvanmiu @eea
8
+
9
+ ### Documentation
10
+
11
+ - volto-slate documentation @nileshgulia1
12
+
13
+ ## 16.0.0-alpha.14 (2022-07-20)
14
+
15
+ ### Breaking
16
+
17
+ - Action `listUsers`to be called with Object. Distinguish between search for id or search for fullname, email, username @ksuess
18
+
19
+ ### Feature
20
+
21
+ - Add user group membership control panel @ksuess
22
+ - Action `listUsers`: Support search for fullname, email, username. @ksuess
23
+
24
+ ### Bugfix
25
+
26
+ - Fix typo in de locale @wolbernd
27
+
28
+ ## 16.0.0-alpha.13 (2022-07-18)
29
+
30
+ ### Feature
31
+
32
+ - Add schema to video block sidebar @iRohitSingh @danielamormocea
33
+
34
+ ### Bugfix
35
+
36
+ - Prevent the `defaultView` to show anything if the content is not loaded yet. This fixes showing the non-blocks enabled view for a fraction of a second before showing the blocks-enabled one once the content is loaded. @sneridagh
37
+
38
+ ### Documentation
39
+
40
+ - `aria-*` attributes are now parsed correctly by jsx-lexer 2.0. @stevepiercy
41
+
3
42
  ## 16.0.0-alpha.12 (2022-07-13)
4
43
 
5
44
  ### Feature
package/addon-registry.js CHANGED
@@ -184,6 +184,32 @@ class AddonConfigurationRegistry {
184
184
  this.packages[name] = Object.assign(this.packages[name] || {}, pkg);
185
185
  });
186
186
  }
187
+ this.initSlate();
188
+ }
189
+
190
+ initSlate() {
191
+ if (this.packages['@plone/volto-slate']) return;
192
+
193
+ const slatePath = path.normalize(
194
+ `${this.voltoPath}/packages/volto-slate/src`,
195
+ );
196
+ const slatePackageJsonPath = path.normalize(
197
+ `${this.voltoPath}/packages/volto-slate/package.json`,
198
+ );
199
+
200
+ // some tests set the root in a location that doesn't have the packages
201
+ if (!fs.existsSync(slatePath)) return;
202
+
203
+ this.packages['@plone/volto-slate'] = {
204
+ modulePath: slatePath,
205
+ packageJson: slatePackageJsonPath,
206
+ version: require(slatePackageJsonPath).version,
207
+ isPublishedPackage: false,
208
+ isRegisteredAddon: false,
209
+ name: '@plone/volto-slate',
210
+ addons: [],
211
+ };
212
+ this.addonNames.push('@plone/volto-slate');
187
213
  }
188
214
 
189
215
  /**
@@ -297,10 +323,13 @@ class AddonConfigurationRegistry {
297
323
  * Returns a mapping name:diskpath to be uses in webpack's resolve aliases
298
324
  */
299
325
  getResolveAliases() {
300
- const pairs = Object.keys(this.packages).map((o) => [
301
- o,
302
- this.packages[o].modulePath,
303
- ]);
326
+ const pairs = [
327
+ ...Object.keys(this.packages).map((o) => [
328
+ o,
329
+ this.packages[o].modulePath,
330
+ ]),
331
+ ];
332
+
304
333
  return fromEntries(pairs);
305
334
  }
306
335
 
@@ -7,6 +7,9 @@ const PLONE_SITE_ID = Cypress.env('SITE_ID') || 'plone';
7
7
  const PLONE_API_URL =
8
8
  Cypress.env('API_PATH') || `http://${HOSTNAME}:55001/${PLONE_SITE_ID}`;
9
9
 
10
+ const SLATE_SELECTOR = '.content-area .slate-editor [contenteditable=true]';
11
+ const SLATE_TITLE_SELECTOR = '.block.inner.title [contenteditable="true"]';
12
+
10
13
  // --- AUTOLOGIN -------------------------------------------------------------
11
14
  Cypress.Commands.add('autologin', (usr, pass) => {
12
15
  let api_url, user, password;
@@ -116,7 +119,7 @@ Cypress.Commands.add(
116
119
  title: contentTitle,
117
120
  blocks: {
118
121
  'd3f1c443-583f-4e8e-a682-3bf25752a300': { '@type': 'title' },
119
- '7624cf59-05d0-4055-8f55-5fd6597d84b0': { '@type': 'text' },
122
+ '7624cf59-05d0-4055-8f55-5fd6597d84b0': { '@type': 'slate' },
120
123
  },
121
124
  blocks_layout: {
122
125
  items: [
@@ -164,6 +167,7 @@ Cypress.Commands.add(
164
167
  }
165
168
  },
166
169
  );
170
+
167
171
  // Remove content
168
172
  Cypress.Commands.add('removeContent', ({ path = '' }) => {
169
173
  let api_url, auth;
@@ -180,6 +184,7 @@ Cypress.Commands.add('removeContent', ({ path = '' }) => {
180
184
  pass: 'secret',
181
185
  };
182
186
  }
187
+
183
188
  return cy.request({
184
189
  method: 'DELETE',
185
190
  url: `${api_url}/${path}`,
@@ -190,6 +195,100 @@ Cypress.Commands.add('removeContent', ({ path = '' }) => {
190
195
  });
191
196
  });
192
197
 
198
+ // --- Add DX Content-Type ----------------------------------------------------------
199
+ Cypress.Commands.add('addContentType', (name) => {
200
+ let api_url, auth;
201
+ api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone';
202
+ auth = {
203
+ user: 'admin',
204
+ pass: 'secret',
205
+ };
206
+ return cy
207
+ .request({
208
+ method: 'POST',
209
+ url: `${api_url}/@controlpanels/dexterity-types/${name}`,
210
+ headers: {
211
+ Accept: 'application/json',
212
+ },
213
+ auth: auth,
214
+ body: {
215
+ title: name,
216
+ },
217
+ })
218
+ .then(() => console.log(`${name} content-type added.`));
219
+ });
220
+
221
+ // --- Remove DX behavior ----------------------------------------------------------
222
+ Cypress.Commands.add('removeContentType', (name) => {
223
+ let api_url, auth;
224
+ api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone';
225
+ auth = {
226
+ user: 'admin',
227
+ pass: 'secret',
228
+ };
229
+ return cy
230
+ .request({
231
+ method: 'DELETE',
232
+ url: `${api_url}/@controlpanels/dexterity-types/${name}`,
233
+ headers: {
234
+ Accept: 'application/json',
235
+ },
236
+ auth: auth,
237
+ body: {},
238
+ })
239
+ .then(() => console.log(`${name} content-type removed.`));
240
+ });
241
+
242
+ // --- Add DX field ----------------------------------------------------------
243
+ Cypress.Commands.add('addSlateJSONField', (type, name) => {
244
+ let api_url, auth;
245
+ api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone';
246
+ auth = {
247
+ user: 'admin',
248
+ pass: 'secret',
249
+ };
250
+ return cy
251
+ .request({
252
+ method: 'POST',
253
+ url: `${api_url}/@types/${type}`,
254
+ headers: {
255
+ Accept: 'application/json',
256
+ },
257
+ auth: auth,
258
+ body: {
259
+ id: name,
260
+ title: name,
261
+ description: 'Slate JSON Field',
262
+ factory: 'SlateJSONField',
263
+ required: false,
264
+ },
265
+ })
266
+ .then(() => console.log(`${name} SlateJSONField field added to ${type}`));
267
+ });
268
+
269
+ // --- Remove DX field ----------------------------------------------------------
270
+ Cypress.Commands.add('removeSlateJSONField', (type, name) => {
271
+ let api_url, auth;
272
+ api_url = Cypress.env('API_PATH') || 'http://localhost:8080/Plone';
273
+ auth = {
274
+ user: 'admin',
275
+ pass: 'secret',
276
+ };
277
+ return cy
278
+ .request({
279
+ method: 'DELETE',
280
+ url: `${api_url}/@types/${type}/${name}`,
281
+ headers: {
282
+ Accept: 'application/json',
283
+ },
284
+ auth: auth,
285
+ body: {},
286
+ })
287
+ .then(() =>
288
+ console.log(`${name} SlateJSONField field removed from ${type}`),
289
+ );
290
+ });
291
+
193
292
  // --- CREATE USER --------------------------------------------------------
194
293
  Cypress.Commands.add(
195
294
  'createUser',
@@ -199,6 +298,16 @@ Cypress.Commands.add(
199
298
  email = 'editor@local.dev',
200
299
  password = 'secret',
201
300
  roles = ['Member', 'Reader', 'Editor'],
301
+ groups = {
302
+ '@id': 'http://localhost:3000/@users',
303
+ items: [
304
+ {
305
+ id: 'AuthenticatedUsers',
306
+ title: 'AuthenticatedUsers',
307
+ },
308
+ ],
309
+ items_total: 1,
310
+ },
202
311
  }) => {
203
312
  let api_url, auth, path;
204
313
  if (Cypress.env('API') === 'guillotina') {
@@ -232,6 +341,7 @@ Cypress.Commands.add(
232
341
  email: email,
233
342
  password: password,
234
343
  roles: roles,
344
+ groups: groups,
235
345
  },
236
346
  })
237
347
  .then(() => console.log(`User ${username} created`));
@@ -269,6 +379,59 @@ Cypress.Commands.add('removeUser', (username = 'editor') => {
269
379
  .then(() => console.log(`User ${username} removed`));
270
380
  });
271
381
 
382
+ // --- GROUP -----------------------------------------------------------------
383
+
384
+ Cypress.Commands.add(
385
+ 'createGroup',
386
+ ({
387
+ groupname = 'teachers',
388
+ email = 'teachers@local.dev',
389
+ password = 'secret',
390
+ roles = ['Member', 'Reader'],
391
+ users = {
392
+ '@id': 'http://localhost:3000/@groups',
393
+ items: [],
394
+ items_total: 0,
395
+ },
396
+ }) => {
397
+ let api_url, auth, path;
398
+ if (Cypress.env('API') === 'guillotina') {
399
+ api_url = GUILLOTINA_API_URL;
400
+ auth = {
401
+ user: 'root',
402
+ pass: 'root',
403
+ };
404
+ path = 'groups';
405
+ } else {
406
+ api_url = PLONE_API_URL;
407
+ auth = {
408
+ user: 'admin',
409
+ pass: 'secret',
410
+ };
411
+ path = '@groups';
412
+ }
413
+
414
+ return cy
415
+ .request({
416
+ method: 'POST',
417
+ url: `${api_url}/${path}`,
418
+ headers: {
419
+ Accept: 'application/json',
420
+ },
421
+ auth: auth,
422
+ body: {
423
+ '@type': 'Group',
424
+ groupname: groupname,
425
+ email: email,
426
+ password: password,
427
+ roles: roles,
428
+ users: users,
429
+ },
430
+ })
431
+ .then(() => console.log(`Group ${groupname} created`));
432
+ },
433
+ );
434
+
272
435
  // --- SET WORKFLOW ----------------------------------------------------------
273
436
  Cypress.Commands.add(
274
437
  'setWorkflow',
@@ -371,7 +534,12 @@ Cypress.Commands.add('setRegistry', (record, value) => {
371
534
 
372
535
  // Low level command reused by `setSelection` and low level command `setCursor`
373
536
  Cypress.Commands.add('selection', { prevSubject: true }, (subject, fn) => {
374
- cy.wrap(subject).trigger('mousedown').then(fn).trigger('mouseup');
537
+ cy.wrap(subject)
538
+ .trigger('mousedown')
539
+ .wait(1000) //multiple waits between selecting the text to ensure toolbar is visible.
540
+ .then(fn)
541
+ .wait(1000)
542
+ .trigger('mouseup');
375
543
 
376
544
  cy.document().trigger('selectionchange');
377
545
  return cy.wrap(subject);
@@ -438,6 +606,128 @@ Cypress.Commands.add(
438
606
  },
439
607
  );
440
608
 
609
+ Cypress.Commands.add(
610
+ 'pasteClipboard',
611
+ { prevSubject: true },
612
+ (query, htmlContent) => {
613
+ return cy
614
+ .wrap(query)
615
+ .type(' ')
616
+ .trigger('paste', createHtmlPasteEvent(htmlContent));
617
+ },
618
+ );
619
+
620
+ Cypress.Commands.add('toolbarSave', () => {
621
+ // Save
622
+ cy.get('#toolbar-save', { timeout: 10000 }).click();
623
+ cy.waitForResourceToLoad('@navigation');
624
+ cy.waitForResourceToLoad('@breadcrumbs');
625
+ cy.waitForResourceToLoad('@actions');
626
+ cy.waitForResourceToLoad('@types');
627
+ });
628
+
629
+ Cypress.Commands.add('clearSlate', (selector) => {
630
+ return cy
631
+ .get(selector)
632
+ .focus()
633
+ .click()
634
+ .wait(1000)
635
+ .type('{selectAll}')
636
+ .wait(1000)
637
+ .type('{backspace}');
638
+ });
639
+
640
+ Cypress.Commands.add('getSlate', (createNewSlate = false) => {
641
+ let slate;
642
+ cy.getIfExists(
643
+ SLATE_SELECTOR,
644
+ () => {
645
+ slate = cy.get(SLATE_SELECTOR).last();
646
+ },
647
+ () => {
648
+ if (createNewSlate) {
649
+ cy.get('.block.inner').last().type('{enter}');
650
+ slate = cy.get(SLATE_SELECTOR, { timeout: 10000 }).last();
651
+ } else {
652
+ slate = cy.get(SLATE_SELECTOR, { timeout: 10000 }).last();
653
+ }
654
+ },
655
+ );
656
+ return slate;
657
+ });
658
+
659
+ Cypress.Commands.add('getSlateTitle', () => {
660
+ return cy.get(SLATE_TITLE_SELECTOR, {
661
+ timeout: 10000,
662
+ });
663
+ });
664
+
665
+ Cypress.Commands.add('clearSlateTitle', () => {
666
+ return cy.clearSlate(SLATE_TITLE_SELECTOR);
667
+ });
668
+
669
+ // Slate commands
670
+ Cypress.Commands.add('typeInSlate', { prevSubject: true }, (subject, text) => {
671
+ return (
672
+ cy
673
+ .wrap(subject)
674
+ .then((subject) => {
675
+ subject[0].dispatchEvent(
676
+ new InputEvent('beforeinput', {
677
+ inputType: 'insertText',
678
+ data: text,
679
+ }),
680
+ );
681
+ return subject;
682
+ })
683
+ // TODO: do this only for Electron-based browser which does not understand instantaneously
684
+ // that the user inserted some text in the block
685
+ .wait(1000)
686
+ );
687
+ });
688
+
689
+ Cypress.Commands.add('lineBreakInSlate', { prevSubject: true }, (subject) => {
690
+ return (
691
+ cy
692
+ .wrap(subject)
693
+ .then((subject) => {
694
+ subject[0].dispatchEvent(
695
+ new InputEvent('beforeinput', { inputType: 'insertLineBreak' }),
696
+ );
697
+ return subject;
698
+ })
699
+ // TODO: do this only for Electron-based browser which does not understand instantaneously
700
+ // that the block was split
701
+ .wait(1000)
702
+ );
703
+ });
704
+
705
+ Cypress.Commands.add('setSlateSelection', (subject, query, endQuery) => {
706
+ cy.get('.slate-editor.selected [contenteditable=true]')
707
+ .focus()
708
+ .click()
709
+ .setSelection(subject, query, endQuery)
710
+ .wait(1000); // this wait is needed for the selection change to be detected after
711
+ });
712
+
713
+ Cypress.Commands.add('getSlateEditorAndType', (type) => {
714
+ cy.getSlate().focus().click().type(type);
715
+ });
716
+
717
+ Cypress.Commands.add('setSlateCursor', (subject, query, endQuery) => {
718
+ cy.get('.slate-editor.selected [contenteditable=true]')
719
+ .focus()
720
+ .click()
721
+ .setCursor(subject, query, endQuery)
722
+ .wait(1000); // this wait is needed for the selection change to be detected after
723
+ });
724
+
725
+ Cypress.Commands.add('clickSlateButton', (button) => {
726
+ cy.get(`.slate-inline-toolbar .button-wrapper a[title="${button}"]`, {
727
+ timeout: 10000,
728
+ }).click({ force: true }); //force click is needed to ensure the button in visible in view.
729
+ });
730
+
441
731
  // Helper functions
442
732
  function getTextNode(el, match) {
443
733
  const walk = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null, false);
@@ -460,6 +750,18 @@ function setBaseAndExtent(...args) {
460
750
  document.getSelection().setBaseAndExtent(...args);
461
751
  }
462
752
 
753
+ function createHtmlPasteEvent(htmlContent) {
754
+ return Object.assign(
755
+ new Event('paste', { bubbles: true, cancelable: true }),
756
+ {
757
+ clipboardData: {
758
+ getData: () => htmlContent,
759
+ types: ['text/html'],
760
+ },
761
+ },
762
+ );
763
+ }
764
+
463
765
  Cypress.Commands.add('navigate', (route = '') => {
464
766
  return cy.window().its('appHistory').invoke('push', route);
465
767
  });
@@ -28,3 +28,5 @@ afterEach(function () {
28
28
  teardown();
29
29
  }
30
30
  });
31
+
32
+ export * from './volto-slate';
@@ -0,0 +1,78 @@
1
+ export const slateBeforeEach = (contentType = 'Document') => {
2
+ cy.autologin();
3
+ cy.createContent({
4
+ contentType: contentType,
5
+ contentId: 'my-page',
6
+ contentTitle: 'My Page',
7
+ });
8
+ cy.visit('/my-page');
9
+ cy.waitForResourceToLoad('@navigation');
10
+ cy.waitForResourceToLoad('@breadcrumbs');
11
+ cy.waitForResourceToLoad('@actions');
12
+ cy.waitForResourceToLoad('@types');
13
+ cy.waitForResourceToLoad('my-page');
14
+ cy.navigate('/my-page/edit');
15
+ };
16
+
17
+ export const getSelectedSlateEditor = () => {
18
+ return cy.get('.slate-editor.selected [contenteditable=true]').click();
19
+ };
20
+
21
+ export const createSlateBlock = () => {
22
+ cy.get('.ui.basic.icon.button.block-add-button').first().click();
23
+ cy.get('.blocks-chooser .title').contains('Text').click();
24
+ cy.get('.ui.basic.icon.button.slate').contains('Text').click();
25
+ return getSelectedSlateEditor();
26
+ };
27
+
28
+ export const getSlateBlockValue = (sb) => {
29
+ return sb.invoke('attr', 'data-slate-value').then((str) => {
30
+ return typeof str === 'undefined' ? [] : JSON.parse(str);
31
+ });
32
+ };
33
+
34
+ export const createSlateBlockWithList = ({
35
+ numbered,
36
+ firstItemText,
37
+ secondItemText,
38
+ }) => {
39
+ let s1 = createSlateBlock();
40
+
41
+ s1.typeInSlate(firstItemText + secondItemText);
42
+
43
+ // select all contents of slate block
44
+ // - this opens hovering toolbar
45
+ cy.contains(firstItemText + secondItemText).then((el) => {
46
+ selectSlateNodeOfWord(el);
47
+ });
48
+
49
+ // TODO: do not hardcode these selectors:
50
+ if (numbered) {
51
+ // this is the numbered list option in the hovering toolbar
52
+ cy.get('.slate-inline-toolbar > :nth-child(9)').click();
53
+ } else {
54
+ // this is the bulleted list option in the hovering toolbar
55
+ cy.get('.slate-inline-toolbar > :nth-child(10)').click();
56
+ }
57
+
58
+ // move the text cursor
59
+ const sse = getSelectedSlateEditor();
60
+ sse.type('{leftarrow}');
61
+ for (let i = 0; i < firstItemText.length; ++i) {
62
+ sse.type('{rightarrow}');
63
+ }
64
+
65
+ // simulate pressing Enter
66
+ getSelectedSlateEditor().lineBreakInSlate();
67
+
68
+ return s1;
69
+ };
70
+
71
+ export const selectSlateNodeOfWord = (el) => {
72
+ return cy.window().then((win) => {
73
+ var event = new CustomEvent('Test_SelectWord', {
74
+ detail: el[0],
75
+ });
76
+ win.document.dispatchEvent(event);
77
+ });
78
+ };