@atlaskit/editor-core 187.14.4 → 187.14.8

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.
@@ -15,8 +15,9 @@ import { messages } from './resizable-media-single-messages';
15
15
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
16
16
  import classnames from 'classnames';
17
17
  import { richMediaClassName, resizerStyles } from '@atlaskit/editor-common/styles';
18
- import { MEDIA_SINGLE_MIN_PIXEL_WIDTH, MEDIA_SINGLE_SNAP_GAP, MEDIA_SINGLE_HIGHLIGHT_GAP, calculateOffsetLeft, DEFAULT_IMAGE_WIDTH } from '@atlaskit/editor-common/media-single';
19
- import { findClosestSnap, getSnapWidth, getGuidelinesWithHighlights, generateDefaultGuidelines, generateDynamicGuidelines } from '@atlaskit/editor-common/guideline';
18
+ import { MEDIA_SINGLE_MIN_PIXEL_WIDTH, MEDIA_SINGLE_SNAP_GAP, calculateOffsetLeft, DEFAULT_IMAGE_WIDTH, calcMediaSingleMaxWidth } from '@atlaskit/editor-common/media-single';
19
+ import { findClosestSnap, getGuidelinesWithHighlights, generateDefaultGuidelines, generateDynamicGuidelines, getGuidelineSnaps } from '@atlaskit/editor-common/guideline';
20
+ import memoizeOne from 'memoize-one';
20
21
  export const resizerNextTestId = 'mediaSingle.resizerNext.testid';
21
22
 
22
23
  // TODO: Create new fixed image size event
@@ -36,6 +37,23 @@ const getResizeAnalyticsEvent = (type, size, layout) => {
36
37
  class ResizableMediaSingleNext extends React.Component {
37
38
  constructor(props) {
38
39
  super(props);
40
+ _defineProperty(this, "guidelines", []);
41
+ _defineProperty(this, "getAllGuidelines", () => {
42
+ const {
43
+ view,
44
+ lineLength
45
+ } = this.props;
46
+ const defaultGuidelines = this.getDefaultGuidelines();
47
+ // disable guidelines for nested media single node
48
+ const dynamicGuidelines = this.isNestedNode() ? [] : generateDynamicGuidelines(view.state, lineLength, {
49
+ styles: {
50
+ lineStyle: 'dashed'
51
+ },
52
+ show: false
53
+ });
54
+ const guidelines = [...defaultGuidelines, ...dynamicGuidelines];
55
+ return guidelines;
56
+ });
39
57
  _defineProperty(this, "calcNewSize", (newWidth, stop) => {
40
58
  const {
41
59
  layout,
@@ -110,6 +128,106 @@ class ResizableMediaSingleNext extends React.Component {
110
128
  tr.setMeta('mediaSinglePlugin.isResizing', isResizing);
111
129
  return dispatch(tr);
112
130
  });
131
+ _defineProperty(this, "calcMaxWidth", memoizeOne((contentWidth, containerWidth, fullWidthMode) => {
132
+ if (this.isNestedNode() || fullWidthMode) {
133
+ return contentWidth;
134
+ }
135
+ return calcMediaSingleMaxWidth(containerWidth);
136
+ }));
137
+ _defineProperty(this, "updateActiveGuidelines", (width = 0, guidelines, guidelineSnapsReference) => {
138
+ if (guidelineSnapsReference.snaps.x) {
139
+ const {
140
+ gap,
141
+ keys: activeGuidelineKeys
142
+ } = findClosestSnap(width, guidelineSnapsReference.snaps.x, guidelineSnapsReference.guidelineReference, MEDIA_SINGLE_SNAP_GAP);
143
+ this.displayGuideline(getGuidelinesWithHighlights(gap, MEDIA_SINGLE_SNAP_GAP, activeGuidelineKeys, guidelines));
144
+ }
145
+ });
146
+ _defineProperty(this, "roundPixelValue", value => Math.round(value));
147
+ _defineProperty(this, "getHeightFromNewWidth", (originalWidth, originalHeight, newWidth) => this.roundPixelValue(originalHeight / originalWidth * newWidth));
148
+ _defineProperty(this, "calculateSizeState", (size, delta, originalWidth = 0, originalHeight, onResizeStop = false) => {
149
+ const calculatedWidth = this.roundPixelValue(size.width + delta.width);
150
+ const calculatedWidthWithLayout = this.calcNewSize(calculatedWidth, onResizeStop);
151
+ const calculatedHeightWithLayout = this.getHeightFromNewWidth(originalWidth, originalHeight, calculatedWidth);
152
+ return {
153
+ width: calculatedWidth,
154
+ height: calculatedHeightWithLayout,
155
+ calculatedWidthWithLayout
156
+ };
157
+ });
158
+ _defineProperty(this, "selectCurrentMediaNode", () => {
159
+ // TODO: if adding !this.props.selected, it doesn't work if media single node is at top postion
160
+ if (typeof this.props.getPos === 'function') {
161
+ const propPos = this.props.getPos();
162
+ if (propPos !== undefined) {
163
+ setNodeSelection(this.props.view, propPos);
164
+ }
165
+ }
166
+ });
167
+ _defineProperty(this, "handleResizeStart", () => {
168
+ this.setState({
169
+ isResizing: true
170
+ });
171
+ this.selectCurrentMediaNode();
172
+ this.setIsResizing(true);
173
+ // re-calucate guidelines
174
+ this.guidelines = this.getAllGuidelines();
175
+ return 0;
176
+ });
177
+ _defineProperty(this, "handleResize", (size, delta) => {
178
+ const {
179
+ width: originalWidth,
180
+ height: originalHeight,
181
+ layout,
182
+ updateSize,
183
+ lineLength
184
+ } = this.props;
185
+ const {
186
+ width,
187
+ height,
188
+ calculatedWidthWithLayout
189
+ } = this.calculateSizeState(size, delta, originalWidth, originalHeight);
190
+ const guidelineSnaps = getGuidelineSnaps(this.guidelines, lineLength, layout);
191
+ this.updateActiveGuidelines(width, this.guidelines, guidelineSnaps);
192
+ this.setState({
193
+ size: {
194
+ width,
195
+ height
196
+ },
197
+ snaps: guidelineSnaps.snaps
198
+ });
199
+ if (calculatedWidthWithLayout.layout !== layout) {
200
+ updateSize(width, calculatedWidthWithLayout.layout);
201
+ }
202
+ });
203
+ _defineProperty(this, "handleResizeStop", (size, delta) => {
204
+ const {
205
+ width: originalWidth,
206
+ height: originalHeight,
207
+ updateSize,
208
+ dispatchAnalyticsEvent,
209
+ nodeType
210
+ } = this.props;
211
+ const {
212
+ width,
213
+ height,
214
+ calculatedWidthWithLayout
215
+ } = this.calculateSizeState(size, delta, originalWidth, originalHeight, true);
216
+ this.setIsResizing(false);
217
+ this.displayGuideline([]);
218
+ if (dispatchAnalyticsEvent) {
219
+ dispatchAnalyticsEvent(getResizeAnalyticsEvent(nodeType, calculatedWidthWithLayout.width, calculatedWidthWithLayout.layout));
220
+ }
221
+ this.setState({
222
+ isResizing: false,
223
+ size: {
224
+ width,
225
+ height
226
+ }
227
+ }, () => {
228
+ updateSize(width, calculatedWidthWithLayout.layout);
229
+ });
230
+ });
113
231
  const initialWidth = props.mediaSingleWidth || DEFAULT_IMAGE_WIDTH;
114
232
  this.state = {
115
233
  offsetLeft: calculateOffsetLeft(this.insideInlineLike, this.insideLayout, this.props.view.dom, undefined),
@@ -119,7 +237,8 @@ class ResizableMediaSingleNext extends React.Component {
119
237
  size: {
120
238
  width: initialWidth,
121
239
  height: this.calcPxHeight(initialWidth)
122
- }
240
+ },
241
+ snaps: {}
123
242
  };
124
243
  }
125
244
 
@@ -137,7 +256,7 @@ class ResizableMediaSingleNext extends React.Component {
137
256
  } = this.props;
138
257
  return Math.max(Math.min(origWidth || DEFAULT_IMAGE_WIDTH, contentWidth || containerWidth || akEditorDefaultLayoutWidth), MEDIA_SINGLE_MIN_PIXEL_WIDTH);
139
258
  }
140
- componentDidUpdate(prevProps, prevState) {
259
+ componentDidUpdate(prevProps) {
141
260
  const offsetLeft = calculateOffsetLeft(this.insideInlineLike, this.insideLayout, this.props.view.dom, this.wrapper);
142
261
  if (offsetLeft !== this.state.offsetLeft && offsetLeft >= 0) {
143
262
  this.setState({
@@ -152,10 +271,6 @@ class ResizableMediaSingleNext extends React.Component {
152
271
  resizedPctWidth: this.props.pctWidth
153
272
  });
154
273
  }
155
- if (prevState.isResizing !== this.state.isResizing && this.state.isResizing) {
156
- const guidelines = this.getDefaultGuidelines();
157
- this.displayGuideline(guidelines);
158
- }
159
274
  if (prevProps.mediaSingleWidth !== this.props.mediaSingleWidth && this.props.mediaSingleWidth) {
160
275
  // update size when lineLength becomes defined later
161
276
  // ensures extended experience renders legacy image with the same size as the legacy experience
@@ -184,71 +299,6 @@ class ResizableMediaSingleNext extends React.Component {
184
299
  // disable guidelines for nested media single node
185
300
  return this.isNestedNode() ? [] : generateDefaultGuidelines(lineLength, containerWidth, fullWidthMode);
186
301
  }
187
-
188
- // Calculate width of media nodes for snaps based on dynamic guidelines
189
- // TODO: refactor this later, maybe use state to hold snaps array
190
- getSnaps() {
191
- const {
192
- view,
193
- lineLength
194
- } = this.props;
195
- const {
196
- dom
197
- } = view;
198
- const defaultGuidelines = this.getDefaultGuidelines();
199
- // disable guidelines for nested media single node
200
- const dynamicGuidelines = this.isNestedNode() ? [] : generateDynamicGuidelines(view.state, lineLength, {
201
- styles: {
202
- lineStyle: 'dashed'
203
- },
204
- show: false
205
- });
206
- const guidelines = [...defaultGuidelines, ...dynamicGuidelines];
207
- const mediaSingleSelector = 'div.mediaSingleView-content-wrap.ProseMirror-selectednode';
208
- const {
209
- width
210
- } = dom.getBoundingClientRect();
211
- const halfWidth = width / 2;
212
- const selectedMedia = dom.querySelector(mediaSingleSelector);
213
- if (selectedMedia) {
214
- const pixelWidth = parseFloat(selectedMedia.getAttribute('width') || '') || 0;
215
- const layout = selectedMedia.getAttribute('layout');
216
- let snap = 0;
217
- switch (layout) {
218
- case 'align-start':
219
- case 'wrap-left':
220
- snap = pixelWidth - halfWidth;
221
- break;
222
- case 'align-end':
223
- case 'wrap-right':
224
- snap = width - pixelWidth - halfWidth;
225
- break;
226
- case 'center':
227
- case 'wide':
228
- case 'full-width':
229
- snap = -pixelWidth / 2;
230
- break;
231
- // we ingnore full-width and wide
232
- default:
233
- snap = 0;
234
- }
235
- const snapWidths = getSnapWidth(guidelines, pixelWidth, snap, layout);
236
- const snapToWidths = snapWidths.map(s => s && s.width);
237
-
238
- // update guidelines
239
- if (this.state.isResizing) {
240
- const {
241
- gap,
242
- keys: activeGuidelineKeys
243
- } = findClosestSnap(this.state.size.width, snapToWidths, snapWidths, MEDIA_SINGLE_HIGHLIGHT_GAP);
244
- this.displayGuideline(getGuidelinesWithHighlights(gap, MEDIA_SINGLE_HIGHLIGHT_GAP, activeGuidelineKeys, guidelines));
245
- }
246
- return snapToWidths.length > 0 ? {
247
- x: snapToWidths
248
- } : {};
249
- }
250
- return {};
251
- }
252
302
  get wrappedLayout() {
253
303
  return wrappedLayouts.indexOf(this.props.layout) > -1;
254
304
  }
@@ -341,7 +391,8 @@ class ResizableMediaSingleNext extends React.Component {
341
391
  fullWidthMode,
342
392
  selected,
343
393
  children,
344
- intl
394
+ intl,
395
+ lineLength
345
396
  } = this.props;
346
397
  const {
347
398
  isResizing,
@@ -356,96 +407,6 @@ class ResizableMediaSingleNext extends React.Component {
356
407
  }
357
408
  });
358
409
 
359
- /**
360
- * NEW REFACTOR
361
- */
362
- const roundPixelValue = value => Math.round(value);
363
- const getHeightFromNewWidth = (originalWidth, originalHeight, newWidth) => roundPixelValue(originalHeight / originalWidth * newWidth);
364
- const calculateSizeState = (size, delta, originalWidth = 0, originalHeight, onResizeStop = false) => {
365
- const calculatedWidth = roundPixelValue(size.width + delta.width);
366
- const calculatedWidthWithLayout = this.calcNewSize(calculatedWidth, onResizeStop);
367
- const calculatedHeightWithLayout = getHeightFromNewWidth(originalWidth, originalHeight, calculatedWidth);
368
- return {
369
- width: calculatedWidth,
370
- height: calculatedHeightWithLayout,
371
- calculatedWidthWithLayout
372
- };
373
- };
374
- const selectCurrentMediaNode = () => {
375
- if (!this.props.selected && typeof this.props.getPos === 'function') {
376
- const propPos = this.props.getPos();
377
- if (propPos !== undefined) {
378
- setNodeSelection(this.props.view, propPos);
379
- }
380
- }
381
- };
382
- const handleResizeStart = () => {
383
- this.setState({
384
- isResizing: true
385
- });
386
- selectCurrentMediaNode();
387
- this.setIsResizing(true);
388
-
389
- // TODO: Update once type updated from editor common resizer
390
- return 0;
391
- };
392
- const handleResize = (size, delta) => {
393
- const {
394
- width: originalWidth,
395
- height: originalHeight,
396
- layout,
397
- updateSize
398
- } = this.props;
399
- const {
400
- width,
401
- height,
402
- calculatedWidthWithLayout
403
- } = calculateSizeState(size, delta, originalWidth, originalHeight);
404
- this.setState({
405
- size: {
406
- width,
407
- height
408
- }
409
- });
410
- if (calculatedWidthWithLayout.layout !== layout) {
411
- updateSize(width, calculatedWidthWithLayout.layout);
412
- }
413
-
414
- // TODO: Update once type updated from editor common resizer
415
- return 0;
416
- };
417
- const handleResizeStop = (size, delta) => {
418
- const {
419
- width: originalWidth,
420
- height: originalHeight,
421
- updateSize,
422
- dispatchAnalyticsEvent,
423
- nodeType
424
- } = this.props;
425
- const {
426
- width,
427
- height,
428
- calculatedWidthWithLayout
429
- } = calculateSizeState(size, delta, originalWidth, originalHeight, true);
430
- this.setIsResizing(false);
431
- this.displayGuideline([]);
432
- if (dispatchAnalyticsEvent) {
433
- dispatchAnalyticsEvent(getResizeAnalyticsEvent(nodeType, calculatedWidthWithLayout.width, calculatedWidthWithLayout.layout));
434
- }
435
- this.setState({
436
- isResizing: false,
437
- size: {
438
- width,
439
- height
440
- }
441
- }, () => {
442
- updateSize(width, calculatedWidthWithLayout.layout);
443
- });
444
-
445
- // TODO: Update once type updated from editor common resizer
446
- return 0;
447
- };
448
-
449
410
  // TODO: Clean up where this lives and how it gets generated
450
411
  const className = classnames(richMediaClassName, `image-${layout}`, isResizing ? 'is-resizing' : 'not-resizing', this.props.className, {
451
412
  'not-resized': !pctWidth,
@@ -455,6 +416,7 @@ class ResizableMediaSingleNext extends React.Component {
455
416
  const resizerNextClassName = classnames(className, resizerStyles);
456
417
  const showSizeGuide = selected || isResizing;
457
418
  const label = layout === 'full-width' ? intl.formatMessage(messages.fullWidthImage) : `${this.state.size.width} x ${this.state.size.height}`;
419
+ const maxWidth = this.calcMaxWidth(lineLength, containerWidth, fullWidthMode);
458
420
  return jsx("div", {
459
421
  ref: this.saveWrapper,
460
422
  css: wrapperStyle({
@@ -468,14 +430,15 @@ class ResizableMediaSingleNext extends React.Component {
468
430
  })
469
431
  }, jsx(ResizerNext, {
470
432
  minWidth: MEDIA_SINGLE_MIN_PIXEL_WIDTH,
433
+ maxWidth: maxWidth,
471
434
  className: resizerNextClassName,
472
435
  snapGap: MEDIA_SINGLE_SNAP_GAP,
473
436
  enable: enable,
474
437
  width: size.width,
475
- handleResizeStart: handleResizeStart,
476
- handleResize: handleResize,
477
- handleResizeStop: handleResizeStop,
478
- snap: this.getSnaps(),
438
+ handleResizeStart: this.handleResizeStart,
439
+ handleResize: this.handleResize,
440
+ handleResizeStop: this.handleResizeStop,
441
+ snap: this.state.snaps,
479
442
  resizeRatio: nonWrappedLayouts.includes(layout) ? 2 : 1,
480
443
  "data-testid": resizerNextTestId
481
444
  }, showSizeGuide && jsx(ResizeLabel, {
@@ -1,5 +1,5 @@
1
1
  export const name = "@atlaskit/editor-core";
2
- export const version = "187.14.4";
2
+ export const version = "187.14.8";
3
3
  export const nextMajorVersion = () => {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-core",
3
- "version": "187.14.4",
3
+ "version": "187.14.8",
4
4
  "sideEffects": false
5
5
  }
@@ -17,6 +17,7 @@ import ReactDOM from 'react-dom';
17
17
  import { injectIntl } from 'react-intl-next';
18
18
  import { EmojiPicker as AkEmojiPicker } from '@atlaskit/emoji/picker';
19
19
  import { Popup } from '@atlaskit/editor-common/ui';
20
+ import { pluginCommandToPMCommand } from '@atlaskit/editor-common/preset';
20
21
  import ToolbarButton from '../../../../ui/ToolbarButton';
21
22
  import { separatorStyles, buttonGroupStyle, wrapperStyle } from '@atlaskit/editor-common/styles';
22
23
  import { insertDate } from '../../../date/actions';
@@ -172,7 +173,9 @@ export var ToolbarInsertBlock = /*#__PURE__*/function (_React$PureComponent) {
172
173
  pluginInjectionApi = _this$props.pluginInjectionApi;
173
174
  var state = editorView.state,
174
175
  dispatch = editorView.dispatch;
175
- pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$d = pluginInjectionApi.dependencies) === null || _pluginInjectionApi$d === void 0 ? void 0 : (_pluginInjectionApi$d2 = _pluginInjectionApi$d.hyperlink) === null || _pluginInjectionApi$d2 === void 0 ? void 0 : _pluginInjectionApi$d2.actions.showLinkToolbar(inputMethod)(state, dispatch);
176
+
177
+ // We should update this to use `pluginInjectionApi.executeCommand` once available
178
+ pluginCommandToPMCommand(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$d = pluginInjectionApi.dependencies) === null || _pluginInjectionApi$d === void 0 ? void 0 : (_pluginInjectionApi$d2 = _pluginInjectionApi$d.hyperlink) === null || _pluginInjectionApi$d2 === void 0 ? void 0 : _pluginInjectionApi$d2.commands.showLinkToolbar(inputMethod))(state, dispatch);
176
179
  return true;
177
180
  });
178
181
  _defineProperty(_assertThisInitialized(_this), "insertMention", function (inputMethod) {
@@ -1,4 +1,5 @@
1
1
  import _get from "@babel/runtime/helpers/get";
2
+ import _extends from "@babel/runtime/helpers/extends";
2
3
  import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
4
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
4
5
  import _createClass from "@babel/runtime/helpers/createClass";
@@ -238,11 +239,17 @@ var MediaSingleNode = /*#__PURE__*/function (_Component) {
238
239
  }
239
240
  insertAndSelectCaptionFromMediaSinglePos(getPos(), node)(view.state, view.dispatch);
240
241
  });
241
- _defineProperty(_assertThisInitialized(_this), "getLineLength", function (view, pos) {
242
+ /**
243
+ * Get parent width for a nested media single node
244
+ * @param view Editor view
245
+ * @param pos node position
246
+ * @param includeMoreParentNodeTypes should consider table and list as parent nodes(only true for new experience)
247
+ */
248
+ _defineProperty(_assertThisInitialized(_this), "getLineLength", function (view, pos, includeMoreParentNodeTypes) {
242
249
  if (typeof pos !== 'number') {
243
250
  return null;
244
251
  }
245
- if (isRichMediaInsideOfBlockNode(view, pos)) {
252
+ if (isRichMediaInsideOfBlockNode(view, pos, includeMoreParentNodeTypes)) {
246
253
  var $pos = view.state.doc.resolve(pos);
247
254
  var domNode = view.nodeDOM($pos.pos);
248
255
  if ($pos.nodeAfter && floatingLayouts.indexOf($pos.nodeAfter.attrs.layout) > -1 && domNode && domNode.parentElement) {
@@ -354,7 +361,8 @@ var MediaSingleNode = /*#__PURE__*/function (_Component) {
354
361
  height = DEFAULT_IMAGE_HEIGHT;
355
362
  }
356
363
  var isSelected = selected();
357
- var contentWidth = this.getLineLength(view, getPos()) || lineLength;
364
+ var contentWidthForLegacyExperience = this.getLineLength(view, getPos()) || lineLength;
365
+ var contentWidth = this.getLineLength(view, getPos(), true) || lineLength;
358
366
  var mediaSingleProps = {
359
367
  layout: layout,
360
368
  width: width,
@@ -369,7 +377,9 @@ var MediaSingleNode = /*#__PURE__*/function (_Component) {
369
377
  widthType: widthType,
370
378
  origWidth: width,
371
379
  layout: layout,
372
- contentWidth: contentWidth,
380
+ // This will only be used when calculating legacy media single width
381
+ // thus we use the legecy value (exclude table as container node)
382
+ contentWidth: contentWidthForLegacyExperience,
373
383
  containerWidth: containerWidth,
374
384
  gutterOffset: MEDIA_SINGLE_GUTTER_SIZE
375
385
  })
@@ -408,7 +418,9 @@ var MediaSingleNode = /*#__PURE__*/function (_Component) {
408
418
  ref: this.captionPlaceHolderRef,
409
419
  onClick: this.clickPlaceholder
410
420
  }));
411
- return canResize ? getBooleanFF('platform.editor.media.extended-resize-experience') ? jsx(ResizableMediaSingleNext, ResizableMediaSingleProps, MediaChildren) : jsx(ResizableMediaSingle, ResizableMediaSingleProps, MediaChildren) : jsx(MediaSingle, mediaSingleProps, MediaChildren);
421
+ return canResize ? getBooleanFF('platform.editor.media.extended-resize-experience') ? jsx(ResizableMediaSingleNext, ResizableMediaSingleProps, MediaChildren) : jsx(ResizableMediaSingle, _extends({}, ResizableMediaSingleProps, {
422
+ lineLength: contentWidthForLegacyExperience
423
+ }), MediaChildren) : jsx(MediaSingle, mediaSingleProps, MediaChildren);
412
424
  }
413
425
  }]);
414
426
  return MediaSingleNode;