@atlaskit/code 14.4.8 → 14.5.1

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 +25 -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 +14 -10
  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,122 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = processLines;
8
+ var _createLine = _interopRequireDefault(require("./create-line"));
9
+ var _createLineElement = _interopRequireDefault(require("./create-line-element"));
10
+ var _flattenCodeTree = _interopRequireDefault(require("./flatten-code-tree"));
11
+ var _getCodeTree = _interopRequireDefault(require("./get-code-tree"));
12
+ var newLineRegex = /\n/g;
13
+ function getNewLines(str) {
14
+ return str.match(newLineRegex);
15
+ }
16
+ /**
17
+ * __Line Processor__
18
+ *
19
+ * A line processor, that uses refractor to turn code into a tree structure
20
+ * with highlighting metadata and collapses this tree into lines for a renderer.
21
+ */
22
+ function processLines(_ref) {
23
+ var astGenerator = _ref.astGenerator,
24
+ code = _ref.code,
25
+ language = _ref.language,
26
+ shouldCreateParentElementForLines = _ref.shouldCreateParentElementForLines,
27
+ lineProps = _ref.lineProps,
28
+ showLineNumbers = _ref.showLineNumbers;
29
+ var codeTree = (0, _getCodeTree.default)(language, code, astGenerator);
30
+ var startingLineNumber = 1;
31
+ var createLine = (0, _createLine.default)(lineProps, shouldCreateParentElementForLines, showLineNumbers);
32
+ var newTree = [];
33
+ var lastLineBreakIndex = -1;
34
+ var index = 0;
35
+
36
+ // Seems odd we flatten the tree immediately - what work could we do on it more performantly than on the lines?
37
+ var tree = (0, _flattenCodeTree.default)(codeTree);
38
+ var _loop = function _loop() {
39
+ var testNode = tree[index];
40
+ if (testNode.type === 'text') {
41
+ index++;
42
+ return "continue";
43
+ }
44
+ var node = testNode;
45
+ var firstChildNode = node.children[0];
46
+ if (firstChildNode.type === 'text') {
47
+ var value = firstChildNode.value;
48
+ var newLines = getNewLines(value);
49
+ if (newLines) {
50
+ var splitValue = value.split('\n');
51
+ splitValue.forEach(function (text, i) {
52
+ var lineNumber = newTree.length + startingLineNumber;
53
+ var newChild = {
54
+ type: 'text',
55
+ value: "".concat(text, "\n")
56
+ };
57
+
58
+ // if it's the first line
59
+ if (i === 0) {
60
+ var _children = tree.slice(lastLineBreakIndex + 1, index).concat((0, _createLineElement.default)({
61
+ children: [newChild],
62
+ className: node.properties.className,
63
+ lineNumber: lineNumber
64
+ }));
65
+ var _line = createLine(_children, lineNumber);
66
+ newTree.push(_line);
67
+
68
+ // if it's the last line
69
+ } else if (i === splitValue.length - 1) {
70
+ var nextNode = tree[index + 1];
71
+ var stringChild = nextNode && nextNode.children && nextNode.children[0];
72
+ // Similar to newChild above, but no newline
73
+ var lastLineInPreviousSpan = {
74
+ type: 'text',
75
+ value: "".concat(text)
76
+ };
77
+ if (stringChild) {
78
+ var newElem = (0, _createLineElement.default)({
79
+ children: [lastLineInPreviousSpan],
80
+ className: node.properties.className,
81
+ lineNumber: lineNumber
82
+ });
83
+ tree.splice(index + 1, 0, newElem);
84
+ } else {
85
+ var _children2 = [lastLineInPreviousSpan];
86
+ var _line2 = createLine(_children2, lineNumber, node.properties.className);
87
+ newTree.push(_line2);
88
+ }
89
+
90
+ // if it's neither the first nor the last line
91
+ } else {
92
+ var _children3 = [newChild];
93
+ var _line3 = createLine(_children3, lineNumber, node.properties.className);
94
+ newTree.push(_line3);
95
+ }
96
+ });
97
+ lastLineBreakIndex = index;
98
+ }
99
+ }
100
+ index++;
101
+ };
102
+ while (index < tree.length) {
103
+ var _ret = _loop();
104
+ if (_ret === "continue") continue;
105
+ }
106
+ if (lastLineBreakIndex !== tree.length - 1) {
107
+ var children = tree.slice(lastLineBreakIndex + 1, tree.length);
108
+ if (children && children.length) {
109
+ var lineNumber = newTree.length + startingLineNumber;
110
+ var line = createLine(children, lineNumber);
111
+ newTree.push(line);
112
+ }
113
+ }
114
+ if (shouldCreateParentElementForLines) {
115
+ return newTree;
116
+ }
117
+
118
+ // If shouldCreateParentElementForLines was off, we still have a tree structure we need to flatten
119
+ // We have (RefractorNode | RefractorNode[])[] but need RefractorNode[]
120
+ // This seems like a code smell to review
121
+ return newTree.flat(1);
122
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = createChildren;
8
+ var _createElement = _interopRequireDefault(require("./create-element"));
9
+ function createChildren(codeBidiWarningConfig) {
10
+ var childrenCount = 0;
11
+ return function (children) {
12
+ childrenCount += 1;
13
+ return children.map(function (child, i) {
14
+ return (0, _createElement.default)({
15
+ node: child,
16
+ codeBidiWarningConfig: codeBidiWarningConfig,
17
+ key: "code-segment-".concat(childrenCount, "-").concat(i)
18
+ });
19
+ });
20
+ };
21
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = createElement;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _react = _interopRequireDefault(require("react"));
10
+ var _bidiWarning = _interopRequireDefault(require("../../../bidi-warning"));
11
+ var _bidiWarningDecorator = _interopRequireDefault(require("../../../bidi-warning/bidi-warning-decorator"));
12
+ var _createChildren = _interopRequireDefault(require("./create-children"));
13
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
14
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
15
+ function createClassNameString(classNames) {
16
+ return classNames ? classNames.join(' ') : '';
17
+ }
18
+
19
+ // NOTE: This is a function call rather than a React component because, for
20
+ // unknown reasons, it appears to be more performant. We tried and measured both
21
+ // and this stacks up better than as a memoised React component. Something to look
22
+ // into in the future.
23
+ function createElement(_ref) {
24
+ var node = _ref.node,
25
+ codeBidiWarningConfig = _ref.codeBidiWarningConfig,
26
+ key = _ref.key;
27
+ if (node.type === 'text') {
28
+ var value = node.value;
29
+ // occasionally a numeric value is passed when the type is text
30
+ var textValue = "".concat(value);
31
+ if (codeBidiWarningConfig.codeBidiWarnings) {
32
+ var decorated = (0, _bidiWarningDecorator.default)(textValue, function (_ref2) {
33
+ var bidiCharacter = _ref2.bidiCharacter,
34
+ index = _ref2.index;
35
+ return /*#__PURE__*/_react.default.createElement(_bidiWarning.default, {
36
+ bidiCharacter: bidiCharacter,
37
+ key: index,
38
+ label: codeBidiWarningConfig.codeBidiWarningLabel,
39
+ tooltipEnabled: codeBidiWarningConfig.codeBidiWarningTooltipEnabled
40
+ });
41
+ });
42
+ return decorated;
43
+ }
44
+ return textValue;
45
+ } else {
46
+ var properties = node.properties,
47
+ tagName = node.tagName;
48
+ var childrenCreator = (0, _createChildren.default)(codeBidiWarningConfig);
49
+ var props = _objectSpread(_objectSpread({}, properties), {}, {
50
+ className: createClassNameString(properties.className)
51
+ });
52
+ var children = childrenCreator(node.children);
53
+ return /*#__PURE__*/_react.default.createElement(tagName, _objectSpread({
54
+ key: key
55
+ }, props), children);
56
+ }
57
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = ReactRenderer;
8
+ var _react = _interopRequireDefault(require("react"));
9
+ var _createElement = _interopRequireDefault(require("./create-element"));
10
+ /**
11
+ * __React Renderer__
12
+ *
13
+ * A component that receives processed code lines and renders them into the code
14
+ * rows inside the wrapping span and nested code tag, applying passed props and
15
+ * code bidi warning config settings.
16
+ */
17
+ function ReactRenderer(_ref) {
18
+ var containerProps = _ref.containerProps,
19
+ codeTagProps = _ref.codeTagProps,
20
+ rows = _ref.rows,
21
+ codeBidiWarningConfig = _ref.codeBidiWarningConfig;
22
+ var renderedRows = rows.map(function (node, i) {
23
+ return (0, _createElement.default)({
24
+ node: node,
25
+ codeBidiWarningConfig: codeBidiWarningConfig,
26
+ key: "code-segment".concat(i)
27
+ });
28
+ });
29
+ return /*#__PURE__*/_react.default.createElement("span", containerProps, /*#__PURE__*/_react.default.createElement("code", codeTagProps, renderedRows));
30
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.SyntaxHighlighter = void 0;
8
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
9
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
10
+ var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
11
+ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
12
+ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
13
+ var _react = _interopRequireDefault(require("react"));
14
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
15
+ 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; } }
16
+ // This wrapper supports the async loading of refractor and language grammars. The internal Highlight is a memo() functional component as expected
17
+ // eslint-disable-next-line @repo/internal/react/no-class-components
18
+ var SyntaxHighlighter = /*#__PURE__*/function (_React$PureComponent) {
19
+ (0, _inherits2.default)(SyntaxHighlighter, _React$PureComponent);
20
+ var _super = _createSuper(SyntaxHighlighter);
21
+ function SyntaxHighlighter() {
22
+ (0, _classCallCheck2.default)(this, SyntaxHighlighter);
23
+ return _super.apply(this, arguments);
24
+ }
25
+ return (0, _createClass2.default)(SyntaxHighlighter);
26
+ }(_react.default.PureComponent);
27
+ /**
28
+ * Function that receives current line number as argument and returns a
29
+ * line props object to be applied to each `span` wrapping code line.
30
+ */
31
+ exports.SyntaxHighlighter = SyntaxHighlighter;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/code",
3
- "version": "14.4.8",
3
+ "version": "14.5.1",
4
4
  "sideEffects": false
5
5
  }
@@ -1,4 +1,12 @@
1
1
  export const bidiCharacterRegex = /[\u202A-\u202E\u2066-\u2069]/g;
2
+
3
+ /**
4
+ * __Code Bidi Warning Decorator__
5
+ *
6
+ * Checks the code to see if it contains any bidi characters.
7
+ * In case if bidi characters found - returns children with decorated
8
+ * bidi characters. If no bidi characters found - original text returned.
9
+ */
2
10
  export default function codeBidiWarningDecorator(originalText, decorate) {
3
11
  const matches = [...originalText.matchAll(bidiCharacterRegex)];
4
12
  if (matches.length === 0) {
@@ -2,6 +2,14 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
  import React from 'react';
3
3
  import Tooltip from '@atlaskit/tooltip';
4
4
  import { Decorator } from './styled';
5
+ /**
6
+ * __Bidi Warning__
7
+ *
8
+ * A component used to render a bidi character warning.
9
+ * A bidi character can be used to perform a "bidi override attack".
10
+ *
11
+ * 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
12
+ */
5
13
  export default function BidiWarning({
6
14
  testId,
7
15
  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__
@@ -27,13 +26,14 @@ const CodeBlock = /*#__PURE__*/memo(function CodeBlock({
27
26
  text,
28
27
  codeBidiWarnings = true,
29
28
  codeBidiWarningLabel,
30
- codeBidiWarningTooltipEnabled = true
29
+ codeBidiWarningTooltipEnabled = true,
30
+ shouldWrapLongLines = false
31
31
  }) {
32
32
  const numLines = (text || '').split('\n').length;
33
33
  const globalTheme = useGlobalTheme();
34
34
  const theme = useMemo(() => getCodeBlockTheme(globalTheme, numLines), [globalTheme, numLines]);
35
35
  const getStyles = useMemo(() => getCodeBlockStyles(theme), [theme]);
36
- const styles = useMemo(() => css(getStyles(highlightedStartText, highlightedEndText, showLineNumbers)), [highlightedStartText, highlightedEndText, showLineNumbers, getStyles]);
36
+ const styles = useMemo(() => css(getStyles(highlightedStartText, highlightedEndText, showLineNumbers, shouldWrapLongLines)), [highlightedStartText, highlightedEndText, showLineNumbers, shouldWrapLongLines, getStyles]);
37
37
  const {
38
38
  getHighlightStyles,
39
39
  highlightedLines
@@ -46,25 +46,25 @@ const CodeBlock = /*#__PURE__*/memo(function CodeBlock({
46
46
 
47
47
  // https://product-fabric.atlassian.net/browse/DST-2472
48
48
  const languageToUse = text ? language : 'text';
49
- const renderer = codeBidiWarnings ? createBidiWarningRenderer({
50
- codeBidiWarningLabel,
51
- codeBidiWarningTooltipEnabled
52
- }) : undefined;
53
49
  return jsx(SyntaxHighlighter, {
54
- "data-testid": testId,
55
50
  "data-code-lang": language,
56
51
  "data-ds--code--code-block": "",
57
- css: styles,
52
+ testId: testId,
58
53
  language: languageToUse,
59
- PreTag: "span",
60
- showLineNumbers: showLineNumbers
61
- // Wrap lines is needed to set styles on the line when highlighting.
54
+ css: styles,
55
+ showLineNumbers: showLineNumbers,
56
+ lineProps: getLineProps
57
+ // shouldCreateParentElementForLines is needed to pass down props to each line.
58
+ // This is necessary for both line highlighting and testId's, as each of
59
+ // these rely on a data attribute being passed down to lines.
62
60
  ,
63
- wrapLines: highlight.length > 0 || !!testId,
64
- lineProps: getLineProps,
65
- useInlineStyles: false,
66
- renderer: renderer
67
- }, text);
61
+ shouldCreateParentElementForLines: highlight.length > 0 || !!testId,
62
+ shouldWrapLongLines: shouldWrapLongLines,
63
+ codeBidiWarnings: codeBidiWarnings,
64
+ codeBidiWarningLabel: codeBidiWarningLabel,
65
+ codeBidiWarningTooltipEnabled: codeBidiWarningTooltipEnabled,
66
+ text: text
67
+ });
68
68
  });
69
69
  CodeBlock.displayName = 'CodeBlock';
70
70
  export default CodeBlock;
@@ -23,7 +23,13 @@ const lineNumberStyle = theme => ({
23
23
  textAlign: 'right',
24
24
  userSelect: 'none',
25
25
  // this is to fix SSR spacing issue
26
- display: 'block'
26
+ display: 'block',
27
+ // This is how we are preventing line numbers being copied to clipboard.
28
+ // (`user-select: none;` was not sufficent).
29
+ // https://product-fabric.atlassian.net/browse/DSP-2729
30
+ '&::after': {
31
+ content: `attr(data-ds--line-number)`
32
+ }
27
33
  });
28
34
 
29
35
  // order of these keys does matter as it will affect the css precedence
@@ -192,11 +198,11 @@ export const getBaseCodeStyles = theme => ({
192
198
  *
193
199
  * @param theme
194
200
  */
195
- export const getCodeBlockStyles = theme => (highlightedStartText, highlightedEndText, hasLineNumbers) => ({
201
+ export const getCodeBlockStyles = theme => (highlightedStartText, highlightedEndText, showLineNumbers, shouldWrapLongLines) => ({
196
202
  // this is required to account for prismjs styles leaking into the codeblock
197
203
  'code[class*="language-"], pre[class*="language-"], code': {
198
204
  all: 'unset',
199
- padding: hasLineNumbers ? `${SPACING}px 0` : SPACING
205
+ padding: showLineNumbers ? `${SPACING}px 0` : SPACING
200
206
  },
201
207
  display: 'flex',
202
208
  lineHeight: CODE_LINE_HEIGHT,
@@ -206,14 +212,14 @@ export const getCodeBlockStyles = theme => (highlightedStartText, highlightedEnd
206
212
  ...getBaseCodeStyles(theme),
207
213
  ...syntaxKeywordColors(theme),
208
214
  // this is to account for SSR spacing issue once loaded in browser
209
- '& .linenumber, .react-syntax-highlighter-line-number': lineNumberStyle(theme),
215
+ '& .linenumber, .ds-sh-line-number': lineNumberStyle(theme),
210
216
  '& .linenumber': {
211
217
  display: 'inline-block !important',
212
218
  float: 'left'
213
219
  },
214
220
  // these styles are for line highlighting
215
221
  '& [data-ds--code--row]': {
216
- display: 'block',
222
+ display: showLineNumbers ? 'flex' : 'block',
217
223
  paddingRight: `${SPACING}px !important`,
218
224
  marginRight: `-${SPACING}px`
219
225
  },
@@ -229,11 +235,12 @@ export const getCodeBlockStyles = theme => (highlightedStartText, highlightedEnd
229
235
  whiteSpace: 'nowrap',
230
236
  width: '1px'
231
237
  },
238
+ // The formatting here is an accessibility convention
232
239
  '&::before': {
233
- content: `", ${highlightedStartText}, "`
240
+ content: `" [${highlightedStartText}] "`
234
241
  },
235
242
  '&::after': {
236
- content: `", ${highlightedEndText}, "`
243
+ content: `" [${highlightedEndText}] "`
237
244
  }
238
245
  },
239
246
  '& [data-ds--code--row--highlight] .linenumber': {
@@ -258,7 +265,7 @@ export const getCodeBlockStyles = theme => (highlightedStartText, highlightedEnd
258
265
  },
259
266
  '& code:first-of-type': {
260
267
  paddingRight: `0px !important`,
261
- backgroundImage: hasLineNumbers ? `linear-gradient(to right, var(${VAR_CODE_LINE_NUMBER_BG_COLOR},${theme.lineNumberBgColor}), var(${VAR_CODE_LINE_NUMBER_BG_COLOR},${theme.lineNumberBgColor})
268
+ backgroundImage: showLineNumbers ? `linear-gradient(to right, var(${VAR_CODE_LINE_NUMBER_BG_COLOR},${theme.lineNumberBgColor}), var(${VAR_CODE_LINE_NUMBER_BG_COLOR},${theme.lineNumberBgColor})
262
269
  calc(${theme.lineNumberWidth} + ${LINE_NUMBER_GUTTER}px), transparent calc(${theme.lineNumberWidth} + ${LINE_NUMBER_GUTTER}px), transparent)` : undefined
263
270
  },
264
271
  // we need to use last-of-type because when Code is SSR'd
@@ -266,7 +273,11 @@ export const getCodeBlockStyles = theme => (highlightedStartText, highlightedEnd
266
273
  // applied to the first one
267
274
  '& code:last-of-type': {
268
275
  paddingRight: `${SPACING}px !important`,
269
- flex: '1 0 auto'
276
+ flexBasis: 'auto',
277
+ flexGrow: 1,
278
+ // Needed for the highlight line to extend full-width
279
+ flexShrink: shouldWrapLongLines ? 1 : 0,
280
+ wordBreak: 'break-word'
270
281
  },
271
282
  // Prevents empty code blocks from vertically collapsing
272
283
  'code > span:only-child:empty:before, code > span:only-child > span:only-child:empty:before': {
@@ -0,0 +1,51 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
+ import React from 'react';
4
+ import highlight from './lib/highlight';
5
+ // Uses the loader method of async bundling
6
+ // Instantiates highligher as a singleton, loading refractor only once per page (refractor/prism are singleton modules)
7
+ const generator = options => {
8
+ const {
9
+ loader
10
+ } = options;
11
+
12
+ // eslint-disable-next-line @repo/internal/react/no-class-components
13
+ class AsyncHighlighter extends React.PureComponent {
14
+ // Useful in tests
15
+ static preload() {
16
+ return AsyncHighlighter.loadAstGenerator();
17
+ }
18
+ static loadAstGenerator() {
19
+ AsyncHighlighter.astGeneratorPromise = loader().then(astGenerator => {
20
+ AsyncHighlighter.astGenerator = astGenerator;
21
+ return astGenerator;
22
+ });
23
+ return AsyncHighlighter.astGeneratorPromise;
24
+ }
25
+ componentDidMount() {
26
+ if (!AsyncHighlighter.astGeneratorPromise) {
27
+ AsyncHighlighter.loadAstGenerator();
28
+ }
29
+ if (!AsyncHighlighter.astGenerator && AsyncHighlighter.astGeneratorPromise) {
30
+ AsyncHighlighter.astGeneratorPromise.then(() => {
31
+ this.forceUpdate();
32
+ });
33
+ }
34
+ }
35
+ render() {
36
+ return /*#__PURE__*/React.createElement(AsyncHighlighter.highlightInstance, _extends({}, this.props, {
37
+ astGenerator: AsyncHighlighter.astGenerator
38
+ }));
39
+ }
40
+ }
41
+ _defineProperty(AsyncHighlighter, "astGenerator", null);
42
+ _defineProperty(AsyncHighlighter, "highlightInstance", highlight);
43
+ return AsyncHighlighter;
44
+ };
45
+ export default generator({
46
+ loader: () => import( /* webpackChunkName: "@atlaskit-internal_refractor-import" */
47
+ 'refractor').then(module => {
48
+ // Webpack 3 returns module.exports as default as module, but webpack 4 returns module.exports as module.default
49
+ return module.default || module;
50
+ })
51
+ });
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Original library: https://github.com/react-syntax-highlighter/react-syntax-highlighter
3
+ * All modifications by Atlassian
4
+ */
5
+
6
+ /**
7
+ * MIT License
8
+ *
9
+ * Copyright (c) 2019 Conor Hastings
10
+ *
11
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ * of this software and associated documentation files (the "Software"), to deal
13
+ * in the Software without restriction, including without limitation the rights
14
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ * copies of the Software, and to permit persons to whom the Software is
16
+ * furnished to do so, subject to the following conditions:
17
+ *
18
+ * The above copyright notice and this permission notice shall be included in all
19
+ * copies or substantial portions of the Software.
20
+ *
21
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ * SOFTWARE.
28
+ */
29
+
30
+ /**
31
+ * __Syntax Highlighter__
32
+ *
33
+ * A syntax highlighter based on top of [refractor](https://github.com/wooorm/refractor).
34
+ * @atlaskit/code uses this under-the-hood, but it is not intended for public consumption.
35
+ * You should be using @atlaskit/code directly.
36
+ */
37
+ import SyntaxHighlighter from './async';
38
+ export default SyntaxHighlighter;
@@ -0,0 +1,73 @@
1
+ import { memo } from 'react';
2
+ import processLines from './process';
3
+ import ReactRenderer from './react-renderer';
4
+
5
+ /**
6
+ * Takes in a code string and (in the default behaviour):
7
+ * - Uses refractor to turn it into a tree structure with highlighting metadata
8
+ * - Collapses this tree into lines for a renderer
9
+ * - Passes these lines to a React renderer
10
+ *
11
+ * In future, the final step could have a custom renderer.
12
+ */
13
+ const Highlight = /*#__PURE__*/memo(function Highlight({
14
+ language = 'text',
15
+ testId,
16
+ text = '',
17
+ codeTagProps = {
18
+ className: `language-${language}`
19
+ },
20
+ showLineNumbers = false,
21
+ shouldCreateParentElementForLines = false,
22
+ shouldWrapLongLines = false,
23
+ lineProps = {},
24
+ codeBidiWarnings,
25
+ codeBidiWarningLabel,
26
+ codeBidiWarningTooltipEnabled,
27
+ astGenerator = null,
28
+ ...rest
29
+ }) {
30
+ // TODO maybe we call this code or text everywhere; for now we match the API in
31
+ // @atlaskit/codeblock
32
+ const code = text;
33
+ const generatorClassName = 'prismjs';
34
+ const containerProps = {
35
+ ...rest,
36
+ 'data-testid': testId,
37
+ className: rest.className ? `${generatorClassName} ${rest.className}` : generatorClassName
38
+ };
39
+ if (shouldWrapLongLines) {
40
+ codeTagProps.style = {
41
+ whiteSpace: 'pre-wrap',
42
+ wordBreak: 'break-word'
43
+ };
44
+ } else {
45
+ codeTagProps.style = {
46
+ whiteSpace: 'pre'
47
+ };
48
+ }
49
+ const codeBidiWarningConfig = {
50
+ codeBidiWarnings,
51
+ codeBidiWarningLabel,
52
+ codeBidiWarningTooltipEnabled
53
+ };
54
+
55
+ // Tree + logic into rows
56
+ const rows = processLines({
57
+ astGenerator,
58
+ code,
59
+ language,
60
+ shouldCreateParentElementForLines: shouldCreateParentElementForLines || !!shouldWrapLongLines,
61
+ lineProps,
62
+ showLineNumbers
63
+ });
64
+
65
+ // Rows + logic into a renderer
66
+ return ReactRenderer({
67
+ containerProps,
68
+ codeTagProps,
69
+ rows,
70
+ codeBidiWarningConfig
71
+ });
72
+ });
73
+ export default Highlight;