@atlaskit/renderer 133.4.2 → 133.4.4
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 +18 -0
- package/dist/cjs/react/index.js +3 -1
- package/dist/cjs/react/nodes/codeBlock/components/codeBlockDownloadButton.js +21 -2
- package/dist/cjs/react/nodes/heading.js +18 -3
- package/dist/cjs/ui/Renderer/index.js +2 -1
- package/dist/es2019/react/index.js +3 -1
- package/dist/es2019/react/nodes/codeBlock/components/codeBlockDownloadButton.js +19 -2
- package/dist/es2019/react/nodes/heading.js +15 -3
- package/dist/es2019/ui/Renderer/index.js +2 -1
- package/dist/esm/react/index.js +3 -1
- package/dist/esm/react/nodes/codeBlock/components/codeBlockDownloadButton.js +21 -2
- package/dist/esm/react/nodes/heading.js +18 -3
- package/dist/esm/ui/Renderer/index.js +2 -1
- package/dist/types/react/index.d.ts +2 -0
- package/dist/types/ui/Renderer/types.d.ts +1 -0
- package/dist/types/ui/renderer-props.d.ts +5 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @atlaskit/renderer
|
|
2
2
|
|
|
3
|
+
## 133.4.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`29e91091708d1`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/29e91091708d1) -
|
|
8
|
+
Add headingIdPrefix and custom heading-link copy support for nested renderers to namespace
|
|
9
|
+
generated heading IDs and copy canonical page links.
|
|
10
|
+
- Updated dependencies
|
|
11
|
+
|
|
12
|
+
## 133.4.3
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- [`db98e2e76d7f9`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/db98e2e76d7f9) -
|
|
17
|
+
Improve code block download filename suggestion. Filenames are now derived from comment lines
|
|
18
|
+
(e.g. `# cats.py`), fence marker filenames (e.g. ` ```python cats.py `), or fall back to
|
|
19
|
+
`rovo-snippet.<ext>`.
|
|
20
|
+
|
|
3
21
|
## 133.4.2
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/dist/cjs/react/index.js
CHANGED
|
@@ -195,6 +195,7 @@ var ReactSerializer = exports.default = /*#__PURE__*/function () {
|
|
|
195
195
|
this.appearance = init.appearance;
|
|
196
196
|
this.contentMode = init.contentMode;
|
|
197
197
|
this.disableHeadingIDs = init.disableHeadingIDs;
|
|
198
|
+
this.headingIdPrefix = init.headingIdPrefix;
|
|
198
199
|
this.disableActions = init.disableActions;
|
|
199
200
|
this.allowHeadingAnchorLinks = init.allowHeadingAnchorLinks;
|
|
200
201
|
this.allowCopyToClipboard = init.allowCopyToClipboard;
|
|
@@ -769,7 +770,8 @@ var ReactSerializer = exports.default = /*#__PURE__*/function () {
|
|
|
769
770
|
if (!nodeContent) {
|
|
770
771
|
return;
|
|
771
772
|
}
|
|
772
|
-
|
|
773
|
+
var uniqueId = this.getUniqueHeadingId(nodeContent, headingIds);
|
|
774
|
+
return this.headingIdPrefix ? "".concat(this.headingIdPrefix, "-").concat(uniqueId) : uniqueId;
|
|
773
775
|
}
|
|
774
776
|
}, {
|
|
775
777
|
key: "getUniqueHeadingId",
|
|
@@ -67,13 +67,32 @@ var getFileExtension = function getFileExtension(language) {
|
|
|
67
67
|
}
|
|
68
68
|
return (_languageToExtension$ = languageToExtension[language.toLowerCase()]) !== null && _languageToExtension$ !== void 0 ? _languageToExtension$ : 'txt';
|
|
69
69
|
};
|
|
70
|
+
var suggestBaseName = function suggestBaseName(content) {
|
|
71
|
+
var _content$split$find;
|
|
72
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
73
|
+
var filenameCommentPattern = /^(?:#|\/\/|<!--)\s*([\w.\-]+)\s*(?:-->)?$/;
|
|
74
|
+
var firstMeaningfulLine = (_content$split$find = content.split('\n').find(function (l) {
|
|
75
|
+
return l.trim();
|
|
76
|
+
})) !== null && _content$split$find !== void 0 ? _content$split$find : '';
|
|
77
|
+
var filenameMatch = firstMeaningfulLine.trim().match(filenameCommentPattern);
|
|
78
|
+
if (filenameMatch) {
|
|
79
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
80
|
+
return filenameMatch[1].replace(/\.[^.]+$/, '') || 'rovo-snippet';
|
|
81
|
+
}
|
|
82
|
+
var cleaned = firstMeaningfulLine
|
|
83
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
84
|
+
.replace(/[^a-zA-Z0-9\s]/g, ' ').trim()
|
|
85
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
86
|
+
.replace(/\s+/g, '-').toLowerCase().slice(0, 30);
|
|
87
|
+
return cleaned || 'rovo-snippet';
|
|
88
|
+
};
|
|
70
89
|
var triggerDownload = function triggerDownload(content, language) {
|
|
71
90
|
// eslint-disable-next-line @atlaskit/platform/no-direct-document-usage
|
|
72
91
|
if (typeof document === 'undefined') {
|
|
73
92
|
return;
|
|
74
93
|
}
|
|
75
94
|
var extension = getFileExtension(language);
|
|
76
|
-
var
|
|
95
|
+
var resolvedFilename = "".concat(suggestBaseName(content), ".").concat(extension);
|
|
77
96
|
// eslint-disable-next-line @atlaskit/platform/no-direct-document-usage
|
|
78
97
|
var doc = document;
|
|
79
98
|
var blob = new Blob([content], {
|
|
@@ -82,7 +101,7 @@ var triggerDownload = function triggerDownload(content, language) {
|
|
|
82
101
|
var url = URL.createObjectURL(blob);
|
|
83
102
|
var anchor = doc.createElement('a');
|
|
84
103
|
anchor.href = url;
|
|
85
|
-
anchor.download =
|
|
104
|
+
anchor.download = resolvedFilename;
|
|
86
105
|
anchor.style.display = 'none';
|
|
87
106
|
doc.body.appendChild(anchor);
|
|
88
107
|
anchor.dispatchEvent(new MouseEvent('click', {
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.default = void 0;
|
|
8
|
+
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
8
9
|
var _react = _interopRequireDefault(require("react"));
|
|
9
10
|
var _interactionMetrics = require("@atlaskit/react-ufo/interaction-metrics");
|
|
10
11
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
@@ -45,8 +46,12 @@ var wrapperStyles = (0, _react2.css)({
|
|
|
45
46
|
// last character of the heading (i.e. after the final wrapped line), so we use normal inline flow.
|
|
46
47
|
display: 'block'
|
|
47
48
|
});
|
|
49
|
+
var getHeadingAnchorLinksConfig = function getHeadingAnchorLinksConfig(allowHeadingAnchorLinks) {
|
|
50
|
+
return (0, _typeof2.default)(allowHeadingAnchorLinks) === 'object' ? allowHeadingAnchorLinks : undefined;
|
|
51
|
+
};
|
|
48
52
|
function WrappedHeadingAnchor(_ref) {
|
|
49
53
|
var enableNestedHeaderLinks = _ref.enableNestedHeaderLinks,
|
|
54
|
+
getHeadingLink = _ref.getHeadingLink,
|
|
50
55
|
level = _ref.level,
|
|
51
56
|
headingId = _ref.headingId,
|
|
52
57
|
hideFromScreenReader = _ref.hideFromScreenReader;
|
|
@@ -58,13 +63,14 @@ function WrappedHeadingAnchor(_ref) {
|
|
|
58
63
|
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
|
|
59
64
|
,
|
|
60
65
|
onCopyText: function onCopyText() {
|
|
66
|
+
var _getHeadingLink;
|
|
61
67
|
fireAnalyticsEvent({
|
|
62
68
|
action: _analytics.ACTION.CLICKED,
|
|
63
69
|
actionSubject: _analytics.ACTION_SUBJECT.BUTTON,
|
|
64
70
|
actionSubjectId: _analytics.ACTION_SUBJECT_ID.HEADING_ANCHOR_LINK,
|
|
65
71
|
eventType: _analytics.EVENT_TYPE.UI
|
|
66
72
|
});
|
|
67
|
-
return (0, _clipboard.copyTextToClipboard)(getCurrentUrlWithHash(headingId));
|
|
73
|
+
return (0, _clipboard.copyTextToClipboard)((_getHeadingLink = getHeadingLink === null || getHeadingLink === void 0 ? void 0 : getHeadingLink(headingId)) !== null && _getHeadingLink !== void 0 ? _getHeadingLink : getCurrentUrlWithHash(headingId));
|
|
68
74
|
},
|
|
69
75
|
hideFromScreenReader: hideFromScreenReader,
|
|
70
76
|
headingId: headingId
|
|
@@ -90,7 +96,9 @@ function HeadingWithDuplicateAnchor(props) {
|
|
|
90
96
|
var mouseEntered = _react.default.useRef(false);
|
|
91
97
|
var showAnchorLink = !!props.showAnchorLink;
|
|
92
98
|
var isRightAligned = hasRightAlignmentMark(marks);
|
|
93
|
-
var
|
|
99
|
+
var headingAnchorLinksConfig = getHeadingAnchorLinksConfig(allowHeadingAnchorLinks);
|
|
100
|
+
var enableNestedHeaderLinks = headingAnchorLinksConfig === null || headingAnchorLinksConfig === void 0 ? void 0 : headingAnchorLinksConfig.allowNestedHeaderLinks;
|
|
101
|
+
var getHeadingLink = headingAnchorLinksConfig === null || headingAnchorLinksConfig === void 0 ? void 0 : headingAnchorLinksConfig.getHeadingLink;
|
|
94
102
|
var headingIdToUse = invisible ? undefined : headingId;
|
|
95
103
|
var mouseEnterHandler = function mouseEnterHandler() {
|
|
96
104
|
if (showAnchorLink && !mouseEntered.current) {
|
|
@@ -111,11 +119,13 @@ function HeadingWithDuplicateAnchor(props) {
|
|
|
111
119
|
}, (0, _react2.jsx)(_react.default.Fragment, null, showAnchorLink && headingId && isRightAligned && (0, _react2.jsx)(WrappedHeadingAnchor, {
|
|
112
120
|
level: props.level,
|
|
113
121
|
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
122
|
+
getHeadingLink: getHeadingLink,
|
|
114
123
|
headingId: headingId,
|
|
115
124
|
hideFromScreenReader: true
|
|
116
125
|
}), props.children, showAnchorLink && headingId && !isRightAligned && (0, _react2.jsx)(WrappedHeadingAnchor, {
|
|
117
126
|
level: props.level,
|
|
118
127
|
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
128
|
+
getHeadingLink: getHeadingLink,
|
|
119
129
|
headingId: headingId,
|
|
120
130
|
hideFromScreenReader: true
|
|
121
131
|
}))), (0, _react2.jsx)(_visuallyHidden.default, {
|
|
@@ -123,6 +133,7 @@ function HeadingWithDuplicateAnchor(props) {
|
|
|
123
133
|
}, showAnchorLink && headingId && (0, _react2.jsx)(WrappedHeadingAnchor, {
|
|
124
134
|
level: props.level,
|
|
125
135
|
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
136
|
+
getHeadingLink: getHeadingLink,
|
|
126
137
|
headingId: headingId
|
|
127
138
|
})));
|
|
128
139
|
}
|
|
@@ -145,7 +156,9 @@ function HeadingWithWrapper(props) {
|
|
|
145
156
|
var mouseEntered = _react.default.useRef(false);
|
|
146
157
|
var showAnchorLink = !!props.showAnchorLink;
|
|
147
158
|
var isRightAligned = hasRightAlignmentMark(marks);
|
|
148
|
-
var
|
|
159
|
+
var headingAnchorLinksConfig = getHeadingAnchorLinksConfig(allowHeadingAnchorLinks);
|
|
160
|
+
var enableNestedHeaderLinks = headingAnchorLinksConfig === null || headingAnchorLinksConfig === void 0 ? void 0 : headingAnchorLinksConfig.allowNestedHeaderLinks;
|
|
161
|
+
var getHeadingLink = headingAnchorLinksConfig === null || headingAnchorLinksConfig === void 0 ? void 0 : headingAnchorLinksConfig.getHeadingLink;
|
|
149
162
|
var headingIdToUse = invisible ? undefined : headingId;
|
|
150
163
|
var mouseEnterHandler = function mouseEnterHandler() {
|
|
151
164
|
if (showAnchorLink && !mouseEntered.current) {
|
|
@@ -165,6 +178,7 @@ function HeadingWithWrapper(props) {
|
|
|
165
178
|
}, showAnchorLink && headingId && isRightAligned && (0, _react2.jsx)(WrappedHeadingAnchor, {
|
|
166
179
|
level: props.level,
|
|
167
180
|
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
181
|
+
getHeadingLink: getHeadingLink,
|
|
168
182
|
headingId: headingId,
|
|
169
183
|
hideFromScreenReader: false
|
|
170
184
|
}), (0, _react2.jsx)(HX, {
|
|
@@ -177,6 +191,7 @@ function HeadingWithWrapper(props) {
|
|
|
177
191
|
}, props.children), showAnchorLink && headingId && !isRightAligned && (0, _react2.jsx)(WrappedHeadingAnchor, {
|
|
178
192
|
level: props.level,
|
|
179
193
|
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
194
|
+
getHeadingLink: getHeadingLink,
|
|
180
195
|
headingId: headingId,
|
|
181
196
|
hideFromScreenReader: false
|
|
182
197
|
}));
|
|
@@ -72,7 +72,7 @@ var DEGRADED_SEVERITY_THRESHOLD = exports.DEGRADED_SEVERITY_THRESHOLD = 3000;
|
|
|
72
72
|
var TABLE_INFO_TIMEOUT = 10000;
|
|
73
73
|
var RENDER_EVENT_SAMPLE_RATE = 0.2;
|
|
74
74
|
var packageName = "@atlaskit/renderer";
|
|
75
|
-
var packageVersion = "133.4.
|
|
75
|
+
var packageVersion = "133.4.3";
|
|
76
76
|
var setAsQueryContainerStyles = (0, _react2.css)({
|
|
77
77
|
containerName: 'ak-renderer-wrapper',
|
|
78
78
|
containerType: 'inline-size'
|
|
@@ -248,6 +248,7 @@ var RendererFunctionalComponent = exports.RendererFunctionalComponent = function
|
|
|
248
248
|
contentMode: props.contentMode,
|
|
249
249
|
onSetLinkTarget: props.onSetLinkTarget,
|
|
250
250
|
disableHeadingIDs: props.disableHeadingIDs,
|
|
251
|
+
headingIdPrefix: props.headingIdPrefix,
|
|
251
252
|
disableActions: props.disableActions,
|
|
252
253
|
allowHeadingAnchorLinks: props.allowHeadingAnchorLinks,
|
|
253
254
|
allowColumnSorting: props.allowColumnSorting,
|
|
@@ -182,6 +182,7 @@ export default class ReactSerializer {
|
|
|
182
182
|
this.appearance = init.appearance;
|
|
183
183
|
this.contentMode = init.contentMode;
|
|
184
184
|
this.disableHeadingIDs = init.disableHeadingIDs;
|
|
185
|
+
this.headingIdPrefix = init.headingIdPrefix;
|
|
185
186
|
this.disableActions = init.disableActions;
|
|
186
187
|
this.allowHeadingAnchorLinks = init.allowHeadingAnchorLinks;
|
|
187
188
|
this.allowCopyToClipboard = init.allowCopyToClipboard;
|
|
@@ -685,7 +686,8 @@ export default class ReactSerializer {
|
|
|
685
686
|
if (!nodeContent) {
|
|
686
687
|
return;
|
|
687
688
|
}
|
|
688
|
-
|
|
689
|
+
const uniqueId = this.getUniqueHeadingId(nodeContent, headingIds);
|
|
690
|
+
return this.headingIdPrefix ? `${this.headingIdPrefix}-${uniqueId}` : uniqueId;
|
|
689
691
|
}
|
|
690
692
|
getUniqueHeadingId(baseId, headingIds, counter = 0) {
|
|
691
693
|
if (counter === 0 && headingIds.indexOf(baseId) === -1) {
|
|
@@ -59,13 +59,30 @@ const getFileExtension = language => {
|
|
|
59
59
|
}
|
|
60
60
|
return (_languageToExtension$ = languageToExtension[language.toLowerCase()]) !== null && _languageToExtension$ !== void 0 ? _languageToExtension$ : 'txt';
|
|
61
61
|
};
|
|
62
|
+
const suggestBaseName = content => {
|
|
63
|
+
var _content$split$find;
|
|
64
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
65
|
+
const filenameCommentPattern = /^(?:#|\/\/|<!--)\s*([\w.\-]+)\s*(?:-->)?$/;
|
|
66
|
+
const firstMeaningfulLine = (_content$split$find = content.split('\n').find(l => l.trim())) !== null && _content$split$find !== void 0 ? _content$split$find : '';
|
|
67
|
+
const filenameMatch = firstMeaningfulLine.trim().match(filenameCommentPattern);
|
|
68
|
+
if (filenameMatch) {
|
|
69
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
70
|
+
return filenameMatch[1].replace(/\.[^.]+$/, '') || 'rovo-snippet';
|
|
71
|
+
}
|
|
72
|
+
const cleaned = firstMeaningfulLine
|
|
73
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
74
|
+
.replace(/[^a-zA-Z0-9\s]/g, ' ').trim()
|
|
75
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
76
|
+
.replace(/\s+/g, '-').toLowerCase().slice(0, 30);
|
|
77
|
+
return cleaned || 'rovo-snippet';
|
|
78
|
+
};
|
|
62
79
|
const triggerDownload = (content, language) => {
|
|
63
80
|
// eslint-disable-next-line @atlaskit/platform/no-direct-document-usage
|
|
64
81
|
if (typeof document === 'undefined') {
|
|
65
82
|
return;
|
|
66
83
|
}
|
|
67
84
|
const extension = getFileExtension(language);
|
|
68
|
-
const
|
|
85
|
+
const resolvedFilename = `${suggestBaseName(content)}.${extension}`;
|
|
69
86
|
// eslint-disable-next-line @atlaskit/platform/no-direct-document-usage
|
|
70
87
|
const doc = document;
|
|
71
88
|
const blob = new Blob([content], {
|
|
@@ -74,7 +91,7 @@ const triggerDownload = (content, language) => {
|
|
|
74
91
|
const url = URL.createObjectURL(blob);
|
|
75
92
|
const anchor = doc.createElement('a');
|
|
76
93
|
anchor.href = url;
|
|
77
|
-
anchor.download =
|
|
94
|
+
anchor.download = resolvedFilename;
|
|
78
95
|
anchor.style.display = 'none';
|
|
79
96
|
doc.body.appendChild(anchor);
|
|
80
97
|
anchor.dispatchEvent(new MouseEvent('click', {
|
|
@@ -33,8 +33,10 @@ const wrapperStyles = css({
|
|
|
33
33
|
// last character of the heading (i.e. after the final wrapped line), so we use normal inline flow.
|
|
34
34
|
display: 'block'
|
|
35
35
|
});
|
|
36
|
+
const getHeadingAnchorLinksConfig = allowHeadingAnchorLinks => typeof allowHeadingAnchorLinks === 'object' ? allowHeadingAnchorLinks : undefined;
|
|
36
37
|
function WrappedHeadingAnchor({
|
|
37
38
|
enableNestedHeaderLinks,
|
|
39
|
+
getHeadingLink,
|
|
38
40
|
level,
|
|
39
41
|
headingId,
|
|
40
42
|
hideFromScreenReader
|
|
@@ -47,13 +49,14 @@ function WrappedHeadingAnchor({
|
|
|
47
49
|
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
|
|
48
50
|
,
|
|
49
51
|
onCopyText: () => {
|
|
52
|
+
var _getHeadingLink;
|
|
50
53
|
fireAnalyticsEvent({
|
|
51
54
|
action: ACTION.CLICKED,
|
|
52
55
|
actionSubject: ACTION_SUBJECT.BUTTON,
|
|
53
56
|
actionSubjectId: ACTION_SUBJECT_ID.HEADING_ANCHOR_LINK,
|
|
54
57
|
eventType: EVENT_TYPE.UI
|
|
55
58
|
});
|
|
56
|
-
return copyTextToClipboard(getCurrentUrlWithHash(headingId));
|
|
59
|
+
return copyTextToClipboard((_getHeadingLink = getHeadingLink === null || getHeadingLink === void 0 ? void 0 : getHeadingLink(headingId)) !== null && _getHeadingLink !== void 0 ? _getHeadingLink : getCurrentUrlWithHash(headingId));
|
|
57
60
|
},
|
|
58
61
|
hideFromScreenReader: hideFromScreenReader,
|
|
59
62
|
headingId: headingId
|
|
@@ -80,7 +83,9 @@ function HeadingWithDuplicateAnchor(props) {
|
|
|
80
83
|
const mouseEntered = React.useRef(false);
|
|
81
84
|
const showAnchorLink = !!props.showAnchorLink;
|
|
82
85
|
const isRightAligned = hasRightAlignmentMark(marks);
|
|
83
|
-
const
|
|
86
|
+
const headingAnchorLinksConfig = getHeadingAnchorLinksConfig(allowHeadingAnchorLinks);
|
|
87
|
+
const enableNestedHeaderLinks = headingAnchorLinksConfig === null || headingAnchorLinksConfig === void 0 ? void 0 : headingAnchorLinksConfig.allowNestedHeaderLinks;
|
|
88
|
+
const getHeadingLink = headingAnchorLinksConfig === null || headingAnchorLinksConfig === void 0 ? void 0 : headingAnchorLinksConfig.getHeadingLink;
|
|
84
89
|
const headingIdToUse = invisible ? undefined : headingId;
|
|
85
90
|
const mouseEnterHandler = () => {
|
|
86
91
|
if (showAnchorLink && !mouseEntered.current) {
|
|
@@ -101,11 +106,13 @@ function HeadingWithDuplicateAnchor(props) {
|
|
|
101
106
|
}, jsx(React.Fragment, null, showAnchorLink && headingId && isRightAligned && jsx(WrappedHeadingAnchor, {
|
|
102
107
|
level: props.level,
|
|
103
108
|
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
109
|
+
getHeadingLink: getHeadingLink,
|
|
104
110
|
headingId: headingId,
|
|
105
111
|
hideFromScreenReader: true
|
|
106
112
|
}), props.children, showAnchorLink && headingId && !isRightAligned && jsx(WrappedHeadingAnchor, {
|
|
107
113
|
level: props.level,
|
|
108
114
|
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
115
|
+
getHeadingLink: getHeadingLink,
|
|
109
116
|
headingId: headingId,
|
|
110
117
|
hideFromScreenReader: true
|
|
111
118
|
}))), jsx(VisuallyHidden, {
|
|
@@ -113,6 +120,7 @@ function HeadingWithDuplicateAnchor(props) {
|
|
|
113
120
|
}, showAnchorLink && headingId && jsx(WrappedHeadingAnchor, {
|
|
114
121
|
level: props.level,
|
|
115
122
|
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
123
|
+
getHeadingLink: getHeadingLink,
|
|
116
124
|
headingId: headingId
|
|
117
125
|
})));
|
|
118
126
|
}
|
|
@@ -137,7 +145,9 @@ function HeadingWithWrapper(props) {
|
|
|
137
145
|
const mouseEntered = React.useRef(false);
|
|
138
146
|
const showAnchorLink = !!props.showAnchorLink;
|
|
139
147
|
const isRightAligned = hasRightAlignmentMark(marks);
|
|
140
|
-
const
|
|
148
|
+
const headingAnchorLinksConfig = getHeadingAnchorLinksConfig(allowHeadingAnchorLinks);
|
|
149
|
+
const enableNestedHeaderLinks = headingAnchorLinksConfig === null || headingAnchorLinksConfig === void 0 ? void 0 : headingAnchorLinksConfig.allowNestedHeaderLinks;
|
|
150
|
+
const getHeadingLink = headingAnchorLinksConfig === null || headingAnchorLinksConfig === void 0 ? void 0 : headingAnchorLinksConfig.getHeadingLink;
|
|
141
151
|
const headingIdToUse = invisible ? undefined : headingId;
|
|
142
152
|
const mouseEnterHandler = () => {
|
|
143
153
|
if (showAnchorLink && !mouseEntered.current) {
|
|
@@ -157,6 +167,7 @@ function HeadingWithWrapper(props) {
|
|
|
157
167
|
}, showAnchorLink && headingId && isRightAligned && jsx(WrappedHeadingAnchor, {
|
|
158
168
|
level: props.level,
|
|
159
169
|
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
170
|
+
getHeadingLink: getHeadingLink,
|
|
160
171
|
headingId: headingId,
|
|
161
172
|
hideFromScreenReader: false
|
|
162
173
|
}), jsx(HX, {
|
|
@@ -169,6 +180,7 @@ function HeadingWithWrapper(props) {
|
|
|
169
180
|
}, props.children), showAnchorLink && headingId && !isRightAligned && jsx(WrappedHeadingAnchor, {
|
|
170
181
|
level: props.level,
|
|
171
182
|
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
183
|
+
getHeadingLink: getHeadingLink,
|
|
172
184
|
headingId: headingId,
|
|
173
185
|
hideFromScreenReader: false
|
|
174
186
|
}));
|
|
@@ -58,7 +58,7 @@ export const DEGRADED_SEVERITY_THRESHOLD = 3000;
|
|
|
58
58
|
const TABLE_INFO_TIMEOUT = 10000;
|
|
59
59
|
const RENDER_EVENT_SAMPLE_RATE = 0.2;
|
|
60
60
|
const packageName = "@atlaskit/renderer";
|
|
61
|
-
const packageVersion = "133.4.
|
|
61
|
+
const packageVersion = "133.4.3";
|
|
62
62
|
const setAsQueryContainerStyles = css({
|
|
63
63
|
containerName: 'ak-renderer-wrapper',
|
|
64
64
|
containerType: 'inline-size'
|
|
@@ -240,6 +240,7 @@ export const RendererFunctionalComponent = props => {
|
|
|
240
240
|
contentMode: props.contentMode,
|
|
241
241
|
onSetLinkTarget: props.onSetLinkTarget,
|
|
242
242
|
disableHeadingIDs: props.disableHeadingIDs,
|
|
243
|
+
headingIdPrefix: props.headingIdPrefix,
|
|
243
244
|
disableActions: props.disableActions,
|
|
244
245
|
allowHeadingAnchorLinks: props.allowHeadingAnchorLinks,
|
|
245
246
|
allowColumnSorting: props.allowColumnSorting,
|
package/dist/esm/react/index.js
CHANGED
|
@@ -188,6 +188,7 @@ var ReactSerializer = /*#__PURE__*/function () {
|
|
|
188
188
|
this.appearance = init.appearance;
|
|
189
189
|
this.contentMode = init.contentMode;
|
|
190
190
|
this.disableHeadingIDs = init.disableHeadingIDs;
|
|
191
|
+
this.headingIdPrefix = init.headingIdPrefix;
|
|
191
192
|
this.disableActions = init.disableActions;
|
|
192
193
|
this.allowHeadingAnchorLinks = init.allowHeadingAnchorLinks;
|
|
193
194
|
this.allowCopyToClipboard = init.allowCopyToClipboard;
|
|
@@ -762,7 +763,8 @@ var ReactSerializer = /*#__PURE__*/function () {
|
|
|
762
763
|
if (!nodeContent) {
|
|
763
764
|
return;
|
|
764
765
|
}
|
|
765
|
-
|
|
766
|
+
var uniqueId = this.getUniqueHeadingId(nodeContent, headingIds);
|
|
767
|
+
return this.headingIdPrefix ? "".concat(this.headingIdPrefix, "-").concat(uniqueId) : uniqueId;
|
|
766
768
|
}
|
|
767
769
|
}, {
|
|
768
770
|
key: "getUniqueHeadingId",
|
|
@@ -59,13 +59,32 @@ var getFileExtension = function getFileExtension(language) {
|
|
|
59
59
|
}
|
|
60
60
|
return (_languageToExtension$ = languageToExtension[language.toLowerCase()]) !== null && _languageToExtension$ !== void 0 ? _languageToExtension$ : 'txt';
|
|
61
61
|
};
|
|
62
|
+
var suggestBaseName = function suggestBaseName(content) {
|
|
63
|
+
var _content$split$find;
|
|
64
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
65
|
+
var filenameCommentPattern = /^(?:#|\/\/|<!--)\s*([\w.\-]+)\s*(?:-->)?$/;
|
|
66
|
+
var firstMeaningfulLine = (_content$split$find = content.split('\n').find(function (l) {
|
|
67
|
+
return l.trim();
|
|
68
|
+
})) !== null && _content$split$find !== void 0 ? _content$split$find : '';
|
|
69
|
+
var filenameMatch = firstMeaningfulLine.trim().match(filenameCommentPattern);
|
|
70
|
+
if (filenameMatch) {
|
|
71
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
72
|
+
return filenameMatch[1].replace(/\.[^.]+$/, '') || 'rovo-snippet';
|
|
73
|
+
}
|
|
74
|
+
var cleaned = firstMeaningfulLine
|
|
75
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
76
|
+
.replace(/[^a-zA-Z0-9\s]/g, ' ').trim()
|
|
77
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
78
|
+
.replace(/\s+/g, '-').toLowerCase().slice(0, 30);
|
|
79
|
+
return cleaned || 'rovo-snippet';
|
|
80
|
+
};
|
|
62
81
|
var triggerDownload = function triggerDownload(content, language) {
|
|
63
82
|
// eslint-disable-next-line @atlaskit/platform/no-direct-document-usage
|
|
64
83
|
if (typeof document === 'undefined') {
|
|
65
84
|
return;
|
|
66
85
|
}
|
|
67
86
|
var extension = getFileExtension(language);
|
|
68
|
-
var
|
|
87
|
+
var resolvedFilename = "".concat(suggestBaseName(content), ".").concat(extension);
|
|
69
88
|
// eslint-disable-next-line @atlaskit/platform/no-direct-document-usage
|
|
70
89
|
var doc = document;
|
|
71
90
|
var blob = new Blob([content], {
|
|
@@ -74,7 +93,7 @@ var triggerDownload = function triggerDownload(content, language) {
|
|
|
74
93
|
var url = URL.createObjectURL(blob);
|
|
75
94
|
var anchor = doc.createElement('a');
|
|
76
95
|
anchor.href = url;
|
|
77
|
-
anchor.download =
|
|
96
|
+
anchor.download = resolvedFilename;
|
|
78
97
|
anchor.style.display = 'none';
|
|
79
98
|
doc.body.appendChild(anchor);
|
|
80
99
|
anchor.dispatchEvent(new MouseEvent('click', {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _typeof from "@babel/runtime/helpers/typeof";
|
|
1
2
|
/**
|
|
2
3
|
* @jsxRuntime classic
|
|
3
4
|
* @jsx jsx
|
|
@@ -36,8 +37,12 @@ var wrapperStyles = css({
|
|
|
36
37
|
// last character of the heading (i.e. after the final wrapped line), so we use normal inline flow.
|
|
37
38
|
display: 'block'
|
|
38
39
|
});
|
|
40
|
+
var getHeadingAnchorLinksConfig = function getHeadingAnchorLinksConfig(allowHeadingAnchorLinks) {
|
|
41
|
+
return _typeof(allowHeadingAnchorLinks) === 'object' ? allowHeadingAnchorLinks : undefined;
|
|
42
|
+
};
|
|
39
43
|
function WrappedHeadingAnchor(_ref) {
|
|
40
44
|
var enableNestedHeaderLinks = _ref.enableNestedHeaderLinks,
|
|
45
|
+
getHeadingLink = _ref.getHeadingLink,
|
|
41
46
|
level = _ref.level,
|
|
42
47
|
headingId = _ref.headingId,
|
|
43
48
|
hideFromScreenReader = _ref.hideFromScreenReader;
|
|
@@ -49,13 +54,14 @@ function WrappedHeadingAnchor(_ref) {
|
|
|
49
54
|
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
|
|
50
55
|
,
|
|
51
56
|
onCopyText: function onCopyText() {
|
|
57
|
+
var _getHeadingLink;
|
|
52
58
|
fireAnalyticsEvent({
|
|
53
59
|
action: ACTION.CLICKED,
|
|
54
60
|
actionSubject: ACTION_SUBJECT.BUTTON,
|
|
55
61
|
actionSubjectId: ACTION_SUBJECT_ID.HEADING_ANCHOR_LINK,
|
|
56
62
|
eventType: EVENT_TYPE.UI
|
|
57
63
|
});
|
|
58
|
-
return copyTextToClipboard(getCurrentUrlWithHash(headingId));
|
|
64
|
+
return copyTextToClipboard((_getHeadingLink = getHeadingLink === null || getHeadingLink === void 0 ? void 0 : getHeadingLink(headingId)) !== null && _getHeadingLink !== void 0 ? _getHeadingLink : getCurrentUrlWithHash(headingId));
|
|
59
65
|
},
|
|
60
66
|
hideFromScreenReader: hideFromScreenReader,
|
|
61
67
|
headingId: headingId
|
|
@@ -81,7 +87,9 @@ function HeadingWithDuplicateAnchor(props) {
|
|
|
81
87
|
var mouseEntered = React.useRef(false);
|
|
82
88
|
var showAnchorLink = !!props.showAnchorLink;
|
|
83
89
|
var isRightAligned = hasRightAlignmentMark(marks);
|
|
84
|
-
var
|
|
90
|
+
var headingAnchorLinksConfig = getHeadingAnchorLinksConfig(allowHeadingAnchorLinks);
|
|
91
|
+
var enableNestedHeaderLinks = headingAnchorLinksConfig === null || headingAnchorLinksConfig === void 0 ? void 0 : headingAnchorLinksConfig.allowNestedHeaderLinks;
|
|
92
|
+
var getHeadingLink = headingAnchorLinksConfig === null || headingAnchorLinksConfig === void 0 ? void 0 : headingAnchorLinksConfig.getHeadingLink;
|
|
85
93
|
var headingIdToUse = invisible ? undefined : headingId;
|
|
86
94
|
var mouseEnterHandler = function mouseEnterHandler() {
|
|
87
95
|
if (showAnchorLink && !mouseEntered.current) {
|
|
@@ -102,11 +110,13 @@ function HeadingWithDuplicateAnchor(props) {
|
|
|
102
110
|
}, jsx(React.Fragment, null, showAnchorLink && headingId && isRightAligned && jsx(WrappedHeadingAnchor, {
|
|
103
111
|
level: props.level,
|
|
104
112
|
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
113
|
+
getHeadingLink: getHeadingLink,
|
|
105
114
|
headingId: headingId,
|
|
106
115
|
hideFromScreenReader: true
|
|
107
116
|
}), props.children, showAnchorLink && headingId && !isRightAligned && jsx(WrappedHeadingAnchor, {
|
|
108
117
|
level: props.level,
|
|
109
118
|
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
119
|
+
getHeadingLink: getHeadingLink,
|
|
110
120
|
headingId: headingId,
|
|
111
121
|
hideFromScreenReader: true
|
|
112
122
|
}))), jsx(VisuallyHidden, {
|
|
@@ -114,6 +124,7 @@ function HeadingWithDuplicateAnchor(props) {
|
|
|
114
124
|
}, showAnchorLink && headingId && jsx(WrappedHeadingAnchor, {
|
|
115
125
|
level: props.level,
|
|
116
126
|
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
127
|
+
getHeadingLink: getHeadingLink,
|
|
117
128
|
headingId: headingId
|
|
118
129
|
})));
|
|
119
130
|
}
|
|
@@ -136,7 +147,9 @@ function HeadingWithWrapper(props) {
|
|
|
136
147
|
var mouseEntered = React.useRef(false);
|
|
137
148
|
var showAnchorLink = !!props.showAnchorLink;
|
|
138
149
|
var isRightAligned = hasRightAlignmentMark(marks);
|
|
139
|
-
var
|
|
150
|
+
var headingAnchorLinksConfig = getHeadingAnchorLinksConfig(allowHeadingAnchorLinks);
|
|
151
|
+
var enableNestedHeaderLinks = headingAnchorLinksConfig === null || headingAnchorLinksConfig === void 0 ? void 0 : headingAnchorLinksConfig.allowNestedHeaderLinks;
|
|
152
|
+
var getHeadingLink = headingAnchorLinksConfig === null || headingAnchorLinksConfig === void 0 ? void 0 : headingAnchorLinksConfig.getHeadingLink;
|
|
140
153
|
var headingIdToUse = invisible ? undefined : headingId;
|
|
141
154
|
var mouseEnterHandler = function mouseEnterHandler() {
|
|
142
155
|
if (showAnchorLink && !mouseEntered.current) {
|
|
@@ -156,6 +169,7 @@ function HeadingWithWrapper(props) {
|
|
|
156
169
|
}, showAnchorLink && headingId && isRightAligned && jsx(WrappedHeadingAnchor, {
|
|
157
170
|
level: props.level,
|
|
158
171
|
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
172
|
+
getHeadingLink: getHeadingLink,
|
|
159
173
|
headingId: headingId,
|
|
160
174
|
hideFromScreenReader: false
|
|
161
175
|
}), jsx(HX, {
|
|
@@ -168,6 +182,7 @@ function HeadingWithWrapper(props) {
|
|
|
168
182
|
}, props.children), showAnchorLink && headingId && !isRightAligned && jsx(WrappedHeadingAnchor, {
|
|
169
183
|
level: props.level,
|
|
170
184
|
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
185
|
+
getHeadingLink: getHeadingLink,
|
|
171
186
|
headingId: headingId,
|
|
172
187
|
hideFromScreenReader: false
|
|
173
188
|
}));
|
|
@@ -63,7 +63,7 @@ export var DEGRADED_SEVERITY_THRESHOLD = 3000;
|
|
|
63
63
|
var TABLE_INFO_TIMEOUT = 10000;
|
|
64
64
|
var RENDER_EVENT_SAMPLE_RATE = 0.2;
|
|
65
65
|
var packageName = "@atlaskit/renderer";
|
|
66
|
-
var packageVersion = "133.4.
|
|
66
|
+
var packageVersion = "133.4.3";
|
|
67
67
|
var setAsQueryContainerStyles = css({
|
|
68
68
|
containerName: 'ak-renderer-wrapper',
|
|
69
69
|
containerType: 'inline-size'
|
|
@@ -239,6 +239,7 @@ export var RendererFunctionalComponent = function RendererFunctionalComponent(pr
|
|
|
239
239
|
contentMode: props.contentMode,
|
|
240
240
|
onSetLinkTarget: props.onSetLinkTarget,
|
|
241
241
|
disableHeadingIDs: props.disableHeadingIDs,
|
|
242
|
+
headingIdPrefix: props.headingIdPrefix,
|
|
242
243
|
disableActions: props.disableActions,
|
|
243
244
|
allowHeadingAnchorLinks: props.allowHeadingAnchorLinks,
|
|
244
245
|
allowColumnSorting: props.allowColumnSorting,
|
|
@@ -31,6 +31,7 @@ export interface ReactSerializerInit {
|
|
|
31
31
|
disableActions?: boolean;
|
|
32
32
|
disableHeadingIDs?: boolean;
|
|
33
33
|
disableTableOverflowShadow?: boolean;
|
|
34
|
+
headingIdPrefix?: string;
|
|
34
35
|
emojiResourceConfig?: EmojiResourceConfig;
|
|
35
36
|
eventHandlers?: EventHandlers;
|
|
36
37
|
extensionHandlers?: ExtensionHandlers;
|
|
@@ -72,6 +73,7 @@ export default class ReactSerializer implements Serializer<JSX.Element> {
|
|
|
72
73
|
private appearance?;
|
|
73
74
|
private contentMode?;
|
|
74
75
|
private disableHeadingIDs?;
|
|
76
|
+
private headingIdPrefix?;
|
|
75
77
|
private disableActions?;
|
|
76
78
|
private headingIds;
|
|
77
79
|
/**
|
|
@@ -29,6 +29,7 @@ export type StickyHeaderProps = boolean | ({
|
|
|
29
29
|
export type HeadingAnchorLinksConfig = {
|
|
30
30
|
activeHeadingId?: string;
|
|
31
31
|
allowNestedHeaderLinks?: boolean;
|
|
32
|
+
getHeadingLink?: (headingId: string) => string;
|
|
32
33
|
};
|
|
33
34
|
export type NodeComponentsProps = {
|
|
34
35
|
[key: string]: React.ComponentType<React.PropsWithChildren<any>>;
|
|
@@ -76,6 +76,11 @@ export interface RendererProps {
|
|
|
76
76
|
* of tables.
|
|
77
77
|
*/
|
|
78
78
|
disableTableOverflowShadow?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Optional prefix to prepend to all generated heading IDs.
|
|
81
|
+
* Used by nested renderers to namespace heading IDs and avoid collisions with the host page.
|
|
82
|
+
*/
|
|
83
|
+
headingIdPrefix?: string;
|
|
79
84
|
document: DocNode;
|
|
80
85
|
emojiResourceConfig?: EmojiResourceConfig;
|
|
81
86
|
enableSsrInlineScripts?: boolean;
|