@atlaskit/editor-plugin-media 1.27.1 → 1.27.2

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 (52) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/cjs/nodeviews/lazy-media-group.js +36 -0
  3. package/dist/cjs/nodeviews/lazy-media-inline.js +34 -0
  4. package/dist/cjs/nodeviews/lazy-media-single.js +35 -0
  5. package/dist/cjs/nodeviews/lazy-media.js +36 -0
  6. package/dist/cjs/plugin.js +17 -15
  7. package/dist/cjs/toDOM-fixes/media.js +25 -0
  8. package/dist/cjs/toDOM-fixes/mediaGroup.js +94 -0
  9. package/dist/cjs/toDOM-fixes/mediaInline.js +48 -0
  10. package/dist/cjs/toDOM-fixes/mediaSingle.js +160 -0
  11. package/dist/cjs/toDOM-fixes/toDOMAttrs.js +80 -0
  12. package/dist/es2019/nodeviews/lazy-media-group.js +23 -0
  13. package/dist/es2019/nodeviews/lazy-media-inline.js +23 -0
  14. package/dist/es2019/nodeviews/lazy-media-single.js +23 -0
  15. package/dist/es2019/nodeviews/lazy-media.js +23 -0
  16. package/dist/es2019/plugin.js +20 -19
  17. package/dist/es2019/toDOM-fixes/media.js +17 -0
  18. package/dist/es2019/toDOM-fixes/mediaGroup.js +85 -0
  19. package/dist/es2019/toDOM-fixes/mediaInline.js +41 -0
  20. package/dist/es2019/toDOM-fixes/mediaSingle.js +152 -0
  21. package/dist/es2019/toDOM-fixes/toDOMAttrs.js +69 -0
  22. package/dist/esm/nodeviews/lazy-media-group.js +24 -0
  23. package/dist/esm/nodeviews/lazy-media-inline.js +22 -0
  24. package/dist/esm/nodeviews/lazy-media-single.js +23 -0
  25. package/dist/esm/nodeviews/lazy-media.js +24 -0
  26. package/dist/esm/plugin.js +20 -19
  27. package/dist/esm/toDOM-fixes/media.js +19 -0
  28. package/dist/esm/toDOM-fixes/mediaGroup.js +87 -0
  29. package/dist/esm/toDOM-fixes/mediaInline.js +41 -0
  30. package/dist/esm/toDOM-fixes/mediaSingle.js +152 -0
  31. package/dist/esm/toDOM-fixes/toDOMAttrs.js +74 -0
  32. package/dist/types/media-plugin-options.d.ts +3 -4
  33. package/dist/types/nodeviews/lazy-media-group.d.ts +7 -0
  34. package/dist/types/nodeviews/lazy-media-inline.d.ts +7 -0
  35. package/dist/types/nodeviews/lazy-media-single.d.ts +9 -0
  36. package/dist/types/nodeviews/lazy-media.d.ts +8 -0
  37. package/dist/types/toDOM-fixes/media.d.ts +1 -0
  38. package/dist/types/toDOM-fixes/mediaGroup.d.ts +36 -0
  39. package/dist/types/toDOM-fixes/mediaInline.d.ts +1 -0
  40. package/dist/types/toDOM-fixes/mediaSingle.d.ts +29 -0
  41. package/dist/types/toDOM-fixes/toDOMAttrs.d.ts +35 -0
  42. package/dist/types-ts4.5/media-plugin-options.d.ts +3 -4
  43. package/dist/types-ts4.5/nodeviews/lazy-media-group.d.ts +7 -0
  44. package/dist/types-ts4.5/nodeviews/lazy-media-inline.d.ts +7 -0
  45. package/dist/types-ts4.5/nodeviews/lazy-media-single.d.ts +9 -0
  46. package/dist/types-ts4.5/nodeviews/lazy-media.d.ts +8 -0
  47. package/dist/types-ts4.5/toDOM-fixes/media.d.ts +1 -0
  48. package/dist/types-ts4.5/toDOM-fixes/mediaGroup.d.ts +36 -0
  49. package/dist/types-ts4.5/toDOM-fixes/mediaInline.d.ts +1 -0
  50. package/dist/types-ts4.5/toDOM-fixes/mediaSingle.d.ts +29 -0
  51. package/dist/types-ts4.5/toDOM-fixes/toDOMAttrs.d.ts +35 -0
  52. package/package.json +5 -2
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getMediaAttrs = exports.getAttrsFromNodeMediaSingle = exports.camelCaseToKebabCase = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _colors = require("@atlaskit/theme/colors");
10
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
11
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
12
+ /**
13
+ * Copied from `packages/adf-schema/src/schema/nodes/media.ts`
14
+ *
15
+ * When we patch adf-schema with media `toDOM` fixes we can remove this.
16
+ */
17
+ var getMediaAttrs = exports.getMediaAttrs = function getMediaAttrs(nodeName, node) {
18
+ var copyPrivateAttributes = function copyPrivateAttributes(from, to, map) {
19
+ if (node.attrs) {
20
+ Object.keys(node.attrs).forEach(function (key) {
21
+ if (key[0] === '_' && key[1] === '_' && from[key]) {
22
+ to[map ? map(key) : key] = from[key];
23
+ }
24
+ });
25
+ }
26
+ };
27
+ var attrs = {
28
+ 'data-id': node.attrs.id,
29
+ 'data-node-type': "".concat(nodeName),
30
+ 'data-type': node.attrs.type,
31
+ 'data-collection': node.attrs.collection,
32
+ 'data-occurrence-key': node.attrs.occurrenceKey,
33
+ 'data-width': node.attrs.width,
34
+ 'data-height': node.attrs.height,
35
+ 'data-url': node.attrs.url,
36
+ 'data-alt': node.attrs.alt,
37
+ // toDOM is used for static rendering as well as editor rendering. This comes into play for
38
+ // emails, copy/paste, etc, so the title and styling here *is* useful (despite a React-based
39
+ // node view being used for editing).
40
+ title: 'Attachment',
41
+ // Manually kept in sync with the style of media cards. The goal is to render a plain gray
42
+ // rectangle that provides an affordance for media.
43
+ style: "display: inline-block; border-radius: 3px; background: ".concat(_colors.N30, "; box-shadow: 0 1px 1px rgba(9, 30, 66, 0.2), 0 0 1px 0 rgba(9, 30, 66, 0.24);")
44
+ };
45
+ copyPrivateAttributes(node.attrs, attrs, function (key) {
46
+ return "data-".concat(camelCaseToKebabCase(key.slice(2)));
47
+ });
48
+ return attrs;
49
+ };
50
+ var camelCaseToKebabCase = exports.camelCaseToKebabCase = function camelCaseToKebabCase(str) {
51
+ return str.replace(/([^A-Z]+)([A-Z])/g, function (_, x, y) {
52
+ return "".concat(x, "-").concat(y.toLowerCase());
53
+ });
54
+ };
55
+
56
+ /**
57
+ * Copied from `packages/adf-schema/src/schema/nodes/media-single.ts`
58
+ *
59
+ * When we patch adf-schema with media `toDOM` fixes we can remove this.
60
+ */
61
+ var getAttrsFromNodeMediaSingle = exports.getAttrsFromNodeMediaSingle = function getAttrsFromNodeMediaSingle(withExtendedWidthTypes, node) {
62
+ var _node$attrs = node.attrs,
63
+ layout = _node$attrs.layout,
64
+ width = _node$attrs.width;
65
+ var attrs = {
66
+ 'data-node-type': 'mediaSingle',
67
+ 'data-layout': layout,
68
+ 'data-width': ''
69
+ };
70
+ if (width) {
71
+ attrs['data-width'] = isFinite(width) && Math.floor(width) === width ? width : width.toFixed(2);
72
+ }
73
+ if (withExtendedWidthTypes && node.attrs.widthType) {
74
+ var widthType = node.attrs.widthType;
75
+ return _objectSpread(_objectSpread({}, attrs), {}, {
76
+ 'data-width-type': widthType || 'percentage'
77
+ });
78
+ }
79
+ return attrs;
80
+ };
@@ -0,0 +1,23 @@
1
+ import { withLazyLoading } from '@atlaskit/editor-common/lazy-node-view';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
3
+ import { ReactMediaGroupNode } from './mediaGroup';
4
+ export const lazyMediaGroupView = (portalProviderAPI, eventDispatcher, providerFactory, options = {}, api) => {
5
+ if (!fg('platform_editor_lazy-node-views')) {
6
+ return ReactMediaGroupNode(portalProviderAPI, eventDispatcher, providerFactory, options, api);
7
+ }
8
+ return withLazyLoading({
9
+ nodeName: 'mediaGroup',
10
+ getNodeViewOptions: () => {},
11
+ loader: () => {
12
+ const result = import( /* webpackChunkName: "@atlaskit-internal_editor-plugin-media-group-lazy-node-view" */
13
+ './mediaGroup').then(({
14
+ ReactMediaGroupNode
15
+ }) => {
16
+ return (node, view, getPos) => {
17
+ return ReactMediaGroupNode(portalProviderAPI, eventDispatcher, providerFactory, options, api)(node, view, getPos);
18
+ };
19
+ });
20
+ return result;
21
+ }
22
+ });
23
+ };
@@ -0,0 +1,23 @@
1
+ import { withLazyLoading } from '@atlaskit/editor-common/lazy-node-view';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
3
+ import { ReactMediaInlineNode } from './mediaInline';
4
+ export const lazyMediaInlineView = (portalProviderAPI, eventDispatcher, providerFactory, api, dispatchAnalyticsEvent) => {
5
+ if (!fg('platform_editor_lazy-node-views')) {
6
+ return ReactMediaInlineNode(portalProviderAPI, eventDispatcher, providerFactory, api, dispatchAnalyticsEvent);
7
+ }
8
+ return withLazyLoading({
9
+ nodeName: 'mediaInline',
10
+ getNodeViewOptions: () => {},
11
+ loader: () => {
12
+ const result = import( /* webpackChunkName: "@atlaskit-internal_editor-plugin-media-inline-lazy-node-view" */
13
+ './mediaInline').then(({
14
+ ReactMediaInlineNode
15
+ }) => {
16
+ return (node, view, getPos) => {
17
+ return ReactMediaInlineNode(portalProviderAPI, eventDispatcher, providerFactory, api, dispatchAnalyticsEvent)(node, view, getPos);
18
+ };
19
+ });
20
+ return result;
21
+ }
22
+ });
23
+ };
@@ -0,0 +1,23 @@
1
+ import { withLazyLoading } from '@atlaskit/editor-common/lazy-node-view';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
3
+ import { ReactMediaSingleNode } from './mediaSingle';
4
+ export const lazyMediaSingleView = (portalProviderAPI, eventDispatcher, providerFactory, api, dispatchAnalyticsEvent, options = {}) => {
5
+ if (!fg('platform_editor_lazy-node-views')) {
6
+ return ReactMediaSingleNode(portalProviderAPI, eventDispatcher, providerFactory, api, dispatchAnalyticsEvent, options);
7
+ }
8
+ return withLazyLoading({
9
+ nodeName: 'mediaSingle',
10
+ getNodeViewOptions: () => {},
11
+ loader: () => {
12
+ const result = import( /* webpackChunkName: "@atlaskit-internal_editor-plugin-media-single-lazy-node-view" */
13
+ './mediaSingle').then(({
14
+ ReactMediaSingleNode
15
+ }) => {
16
+ return (node, view, getPos) => {
17
+ return ReactMediaSingleNode(portalProviderAPI, eventDispatcher, providerFactory, api, dispatchAnalyticsEvent, options)(node, view, getPos);
18
+ };
19
+ });
20
+ return result;
21
+ }
22
+ });
23
+ };
@@ -0,0 +1,23 @@
1
+ import { withLazyLoading } from '@atlaskit/editor-common/lazy-node-view';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
3
+ import { ReactMediaNode } from './mediaNodeView';
4
+ export const lazyMediaView = (portalProviderAPI, eventDispatcher, providerFactory, options = {}, api) => {
5
+ if (!fg('platform_editor_lazy-node-views')) {
6
+ return ReactMediaNode(portalProviderAPI, eventDispatcher, providerFactory, options, api);
7
+ }
8
+ return withLazyLoading({
9
+ nodeName: 'media',
10
+ getNodeViewOptions: () => {},
11
+ loader: () => {
12
+ const result = import( /* webpackChunkName: "@atlaskit-internal_editor-plugin-media-lazy-node-view" */
13
+ './mediaNodeView').then(({
14
+ ReactMediaNode
15
+ }) => {
16
+ return (node, view, getPos) => {
17
+ return ReactMediaNode(portalProviderAPI, eventDispatcher, providerFactory, options, api)(node, view, getPos);
18
+ };
19
+ });
20
+ return result;
21
+ }
22
+ });
23
+ };
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import { media, mediaGroup, mediaInline, mediaSingleSpec } from '@atlaskit/adf-schema';
3
2
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
4
3
  import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
5
4
  import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
@@ -7,19 +6,22 @@ import { IconImages } from '@atlaskit/editor-common/quick-insert';
7
6
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
8
7
  import { NodeSelection, PluginKey } from '@atlaskit/editor-prosemirror/state';
9
8
  import { getMediaFeatureFlag } from '@atlaskit/media-common';
10
- import { getBooleanFF } from '@atlaskit/platform-feature-flags';
11
- import { ReactMediaGroupNode } from './nodeviews/mediaGroup';
12
- import { ReactMediaInlineNode } from './nodeviews/mediaInline';
13
- import { ReactMediaNode } from './nodeviews/mediaNodeView';
14
- import { ReactMediaSingleNode } from './nodeviews/mediaSingle';
9
+ import { fg } from '@atlaskit/platform-feature-flags';
10
+ import { lazyMediaView } from './nodeviews/lazy-media';
11
+ import { lazyMediaGroupView } from './nodeviews/lazy-media-group';
12
+ import { lazyMediaInlineView } from './nodeviews/lazy-media-inline';
13
+ import { lazyMediaSingleView } from './nodeviews/lazy-media-single';
15
14
  import { createPlugin as createMediaAltTextPlugin } from './pm-plugins/alt-text';
16
15
  import keymapMediaAltTextPlugin from './pm-plugins/alt-text/keymap';
17
16
  import keymapPlugin from './pm-plugins/keymap';
18
17
  import keymapMediaSinglePlugin from './pm-plugins/keymap-media-single';
19
18
  import linkingPlugin from './pm-plugins/linking';
20
19
  import keymapLinkingPlugin from './pm-plugins/linking/keymap';
21
- import { stateKey } from './pm-plugins/main';
22
- import { createPlugin, stateKey as pluginKey } from './pm-plugins/main';
20
+ import { createPlugin, stateKey } from './pm-plugins/main';
21
+ import { mediaSpecWithFixedToDOM } from './toDOM-fixes/media';
22
+ import { mediaGroupSpecWithFixedToDOM } from './toDOM-fixes/mediaGroup';
23
+ import { mediaInlineSpecWithFixedToDOM } from './toDOM-fixes/mediaInline';
24
+ import { mediaSingleSpecWithFixedToDOM } from './toDOM-fixes/mediaSingle';
23
25
  import { floatingToolbar } from './toolbar';
24
26
  import { MediaPickerComponents } from './ui/MediaPicker';
25
27
  import ToolbarMedia from './ui/ToolbarMedia';
@@ -77,26 +79,25 @@ export const mediaPlugin = ({
77
79
  featureFlags: mediaFeatureFlags
78
80
  } = options || {};
79
81
  const allowMediaInline = getMediaFeatureFlag('mediaInline', mediaFeatureFlags);
80
- const mediaSingleOption = getBooleanFF('platform.editor.media.extended-resize-experience') ? {
82
+ const mediaSingleOption = fg('platform.editor.media.extended-resize-experience') ? {
81
83
  withCaption: allowCaptions,
82
84
  withExtendedWidthTypes: true
83
85
  } : {
84
86
  withCaption: allowCaptions,
85
87
  withExtendedWidthTypes: false
86
88
  };
87
- const mediaSingleNode = mediaSingleSpec(mediaSingleOption);
88
89
  return [{
89
90
  name: 'mediaGroup',
90
- node: mediaGroup
91
+ node: mediaGroupSpecWithFixedToDOM()
91
92
  }, {
92
93
  name: 'mediaSingle',
93
- node: mediaSingleNode
94
+ node: mediaSingleSpecWithFixedToDOM(mediaSingleOption)
94
95
  }, {
95
96
  name: 'media',
96
- node: media
97
+ node: mediaSpecWithFixedToDOM()
97
98
  }, {
98
99
  name: 'mediaInline',
99
- node: mediaInline
100
+ node: mediaInlineSpecWithFixedToDOM()
100
101
  }].filter(node => {
101
102
  if (node.name === 'mediaGroup') {
102
103
  return allowMediaGroup;
@@ -127,10 +128,10 @@ export const mediaPlugin = ({
127
128
  return createPlugin(schema, {
128
129
  providerFactory,
129
130
  nodeViews: {
130
- mediaGroup: ReactMediaGroupNode(portalProviderAPI, eventDispatcher, providerFactory, options, api),
131
- mediaSingle: ReactMediaSingleNode(portalProviderAPI, eventDispatcher, providerFactory, api, dispatchAnalyticsEvent, options),
132
- media: ReactMediaNode(portalProviderAPI, eventDispatcher, providerFactory, options, api),
133
- mediaInline: ReactMediaInlineNode(portalProviderAPI, eventDispatcher, providerFactory, api)
131
+ mediaGroup: lazyMediaGroupView(portalProviderAPI, eventDispatcher, providerFactory, options, api),
132
+ mediaSingle: lazyMediaSingleView(portalProviderAPI, eventDispatcher, providerFactory, api, dispatchAnalyticsEvent, options),
133
+ media: lazyMediaView(portalProviderAPI, eventDispatcher, providerFactory, options, api),
134
+ mediaInline: lazyMediaInlineView(portalProviderAPI, eventDispatcher, providerFactory, api)
134
135
  },
135
136
  errorReporter,
136
137
  uploadErrorHandler: options && options.uploadErrorHandler,
@@ -255,7 +256,7 @@ export const mediaPlugin = ({
255
256
  icon: () => /*#__PURE__*/React.createElement(IconImages, null),
256
257
  action(insert, state) {
257
258
  var _api$analytics4;
258
- const pluginState = pluginKey.getState(state);
259
+ const pluginState = stateKey.getState(state);
259
260
  pluginState === null || pluginState === void 0 ? void 0 : pluginState.showMediaPicker();
260
261
  const tr = insert('');
261
262
  api === null || api === void 0 ? void 0 : (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions.attachAnalyticsEvent({
@@ -0,0 +1,17 @@
1
+ import { media } from '@atlaskit/adf-schema';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
3
+ import { getMediaAttrs } from './toDOMAttrs';
4
+
5
+ // @nodeSpecException:toDOM patch
6
+ export const mediaSpecWithFixedToDOM = () => {
7
+ if (!fg('platform_editor_lazy-node-views')) {
8
+ return media;
9
+ }
10
+ return {
11
+ ...media,
12
+ toDOM: node => {
13
+ const attrs = getMediaAttrs('media', node);
14
+ return ['div', attrs];
15
+ }
16
+ };
17
+ };
@@ -0,0 +1,85 @@
1
+ import { mediaGroup } from '@atlaskit/adf-schema';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
3
+ const skeletonStyling = `background: ${"var(--ds-background-neutral, #091E420F)"};`;
4
+
5
+ /**
6
+ * Duplicate consts from `media-card`.
7
+ * `packages/media/media-card/src/utils/cardDimensions.ts`
8
+ *
9
+ * WHY?
10
+ * This will eventually move to `@atlaskit/adf-schema` and we cannot reference
11
+ * `media-card` from here or it will cause dependency issues.
12
+ *
13
+ * In the long term likely `toDOM` will move back out of `adf-schema` in which
14
+ * case we can consolidate them.
15
+ */
16
+ export const defaultImageCardDimensions = {
17
+ width: 156,
18
+ height: 125
19
+ };
20
+ export const defaultHorizontalCardDimensions = {
21
+ width: 435,
22
+ height: 125
23
+ };
24
+ export const defaultSquareCardDimensions = {
25
+ width: 300,
26
+ height: 300
27
+ };
28
+
29
+ /**
30
+ * Duplicate logic from `@atlaskit/media-card` for computing the dimensions of a media group card.
31
+ * From: `packages/media/media-card/src/utils/cardDimensions.ts`
32
+ *
33
+ * WHY?
34
+ * This will eventually move to `@atlaskit/adf-schema` and we cannot reference
35
+ * `@atlaskit/media-card` from here or it will cause dependency issues.
36
+ *
37
+ * In the long term likely `toDOM` will move back out of `adf-schema` in which
38
+ * case we can consolidate them.
39
+ */
40
+ export const getDefaultCardDimensions = (appearance = 'auto') => {
41
+ if (appearance === 'image') {
42
+ return defaultImageCardDimensions;
43
+ }
44
+ if (appearance === 'square') {
45
+ return defaultSquareCardDimensions;
46
+ }
47
+ if (appearance === 'horizontal') {
48
+ return defaultHorizontalCardDimensions;
49
+ }
50
+ return defaultImageCardDimensions;
51
+ };
52
+
53
+ // @nodeSpecException:toDOM patch
54
+ export const mediaGroupSpecWithFixedToDOM = () => {
55
+ if (!fg('platform_editor_lazy-node-views')) {
56
+ return mediaGroup;
57
+ }
58
+ return {
59
+ ...mediaGroup,
60
+ toDOM: node => {
61
+ const childNodes = [];
62
+ for (let i = 0; i < node.childCount; i++) {
63
+ const {
64
+ width,
65
+ height
66
+ } = getDefaultCardDimensions();
67
+ const nodeHolder = ['img', {
68
+ width,
69
+ height,
70
+ // Transparent image workaround to control styling
71
+ src: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
72
+ style: `margin-left: ${i !== 0 ? `4px` : '0'}; margin-right: 4px; border-radius: ${"var(--ds-border-radius, 3px)"}; ${skeletonStyling}`
73
+ }];
74
+ childNodes.push(nodeHolder);
75
+ }
76
+
77
+ // Margin margin that consolidates the margin in the
78
+ return ['div', {
79
+ style: 'margin: "3px 5px";',
80
+ // From adf-schema
81
+ 'data-node-type': 'mediaGroup'
82
+ }, ...childNodes];
83
+ }
84
+ };
85
+ };
@@ -0,0 +1,41 @@
1
+ import { mediaInline } from '@atlaskit/adf-schema';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
3
+ import { getMediaAttrs } from './toDOMAttrs';
4
+ const skeletonStyling = `background: ${"var(--ds-background-neutral, #091E420F)"};`;
5
+ // Matches media
6
+ const fallbackAspectRatio = 1.25;
7
+
8
+ // @nodeSpecException:toDOM patch
9
+ export const mediaInlineSpecWithFixedToDOM = () => {
10
+ if (!fg('platform_editor_lazy-node-views')) {
11
+ return mediaInline;
12
+ }
13
+ return {
14
+ ...mediaInline,
15
+ toDOM: node => {
16
+ const dataAttrs = getMediaAttrs('mediaInline', node);
17
+ if (node.attrs.type === 'image') {
18
+ const aspectRatio = node.attrs.width && node.attrs.height ? node.attrs.width / node.attrs.height : fallbackAspectRatio;
19
+ return ['span', {
20
+ ...dataAttrs,
21
+ style: 'display: inline-block; transform: translateY(6px)',
22
+ class: 'media-inline-image-wrapper'
23
+ }, ['span', {
24
+ height: '100%',
25
+ width: '100%',
26
+ // Transparent image workaround to control styling
27
+ src: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
28
+ style: `display: inline-block; aspect-ratio: ${aspectRatio}; height: 100%; width: 100%; border-radius: ${"var(--ds-border-radius, 3px)"}; ${skeletonStyling}`
29
+ }]];
30
+ } else {
31
+ return ['span', {
32
+ ...dataAttrs,
33
+ style: `display: inline-block; transform: translateY(6px); ${skeletonStyling}`,
34
+ class: 'media-inline-image-wrapper'
35
+ }, ['span', {
36
+ style: `display: inline-block; height: 100%; width: 100%; aspect-ratio: ${fallbackAspectRatio};`
37
+ }]];
38
+ }
39
+ }
40
+ };
41
+ };
@@ -0,0 +1,152 @@
1
+ import { mediaSingleSpec } from '@atlaskit/adf-schema';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
3
+ import { getAttrsFromNodeMediaSingle, getMediaAttrs } from './toDOMAttrs';
4
+ const skeletonStyling = `background: ${"var(--ds-background-neutral, #091E420F)"}; outline: none;`;
5
+ export const wrappedLayouts = ['wrap-left', 'wrap-right', 'align-end', 'align-start'];
6
+
7
+ /**
8
+ * Duplicate of method from `@atlaskit/editor-common/utils`.
9
+ * `packages/editor/editor-common/src/utils/rich-media-utils.ts`
10
+ *
11
+ * WHY?
12
+ * This will eventually move to `@atlaskit/adf-schema` and we cannot reference
13
+ * `@atlaskit/editor-common` from here or it will cause dependency issues.
14
+ *
15
+ * In the long term likely `toDOM` will move back out of `adf-schema` in which
16
+ * case we can consolidate them.
17
+ */
18
+ export const shouldAddDefaultWrappedWidth = (layout, width, lineLength) => {
19
+ return wrappedLayouts.indexOf(layout) > -1 && lineLength && width && width > 0.5 * lineLength;
20
+ };
21
+ const MEDIA_SINGLE_GUTTER_SIZE = 24;
22
+ const DEFAULT_EMBED_CARD_WIDTH = 680;
23
+ const akEditorMediaResizeHandlerPaddingWide = 12;
24
+
25
+ /**
26
+ * Duplicate of method from `@atlaskit/editor-common/media-single`.
27
+ * `packages/editor/editor-common/src/media-single/utils.ts`
28
+ *
29
+ * WHY?
30
+ * This will eventually move to `@atlaskit/adf-schema` and we cannot reference
31
+ * `@atlaskit/editor-common` from here or it will cause dependency issues.
32
+ *
33
+ * In the long term likely `toDOM` will move back out of `adf-schema` in which
34
+ * case we can consolidate them.
35
+ */
36
+ export function getMediaSinglePixelWidth(width, editorWidth, widthType = 'percentage', gutterOffset = 0) {
37
+ if (widthType === 'pixel') {
38
+ return width;
39
+ }
40
+ return Math.ceil((editorWidth + gutterOffset) * (width / 100) - gutterOffset);
41
+ }
42
+
43
+ /**
44
+ * Duplicate logic from `@atlaskit/editor-common/ui` for MediaSingle.
45
+ * `packages/editor/editor-common/src/ui/MediaSingle/index.tsx`
46
+ *
47
+ * WHY?
48
+ * This will eventually move to `@atlaskit/adf-schema` and we cannot reference
49
+ * `@atlaskit/editor-common` from here or it will cause dependency issues.
50
+ *
51
+ * In the long term likely `toDOM` will move back out of `adf-schema` in which
52
+ * case we can consolidate them.
53
+ */
54
+ function computeMediaSingleDimensions({
55
+ childNode,
56
+ mediaSingleWidth,
57
+ widthType
58
+ }) {
59
+ // TODO: We can't retrieve the editor width from here easily.
60
+ // For now we're using the default line length here, but this will be
61
+ // incorrect on smaller devices.
62
+ const editorWidth = 760;
63
+ const width = childNode === null || childNode === void 0 ? void 0 : childNode.attrs.width;
64
+ const height = childNode === null || childNode === void 0 ? void 0 : childNode.attrs.height;
65
+ if (!mediaSingleWidth && shouldAddDefaultWrappedWidth(childNode === null || childNode === void 0 ? void 0 : childNode.attrs.layout, width, editorWidth)) {
66
+ mediaSingleWidth = widthType === 'pixel' ? editorWidth / 2 : 50;
67
+ }
68
+ const isHeightOnly = width === undefined;
69
+ if (mediaSingleWidth) {
70
+ const pxWidth = getMediaSinglePixelWidth(mediaSingleWidth, editorWidth, widthType, MEDIA_SINGLE_GUTTER_SIZE);
71
+ if (isHeightOnly) {
72
+ return {
73
+ width: pxWidth - akEditorMediaResizeHandlerPaddingWide,
74
+ height
75
+ };
76
+ } else {
77
+ return {
78
+ width: pxWidth,
79
+ height: height / width * pxWidth
80
+ };
81
+ }
82
+ } else if (isHeightOnly) {
83
+ return {
84
+ width: DEFAULT_EMBED_CARD_WIDTH - akEditorMediaResizeHandlerPaddingWide,
85
+ height
86
+ };
87
+ }
88
+ return {
89
+ height,
90
+ width
91
+ };
92
+ }
93
+ function computeLayoutStyles(width, layout) {
94
+ switch (layout) {
95
+ case 'align-end':
96
+ return `margin-left: auto; margin-right: 0; width: ${width}px;`;
97
+ case 'align-start':
98
+ return `margin-left: 0; margin-right: auto; width: ${width}px;`;
99
+ case 'center':
100
+ return 'margin-left: auto; margin-right: auto;';
101
+ case 'full-width':
102
+ case 'wide':
103
+ return 'width: 100%; margin-top: 56px; margin-bottom: 56px;';
104
+ case 'wrap-left':
105
+ return 'float: left;';
106
+ case 'wrap-right':
107
+ return 'float: right;';
108
+ }
109
+ }
110
+
111
+ // @nodeSpecException:toDOM patch
112
+ export const mediaSingleSpecWithFixedToDOM = mediaSingleOption => {
113
+ const mediaSingleNode = mediaSingleSpec(mediaSingleOption);
114
+ if (!fg('platform_editor_lazy-node-views')) {
115
+ return mediaSingleNode;
116
+ }
117
+ return {
118
+ ...mediaSingleNode,
119
+ toDOM: node => {
120
+ var _mediaSingleAttrs$lay, _childNode$type;
121
+ const childNode = node.firstChild;
122
+ const mediaSingleAttrs = node.attrs;
123
+ const layout = (_mediaSingleAttrs$lay = mediaSingleAttrs === null || mediaSingleAttrs === void 0 ? void 0 : mediaSingleAttrs.layout) !== null && _mediaSingleAttrs$lay !== void 0 ? _mediaSingleAttrs$lay : 'center';
124
+ const mediaSingleWidth = mediaSingleAttrs === null || mediaSingleAttrs === void 0 ? void 0 : mediaSingleAttrs.width;
125
+ const widthType = mediaSingleAttrs === null || mediaSingleAttrs === void 0 ? void 0 : mediaSingleAttrs.widthType;
126
+ const dataAttrs = getAttrsFromNodeMediaSingle(mediaSingleOption.withExtendedWidthTypes, node);
127
+ const mediaAttrs = (childNode === null || childNode === void 0 ? void 0 : (_childNode$type = childNode.type) === null || _childNode$type === void 0 ? void 0 : _childNode$type.name) === 'media' ? getMediaAttrs('media', childNode) : undefined;
128
+ const {
129
+ width,
130
+ height
131
+ } = computeMediaSingleDimensions({
132
+ childNode,
133
+ widthType,
134
+ mediaSingleWidth
135
+ });
136
+ const layoutStyles = computeLayoutStyles(width, layout);
137
+ const style = `display: block; margin-top: ${"var(--ds-space-300, 24px)"}; margin-bottom: ${"var(--ds-space-300, 24px)"}; ${layoutStyles}`;
138
+ if ((childNode === null || childNode === void 0 ? void 0 : childNode.attrs.type) === 'external') {
139
+ return ['div', dataAttrs, ['img', {
140
+ ...mediaAttrs,
141
+ src: childNode.attrs.url,
142
+ style
143
+ }]];
144
+ }
145
+ return ['div', dataAttrs, ['div', {
146
+ ...mediaAttrs,
147
+ // Transparent image workaround to control styling
148
+ style: `width: ${width}px; height: ${height}px; ${style} ${skeletonStyling} border-radius: ${"var(--ds-border-radius, 3px)"};`
149
+ }]];
150
+ }
151
+ };
152
+ };
@@ -0,0 +1,69 @@
1
+ import { N30 } from '@atlaskit/theme/colors';
2
+
3
+ /**
4
+ * Copied from `packages/adf-schema/src/schema/nodes/media.ts`
5
+ *
6
+ * When we patch adf-schema with media `toDOM` fixes we can remove this.
7
+ */
8
+ export const getMediaAttrs = (nodeName, node) => {
9
+ const copyPrivateAttributes = (from, to, map) => {
10
+ if (node.attrs) {
11
+ Object.keys(node.attrs).forEach(key => {
12
+ if (key[0] === '_' && key[1] === '_' && from[key]) {
13
+ to[map ? map(key) : key] = from[key];
14
+ }
15
+ });
16
+ }
17
+ };
18
+ const attrs = {
19
+ 'data-id': node.attrs.id,
20
+ 'data-node-type': `${nodeName}`,
21
+ 'data-type': node.attrs.type,
22
+ 'data-collection': node.attrs.collection,
23
+ 'data-occurrence-key': node.attrs.occurrenceKey,
24
+ 'data-width': node.attrs.width,
25
+ 'data-height': node.attrs.height,
26
+ 'data-url': node.attrs.url,
27
+ 'data-alt': node.attrs.alt,
28
+ // toDOM is used for static rendering as well as editor rendering. This comes into play for
29
+ // emails, copy/paste, etc, so the title and styling here *is* useful (despite a React-based
30
+ // node view being used for editing).
31
+ title: 'Attachment',
32
+ // Manually kept in sync with the style of media cards. The goal is to render a plain gray
33
+ // rectangle that provides an affordance for media.
34
+ style: `display: inline-block; border-radius: 3px; background: ${N30}; box-shadow: 0 1px 1px rgba(9, 30, 66, 0.2), 0 0 1px 0 rgba(9, 30, 66, 0.24);`
35
+ };
36
+ copyPrivateAttributes(node.attrs, attrs, key => `data-${camelCaseToKebabCase(key.slice(2))}`);
37
+ return attrs;
38
+ };
39
+ export const camelCaseToKebabCase = str => str.replace(/([^A-Z]+)([A-Z])/g, (_, x, y) => `${x}-${y.toLowerCase()}`);
40
+
41
+ /**
42
+ * Copied from `packages/adf-schema/src/schema/nodes/media-single.ts`
43
+ *
44
+ * When we patch adf-schema with media `toDOM` fixes we can remove this.
45
+ */
46
+ export const getAttrsFromNodeMediaSingle = (withExtendedWidthTypes, node) => {
47
+ const {
48
+ layout,
49
+ width
50
+ } = node.attrs;
51
+ const attrs = {
52
+ 'data-node-type': 'mediaSingle',
53
+ 'data-layout': layout,
54
+ 'data-width': ''
55
+ };
56
+ if (width) {
57
+ attrs['data-width'] = isFinite(width) && Math.floor(width) === width ? width : width.toFixed(2);
58
+ }
59
+ if (withExtendedWidthTypes && node.attrs.widthType) {
60
+ const {
61
+ widthType
62
+ } = node.attrs;
63
+ return {
64
+ ...attrs,
65
+ 'data-width-type': widthType || 'percentage'
66
+ };
67
+ }
68
+ return attrs;
69
+ };
@@ -0,0 +1,24 @@
1
+ import { withLazyLoading } from '@atlaskit/editor-common/lazy-node-view';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
3
+ import { ReactMediaGroupNode } from './mediaGroup';
4
+ export var lazyMediaGroupView = function lazyMediaGroupView(portalProviderAPI, eventDispatcher, providerFactory) {
5
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
6
+ var api = arguments.length > 4 ? arguments[4] : undefined;
7
+ if (!fg('platform_editor_lazy-node-views')) {
8
+ return ReactMediaGroupNode(portalProviderAPI, eventDispatcher, providerFactory, options, api);
9
+ }
10
+ return withLazyLoading({
11
+ nodeName: 'mediaGroup',
12
+ getNodeViewOptions: function getNodeViewOptions() {},
13
+ loader: function loader() {
14
+ var result = import( /* webpackChunkName: "@atlaskit-internal_editor-plugin-media-group-lazy-node-view" */
15
+ './mediaGroup').then(function (_ref) {
16
+ var ReactMediaGroupNode = _ref.ReactMediaGroupNode;
17
+ return function (node, view, getPos) {
18
+ return ReactMediaGroupNode(portalProviderAPI, eventDispatcher, providerFactory, options, api)(node, view, getPos);
19
+ };
20
+ });
21
+ return result;
22
+ }
23
+ });
24
+ };