@atlaskit/editor-core 219.5.1 → 219.6.1

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 (30) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/cjs/create-editor/ReactEditorView.js +45 -0
  3. package/dist/cjs/create-editor/create-editor.js +6 -1
  4. package/dist/cjs/create-editor/filter-plugins-for-reconfigure.js +49 -0
  5. package/dist/cjs/test-utils.js +3 -1
  6. package/dist/cjs/ui/EditorContentContainer/EditorContentContainer-compiled.compiled.css +283 -6
  7. package/dist/cjs/ui/EditorContentContainer/EditorContentContainer-compiled.js +25 -23
  8. package/dist/cjs/ui/PluginSlot/mount-plugin-hooks.js +10 -3
  9. package/dist/cjs/version-wrapper.js +1 -1
  10. package/dist/es2019/create-editor/ReactEditorView.js +43 -1
  11. package/dist/es2019/create-editor/create-editor.js +6 -1
  12. package/dist/es2019/create-editor/filter-plugins-for-reconfigure.js +35 -0
  13. package/dist/es2019/test-utils.js +3 -1
  14. package/dist/es2019/ui/EditorContentContainer/EditorContentContainer-compiled.compiled.css +283 -6
  15. package/dist/es2019/ui/EditorContentContainer/EditorContentContainer-compiled.js +26 -24
  16. package/dist/es2019/ui/PluginSlot/mount-plugin-hooks.js +18 -9
  17. package/dist/es2019/version-wrapper.js +1 -1
  18. package/dist/esm/create-editor/ReactEditorView.js +45 -0
  19. package/dist/esm/create-editor/create-editor.js +6 -1
  20. package/dist/esm/create-editor/filter-plugins-for-reconfigure.js +43 -0
  21. package/dist/esm/test-utils.js +3 -1
  22. package/dist/esm/ui/EditorContentContainer/EditorContentContainer-compiled.compiled.css +283 -6
  23. package/dist/esm/ui/EditorContentContainer/EditorContentContainer-compiled.js +26 -24
  24. package/dist/esm/ui/PluginSlot/mount-plugin-hooks.js +10 -3
  25. package/dist/esm/version-wrapper.js +1 -1
  26. package/dist/types/create-editor/filter-plugins-for-reconfigure.d.ts +19 -0
  27. package/dist/types/ui/PluginSlot/mount-plugin-hooks.d.ts +2 -2
  28. package/dist/types-ts4.5/create-editor/filter-plugins-for-reconfigure.d.ts +19 -0
  29. package/dist/types-ts4.5/ui/PluginSlot/mount-plugin-hooks.d.ts +2 -2
  30. package/package.json +9 -6
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @atlaskit/editor-core
2
2
 
3
+ ## 219.6.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`48be4becb4ca3`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/48be4becb4ca3) -
8
+ Migrate indentationStyles, overflowShadowStyles, unsupportedStyles, shadowStyles, and
9
+ editorUGCTokenStyles to Compiled CSS
10
+ - [`2a6fb91f8b4a1`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2a6fb91f8b4a1) -
11
+ migrate expand styles from emotion to compiled css
12
+ - Updated dependencies
13
+
14
+ ## 219.6.0
15
+
16
+ ### Minor Changes
17
+
18
+ - [`80e6f41ddfce4`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/80e6f41ddfce4) -
19
+ Reconcile editor plugin set on reconfigureState across preset switches: drop plugins whose schema
20
+ nodes/marks aren't in the current schema, and evict plugins from the injection API that aren't
21
+ part of the new preset. Behind feature gate `platform_editor_reconfigure_filter_plugins`.
22
+
23
+ Adds the `NamedReactHookFactory` type to `@atlaskit/editor-common/types` and annotates each
24
+ plugin's `usePluginHook` with its plugin name in `processPluginsList` so `MountPluginHooks` can
25
+ key React fibers stably per plugin. The shape of `EditorConfig.pluginHooks` is unchanged
26
+ (`ReactHookFactory[]`); the annotation is a non-breaking additive property on the function value
27
+ that falls back to the array index when absent.
28
+
29
+ ### Patch Changes
30
+
31
+ - Updated dependencies
32
+
3
33
  ## 219.5.1
4
34
 
5
35
  ### Patch Changes
@@ -49,6 +49,7 @@ var _consts = require("./consts");
49
49
  var _createEditor = require("./create-editor");
50
50
  var _createPluginsList = _interopRequireDefault(require("./create-plugins-list"));
51
51
  var _createSchema = require("./create-schema");
52
+ var _filterPluginsForReconfigure = require("./filter-plugins-for-reconfigure");
52
53
  var _messages = require("./messages");
53
54
  var _focusEditorElement = require("./ReactEditorView/focusEditorElement");
54
55
  var _getUAPrefix = require("./ReactEditorView/getUAPrefix");
@@ -362,6 +363,10 @@ function ReactEditorView(props) {
362
363
  var _useState = (0, _react.useState)(0),
363
364
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
364
365
  bumpConfigVersion = _useState2[1];
366
+
367
+ // Preset reference last processed by the schema/API reconciliation below.
368
+ // Used to skip that work when reconfigure is called with the same preset.
369
+ var lastFilteredPresetRef = (0, _react.useRef)(null);
365
370
  var reconfigureState = (0, _react.useCallback)(function (props) {
366
371
  if (!viewRef.current) {
367
372
  return;
@@ -371,7 +376,47 @@ function ReactEditorView(props) {
371
376
  // so we blur here to stop ProseMirror from trying to apply selection to detached nodes or
372
377
  // nodes that haven't been re-rendered to the document yet.
373
378
  blur();
379
+
380
+ // Snapshot plugin names registered before createPluginsList runs, so
381
+ // we can tell which plugins are newly added by the new preset vs.
382
+ // which ones already coexisted with the current schema.
383
+ var previousPluginNames = new Set(pluginInjectionAPI.current.getRegisteredPluginNames());
374
384
  var editorPlugins = (0, _createPluginsList.default)(props.preset, 'allowBlockType' in props.editorProps ? props.editorProps : {}, pluginInjectionAPI.current);
385
+
386
+ // `state.reconfigure` keeps the original schema, so switching presets
387
+ // can leave the editor inconsistent in two ways:
388
+ // 1. The new preset may add plugins that reference schema nodes or
389
+ // marks the original schema doesn't have.
390
+ // 2. Plugins registered by a previous preset can linger in the
391
+ // injection API even when the new preset doesn't re-register
392
+ // them, so listeners still fire against a state that no longer
393
+ // has their pmPlugin.
394
+ if (lastFilteredPresetRef.current !== props.preset && (0, _platformFeatureFlags.fg)('platform_editor_reconfigure_filter_plugins')) {
395
+ var _filterPluginsForReco = (0, _filterPluginsForReconfigure.filterPluginsForReconfigure)(editorPlugins, viewRef.current.state.schema, previousPluginNames),
396
+ kept = _filterPluginsForReco.kept,
397
+ dropped = _filterPluginsForReco.dropped;
398
+ editorPlugins = kept;
399
+
400
+ // Reconcile the injection API with the post-filter plugin set.
401
+ // This evicts both the plugins we just dropped above (re-registered
402
+ // by createPluginsList but no longer in editorPlugins) AND any
403
+ // plugin from a previous preset that the new preset doesn't
404
+ // re-register.
405
+ var keptPluginNames = new Set(editorPlugins.map(function (p) {
406
+ return p === null || p === void 0 ? void 0 : p.name;
407
+ }).filter(function (n) {
408
+ return Boolean(n);
409
+ }));
410
+ var evictedFromApi = pluginInjectionAPI.current.retainPlugins(keptPluginNames);
411
+ if (dropped.length > 0 || evictedFromApi.length > 0) {
412
+ // eslint-disable-next-line no-console
413
+ console.warn('[reconfigureState] Cleanup summary:', {
414
+ dropped: dropped,
415
+ evictedFromApi: evictedFromApi
416
+ });
417
+ }
418
+ lastFilteredPresetRef.current = props.preset;
419
+ }
375
420
  config.current = (0, _createEditor.processPluginsList)(editorPlugins);
376
421
  if ((0, _expValEquals.expValEquals)('platform_editor_appearance_shared_state', 'isEnabled', true)) {
377
422
  var _config$current$pmPlu2;
@@ -72,7 +72,12 @@ function processPluginsList(plugins) {
72
72
  acc.contentComponents.push(plugin.contentComponent);
73
73
  }
74
74
  if (plugin.usePluginHook) {
75
- acc.pluginHooks.push(plugin.usePluginHook);
75
+ // Wrap with .bind(null) so we can annotate the function with the
76
+ // plugin name without mutating the plugin's original hook reference.
77
+ // MountPluginHooks reads `pluginName` to derive a stable React key.
78
+ var named = plugin.usePluginHook.bind(null);
79
+ named.pluginName = plugin.name;
80
+ acc.pluginHooks.push(named);
76
81
  }
77
82
  if (plugin.primaryToolbarComponent) {
78
83
  acc.primaryToolbarComponents.push(plugin.primaryToolbarComponent);
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.filterPluginsForReconfigure = filterPluginsForReconfigure;
7
+ /**
8
+ * Used by `reconfigureState` to drop plugins from a freshly-built preset that
9
+ * declare schema nodes/marks the current schema doesn't have. Plugins already
10
+ * present before this reconfigure are kept untouched: they have demonstrably
11
+ * coexisted with the schema (e.g. tests that mock a stripped-down schema), so
12
+ * removing them now would be a regression.
13
+ */
14
+ function filterPluginsForReconfigure(editorPlugins, schema, previousPluginNames) {
15
+ var availableNodeNames = new Set(Object.keys(schema.nodes));
16
+ var availableMarkNames = new Set(Object.keys(schema.marks));
17
+ var dropped = [];
18
+ var kept = editorPlugins.filter(function (plugin) {
19
+ if (!plugin) {
20
+ return false;
21
+ }
22
+ if (previousPluginNames.has(plugin.name)) {
23
+ return true;
24
+ }
25
+ var missingNodes = plugin.nodes ? plugin.nodes().map(function (n) {
26
+ return n.name;
27
+ }).filter(function (n) {
28
+ return !availableNodeNames.has(n);
29
+ }) : [];
30
+ var missingMarks = plugin.marks ? plugin.marks().map(function (m) {
31
+ return m.name;
32
+ }).filter(function (m) {
33
+ return !availableMarkNames.has(m);
34
+ }) : [];
35
+ if (missingNodes.length > 0 || missingMarks.length > 0) {
36
+ dropped.push({
37
+ name: plugin.name,
38
+ missingNodes: missingNodes,
39
+ missingMarks: missingMarks
40
+ });
41
+ return false;
42
+ }
43
+ return true;
44
+ });
45
+ return {
46
+ kept: kept,
47
+ dropped: dropped
48
+ };
49
+ }
@@ -56,7 +56,9 @@ function lightProcessPluginsList(editorPlugins) {
56
56
  acc.contentComponents.push(editorPlugin.contentComponent);
57
57
  }
58
58
  if (editorPlugin.usePluginHook) {
59
- acc.pluginHooks.push(editorPlugin.usePluginHook);
59
+ var named = editorPlugin.usePluginHook.bind(null);
60
+ named.pluginName = editorPlugin.name;
61
+ acc.pluginHooks.push(named);
60
62
  }
61
63
  if (editorPlugin.onEditorViewStateUpdated) {
62
64
  acc.onEditorViewStateUpdatedCallbacks.push(editorPlugin.onEditorViewStateUpdated);