@atlaskit/code 14.4.8 → 14.5.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.
Files changed (81) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/bidi-warning/bidi-warning-decorator.js +8 -0
  3. package/dist/cjs/bidi-warning/ui/index.js +8 -0
  4. package/dist/cjs/code-block.js +22 -20
  5. package/dist/cjs/internal/theme/styles.js +20 -9
  6. package/dist/cjs/syntax-highlighter/async.js +88 -0
  7. package/dist/cjs/syntax-highlighter/index.js +44 -0
  8. package/dist/cjs/syntax-highlighter/lib/highlight.js +91 -0
  9. package/dist/cjs/syntax-highlighter/lib/process/create-line-element.js +74 -0
  10. package/dist/cjs/syntax-highlighter/lib/process/create-line.js +32 -0
  11. package/dist/cjs/syntax-highlighter/lib/process/flatten-code-tree.js +29 -0
  12. package/dist/cjs/syntax-highlighter/lib/process/get-code-tree.js +22 -0
  13. package/dist/cjs/syntax-highlighter/lib/process/get-inline-line-number.js +23 -0
  14. package/dist/cjs/syntax-highlighter/lib/process/index.js +122 -0
  15. package/dist/cjs/syntax-highlighter/lib/react-renderer/create-children.js +21 -0
  16. package/dist/cjs/syntax-highlighter/lib/react-renderer/create-element.js +57 -0
  17. package/dist/cjs/syntax-highlighter/lib/react-renderer/index.js +30 -0
  18. package/dist/cjs/syntax-highlighter/types.js +31 -0
  19. package/dist/cjs/version.json +1 -1
  20. package/dist/es2019/bidi-warning/bidi-warning-decorator.js +8 -0
  21. package/dist/es2019/bidi-warning/ui/index.js +8 -0
  22. package/dist/es2019/code-block.js +18 -18
  23. package/dist/es2019/internal/theme/styles.js +20 -9
  24. package/dist/es2019/syntax-highlighter/async.js +51 -0
  25. package/dist/es2019/syntax-highlighter/index.js +38 -0
  26. package/dist/es2019/syntax-highlighter/lib/highlight.js +73 -0
  27. package/dist/es2019/syntax-highlighter/lib/process/create-line-element.js +65 -0
  28. package/dist/es2019/syntax-highlighter/lib/process/create-line.js +23 -0
  29. package/dist/es2019/syntax-highlighter/lib/process/flatten-code-tree.js +18 -0
  30. package/dist/es2019/syntax-highlighter/lib/process/get-code-tree.js +16 -0
  31. package/dist/es2019/syntax-highlighter/lib/process/get-inline-line-number.js +17 -0
  32. package/dist/es2019/syntax-highlighter/lib/process/index.js +114 -0
  33. package/dist/es2019/syntax-highlighter/lib/react-renderer/create-children.js +12 -0
  34. package/dist/es2019/syntax-highlighter/lib/react-renderer/create-element.js +53 -0
  35. package/dist/es2019/syntax-highlighter/lib/react-renderer/index.js +23 -0
  36. package/dist/es2019/syntax-highlighter/types.js +9 -0
  37. package/dist/es2019/version.json +1 -1
  38. package/dist/esm/bidi-warning/bidi-warning-decorator.js +8 -0
  39. package/dist/esm/bidi-warning/ui/index.js +8 -0
  40. package/dist/esm/code-block.js +20 -19
  41. package/dist/esm/internal/theme/styles.js +20 -9
  42. package/dist/esm/syntax-highlighter/async.js +76 -0
  43. package/dist/esm/syntax-highlighter/index.js +38 -0
  44. package/dist/esm/syntax-highlighter/lib/highlight.js +84 -0
  45. package/dist/esm/syntax-highlighter/lib/process/create-line-element.js +67 -0
  46. package/dist/esm/syntax-highlighter/lib/process/create-line.js +24 -0
  47. package/dist/esm/syntax-highlighter/lib/process/flatten-code-tree.js +22 -0
  48. package/dist/esm/syntax-highlighter/lib/process/get-code-tree.js +16 -0
  49. package/dist/esm/syntax-highlighter/lib/process/get-inline-line-number.js +17 -0
  50. package/dist/esm/syntax-highlighter/lib/process/index.js +115 -0
  51. package/dist/esm/syntax-highlighter/lib/react-renderer/create-children.js +14 -0
  52. package/dist/esm/syntax-highlighter/lib/react-renderer/create-element.js +50 -0
  53. package/dist/esm/syntax-highlighter/lib/react-renderer/index.js +24 -0
  54. package/dist/esm/syntax-highlighter/types.js +24 -0
  55. package/dist/esm/version.json +1 -1
  56. package/dist/types/bidi-warning/bidi-warning-decorator.d.ts +7 -0
  57. package/dist/types/bidi-warning/ui/index.d.ts +8 -0
  58. package/dist/types/bidi-warning/ui/types.d.ts +11 -15
  59. package/dist/types/extract-react-types/code-block.d.ts +24 -14
  60. package/dist/types/internal/theme/styles.d.ts +1 -1
  61. package/dist/types/internal/types.d.ts +31 -18
  62. package/dist/types/syntax-highlighter/async.d.ts +3 -0
  63. package/dist/types/syntax-highlighter/index.d.ts +36 -0
  64. package/dist/types/syntax-highlighter/lib/highlight.d.ts +12 -0
  65. package/dist/types/syntax-highlighter/lib/process/create-line-element.d.ts +9 -0
  66. package/dist/types/syntax-highlighter/lib/process/create-line.d.ts +3 -0
  67. package/dist/types/syntax-highlighter/lib/process/flatten-code-tree.d.ts +2 -0
  68. package/dist/types/syntax-highlighter/lib/process/get-code-tree.d.ts +2 -0
  69. package/dist/types/syntax-highlighter/lib/process/get-inline-line-number.d.ts +2 -0
  70. package/dist/types/syntax-highlighter/lib/process/index.d.ts +17 -0
  71. package/dist/types/syntax-highlighter/lib/react-renderer/create-children.d.ts +3 -0
  72. package/dist/types/syntax-highlighter/lib/react-renderer/create-element.d.ts +7 -0
  73. package/dist/types/syntax-highlighter/lib/react-renderer/index.d.ts +15 -0
  74. package/dist/types/syntax-highlighter/types.d.ts +129 -0
  75. package/dist/types/types.d.ts +10 -11
  76. package/package.json +13 -9
  77. package/report.api.md +1 -0
  78. package/dist/cjs/react-syntax-highlighter-bidi-warning-renderer.js +0 -156
  79. package/dist/es2019/react-syntax-highlighter-bidi-warning-renderer.js +0 -149
  80. package/dist/esm/react-syntax-highlighter-bidi-warning-renderer.js +0 -155
  81. package/dist/types/react-syntax-highlighter-bidi-warning-renderer.d.ts +0 -9
@@ -0,0 +1,65 @@
1
+ import getInlineLineNumber from './get-inline-line-number';
2
+ export default function createLineElement({
3
+ children,
4
+ lineNumber,
5
+ showLineNumbers,
6
+ lineProps = {},
7
+ className = []
8
+ }) {
9
+ const properties = typeof lineProps === 'function' ? lineProps(lineNumber) : lineProps;
10
+ properties.className = className;
11
+ let currentChildren = children;
12
+ if (lineNumber && showLineNumbers) {
13
+ // When syntax highlighting is NOT turned on, the entire LOC is just a single
14
+ // child. We can then happily create the line number and the LOC as siblings...
15
+ if (currentChildren.length === 1) {
16
+ currentChildren = [getInlineLineNumber(lineNumber), ...currentChildren];
17
+ } else {
18
+ // ... However, when syntax highlighting IS on, a span is created for each
19
+ // tokenised node in the AST (eg. <span>import</span><span>React</span>).
20
+ // When shouldWrapLongLines is true, the row becomes `display: flex` and
21
+ // forces all its children to be equal height. This can be a source of
22
+ // visual bugs where a LOC is broken up weirdly into segments.
23
+ //
24
+ // +---------------------------------------+
25
+ // | row |
26
+ // | +----+ +-------+ +--------+ +------+ |
27
+ // | |line| |key | |keywords| |key | |
28
+ // | |no. | |word | | | |word | |
29
+ // | | | | | | | | | |
30
+ // | +----+ +-------+ +--------+ +------+ |
31
+ // +---------------------------------------+
32
+ //
33
+ // Nesting the children one layer deeper (i.e. creating an extra span)
34
+ // ensures that the line number and the ENTIRE line of code are aligned by
35
+ // the parent flexbox (the row).
36
+ //
37
+ // +---------------------------------------------+
38
+ // | row |
39
+ // | +----+ +--------------------------------+ |
40
+ // | |line| | extra span we are creating | |
41
+ // | |no. | | +-------+ +--------+ +------+ | |
42
+ // | | | | |key | |keywords| |key | | |
43
+ // | | | | |word | | | |word | | |
44
+ // | | | | | | | | | | | |
45
+ // | | | | +-------+ +--------+ +------+ | |
46
+ // | +----+ +--------------------------------+ |
47
+ // +---------------------------------------------+
48
+ //
49
+ currentChildren = [getInlineLineNumber(lineNumber), {
50
+ type: 'element',
51
+ tagName: 'span',
52
+ properties: {
53
+ className: []
54
+ },
55
+ children: currentChildren
56
+ }];
57
+ }
58
+ }
59
+ return {
60
+ type: 'element',
61
+ tagName: 'span',
62
+ properties,
63
+ children: currentChildren
64
+ };
65
+ }
@@ -0,0 +1,23 @@
1
+ import createLineElement from './create-line-element';
2
+ import getInlineLineNumber from './get-inline-line-number';
3
+ function createLineGenerator(lineProps, shouldCreateParentElementForLines, showLineNumbers) {
4
+ return (children, lineNumber, className = []) => {
5
+ // Needed for more complex line creation
6
+ if (shouldCreateParentElementForLines || className.length > 0) {
7
+ return createLineElement({
8
+ children,
9
+ lineNumber,
10
+ showLineNumbers,
11
+ lineProps,
12
+ className
13
+ });
14
+ } else {
15
+ // Simple line creation without the bells and whistles
16
+ if (showLineNumbers && lineNumber) {
17
+ children.unshift(getInlineLineNumber(lineNumber));
18
+ }
19
+ return children;
20
+ }
21
+ };
22
+ }
23
+ export default createLineGenerator;
@@ -0,0 +1,18 @@
1
+ import createLineElement from './create-line-element';
2
+ export default function flattenCodeTree(tree, offset = 0, className = []) {
3
+ let newTree = [];
4
+ for (let i = 0; i < tree.length; i++) {
5
+ const node = tree[i];
6
+ if (node.type === 'text') {
7
+ newTree.push(createLineElement({
8
+ children: [node],
9
+ lineNumber: offset,
10
+ className
11
+ }));
12
+ } else if (node.children) {
13
+ const classNames = className.concat(node.properties.className || []);
14
+ flattenCodeTree(node.children, offset + 1, classNames).forEach(i => newTree.push(i));
15
+ }
16
+ }
17
+ return newTree;
18
+ }
@@ -0,0 +1,16 @@
1
+ export default function getCodeTree(language, code, astGenerator) {
2
+ if (language === 'text' || !astGenerator) {
3
+ return [{
4
+ type: 'text',
5
+ value: code
6
+ }];
7
+ }
8
+ try {
9
+ return astGenerator.highlight(code, language);
10
+ } catch (e) {
11
+ return [{
12
+ type: 'text',
13
+ value: code
14
+ }];
15
+ }
16
+ }
@@ -0,0 +1,17 @@
1
+ export default function getInlineLineNumber(lineNumber) {
2
+ return {
3
+ type: 'element',
4
+ tagName: 'span',
5
+ properties: {
6
+ key: `line-number--${lineNumber}`,
7
+ className: ['comment', 'linenumber', 'ds-line-number'],
8
+ // We're placing the lineNumber in a data-attr on an empty span (hence the
9
+ // empty children array below). This allows CodeBlock to use CSS to
10
+ // generate the content in a pseudo-element, which is a fix for a bug
11
+ // where line numbers were being copied (CSS content can't be copied)
12
+ // https://product-fabric.atlassian.net/browse/DSP-2729
13
+ 'data-ds--line-number': lineNumber
14
+ },
15
+ children: []
16
+ };
17
+ }
@@ -0,0 +1,114 @@
1
+ import createLineGenerator from './create-line';
2
+ import createLineElement from './create-line-element';
3
+ import flattenCodeTree from './flatten-code-tree';
4
+ import getCodeTree from './get-code-tree';
5
+ const newLineRegex = /\n/g;
6
+ function getNewLines(str) {
7
+ return str.match(newLineRegex);
8
+ }
9
+ /**
10
+ * __Line Processor__
11
+ *
12
+ * A line processor, that uses refractor to turn code into a tree structure
13
+ * with highlighting metadata and collapses this tree into lines for a renderer.
14
+ */
15
+ export default function processLines({
16
+ astGenerator,
17
+ code,
18
+ language,
19
+ shouldCreateParentElementForLines,
20
+ lineProps,
21
+ showLineNumbers
22
+ }) {
23
+ const codeTree = getCodeTree(language, code, astGenerator);
24
+ const startingLineNumber = 1;
25
+ const createLine = createLineGenerator(lineProps, shouldCreateParentElementForLines, showLineNumbers);
26
+ const newTree = [];
27
+ let lastLineBreakIndex = -1;
28
+ let index = 0;
29
+
30
+ // Seems odd we flatten the tree immediately - what work could we do on it more performantly than on the lines?
31
+ const tree = flattenCodeTree(codeTree);
32
+ while (index < tree.length) {
33
+ const testNode = tree[index];
34
+ if (testNode.type === 'text') {
35
+ index++;
36
+ continue;
37
+ }
38
+ const node = testNode;
39
+ const firstChildNode = node.children[0];
40
+ if (firstChildNode.type === 'text') {
41
+ const {
42
+ value
43
+ } = firstChildNode;
44
+ const newLines = getNewLines(value);
45
+ if (newLines) {
46
+ const splitValue = value.split('\n');
47
+ splitValue.forEach((text, i) => {
48
+ const lineNumber = newTree.length + startingLineNumber;
49
+ const newChild = {
50
+ type: 'text',
51
+ value: `${text}\n`
52
+ };
53
+
54
+ // if it's the first line
55
+ if (i === 0) {
56
+ const children = tree.slice(lastLineBreakIndex + 1, index).concat(createLineElement({
57
+ children: [newChild],
58
+ className: node.properties.className,
59
+ lineNumber
60
+ }));
61
+ const line = createLine(children, lineNumber);
62
+ newTree.push(line);
63
+
64
+ // if it's the last line
65
+ } else if (i === splitValue.length - 1) {
66
+ const nextNode = tree[index + 1];
67
+ const stringChild = nextNode && nextNode.children && nextNode.children[0];
68
+ // Similar to newChild above, but no newline
69
+ const lastLineInPreviousSpan = {
70
+ type: 'text',
71
+ value: `${text}`
72
+ };
73
+ if (stringChild) {
74
+ const newElem = createLineElement({
75
+ children: [lastLineInPreviousSpan],
76
+ className: node.properties.className,
77
+ lineNumber
78
+ });
79
+ tree.splice(index + 1, 0, newElem);
80
+ } else {
81
+ const children = [lastLineInPreviousSpan];
82
+ const line = createLine(children, lineNumber, node.properties.className);
83
+ newTree.push(line);
84
+ }
85
+
86
+ // if it's neither the first nor the last line
87
+ } else {
88
+ const children = [newChild];
89
+ const line = createLine(children, lineNumber, node.properties.className);
90
+ newTree.push(line);
91
+ }
92
+ });
93
+ lastLineBreakIndex = index;
94
+ }
95
+ }
96
+ index++;
97
+ }
98
+ if (lastLineBreakIndex !== tree.length - 1) {
99
+ const children = tree.slice(lastLineBreakIndex + 1, tree.length);
100
+ if (children && children.length) {
101
+ const lineNumber = newTree.length + startingLineNumber;
102
+ const line = createLine(children, lineNumber);
103
+ newTree.push(line);
104
+ }
105
+ }
106
+ if (shouldCreateParentElementForLines) {
107
+ return newTree;
108
+ }
109
+
110
+ // If shouldCreateParentElementForLines was off, we still have a tree structure we need to flatten
111
+ // We have (RefractorNode | RefractorNode[])[] but need RefractorNode[]
112
+ // This seems like a code smell to review
113
+ return newTree.flat(1);
114
+ }
@@ -0,0 +1,12 @@
1
+ import createElement from './create-element';
2
+ export default function createChildren(codeBidiWarningConfig) {
3
+ let childrenCount = 0;
4
+ return children => {
5
+ childrenCount += 1;
6
+ return children.map((child, i) => createElement({
7
+ node: child,
8
+ codeBidiWarningConfig,
9
+ key: `code-segment-${childrenCount}-${i}`
10
+ }));
11
+ };
12
+ }
@@ -0,0 +1,53 @@
1
+ import React from 'react';
2
+ import CodeBidiWarning from '../../../bidi-warning';
3
+ import codeBidiWarningDecorator from '../../../bidi-warning/bidi-warning-decorator';
4
+ import createChildren from './create-children';
5
+ function createClassNameString(classNames) {
6
+ return classNames ? classNames.join(' ') : '';
7
+ }
8
+
9
+ // NOTE: This is a function call rather than a React component because, for
10
+ // unknown reasons, it appears to be more performant. We tried and measured both
11
+ // and this stacks up better than as a memoised React component. Something to look
12
+ // into in the future.
13
+ export default function createElement({
14
+ node,
15
+ codeBidiWarningConfig,
16
+ key
17
+ }) {
18
+ if (node.type === 'text') {
19
+ const {
20
+ value
21
+ } = node;
22
+ // occasionally a numeric value is passed when the type is text
23
+ const textValue = `${value}`;
24
+ if (codeBidiWarningConfig.codeBidiWarnings) {
25
+ const decorated = codeBidiWarningDecorator(textValue, ({
26
+ bidiCharacter,
27
+ index
28
+ }) => /*#__PURE__*/React.createElement(CodeBidiWarning, {
29
+ bidiCharacter: bidiCharacter,
30
+ key: index,
31
+ label: codeBidiWarningConfig.codeBidiWarningLabel,
32
+ tooltipEnabled: codeBidiWarningConfig.codeBidiWarningTooltipEnabled
33
+ }));
34
+ return decorated;
35
+ }
36
+ return textValue;
37
+ } else {
38
+ const {
39
+ properties,
40
+ tagName
41
+ } = node;
42
+ const childrenCreator = createChildren(codeBidiWarningConfig);
43
+ const props = {
44
+ ...properties,
45
+ className: createClassNameString(properties.className)
46
+ };
47
+ const children = childrenCreator(node.children);
48
+ return /*#__PURE__*/React.createElement(tagName, {
49
+ key,
50
+ ...props
51
+ }, children);
52
+ }
53
+ }
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import createElement from './create-element';
3
+
4
+ /**
5
+ * __React Renderer__
6
+ *
7
+ * A component that receives processed code lines and renders them into the code
8
+ * rows inside the wrapping span and nested code tag, applying passed props and
9
+ * code bidi warning config settings.
10
+ */
11
+ export default function ReactRenderer({
12
+ containerProps,
13
+ codeTagProps,
14
+ rows,
15
+ codeBidiWarningConfig
16
+ }) {
17
+ const renderedRows = rows.map((node, i) => createElement({
18
+ node,
19
+ codeBidiWarningConfig,
20
+ key: `code-segment${i}`
21
+ }));
22
+ return /*#__PURE__*/React.createElement("span", containerProps, /*#__PURE__*/React.createElement("code", codeTagProps, renderedRows));
23
+ }
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ // This wrapper supports the async loading of refractor and language grammars. The internal Highlight is a memo() functional component as expected
3
+ // eslint-disable-next-line @repo/internal/react/no-class-components
4
+ export class SyntaxHighlighter extends React.PureComponent {}
5
+
6
+ /**
7
+ * Function that receives current line number as argument and returns a
8
+ * line props object to be applied to each `span` wrapping code line.
9
+ */
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/code",
3
- "version": "14.4.8",
3
+ "version": "14.5.0",
4
4
  "sideEffects": false
5
5
  }
@@ -3,6 +3,14 @@ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol
3
3
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
4
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
5
5
  export var bidiCharacterRegex = /[\u202A-\u202E\u2066-\u2069]/g;
6
+
7
+ /**
8
+ * __Code Bidi Warning Decorator__
9
+ *
10
+ * Checks the code to see if it contains any bidi characters.
11
+ * In case if bidi characters found - returns children with decorated
12
+ * bidi characters. If no bidi characters found - original text returned.
13
+ */
6
14
  export default function codeBidiWarningDecorator(originalText, decorate) {
7
15
  var matches = _toConsumableArray(originalText.matchAll(bidiCharacterRegex));
8
16
  if (matches.length === 0) {
@@ -4,6 +4,14 @@ var _excluded = ["children"];
4
4
  import React from 'react';
5
5
  import Tooltip from '@atlaskit/tooltip';
6
6
  import { Decorator } from './styled';
7
+ /**
8
+ * __Bidi Warning__
9
+ *
10
+ * A component used to render a bidi character warning.
11
+ * A bidi character can be used to perform a "bidi override attack".
12
+ *
13
+ * See https://hello.atlassian.net/wiki/spaces/PRODSEC/pages/1347434677/PSHELP-2943+Investigate+Trojan+Source+Attack+Vulnerability#1)-Providing-visual-cues-for-our-Customers-in-our-affected-products
14
+ */
7
15
  export default function BidiWarning(_ref) {
8
16
  var testId = _ref.testId,
9
17
  bidiCharacter = _ref.bidiCharacter,
@@ -1,12 +1,11 @@
1
1
  /** @jsx jsx */
2
2
  import { memo, useCallback, useMemo } from 'react';
3
3
  import { css, jsx } from '@emotion/react';
4
- import { PrismAsync as SyntaxHighlighter } from 'react-syntax-highlighter';
5
4
  import { useGlobalTheme } from '@atlaskit/theme/components';
6
5
  import { useHighlightLines } from './internal/hooks/use-highlight';
7
6
  import { getCodeBlockStyles, getCodeBlockTheme } from './internal/theme/styles';
8
7
  import { normalizeLanguage } from './internal/utils/get-normalized-language';
9
- import { createBidiWarningRenderer } from './react-syntax-highlighter-bidi-warning-renderer';
8
+ import SyntaxHighlighter from './syntax-highlighter';
10
9
 
11
10
  /**
12
11
  * __Code block__
@@ -34,7 +33,9 @@ var CodeBlock = /*#__PURE__*/memo(function CodeBlock(_ref) {
34
33
  codeBidiWarnings = _ref$codeBidiWarnings === void 0 ? true : _ref$codeBidiWarnings,
35
34
  codeBidiWarningLabel = _ref.codeBidiWarningLabel,
36
35
  _ref$codeBidiWarningT = _ref.codeBidiWarningTooltipEnabled,
37
- codeBidiWarningTooltipEnabled = _ref$codeBidiWarningT === void 0 ? true : _ref$codeBidiWarningT;
36
+ codeBidiWarningTooltipEnabled = _ref$codeBidiWarningT === void 0 ? true : _ref$codeBidiWarningT,
37
+ _ref$shouldWrapLongLi = _ref.shouldWrapLongLines,
38
+ shouldWrapLongLines = _ref$shouldWrapLongLi === void 0 ? false : _ref$shouldWrapLongLi;
38
39
  var numLines = (text || '').split('\n').length;
39
40
  var globalTheme = useGlobalTheme();
40
41
  var theme = useMemo(function () {
@@ -44,8 +45,8 @@ var CodeBlock = /*#__PURE__*/memo(function CodeBlock(_ref) {
44
45
  return getCodeBlockStyles(theme);
45
46
  }, [theme]);
46
47
  var styles = useMemo(function () {
47
- return css(getStyles(highlightedStartText, highlightedEndText, showLineNumbers));
48
- }, [highlightedStartText, highlightedEndText, showLineNumbers, getStyles]);
48
+ return css(getStyles(highlightedStartText, highlightedEndText, showLineNumbers, shouldWrapLongLines));
49
+ }, [highlightedStartText, highlightedEndText, showLineNumbers, shouldWrapLongLines, getStyles]);
49
50
  var _useHighlightLines = useHighlightLines({
50
51
  highlight: highlight,
51
52
  testId: testId
@@ -61,25 +62,25 @@ var CodeBlock = /*#__PURE__*/memo(function CodeBlock(_ref) {
61
62
 
62
63
  // https://product-fabric.atlassian.net/browse/DST-2472
63
64
  var languageToUse = text ? language : 'text';
64
- var renderer = codeBidiWarnings ? createBidiWarningRenderer({
65
- codeBidiWarningLabel: codeBidiWarningLabel,
66
- codeBidiWarningTooltipEnabled: codeBidiWarningTooltipEnabled
67
- }) : undefined;
68
65
  return jsx(SyntaxHighlighter, {
69
- "data-testid": testId,
70
66
  "data-code-lang": language,
71
67
  "data-ds--code--code-block": "",
72
- css: styles,
68
+ testId: testId,
73
69
  language: languageToUse,
74
- PreTag: "span",
75
- showLineNumbers: showLineNumbers
76
- // Wrap lines is needed to set styles on the line when highlighting.
70
+ css: styles,
71
+ showLineNumbers: showLineNumbers,
72
+ lineProps: getLineProps
73
+ // shouldCreateParentElementForLines is needed to pass down props to each line.
74
+ // This is necessary for both line highlighting and testId's, as each of
75
+ // these rely on a data attribute being passed down to lines.
77
76
  ,
78
- wrapLines: highlight.length > 0 || !!testId,
79
- lineProps: getLineProps,
80
- useInlineStyles: false,
81
- renderer: renderer
82
- }, text);
77
+ shouldCreateParentElementForLines: highlight.length > 0 || !!testId,
78
+ shouldWrapLongLines: shouldWrapLongLines,
79
+ codeBidiWarnings: codeBidiWarnings,
80
+ codeBidiWarningLabel: codeBidiWarningLabel,
81
+ codeBidiWarningTooltipEnabled: codeBidiWarningTooltipEnabled,
82
+ text: text
83
+ });
83
84
  });
84
85
  CodeBlock.displayName = 'CodeBlock';
85
86
  export default CodeBlock;
@@ -27,7 +27,13 @@ var lineNumberStyle = function lineNumberStyle(theme) {
27
27
  textAlign: 'right',
28
28
  userSelect: 'none',
29
29
  // this is to fix SSR spacing issue
30
- display: 'block'
30
+ display: 'block',
31
+ // This is how we are preventing line numbers being copied to clipboard.
32
+ // (`user-select: none;` was not sufficent).
33
+ // https://product-fabric.atlassian.net/browse/DSP-2729
34
+ '&::after': {
35
+ content: "attr(data-ds--line-number)"
36
+ }
31
37
  };
32
38
  };
33
39
 
@@ -202,12 +208,12 @@ export var getBaseCodeStyles = function getBaseCodeStyles(theme) {
202
208
  * @param theme
203
209
  */
204
210
  export var getCodeBlockStyles = function getCodeBlockStyles(theme) {
205
- return function (highlightedStartText, highlightedEndText, hasLineNumbers) {
211
+ return function (highlightedStartText, highlightedEndText, showLineNumbers, shouldWrapLongLines) {
206
212
  return _objectSpread(_objectSpread(_objectSpread({
207
213
  // this is required to account for prismjs styles leaking into the codeblock
208
214
  'code[class*="language-"], pre[class*="language-"], code': {
209
215
  all: 'unset',
210
- padding: hasLineNumbers ? "".concat(SPACING, "px 0") : SPACING
216
+ padding: showLineNumbers ? "".concat(SPACING, "px 0") : SPACING
211
217
  },
212
218
  display: 'flex',
213
219
  lineHeight: CODE_LINE_HEIGHT,
@@ -216,14 +222,14 @@ export var getCodeBlockStyles = function getCodeBlockStyles(theme) {
216
222
  direction: 'ltr'
217
223
  }, getBaseCodeStyles(theme)), syntaxKeywordColors(theme)), {}, {
218
224
  // this is to account for SSR spacing issue once loaded in browser
219
- '& .linenumber, .react-syntax-highlighter-line-number': lineNumberStyle(theme),
225
+ '& .linenumber, .ds-sh-line-number': lineNumberStyle(theme),
220
226
  '& .linenumber': {
221
227
  display: 'inline-block !important',
222
228
  float: 'left'
223
229
  },
224
230
  // these styles are for line highlighting
225
231
  '& [data-ds--code--row]': {
226
- display: 'block',
232
+ display: showLineNumbers ? 'flex' : 'block',
227
233
  paddingRight: "".concat(SPACING, "px !important"),
228
234
  marginRight: "-".concat(SPACING, "px")
229
235
  },
@@ -239,11 +245,12 @@ export var getCodeBlockStyles = function getCodeBlockStyles(theme) {
239
245
  whiteSpace: 'nowrap',
240
246
  width: '1px'
241
247
  },
248
+ // The formatting here is an accessibility convention
242
249
  '&::before': {
243
- content: "\", ".concat(highlightedStartText, ", \"")
250
+ content: "\" [".concat(highlightedStartText, "] \"")
244
251
  },
245
252
  '&::after': {
246
- content: "\", ".concat(highlightedEndText, ", \"")
253
+ content: "\" [".concat(highlightedEndText, "] \"")
247
254
  }
248
255
  },
249
256
  '& [data-ds--code--row--highlight] .linenumber': {
@@ -268,14 +275,18 @@ export var getCodeBlockStyles = function getCodeBlockStyles(theme) {
268
275
  },
269
276
  '& code:first-of-type': {
270
277
  paddingRight: "0px !important",
271
- backgroundImage: hasLineNumbers ? "linear-gradient(to right, var(".concat(VAR_CODE_LINE_NUMBER_BG_COLOR, ",").concat(theme.lineNumberBgColor, "), var(").concat(VAR_CODE_LINE_NUMBER_BG_COLOR, ",").concat(theme.lineNumberBgColor, ")\n calc(").concat(theme.lineNumberWidth, " + ").concat(LINE_NUMBER_GUTTER, "px), transparent calc(").concat(theme.lineNumberWidth, " + ").concat(LINE_NUMBER_GUTTER, "px), transparent)") : undefined
278
+ backgroundImage: showLineNumbers ? "linear-gradient(to right, var(".concat(VAR_CODE_LINE_NUMBER_BG_COLOR, ",").concat(theme.lineNumberBgColor, "), var(").concat(VAR_CODE_LINE_NUMBER_BG_COLOR, ",").concat(theme.lineNumberBgColor, ")\n calc(").concat(theme.lineNumberWidth, " + ").concat(LINE_NUMBER_GUTTER, "px), transparent calc(").concat(theme.lineNumberWidth, " + ").concat(LINE_NUMBER_GUTTER, "px), transparent)") : undefined
272
279
  },
273
280
  // we need to use last-of-type because when Code is SSR'd
274
281
  // 2 <code> elements are created and we don't want this style
275
282
  // applied to the first one
276
283
  '& code:last-of-type': {
277
284
  paddingRight: "".concat(SPACING, "px !important"),
278
- flex: '1 0 auto'
285
+ flexBasis: 'auto',
286
+ flexGrow: 1,
287
+ // Needed for the highlight line to extend full-width
288
+ flexShrink: shouldWrapLongLines ? 1 : 0,
289
+ wordBreak: 'break-word'
279
290
  },
280
291
  // Prevents empty code blocks from vertically collapsing
281
292
  'code > span:only-child:empty:before, code > span:only-child > span:only-child:empty:before': {
@@ -0,0 +1,76 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
+ import _createClass from "@babel/runtime/helpers/createClass";
4
+ import _inherits from "@babel/runtime/helpers/inherits";
5
+ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
6
+ import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
7
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
8
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
9
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
10
+ import React from 'react';
11
+ import highlight from './lib/highlight';
12
+ // Uses the loader method of async bundling
13
+ // Instantiates highligher as a singleton, loading refractor only once per page (refractor/prism are singleton modules)
14
+ var generator = function generator(options) {
15
+ var loader = options.loader;
16
+
17
+ // eslint-disable-next-line @repo/internal/react/no-class-components
18
+ var AsyncHighlighter = /*#__PURE__*/function (_React$PureComponent) {
19
+ _inherits(AsyncHighlighter, _React$PureComponent);
20
+ var _super = _createSuper(AsyncHighlighter);
21
+ function AsyncHighlighter() {
22
+ _classCallCheck(this, AsyncHighlighter);
23
+ return _super.apply(this, arguments);
24
+ }
25
+ _createClass(AsyncHighlighter, [{
26
+ key: "componentDidMount",
27
+ value: function componentDidMount() {
28
+ var _this = this;
29
+ if (!AsyncHighlighter.astGeneratorPromise) {
30
+ AsyncHighlighter.loadAstGenerator();
31
+ }
32
+ if (!AsyncHighlighter.astGenerator && AsyncHighlighter.astGeneratorPromise) {
33
+ AsyncHighlighter.astGeneratorPromise.then(function () {
34
+ _this.forceUpdate();
35
+ });
36
+ }
37
+ }
38
+ }, {
39
+ key: "render",
40
+ value: function render() {
41
+ return /*#__PURE__*/React.createElement(AsyncHighlighter.highlightInstance, _extends({}, this.props, {
42
+ astGenerator: AsyncHighlighter.astGenerator
43
+ }));
44
+ }
45
+ }], [{
46
+ key: "preload",
47
+ value:
48
+ // Useful in tests
49
+ function preload() {
50
+ return AsyncHighlighter.loadAstGenerator();
51
+ }
52
+ }, {
53
+ key: "loadAstGenerator",
54
+ value: function loadAstGenerator() {
55
+ AsyncHighlighter.astGeneratorPromise = loader().then(function (astGenerator) {
56
+ AsyncHighlighter.astGenerator = astGenerator;
57
+ return astGenerator;
58
+ });
59
+ return AsyncHighlighter.astGeneratorPromise;
60
+ }
61
+ }]);
62
+ return AsyncHighlighter;
63
+ }(React.PureComponent);
64
+ _defineProperty(AsyncHighlighter, "astGenerator", null);
65
+ _defineProperty(AsyncHighlighter, "highlightInstance", highlight);
66
+ return AsyncHighlighter;
67
+ };
68
+ export default generator({
69
+ loader: function loader() {
70
+ return import( /* webpackChunkName: "@atlaskit-internal_refractor-import" */
71
+ 'refractor').then(function (module) {
72
+ // Webpack 3 returns module.exports as default as module, but webpack 4 returns module.exports as module.default
73
+ return module.default || module;
74
+ });
75
+ }
76
+ });