@atlaskit/renderer 111.0.2 → 111.1.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @atlaskit/renderer
2
2
 
3
+ ## 111.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#147660](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/147660)
8
+ [`a407a8fbc874b`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/a407a8fbc874b) -
9
+ ED-24365 Support commenting inside bodied extension content in the Renderer
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+
3
15
  ## 111.0.2
4
16
 
5
17
  ### Patch Changes
@@ -13,6 +13,7 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/creat
13
13
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
14
14
  var _react = _interopRequireDefault(require("react"));
15
15
  var _model = require("@atlaskit/editor-prosemirror/model");
16
+ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
16
17
  var _links = require("./utils/links");
17
18
  var _nodes = require("./nodes");
18
19
  var _textWrapper = _interopRequireDefault(require("./nodes/text-wrapper"));
@@ -57,7 +58,6 @@ var ReactSerializer = exports.default = /*#__PURE__*/function () {
57
58
  (0, _defineProperty2.default)(this, "allowWrapCodeBlock", false);
58
59
  (0, _defineProperty2.default)(this, "allowPlaceholderText", true);
59
60
  (0, _defineProperty2.default)(this, "allowCustomPanels", false);
60
- (0, _defineProperty2.default)(this, "startPos", 1);
61
61
  (0, _defineProperty2.default)(this, "surroundTextNodesWithTextWrapper", false);
62
62
  (0, _defineProperty2.default)(this, "allowAnnotations", false);
63
63
  (0, _defineProperty2.default)(this, "serializeFragmentChild", function (node, _ref) {
@@ -161,6 +161,13 @@ var ReactSerializer = exports.default = /*#__PURE__*/function () {
161
161
  });
162
162
  return props;
163
163
  });
164
+ if ((0, _experiments.editorExperiment)('comment_on_bodied_extensions', true)) {
165
+ this.initStartPos = init.startPos || 1;
166
+ this.startPos = init.startPos || 1;
167
+ } else {
168
+ this.initStartPos = 1;
169
+ this.startPos = 1;
170
+ }
164
171
  this.providers = init.providers;
165
172
  this.eventHandlers = init.eventHandlers;
166
173
  this.extensionHandlers = init.extensionHandlers;
@@ -198,7 +205,7 @@ var ReactSerializer = exports.default = /*#__PURE__*/function () {
198
205
  value: function resetState() {
199
206
  this.headingIds = [];
200
207
  this.expandHeadingIds = [];
201
- this.startPos = 1;
208
+ this.startPos = this.initStartPos;
202
209
  }
203
210
  }, {
204
211
  key: "getNodeProps",
@@ -531,6 +538,7 @@ var ReactSerializer = exports.default = /*#__PURE__*/function () {
531
538
  key: "getProps",
532
539
  value: function getProps(node) {
533
540
  var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
541
+ var startPos = this.startPos + path.length;
534
542
  return _objectSpread({
535
543
  text: node.text,
536
544
  providers: this.providers,
@@ -553,8 +561,9 @@ var ReactSerializer = exports.default = /*#__PURE__*/function () {
553
561
  dataAttributes: {
554
562
  // We need to account for depth (path.length gives up depth) here
555
563
  // but depth doesnt increment the pos, only accounted for.
556
- 'data-renderer-start-pos': this.startPos + path.length
564
+ 'data-renderer-start-pos': startPos
557
565
  },
566
+ startPos: startPos,
558
567
  path: path
559
568
  }, node.attrs);
560
569
  }
@@ -13,6 +13,7 @@ var _ErrorBoundary = require("../../ui/Renderer/ErrorBoundary");
13
13
  var _ExtensionRenderer = _interopRequireDefault(require("../../ui/ExtensionRenderer"));
14
14
  var _enums = require("../../analytics/enums");
15
15
  var _analytics = require("@atlaskit/editor-common/analytics");
16
+ var _annotations = require("../../ui/annotations");
16
17
  var BodiedExtension = function BodiedExtension(props) {
17
18
  var children = props.children,
18
19
  _props$layout = props.layout,
@@ -31,6 +32,10 @@ var BodiedExtension = function BodiedExtension(props) {
31
32
  componentId: _analytics.ACTION_SUBJECT_ID.EXTENSION_BODIED,
32
33
  createAnalyticsEvent: createAnalyticsEvent,
33
34
  additionalInfo: "".concat(extensionType, ": ").concat(extensionKey, " ")
35
+ }, /*#__PURE__*/_react.default.createElement(_annotations.AnnotationsPositionContext.Provider, {
36
+ value: {
37
+ startPos: props.startPos + 1
38
+ }
34
39
  }, /*#__PURE__*/_react.default.createElement(_ExtensionRenderer.default, (0, _extends2.default)({}, props, {
35
40
  type: "bodiedExtension"
36
41
  }), function (_ref) {
@@ -51,6 +56,6 @@ var BodiedExtension = function BodiedExtension(props) {
51
56
  return (0, _extension.renderExtension)(children, layout, {
52
57
  isTopLevel: path.length < 1
53
58
  }, removeOverflow);
54
- }));
59
+ })));
55
60
  };
56
61
  var _default = exports.default = BodiedExtension;
@@ -5,7 +5,9 @@ var _typeof = require("@babel/runtime/helpers/typeof");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.defaultNodeComponents = exports.default = exports.RendererWithAnalytics = exports.Renderer = exports.NORMAL_SEVERITY_THRESHOLD = exports.DEGRADED_SEVERITY_THRESHOLD = void 0;
8
+ exports.NORMAL_SEVERITY_THRESHOLD = exports.DEGRADED_SEVERITY_THRESHOLD = void 0;
9
+ exports.Renderer = Renderer;
10
+ exports.defaultNodeComponents = exports.default = exports.__RendererClassComponent = exports.RendererWithAnalytics = void 0;
9
11
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
12
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11
13
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
@@ -19,6 +21,7 @@ var _react2 = require("@emotion/react");
19
21
  var _schemaDefault = require("@atlaskit/adf-schema/schema-default");
20
22
  var _traverse = require("@atlaskit/adf-utils/traverse");
21
23
  var _providerFactory = require("@atlaskit/editor-common/provider-factory");
24
+ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
22
25
  var _ui = require("@atlaskit/editor-common/ui");
23
26
  var _performanceMeasures = require("@atlaskit/editor-common/performance-measures");
24
27
  var _utils = require("@atlaskit/editor-common/utils");
@@ -63,14 +66,18 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
63
66
  var NORMAL_SEVERITY_THRESHOLD = exports.NORMAL_SEVERITY_THRESHOLD = 2000;
64
67
  var DEGRADED_SEVERITY_THRESHOLD = exports.DEGRADED_SEVERITY_THRESHOLD = 3000;
65
68
  var packageName = "@atlaskit/renderer";
66
- var packageVersion = "111.0.2";
69
+ var packageVersion = "111.1.0";
67
70
  var defaultNodeComponents = exports.defaultNodeComponents = _nodes.nodeToReact;
68
- var Renderer = exports.Renderer = /*#__PURE__*/function (_PureComponent) {
69
- (0, _inherits2.default)(Renderer, _PureComponent);
70
- var _super = _createSuper(Renderer);
71
- function Renderer(props) {
71
+
72
+ /**
73
+ * Exported due to enzyme test reliance on this component.
74
+ */
75
+ var __RendererClassComponent = exports.__RendererClassComponent = /*#__PURE__*/function (_PureComponent) {
76
+ (0, _inherits2.default)(__RendererClassComponent, _PureComponent);
77
+ var _super = _createSuper(__RendererClassComponent);
78
+ function __RendererClassComponent(props) {
72
79
  var _this;
73
- (0, _classCallCheck2.default)(this, Renderer);
80
+ (0, _classCallCheck2.default)(this, __RendererClassComponent);
74
81
  _this = _super.call(this, props);
75
82
  /**
76
83
  * This is used in measuring the Renderer Mount time and is then
@@ -169,7 +176,7 @@ var Renderer = exports.Renderer = /*#__PURE__*/function (_PureComponent) {
169
176
  }
170
177
  return _this;
171
178
  }
172
- (0, _createClass2.default)(Renderer, [{
179
+ (0, _createClass2.default)(__RendererClassComponent, [{
173
180
  key: "anchorLinkAnalytics",
174
181
  value: function anchorLinkAnalytics() {
175
182
  var hash = window.location.hash && decodeURIComponent(window.location.hash.slice(1));
@@ -257,6 +264,7 @@ var Renderer = exports.Renderer = /*#__PURE__*/function (_PureComponent) {
257
264
  var _this$featureFlags = this.featureFlags(props.featureFlags),
258
265
  featureFlags = _this$featureFlags.featureFlags;
259
266
  return {
267
+ startPos: props.startPos,
260
268
  providers: this.providerFactory,
261
269
  eventHandlers: props.eventHandlers,
262
270
  extensionHandlers: props.extensionHandlers,
@@ -445,8 +453,21 @@ var Renderer = exports.Renderer = /*#__PURE__*/function (_PureComponent) {
445
453
  }
446
454
  }
447
455
  }]);
448
- return Renderer;
456
+ return __RendererClassComponent;
449
457
  }(_react.PureComponent);
458
+ function Renderer(props) {
459
+ var _React$useContext = _react.default.useContext(_annotations.AnnotationsPositionContext),
460
+ startPos = _React$useContext.startPos;
461
+
462
+ // eslint-disable-next-line react/jsx-pascal-case
463
+ return (0, _react2.jsx)(__RendererClassComponent, (0, _extends2.default)({}, props, {
464
+ startPos: startPos
465
+ }));
466
+ }
467
+
468
+ // Usage notes:
469
+ // Used by Confluence for View page renderer
470
+ // For the nested renderers - see RendererWithAnnotationSelection.
450
471
  var RendererWithAnalytics = exports.RendererWithAnalytics = /*#__PURE__*/_react.default.memo(function (props) {
451
472
  return (0, _react2.jsx)(_analyticsNamespacedContext.FabricEditorAnalyticsContext, {
452
473
  data: {
@@ -560,25 +581,54 @@ var RendererWrapper = /*#__PURE__*/_react.default.memo(function (props) {
560
581
  })
561
582
  }, children))));
562
583
  });
584
+ var RootRendererContext = /*#__PURE__*/_react.default.createContext(null);
563
585
  function RendererActionsInternalUpdater(_ref) {
564
586
  var children = _ref.children,
565
587
  doc = _ref.doc,
566
588
  schema = _ref.schema,
567
589
  onAnalyticsEvent = _ref.onAnalyticsEvent;
590
+ var rootRendererContextValue = _react.default.useContext(RootRendererContext);
568
591
  var actions = (0, _react.useContext)(_RendererActionsContext.RendererContext);
569
592
  var rendererRef = (0, _react.useRef)(null);
593
+
594
+ // This doc is used by the renderer actions when applying comments to the document.
595
+ // (via hand crafted steps based on non prosemirror based position calculations)
596
+ // It is set to the root renderer's doc as otherwise the resulting document will
597
+ // be incorrect (nested renderers use a fake document which represents a subset
598
+ // of the actual document).
599
+ var _doc;
600
+ if ((0, _experiments.editorExperiment)('comment_on_bodied_extensions', true) && rootRendererContextValue) {
601
+ // If rootRendererContextValue is set -- we are inside a nested renderer
602
+ // and should always use the doc from the root renderer
603
+ _doc = rootRendererContextValue.doc;
604
+ } else {
605
+ // If rootRendererContextValue is not set -- we are in the root renderer
606
+ // and set the doc to the current doc.
607
+ _doc = doc;
608
+ }
570
609
  (0, _react.useLayoutEffect)(function () {
571
- if (doc) {
572
- actions._privateRegisterRenderer(rendererRef, doc, schema, onAnalyticsEvent);
610
+ if (_doc) {
611
+ actions._privateRegisterRenderer(rendererRef, _doc, schema, onAnalyticsEvent);
573
612
  } else {
574
613
  actions._privateUnregisterRenderer();
575
614
  }
576
615
  return function () {
577
616
  return actions._privateUnregisterRenderer();
578
617
  };
579
- }, [actions, schema, doc, onAnalyticsEvent]);
618
+ }, [actions, schema, _doc, onAnalyticsEvent]);
619
+ if ((0, _experiments.editorExperiment)('comment_on_bodied_extensions', true)) {
620
+ return (0, _react2.jsx)(RootRendererContext.Provider, {
621
+ value: {
622
+ doc: _doc
623
+ }
624
+ }, children);
625
+ }
580
626
  return children;
581
627
  }
628
+
629
+ // Usage notes:
630
+ // Used by Confluence for nested renderers
631
+ // For the View page renderer - see RendererWithAnalytics
582
632
  var RendererWithAnnotationSelection = function RendererWithAnnotationSelection(props) {
583
633
  var allowAnnotations = props.allowAnnotations,
584
634
  adfDocument = props.document;
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "AnnotationMark", {
10
10
  return _element.MarkElement;
11
11
  }
12
12
  });
13
- exports.AnnotationsWrapper = void 0;
13
+ exports.AnnotationsWrapper = exports.AnnotationsPositionContext = void 0;
14
14
  Object.defineProperty(exports, "TextWithAnnotationDraft", {
15
15
  enumerable: true,
16
16
  get: function get() {
@@ -40,6 +40,14 @@ var LoadAnnotations = /*#__PURE__*/_react.default.memo(function (_ref) {
40
40
  });
41
41
  return null;
42
42
  });
43
+
44
+ // This is used by renderers when setting the data-start-pos attribute on commentable nodes
45
+ // By default it is 1 (the possible starting position of any document).
46
+ // The bodied extension component then sets a new value for this context based on its on position
47
+ // in the document.
48
+ var AnnotationsPositionContext = exports.AnnotationsPositionContext = /*#__PURE__*/_react.default.createContext({
49
+ startPos: 1
50
+ });
43
51
  var AnnotationsWrapper = exports.AnnotationsWrapper = function AnnotationsWrapper(props) {
44
52
  var _annotationProvider$i, _annotationProvider$i2;
45
53
  var children = props.children,
@@ -2,6 +2,7 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
3
  import React from 'react';
4
4
  import { MarkType } from '@atlaskit/editor-prosemirror/model';
5
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
5
6
  import { isNestedHeaderLinksEnabled } from './utils/links';
6
7
  import { Doc, DocWithSelectAllTrap, mergeTextNodes, isTextWrapper, isTextNode, toReact } from './nodes';
7
8
  import TextWrapperComponent from './nodes/text-wrapper';
@@ -41,7 +42,6 @@ export default class ReactSerializer {
41
42
  _defineProperty(this, "allowWrapCodeBlock", false);
42
43
  _defineProperty(this, "allowPlaceholderText", true);
43
44
  _defineProperty(this, "allowCustomPanels", false);
44
- _defineProperty(this, "startPos", 1);
45
45
  _defineProperty(this, "surroundTextNodesWithTextWrapper", false);
46
46
  _defineProperty(this, "allowAnnotations", false);
47
47
  _defineProperty(this, "serializeFragmentChild", (node, {
@@ -147,6 +147,13 @@ export default class ReactSerializer {
147
147
  };
148
148
  return props;
149
149
  });
150
+ if (editorExperiment('comment_on_bodied_extensions', true)) {
151
+ this.initStartPos = init.startPos || 1;
152
+ this.startPos = init.startPos || 1;
153
+ } else {
154
+ this.initStartPos = 1;
155
+ this.startPos = 1;
156
+ }
150
157
  this.providers = init.providers;
151
158
  this.eventHandlers = init.eventHandlers;
152
159
  this.extensionHandlers = init.extensionHandlers;
@@ -182,7 +189,7 @@ export default class ReactSerializer {
182
189
  resetState() {
183
190
  this.headingIds = [];
184
191
  this.expandHeadingIds = [];
185
- this.startPos = 1;
192
+ this.startPos = this.initStartPos;
186
193
  }
187
194
  getNodeProps(node, parentInfo) {
188
195
  const path = parentInfo ? parentInfo.path : undefined;
@@ -463,6 +470,7 @@ export default class ReactSerializer {
463
470
  };
464
471
  }
465
472
  getProps(node, path = []) {
473
+ const startPos = this.startPos + path.length;
466
474
  return {
467
475
  text: node.text,
468
476
  providers: this.providers,
@@ -485,8 +493,9 @@ export default class ReactSerializer {
485
493
  dataAttributes: {
486
494
  // We need to account for depth (path.length gives up depth) here
487
495
  // but depth doesnt increment the pos, only accounted for.
488
- 'data-renderer-start-pos': this.startPos + path.length
496
+ 'data-renderer-start-pos': startPos
489
497
  },
498
+ startPos,
490
499
  path,
491
500
  ...node.attrs
492
501
  };
@@ -6,6 +6,7 @@ import { ErrorBoundary } from '../../ui/Renderer/ErrorBoundary';
6
6
  import ExtensionRenderer from '../../ui/ExtensionRenderer';
7
7
  import { ACTION_SUBJECT } from '../../analytics/enums';
8
8
  import { ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
9
+ import { AnnotationsPositionContext } from '../../ui/annotations';
9
10
  const BodiedExtension = props => {
10
11
  const {
11
12
  children,
@@ -23,6 +24,10 @@ const BodiedExtension = props => {
23
24
  componentId: ACTION_SUBJECT_ID.EXTENSION_BODIED,
24
25
  createAnalyticsEvent: createAnalyticsEvent,
25
26
  additionalInfo: `${extensionType}: ${extensionKey} `
27
+ }, /*#__PURE__*/React.createElement(AnnotationsPositionContext.Provider, {
28
+ value: {
29
+ startPos: props.startPos + 1
30
+ }
26
31
  }, /*#__PURE__*/React.createElement(ExtensionRenderer, _extends({}, props, {
27
32
  type: "bodiedExtension"
28
33
  }), ({
@@ -44,6 +49,6 @@ const BodiedExtension = props => {
44
49
  return renderExtension(children, layout, {
45
50
  isTopLevel: path.length < 1
46
51
  }, removeOverflow);
47
- }));
52
+ })));
48
53
  };
49
54
  export default BodiedExtension;
@@ -10,6 +10,7 @@ import { jsx } from '@emotion/react';
10
10
  import { getSchemaBasedOnStage } from '@atlaskit/adf-schema/schema-default';
11
11
  import { reduce } from '@atlaskit/adf-utils/traverse';
12
12
  import { ProviderFactory, ProviderFactoryProvider } from '@atlaskit/editor-common/provider-factory';
13
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
13
14
  import { UnsupportedBlock, BaseTheme, WidthProvider, WithCreateAnalyticsEvent, IntlErrorBoundary } from '@atlaskit/editor-common/ui';
14
15
  import { startMeasure, stopMeasure } from '@atlaskit/editor-common/performance-measures';
15
16
  import { getAnalyticsAppearance, getAnalyticsEventSeverity, shouldForceTracking } from '@atlaskit/editor-common/utils';
@@ -33,7 +34,7 @@ import { Provider as SmartCardStorageProvider } from '../SmartCardStorage';
33
34
  import { BreakoutSSRInlineScript } from './breakout-ssr';
34
35
  import { RendererActionsContext, RendererContext as ActionsContext } from '../RendererActionsContext';
35
36
  import { ActiveHeaderIdProvider } from '../active-header-id-provider';
36
- import { AnnotationsWrapper } from '../annotations';
37
+ import { AnnotationsPositionContext, AnnotationsWrapper } from '../annotations';
37
38
  import { getActiveHeadingId, isNestedHeaderLinksEnabled } from '../../react/utils/links';
38
39
  import { findInTree } from '../../utils';
39
40
  import { isInteractiveElement } from './click-to-edit';
@@ -45,9 +46,13 @@ import { nodeToReact } from '../../react/nodes';
45
46
  export const NORMAL_SEVERITY_THRESHOLD = 2000;
46
47
  export const DEGRADED_SEVERITY_THRESHOLD = 3000;
47
48
  const packageName = "@atlaskit/renderer";
48
- const packageVersion = "111.0.2";
49
+ const packageVersion = "111.1.0";
49
50
  export const defaultNodeComponents = nodeToReact;
50
- export class Renderer extends PureComponent {
51
+
52
+ /**
53
+ * Exported due to enzyme test reliance on this component.
54
+ */
55
+ export class __RendererClassComponent extends PureComponent {
51
56
  constructor(props) {
52
57
  super(props);
53
58
  /**
@@ -236,6 +241,7 @@ export class Renderer extends PureComponent {
236
241
  featureFlags
237
242
  } = this.featureFlags(props.featureFlags);
238
243
  return {
244
+ startPos: props.startPos,
239
245
  providers: this.providerFactory,
240
246
  eventHandlers: props.eventHandlers,
241
247
  extensionHandlers: props.extensionHandlers,
@@ -422,6 +428,20 @@ export class Renderer extends PureComponent {
422
428
  }
423
429
  }
424
430
  }
431
+ export function Renderer(props) {
432
+ const {
433
+ startPos
434
+ } = React.useContext(AnnotationsPositionContext);
435
+
436
+ // eslint-disable-next-line react/jsx-pascal-case
437
+ return jsx(__RendererClassComponent, _extends({}, props, {
438
+ startPos: startPos
439
+ }));
440
+ }
441
+
442
+ // Usage notes:
443
+ // Used by Confluence for View page renderer
444
+ // For the nested renderers - see RendererWithAnnotationSelection.
425
445
  export const RendererWithAnalytics = /*#__PURE__*/React.memo(props => jsx(FabricEditorAnalyticsContext, {
426
446
  data: {
427
447
  appearance: getAnalyticsAppearance(props.appearance),
@@ -533,24 +553,53 @@ const RendererWrapper = /*#__PURE__*/React.memo(props => {
533
553
  })
534
554
  }, children))));
535
555
  });
556
+ const RootRendererContext = /*#__PURE__*/React.createContext(null);
536
557
  function RendererActionsInternalUpdater({
537
558
  children,
538
559
  doc,
539
560
  schema,
540
561
  onAnalyticsEvent
541
562
  }) {
563
+ const rootRendererContextValue = React.useContext(RootRendererContext);
542
564
  const actions = useContext(ActionsContext);
543
565
  const rendererRef = useRef(null);
566
+
567
+ // This doc is used by the renderer actions when applying comments to the document.
568
+ // (via hand crafted steps based on non prosemirror based position calculations)
569
+ // It is set to the root renderer's doc as otherwise the resulting document will
570
+ // be incorrect (nested renderers use a fake document which represents a subset
571
+ // of the actual document).
572
+ let _doc;
573
+ if (editorExperiment('comment_on_bodied_extensions', true) && rootRendererContextValue) {
574
+ // If rootRendererContextValue is set -- we are inside a nested renderer
575
+ // and should always use the doc from the root renderer
576
+ _doc = rootRendererContextValue.doc;
577
+ } else {
578
+ // If rootRendererContextValue is not set -- we are in the root renderer
579
+ // and set the doc to the current doc.
580
+ _doc = doc;
581
+ }
544
582
  useLayoutEffect(() => {
545
- if (doc) {
546
- actions._privateRegisterRenderer(rendererRef, doc, schema, onAnalyticsEvent);
583
+ if (_doc) {
584
+ actions._privateRegisterRenderer(rendererRef, _doc, schema, onAnalyticsEvent);
547
585
  } else {
548
586
  actions._privateUnregisterRenderer();
549
587
  }
550
588
  return () => actions._privateUnregisterRenderer();
551
- }, [actions, schema, doc, onAnalyticsEvent]);
589
+ }, [actions, schema, _doc, onAnalyticsEvent]);
590
+ if (editorExperiment('comment_on_bodied_extensions', true)) {
591
+ return jsx(RootRendererContext.Provider, {
592
+ value: {
593
+ doc: _doc
594
+ }
595
+ }, children);
596
+ }
552
597
  return children;
553
598
  }
599
+
600
+ // Usage notes:
601
+ // Used by Confluence for nested renderers
602
+ // For the View page renderer - see RendererWithAnalytics
554
603
  const RendererWithAnnotationSelection = props => {
555
604
  const {
556
605
  allowAnnotations,
@@ -20,6 +20,14 @@ const LoadAnnotations = /*#__PURE__*/React.memo(({
20
20
  });
21
21
  return null;
22
22
  });
23
+
24
+ // This is used by renderers when setting the data-start-pos attribute on commentable nodes
25
+ // By default it is 1 (the possible starting position of any document).
26
+ // The bodied extension component then sets a new value for this context based on its on position
27
+ // in the document.
28
+ export const AnnotationsPositionContext = /*#__PURE__*/React.createContext({
29
+ startPos: 1
30
+ });
23
31
  export const AnnotationsWrapper = props => {
24
32
  var _annotationProvider$i, _annotationProvider$i2;
25
33
  const {
@@ -9,6 +9,7 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
9
9
  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) { _defineProperty(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; }
10
10
  import React from 'react';
11
11
  import { MarkType } from '@atlaskit/editor-prosemirror/model';
12
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
12
13
  import { isNestedHeaderLinksEnabled } from './utils/links';
13
14
  import { Doc, DocWithSelectAllTrap, mergeTextNodes, isTextWrapper, isTextNode, toReact } from './nodes';
14
15
  import TextWrapperComponent from './nodes/text-wrapper';
@@ -50,7 +51,6 @@ var ReactSerializer = /*#__PURE__*/function () {
50
51
  _defineProperty(this, "allowWrapCodeBlock", false);
51
52
  _defineProperty(this, "allowPlaceholderText", true);
52
53
  _defineProperty(this, "allowCustomPanels", false);
53
- _defineProperty(this, "startPos", 1);
54
54
  _defineProperty(this, "surroundTextNodesWithTextWrapper", false);
55
55
  _defineProperty(this, "allowAnnotations", false);
56
56
  _defineProperty(this, "serializeFragmentChild", function (node, _ref) {
@@ -154,6 +154,13 @@ var ReactSerializer = /*#__PURE__*/function () {
154
154
  });
155
155
  return props;
156
156
  });
157
+ if (editorExperiment('comment_on_bodied_extensions', true)) {
158
+ this.initStartPos = init.startPos || 1;
159
+ this.startPos = init.startPos || 1;
160
+ } else {
161
+ this.initStartPos = 1;
162
+ this.startPos = 1;
163
+ }
157
164
  this.providers = init.providers;
158
165
  this.eventHandlers = init.eventHandlers;
159
166
  this.extensionHandlers = init.extensionHandlers;
@@ -191,7 +198,7 @@ var ReactSerializer = /*#__PURE__*/function () {
191
198
  value: function resetState() {
192
199
  this.headingIds = [];
193
200
  this.expandHeadingIds = [];
194
- this.startPos = 1;
201
+ this.startPos = this.initStartPos;
195
202
  }
196
203
  }, {
197
204
  key: "getNodeProps",
@@ -524,6 +531,7 @@ var ReactSerializer = /*#__PURE__*/function () {
524
531
  key: "getProps",
525
532
  value: function getProps(node) {
526
533
  var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
534
+ var startPos = this.startPos + path.length;
527
535
  return _objectSpread({
528
536
  text: node.text,
529
537
  providers: this.providers,
@@ -546,8 +554,9 @@ var ReactSerializer = /*#__PURE__*/function () {
546
554
  dataAttributes: {
547
555
  // We need to account for depth (path.length gives up depth) here
548
556
  // but depth doesnt increment the pos, only accounted for.
549
- 'data-renderer-start-pos': this.startPos + path.length
557
+ 'data-renderer-start-pos': startPos
550
558
  },
559
+ startPos: startPos,
551
560
  path: path
552
561
  }, node.attrs);
553
562
  }
@@ -6,6 +6,7 @@ import { ErrorBoundary } from '../../ui/Renderer/ErrorBoundary';
6
6
  import ExtensionRenderer from '../../ui/ExtensionRenderer';
7
7
  import { ACTION_SUBJECT } from '../../analytics/enums';
8
8
  import { ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
9
+ import { AnnotationsPositionContext } from '../../ui/annotations';
9
10
  var BodiedExtension = function BodiedExtension(props) {
10
11
  var children = props.children,
11
12
  _props$layout = props.layout,
@@ -24,6 +25,10 @@ var BodiedExtension = function BodiedExtension(props) {
24
25
  componentId: ACTION_SUBJECT_ID.EXTENSION_BODIED,
25
26
  createAnalyticsEvent: createAnalyticsEvent,
26
27
  additionalInfo: "".concat(extensionType, ": ").concat(extensionKey, " ")
28
+ }, /*#__PURE__*/React.createElement(AnnotationsPositionContext.Provider, {
29
+ value: {
30
+ startPos: props.startPos + 1
31
+ }
27
32
  }, /*#__PURE__*/React.createElement(ExtensionRenderer, _extends({}, props, {
28
33
  type: "bodiedExtension"
29
34
  }), function (_ref) {
@@ -44,6 +49,6 @@ var BodiedExtension = function BodiedExtension(props) {
44
49
  return renderExtension(children, layout, {
45
50
  isTopLevel: path.length < 1
46
51
  }, removeOverflow);
47
- }));
52
+ })));
48
53
  };
49
54
  export default BodiedExtension;
@@ -20,6 +20,7 @@ import { jsx } from '@emotion/react';
20
20
  import { getSchemaBasedOnStage } from '@atlaskit/adf-schema/schema-default';
21
21
  import { reduce } from '@atlaskit/adf-utils/traverse';
22
22
  import { ProviderFactory, ProviderFactoryProvider } from '@atlaskit/editor-common/provider-factory';
23
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
23
24
  import { UnsupportedBlock, BaseTheme, WidthProvider, WithCreateAnalyticsEvent, IntlErrorBoundary } from '@atlaskit/editor-common/ui';
24
25
  import { startMeasure, stopMeasure } from '@atlaskit/editor-common/performance-measures';
25
26
  import { getAnalyticsAppearance, getAnalyticsEventSeverity, shouldForceTracking } from '@atlaskit/editor-common/utils';
@@ -43,7 +44,7 @@ import { Provider as SmartCardStorageProvider } from '../SmartCardStorage';
43
44
  import { BreakoutSSRInlineScript } from './breakout-ssr';
44
45
  import { RendererActionsContext, RendererContext as ActionsContext } from '../RendererActionsContext';
45
46
  import { ActiveHeaderIdProvider } from '../active-header-id-provider';
46
- import { AnnotationsWrapper } from '../annotations';
47
+ import { AnnotationsPositionContext, AnnotationsWrapper } from '../annotations';
47
48
  import { getActiveHeadingId, isNestedHeaderLinksEnabled } from '../../react/utils/links';
48
49
  import { findInTree } from '../../utils';
49
50
  import { isInteractiveElement } from './click-to-edit';
@@ -55,14 +56,18 @@ import { nodeToReact } from '../../react/nodes';
55
56
  export var NORMAL_SEVERITY_THRESHOLD = 2000;
56
57
  export var DEGRADED_SEVERITY_THRESHOLD = 3000;
57
58
  var packageName = "@atlaskit/renderer";
58
- var packageVersion = "111.0.2";
59
+ var packageVersion = "111.1.0";
59
60
  export var defaultNodeComponents = nodeToReact;
60
- export var Renderer = /*#__PURE__*/function (_PureComponent) {
61
- _inherits(Renderer, _PureComponent);
62
- var _super = _createSuper(Renderer);
63
- function Renderer(props) {
61
+
62
+ /**
63
+ * Exported due to enzyme test reliance on this component.
64
+ */
65
+ export var __RendererClassComponent = /*#__PURE__*/function (_PureComponent) {
66
+ _inherits(__RendererClassComponent, _PureComponent);
67
+ var _super = _createSuper(__RendererClassComponent);
68
+ function __RendererClassComponent(props) {
64
69
  var _this;
65
- _classCallCheck(this, Renderer);
70
+ _classCallCheck(this, __RendererClassComponent);
66
71
  _this = _super.call(this, props);
67
72
  /**
68
73
  * This is used in measuring the Renderer Mount time and is then
@@ -161,7 +166,7 @@ export var Renderer = /*#__PURE__*/function (_PureComponent) {
161
166
  }
162
167
  return _this;
163
168
  }
164
- _createClass(Renderer, [{
169
+ _createClass(__RendererClassComponent, [{
165
170
  key: "anchorLinkAnalytics",
166
171
  value: function anchorLinkAnalytics() {
167
172
  var hash = window.location.hash && decodeURIComponent(window.location.hash.slice(1));
@@ -249,6 +254,7 @@ export var Renderer = /*#__PURE__*/function (_PureComponent) {
249
254
  var _this$featureFlags = this.featureFlags(props.featureFlags),
250
255
  featureFlags = _this$featureFlags.featureFlags;
251
256
  return {
257
+ startPos: props.startPos,
252
258
  providers: this.providerFactory,
253
259
  eventHandlers: props.eventHandlers,
254
260
  extensionHandlers: props.extensionHandlers,
@@ -437,8 +443,21 @@ export var Renderer = /*#__PURE__*/function (_PureComponent) {
437
443
  }
438
444
  }
439
445
  }]);
440
- return Renderer;
446
+ return __RendererClassComponent;
441
447
  }(PureComponent);
448
+ export function Renderer(props) {
449
+ var _React$useContext = React.useContext(AnnotationsPositionContext),
450
+ startPos = _React$useContext.startPos;
451
+
452
+ // eslint-disable-next-line react/jsx-pascal-case
453
+ return jsx(__RendererClassComponent, _extends({}, props, {
454
+ startPos: startPos
455
+ }));
456
+ }
457
+
458
+ // Usage notes:
459
+ // Used by Confluence for View page renderer
460
+ // For the nested renderers - see RendererWithAnnotationSelection.
442
461
  export var RendererWithAnalytics = /*#__PURE__*/React.memo(function (props) {
443
462
  return jsx(FabricEditorAnalyticsContext, {
444
463
  data: {
@@ -552,25 +571,54 @@ var RendererWrapper = /*#__PURE__*/React.memo(function (props) {
552
571
  })
553
572
  }, children))));
554
573
  });
574
+ var RootRendererContext = /*#__PURE__*/React.createContext(null);
555
575
  function RendererActionsInternalUpdater(_ref) {
556
576
  var children = _ref.children,
557
577
  doc = _ref.doc,
558
578
  schema = _ref.schema,
559
579
  onAnalyticsEvent = _ref.onAnalyticsEvent;
580
+ var rootRendererContextValue = React.useContext(RootRendererContext);
560
581
  var actions = useContext(ActionsContext);
561
582
  var rendererRef = useRef(null);
583
+
584
+ // This doc is used by the renderer actions when applying comments to the document.
585
+ // (via hand crafted steps based on non prosemirror based position calculations)
586
+ // It is set to the root renderer's doc as otherwise the resulting document will
587
+ // be incorrect (nested renderers use a fake document which represents a subset
588
+ // of the actual document).
589
+ var _doc;
590
+ if (editorExperiment('comment_on_bodied_extensions', true) && rootRendererContextValue) {
591
+ // If rootRendererContextValue is set -- we are inside a nested renderer
592
+ // and should always use the doc from the root renderer
593
+ _doc = rootRendererContextValue.doc;
594
+ } else {
595
+ // If rootRendererContextValue is not set -- we are in the root renderer
596
+ // and set the doc to the current doc.
597
+ _doc = doc;
598
+ }
562
599
  useLayoutEffect(function () {
563
- if (doc) {
564
- actions._privateRegisterRenderer(rendererRef, doc, schema, onAnalyticsEvent);
600
+ if (_doc) {
601
+ actions._privateRegisterRenderer(rendererRef, _doc, schema, onAnalyticsEvent);
565
602
  } else {
566
603
  actions._privateUnregisterRenderer();
567
604
  }
568
605
  return function () {
569
606
  return actions._privateUnregisterRenderer();
570
607
  };
571
- }, [actions, schema, doc, onAnalyticsEvent]);
608
+ }, [actions, schema, _doc, onAnalyticsEvent]);
609
+ if (editorExperiment('comment_on_bodied_extensions', true)) {
610
+ return jsx(RootRendererContext.Provider, {
611
+ value: {
612
+ doc: _doc
613
+ }
614
+ }, children);
615
+ }
572
616
  return children;
573
617
  }
618
+
619
+ // Usage notes:
620
+ // Used by Confluence for nested renderers
621
+ // For the View page renderer - see RendererWithAnalytics
574
622
  var RendererWithAnnotationSelection = function RendererWithAnnotationSelection(props) {
575
623
  var allowAnnotations = props.allowAnnotations,
576
624
  adfDocument = props.document;
@@ -19,6 +19,14 @@ var LoadAnnotations = /*#__PURE__*/React.memo(function (_ref) {
19
19
  });
20
20
  return null;
21
21
  });
22
+
23
+ // This is used by renderers when setting the data-start-pos attribute on commentable nodes
24
+ // By default it is 1 (the possible starting position of any document).
25
+ // The bodied extension component then sets a new value for this context based on its on position
26
+ // in the document.
27
+ export var AnnotationsPositionContext = /*#__PURE__*/React.createContext({
28
+ startPos: 1
29
+ });
22
30
  export var AnnotationsWrapper = function AnnotationsWrapper(props) {
23
31
  var _annotationProvider$i, _annotationProvider$i2;
24
32
  var children = props.children,
@@ -12,6 +12,12 @@ import type { MediaOptions } from '../types/mediaOptions';
12
12
  import type { SmartLinksOptions } from '../types/smartLinksOptions';
13
13
  import type { EmojiResourceConfig } from '@atlaskit/emoji/resource';
14
14
  export interface ReactSerializerInit {
15
+ /**
16
+ * Used for to set positions on nodes for annotations.
17
+ *
18
+ * When not provided defaults to 1.
19
+ */
20
+ startPos?: number;
15
21
  providers?: ProviderFactory;
16
22
  eventHandlers?: EventHandlers;
17
23
  extensionHandlers?: ExtensionHandlers;
@@ -79,6 +85,7 @@ export default class ReactSerializer implements Serializer<JSX.Element> {
79
85
  private allowAltTextOnImages?;
80
86
  private stickyHeaders?;
81
87
  private allowMediaLinking?;
88
+ private initStartPos;
82
89
  private startPos;
83
90
  private surroundTextNodesWithTextWrapper;
84
91
  private media?;
@@ -19,6 +19,7 @@ interface Props {
19
19
  layout?: ExtensionLayout;
20
20
  localId?: string;
21
21
  marks?: PMMark[];
22
+ startPos: number;
22
23
  }
23
24
  declare const BodiedExtension: (props: React.PropsWithChildren<Props>) => JSX.Element;
24
25
  export default BodiedExtension;
@@ -9,7 +9,12 @@ import type { RendererProps } from '../renderer-props';
9
9
  export declare const NORMAL_SEVERITY_THRESHOLD = 2000;
10
10
  export declare const DEGRADED_SEVERITY_THRESHOLD = 3000;
11
11
  export declare const defaultNodeComponents: NodeComponentsProps;
12
- export declare class Renderer extends PureComponent<RendererProps> {
12
+ /**
13
+ * Exported due to enzyme test reliance on this component.
14
+ */
15
+ export declare class __RendererClassComponent extends PureComponent<RendererProps & {
16
+ startPos?: number;
17
+ }> {
13
18
  private providerFactory;
14
19
  private serializer;
15
20
  private editorRef;
@@ -21,10 +26,14 @@ export declare class Renderer extends PureComponent<RendererProps> {
21
26
  * deleted once that measurement occurs.
22
27
  */
23
28
  private renderedMeasurementDistortedDurationMonitor?;
24
- constructor(props: RendererProps);
29
+ constructor(props: RendererProps & {
30
+ startPos: number;
31
+ });
25
32
  private anchorLinkAnalytics;
26
33
  componentDidMount(): void;
27
- UNSAFE_componentWillReceiveProps(nextProps: RendererProps): void;
34
+ UNSAFE_componentWillReceiveProps(nextProps: RendererProps & {
35
+ startPos: number;
36
+ }): void;
28
37
  private deriveSerializerProps;
29
38
  private featureFlags;
30
39
  private fireAnalyticsEvent;
@@ -34,6 +43,7 @@ export declare class Renderer extends PureComponent<RendererProps> {
34
43
  render(): jsx.JSX.Element;
35
44
  componentWillUnmount(): void;
36
45
  }
46
+ export declare function Renderer(props: RendererProps): jsx.JSX.Element;
37
47
  export declare const RendererWithAnalytics: React.MemoExoticComponent<(props: RendererProps) => jsx.JSX.Element>;
38
48
  declare const RendererWithAnnotationSelection: (props: RendererProps) => jsx.JSX.Element;
39
49
  export default RendererWithAnnotationSelection;
@@ -1,5 +1,8 @@
1
- /// <reference types="react" />
1
+ import React from 'react';
2
2
  import { type AnnotationsWrapperProps } from './types';
3
+ export declare const AnnotationsPositionContext: React.Context<{
4
+ startPos: number;
5
+ }>;
3
6
  export declare const AnnotationsWrapper: (props: AnnotationsWrapperProps) => JSX.Element;
4
7
  export { TextWithAnnotationDraft } from './draft';
5
8
  export { MarkElement as AnnotationMark } from './element';
@@ -15,10 +15,18 @@ export type AnnotationsWrapperProps = React.PropsWithChildren<{
15
15
  adfDocument: JSONDocNode;
16
16
  annotationProvider: AnnotationProviders | null | undefined;
17
17
  rendererRef: React.RefObject<HTMLDivElement>;
18
+ /**
19
+ * This is set (by consumers) for nested renderers when they are
20
+ * rendering bodied extension content.
21
+ */
18
22
  isNestedRender: boolean;
19
23
  onLoadComplete?: ({ numberOfUnresolvedInlineComments, }: {
20
24
  numberOfUnresolvedInlineComments: number;
21
25
  }) => void;
26
+ /**
27
+ * This is set internally -- and should not be set by consumers.
28
+ */
29
+ _startPos?: number;
22
30
  }>;
23
31
  export type TextPosition = {
24
32
  start: number;
@@ -12,6 +12,12 @@ import type { MediaOptions } from '../types/mediaOptions';
12
12
  import type { SmartLinksOptions } from '../types/smartLinksOptions';
13
13
  import type { EmojiResourceConfig } from '@atlaskit/emoji/resource';
14
14
  export interface ReactSerializerInit {
15
+ /**
16
+ * Used for to set positions on nodes for annotations.
17
+ *
18
+ * When not provided defaults to 1.
19
+ */
20
+ startPos?: number;
15
21
  providers?: ProviderFactory;
16
22
  eventHandlers?: EventHandlers;
17
23
  extensionHandlers?: ExtensionHandlers;
@@ -79,6 +85,7 @@ export default class ReactSerializer implements Serializer<JSX.Element> {
79
85
  private allowAltTextOnImages?;
80
86
  private stickyHeaders?;
81
87
  private allowMediaLinking?;
88
+ private initStartPos;
82
89
  private startPos;
83
90
  private surroundTextNodesWithTextWrapper;
84
91
  private media?;
@@ -19,6 +19,7 @@ interface Props {
19
19
  layout?: ExtensionLayout;
20
20
  localId?: string;
21
21
  marks?: PMMark[];
22
+ startPos: number;
22
23
  }
23
24
  declare const BodiedExtension: (props: React.PropsWithChildren<Props>) => JSX.Element;
24
25
  export default BodiedExtension;
@@ -9,7 +9,12 @@ import type { RendererProps } from '../renderer-props';
9
9
  export declare const NORMAL_SEVERITY_THRESHOLD = 2000;
10
10
  export declare const DEGRADED_SEVERITY_THRESHOLD = 3000;
11
11
  export declare const defaultNodeComponents: NodeComponentsProps;
12
- export declare class Renderer extends PureComponent<RendererProps> {
12
+ /**
13
+ * Exported due to enzyme test reliance on this component.
14
+ */
15
+ export declare class __RendererClassComponent extends PureComponent<RendererProps & {
16
+ startPos?: number;
17
+ }> {
13
18
  private providerFactory;
14
19
  private serializer;
15
20
  private editorRef;
@@ -21,10 +26,14 @@ export declare class Renderer extends PureComponent<RendererProps> {
21
26
  * deleted once that measurement occurs.
22
27
  */
23
28
  private renderedMeasurementDistortedDurationMonitor?;
24
- constructor(props: RendererProps);
29
+ constructor(props: RendererProps & {
30
+ startPos: number;
31
+ });
25
32
  private anchorLinkAnalytics;
26
33
  componentDidMount(): void;
27
- UNSAFE_componentWillReceiveProps(nextProps: RendererProps): void;
34
+ UNSAFE_componentWillReceiveProps(nextProps: RendererProps & {
35
+ startPos: number;
36
+ }): void;
28
37
  private deriveSerializerProps;
29
38
  private featureFlags;
30
39
  private fireAnalyticsEvent;
@@ -34,6 +43,7 @@ export declare class Renderer extends PureComponent<RendererProps> {
34
43
  render(): jsx.JSX.Element;
35
44
  componentWillUnmount(): void;
36
45
  }
46
+ export declare function Renderer(props: RendererProps): jsx.JSX.Element;
37
47
  export declare const RendererWithAnalytics: React.MemoExoticComponent<(props: RendererProps) => jsx.JSX.Element>;
38
48
  declare const RendererWithAnnotationSelection: (props: RendererProps) => jsx.JSX.Element;
39
49
  export default RendererWithAnnotationSelection;
@@ -1,5 +1,8 @@
1
- /// <reference types="react" />
1
+ import React from 'react';
2
2
  import { type AnnotationsWrapperProps } from './types';
3
+ export declare const AnnotationsPositionContext: React.Context<{
4
+ startPos: number;
5
+ }>;
3
6
  export declare const AnnotationsWrapper: (props: AnnotationsWrapperProps) => JSX.Element;
4
7
  export { TextWithAnnotationDraft } from './draft';
5
8
  export { MarkElement as AnnotationMark } from './element';
@@ -15,10 +15,18 @@ export type AnnotationsWrapperProps = React.PropsWithChildren<{
15
15
  adfDocument: JSONDocNode;
16
16
  annotationProvider: AnnotationProviders | null | undefined;
17
17
  rendererRef: React.RefObject<HTMLDivElement>;
18
+ /**
19
+ * This is set (by consumers) for nested renderers when they are
20
+ * rendering bodied extension content.
21
+ */
18
22
  isNestedRender: boolean;
19
23
  onLoadComplete?: ({ numberOfUnresolvedInlineComments, }: {
20
24
  numberOfUnresolvedInlineComments: number;
21
25
  }) => void;
26
+ /**
27
+ * This is set internally -- and should not be set by consumers.
28
+ */
29
+ _startPos?: number;
22
30
  }>;
23
31
  export type TextPosition = {
24
32
  start: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/renderer",
3
- "version": "111.0.2",
3
+ "version": "111.1.0",
4
4
  "description": "Renderer component",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"