@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.
- package/CHANGELOG.md +18 -0
- package/dist/cjs/bidi-warning/bidi-warning-decorator.js +8 -0
- package/dist/cjs/bidi-warning/ui/index.js +8 -0
- package/dist/cjs/code-block.js +22 -20
- package/dist/cjs/internal/theme/styles.js +20 -9
- package/dist/cjs/syntax-highlighter/async.js +88 -0
- package/dist/cjs/syntax-highlighter/index.js +44 -0
- package/dist/cjs/syntax-highlighter/lib/highlight.js +91 -0
- package/dist/cjs/syntax-highlighter/lib/process/create-line-element.js +74 -0
- package/dist/cjs/syntax-highlighter/lib/process/create-line.js +32 -0
- package/dist/cjs/syntax-highlighter/lib/process/flatten-code-tree.js +29 -0
- package/dist/cjs/syntax-highlighter/lib/process/get-code-tree.js +22 -0
- package/dist/cjs/syntax-highlighter/lib/process/get-inline-line-number.js +23 -0
- package/dist/cjs/syntax-highlighter/lib/process/index.js +122 -0
- package/dist/cjs/syntax-highlighter/lib/react-renderer/create-children.js +21 -0
- package/dist/cjs/syntax-highlighter/lib/react-renderer/create-element.js +57 -0
- package/dist/cjs/syntax-highlighter/lib/react-renderer/index.js +30 -0
- package/dist/cjs/syntax-highlighter/types.js +31 -0
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/bidi-warning/bidi-warning-decorator.js +8 -0
- package/dist/es2019/bidi-warning/ui/index.js +8 -0
- package/dist/es2019/code-block.js +18 -18
- package/dist/es2019/internal/theme/styles.js +20 -9
- package/dist/es2019/syntax-highlighter/async.js +51 -0
- package/dist/es2019/syntax-highlighter/index.js +38 -0
- package/dist/es2019/syntax-highlighter/lib/highlight.js +73 -0
- package/dist/es2019/syntax-highlighter/lib/process/create-line-element.js +65 -0
- package/dist/es2019/syntax-highlighter/lib/process/create-line.js +23 -0
- package/dist/es2019/syntax-highlighter/lib/process/flatten-code-tree.js +18 -0
- package/dist/es2019/syntax-highlighter/lib/process/get-code-tree.js +16 -0
- package/dist/es2019/syntax-highlighter/lib/process/get-inline-line-number.js +17 -0
- package/dist/es2019/syntax-highlighter/lib/process/index.js +114 -0
- package/dist/es2019/syntax-highlighter/lib/react-renderer/create-children.js +12 -0
- package/dist/es2019/syntax-highlighter/lib/react-renderer/create-element.js +53 -0
- package/dist/es2019/syntax-highlighter/lib/react-renderer/index.js +23 -0
- package/dist/es2019/syntax-highlighter/types.js +9 -0
- package/dist/es2019/version.json +1 -1
- package/dist/esm/bidi-warning/bidi-warning-decorator.js +8 -0
- package/dist/esm/bidi-warning/ui/index.js +8 -0
- package/dist/esm/code-block.js +20 -19
- package/dist/esm/internal/theme/styles.js +20 -9
- package/dist/esm/syntax-highlighter/async.js +76 -0
- package/dist/esm/syntax-highlighter/index.js +38 -0
- package/dist/esm/syntax-highlighter/lib/highlight.js +84 -0
- package/dist/esm/syntax-highlighter/lib/process/create-line-element.js +67 -0
- package/dist/esm/syntax-highlighter/lib/process/create-line.js +24 -0
- package/dist/esm/syntax-highlighter/lib/process/flatten-code-tree.js +22 -0
- package/dist/esm/syntax-highlighter/lib/process/get-code-tree.js +16 -0
- package/dist/esm/syntax-highlighter/lib/process/get-inline-line-number.js +17 -0
- package/dist/esm/syntax-highlighter/lib/process/index.js +115 -0
- package/dist/esm/syntax-highlighter/lib/react-renderer/create-children.js +14 -0
- package/dist/esm/syntax-highlighter/lib/react-renderer/create-element.js +50 -0
- package/dist/esm/syntax-highlighter/lib/react-renderer/index.js +24 -0
- package/dist/esm/syntax-highlighter/types.js +24 -0
- package/dist/esm/version.json +1 -1
- package/dist/types/bidi-warning/bidi-warning-decorator.d.ts +7 -0
- package/dist/types/bidi-warning/ui/index.d.ts +8 -0
- package/dist/types/bidi-warning/ui/types.d.ts +11 -15
- package/dist/types/extract-react-types/code-block.d.ts +24 -14
- package/dist/types/internal/theme/styles.d.ts +1 -1
- package/dist/types/internal/types.d.ts +31 -18
- package/dist/types/syntax-highlighter/async.d.ts +3 -0
- package/dist/types/syntax-highlighter/index.d.ts +36 -0
- package/dist/types/syntax-highlighter/lib/highlight.d.ts +12 -0
- package/dist/types/syntax-highlighter/lib/process/create-line-element.d.ts +9 -0
- package/dist/types/syntax-highlighter/lib/process/create-line.d.ts +3 -0
- package/dist/types/syntax-highlighter/lib/process/flatten-code-tree.d.ts +2 -0
- package/dist/types/syntax-highlighter/lib/process/get-code-tree.d.ts +2 -0
- package/dist/types/syntax-highlighter/lib/process/get-inline-line-number.d.ts +2 -0
- package/dist/types/syntax-highlighter/lib/process/index.d.ts +17 -0
- package/dist/types/syntax-highlighter/lib/react-renderer/create-children.d.ts +3 -0
- package/dist/types/syntax-highlighter/lib/react-renderer/create-element.d.ts +7 -0
- package/dist/types/syntax-highlighter/lib/react-renderer/index.d.ts +15 -0
- package/dist/types/syntax-highlighter/types.d.ts +129 -0
- package/dist/types/types.d.ts +10 -11
- package/package.json +13 -9
- package/report.api.md +1 -0
- package/dist/cjs/react-syntax-highlighter-bidi-warning-renderer.js +0 -156
- package/dist/es2019/react-syntax-highlighter-bidi-warning-renderer.js +0 -149
- package/dist/esm/react-syntax-highlighter-bidi-warning-renderer.js +0 -155
- package/dist/types/react-syntax-highlighter-bidi-warning-renderer.d.ts +0 -9
|
@@ -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,84 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
|
|
3
|
+
var _excluded = ["language", "testId", "text", "codeTagProps", "showLineNumbers", "shouldCreateParentElementForLines", "shouldWrapLongLines", "lineProps", "codeBidiWarnings", "codeBidiWarningLabel", "codeBidiWarningTooltipEnabled", "astGenerator"];
|
|
4
|
+
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; }
|
|
5
|
+
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) { _defineProperty(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; }
|
|
6
|
+
import { memo } from 'react';
|
|
7
|
+
import processLines from './process';
|
|
8
|
+
import ReactRenderer from './react-renderer';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Takes in a code string and (in the default behaviour):
|
|
12
|
+
* - Uses refractor to turn it into a tree structure with highlighting metadata
|
|
13
|
+
* - Collapses this tree into lines for a renderer
|
|
14
|
+
* - Passes these lines to a React renderer
|
|
15
|
+
*
|
|
16
|
+
* In future, the final step could have a custom renderer.
|
|
17
|
+
*/
|
|
18
|
+
var Highlight = /*#__PURE__*/memo(function Highlight(_ref) {
|
|
19
|
+
var _ref$language = _ref.language,
|
|
20
|
+
language = _ref$language === void 0 ? 'text' : _ref$language,
|
|
21
|
+
testId = _ref.testId,
|
|
22
|
+
_ref$text = _ref.text,
|
|
23
|
+
text = _ref$text === void 0 ? '' : _ref$text,
|
|
24
|
+
_ref$codeTagProps = _ref.codeTagProps,
|
|
25
|
+
codeTagProps = _ref$codeTagProps === void 0 ? {
|
|
26
|
+
className: "language-".concat(language)
|
|
27
|
+
} : _ref$codeTagProps,
|
|
28
|
+
_ref$showLineNumbers = _ref.showLineNumbers,
|
|
29
|
+
showLineNumbers = _ref$showLineNumbers === void 0 ? false : _ref$showLineNumbers,
|
|
30
|
+
_ref$shouldCreatePare = _ref.shouldCreateParentElementForLines,
|
|
31
|
+
shouldCreateParentElementForLines = _ref$shouldCreatePare === void 0 ? false : _ref$shouldCreatePare,
|
|
32
|
+
_ref$shouldWrapLongLi = _ref.shouldWrapLongLines,
|
|
33
|
+
shouldWrapLongLines = _ref$shouldWrapLongLi === void 0 ? false : _ref$shouldWrapLongLi,
|
|
34
|
+
_ref$lineProps = _ref.lineProps,
|
|
35
|
+
lineProps = _ref$lineProps === void 0 ? {} : _ref$lineProps,
|
|
36
|
+
codeBidiWarnings = _ref.codeBidiWarnings,
|
|
37
|
+
codeBidiWarningLabel = _ref.codeBidiWarningLabel,
|
|
38
|
+
codeBidiWarningTooltipEnabled = _ref.codeBidiWarningTooltipEnabled,
|
|
39
|
+
_ref$astGenerator = _ref.astGenerator,
|
|
40
|
+
astGenerator = _ref$astGenerator === void 0 ? null : _ref$astGenerator,
|
|
41
|
+
rest = _objectWithoutProperties(_ref, _excluded);
|
|
42
|
+
// TODO maybe we call this code or text everywhere; for now we match the API in
|
|
43
|
+
// @atlaskit/codeblock
|
|
44
|
+
var code = text;
|
|
45
|
+
var generatorClassName = 'prismjs';
|
|
46
|
+
var containerProps = _objectSpread(_objectSpread({}, rest), {}, {
|
|
47
|
+
'data-testid': testId,
|
|
48
|
+
className: rest.className ? "".concat(generatorClassName, " ").concat(rest.className) : generatorClassName
|
|
49
|
+
});
|
|
50
|
+
if (shouldWrapLongLines) {
|
|
51
|
+
codeTagProps.style = {
|
|
52
|
+
whiteSpace: 'pre-wrap',
|
|
53
|
+
wordBreak: 'break-word'
|
|
54
|
+
};
|
|
55
|
+
} else {
|
|
56
|
+
codeTagProps.style = {
|
|
57
|
+
whiteSpace: 'pre'
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
var codeBidiWarningConfig = {
|
|
61
|
+
codeBidiWarnings: codeBidiWarnings,
|
|
62
|
+
codeBidiWarningLabel: codeBidiWarningLabel,
|
|
63
|
+
codeBidiWarningTooltipEnabled: codeBidiWarningTooltipEnabled
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Tree + logic into rows
|
|
67
|
+
var rows = processLines({
|
|
68
|
+
astGenerator: astGenerator,
|
|
69
|
+
code: code,
|
|
70
|
+
language: language,
|
|
71
|
+
shouldCreateParentElementForLines: shouldCreateParentElementForLines || !!shouldWrapLongLines,
|
|
72
|
+
lineProps: lineProps,
|
|
73
|
+
showLineNumbers: showLineNumbers
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Rows + logic into a renderer
|
|
77
|
+
return ReactRenderer({
|
|
78
|
+
containerProps: containerProps,
|
|
79
|
+
codeTagProps: codeTagProps,
|
|
80
|
+
rows: rows,
|
|
81
|
+
codeBidiWarningConfig: codeBidiWarningConfig
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
export default Highlight;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
import getInlineLineNumber from './get-inline-line-number';
|
|
3
|
+
export default function createLineElement(_ref) {
|
|
4
|
+
var children = _ref.children,
|
|
5
|
+
lineNumber = _ref.lineNumber,
|
|
6
|
+
showLineNumbers = _ref.showLineNumbers,
|
|
7
|
+
_ref$lineProps = _ref.lineProps,
|
|
8
|
+
lineProps = _ref$lineProps === void 0 ? {} : _ref$lineProps,
|
|
9
|
+
_ref$className = _ref.className,
|
|
10
|
+
className = _ref$className === void 0 ? [] : _ref$className;
|
|
11
|
+
var properties = typeof lineProps === 'function' ? lineProps(lineNumber) : lineProps;
|
|
12
|
+
properties.className = className;
|
|
13
|
+
var currentChildren = children;
|
|
14
|
+
if (lineNumber && showLineNumbers) {
|
|
15
|
+
// When syntax highlighting is NOT turned on, the entire LOC is just a single
|
|
16
|
+
// child. We can then happily create the line number and the LOC as siblings...
|
|
17
|
+
if (currentChildren.length === 1) {
|
|
18
|
+
currentChildren = [getInlineLineNumber(lineNumber)].concat(_toConsumableArray(currentChildren));
|
|
19
|
+
} else {
|
|
20
|
+
// ... However, when syntax highlighting IS on, a span is created for each
|
|
21
|
+
// tokenised node in the AST (eg. <span>import</span><span>React</span>).
|
|
22
|
+
// When shouldWrapLongLines is true, the row becomes `display: flex` and
|
|
23
|
+
// forces all its children to be equal height. This can be a source of
|
|
24
|
+
// visual bugs where a LOC is broken up weirdly into segments.
|
|
25
|
+
//
|
|
26
|
+
// +---------------------------------------+
|
|
27
|
+
// | row |
|
|
28
|
+
// | +----+ +-------+ +--------+ +------+ |
|
|
29
|
+
// | |line| |key | |keywords| |key | |
|
|
30
|
+
// | |no. | |word | | | |word | |
|
|
31
|
+
// | | | | | | | | | |
|
|
32
|
+
// | +----+ +-------+ +--------+ +------+ |
|
|
33
|
+
// +---------------------------------------+
|
|
34
|
+
//
|
|
35
|
+
// Nesting the children one layer deeper (i.e. creating an extra span)
|
|
36
|
+
// ensures that the line number and the ENTIRE line of code are aligned by
|
|
37
|
+
// the parent flexbox (the row).
|
|
38
|
+
//
|
|
39
|
+
// +---------------------------------------------+
|
|
40
|
+
// | row |
|
|
41
|
+
// | +----+ +--------------------------------+ |
|
|
42
|
+
// | |line| | extra span we are creating | |
|
|
43
|
+
// | |no. | | +-------+ +--------+ +------+ | |
|
|
44
|
+
// | | | | |key | |keywords| |key | | |
|
|
45
|
+
// | | | | |word | | | |word | | |
|
|
46
|
+
// | | | | | | | | | | | |
|
|
47
|
+
// | | | | +-------+ +--------+ +------+ | |
|
|
48
|
+
// | +----+ +--------------------------------+ |
|
|
49
|
+
// +---------------------------------------------+
|
|
50
|
+
//
|
|
51
|
+
currentChildren = [getInlineLineNumber(lineNumber), {
|
|
52
|
+
type: 'element',
|
|
53
|
+
tagName: 'span',
|
|
54
|
+
properties: {
|
|
55
|
+
className: []
|
|
56
|
+
},
|
|
57
|
+
children: currentChildren
|
|
58
|
+
}];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
type: 'element',
|
|
63
|
+
tagName: 'span',
|
|
64
|
+
properties: properties,
|
|
65
|
+
children: currentChildren
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import createLineElement from './create-line-element';
|
|
2
|
+
import getInlineLineNumber from './get-inline-line-number';
|
|
3
|
+
function createLineGenerator(lineProps, shouldCreateParentElementForLines, showLineNumbers) {
|
|
4
|
+
return function (children, lineNumber) {
|
|
5
|
+
var className = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
6
|
+
// Needed for more complex line creation
|
|
7
|
+
if (shouldCreateParentElementForLines || className.length > 0) {
|
|
8
|
+
return createLineElement({
|
|
9
|
+
children: children,
|
|
10
|
+
lineNumber: lineNumber,
|
|
11
|
+
showLineNumbers: showLineNumbers,
|
|
12
|
+
lineProps: lineProps,
|
|
13
|
+
className: className
|
|
14
|
+
});
|
|
15
|
+
} else {
|
|
16
|
+
// Simple line creation without the bells and whistles
|
|
17
|
+
if (showLineNumbers && lineNumber) {
|
|
18
|
+
children.unshift(getInlineLineNumber(lineNumber));
|
|
19
|
+
}
|
|
20
|
+
return children;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export default createLineGenerator;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import createLineElement from './create-line-element';
|
|
2
|
+
export default function flattenCodeTree(tree) {
|
|
3
|
+
var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
4
|
+
var className = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
5
|
+
var newTree = [];
|
|
6
|
+
for (var i = 0; i < tree.length; i++) {
|
|
7
|
+
var node = tree[i];
|
|
8
|
+
if (node.type === 'text') {
|
|
9
|
+
newTree.push(createLineElement({
|
|
10
|
+
children: [node],
|
|
11
|
+
lineNumber: offset,
|
|
12
|
+
className: className
|
|
13
|
+
}));
|
|
14
|
+
} else if (node.children) {
|
|
15
|
+
var classNames = className.concat(node.properties.className || []);
|
|
16
|
+
flattenCodeTree(node.children, offset + 1, classNames).forEach(function (i) {
|
|
17
|
+
return newTree.push(i);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return newTree;
|
|
22
|
+
}
|
|
@@ -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--".concat(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,115 @@
|
|
|
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
|
+
var 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(_ref) {
|
|
16
|
+
var astGenerator = _ref.astGenerator,
|
|
17
|
+
code = _ref.code,
|
|
18
|
+
language = _ref.language,
|
|
19
|
+
shouldCreateParentElementForLines = _ref.shouldCreateParentElementForLines,
|
|
20
|
+
lineProps = _ref.lineProps,
|
|
21
|
+
showLineNumbers = _ref.showLineNumbers;
|
|
22
|
+
var codeTree = getCodeTree(language, code, astGenerator);
|
|
23
|
+
var startingLineNumber = 1;
|
|
24
|
+
var createLine = createLineGenerator(lineProps, shouldCreateParentElementForLines, showLineNumbers);
|
|
25
|
+
var newTree = [];
|
|
26
|
+
var lastLineBreakIndex = -1;
|
|
27
|
+
var index = 0;
|
|
28
|
+
|
|
29
|
+
// Seems odd we flatten the tree immediately - what work could we do on it more performantly than on the lines?
|
|
30
|
+
var tree = flattenCodeTree(codeTree);
|
|
31
|
+
var _loop = function _loop() {
|
|
32
|
+
var testNode = tree[index];
|
|
33
|
+
if (testNode.type === 'text') {
|
|
34
|
+
index++;
|
|
35
|
+
return "continue";
|
|
36
|
+
}
|
|
37
|
+
var node = testNode;
|
|
38
|
+
var firstChildNode = node.children[0];
|
|
39
|
+
if (firstChildNode.type === 'text') {
|
|
40
|
+
var value = firstChildNode.value;
|
|
41
|
+
var newLines = getNewLines(value);
|
|
42
|
+
if (newLines) {
|
|
43
|
+
var splitValue = value.split('\n');
|
|
44
|
+
splitValue.forEach(function (text, i) {
|
|
45
|
+
var lineNumber = newTree.length + startingLineNumber;
|
|
46
|
+
var newChild = {
|
|
47
|
+
type: 'text',
|
|
48
|
+
value: "".concat(text, "\n")
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// if it's the first line
|
|
52
|
+
if (i === 0) {
|
|
53
|
+
var _children = tree.slice(lastLineBreakIndex + 1, index).concat(createLineElement({
|
|
54
|
+
children: [newChild],
|
|
55
|
+
className: node.properties.className,
|
|
56
|
+
lineNumber: lineNumber
|
|
57
|
+
}));
|
|
58
|
+
var _line = createLine(_children, lineNumber);
|
|
59
|
+
newTree.push(_line);
|
|
60
|
+
|
|
61
|
+
// if it's the last line
|
|
62
|
+
} else if (i === splitValue.length - 1) {
|
|
63
|
+
var nextNode = tree[index + 1];
|
|
64
|
+
var stringChild = nextNode && nextNode.children && nextNode.children[0];
|
|
65
|
+
// Similar to newChild above, but no newline
|
|
66
|
+
var lastLineInPreviousSpan = {
|
|
67
|
+
type: 'text',
|
|
68
|
+
value: "".concat(text)
|
|
69
|
+
};
|
|
70
|
+
if (stringChild) {
|
|
71
|
+
var newElem = createLineElement({
|
|
72
|
+
children: [lastLineInPreviousSpan],
|
|
73
|
+
className: node.properties.className,
|
|
74
|
+
lineNumber: lineNumber
|
|
75
|
+
});
|
|
76
|
+
tree.splice(index + 1, 0, newElem);
|
|
77
|
+
} else {
|
|
78
|
+
var _children2 = [lastLineInPreviousSpan];
|
|
79
|
+
var _line2 = createLine(_children2, lineNumber, node.properties.className);
|
|
80
|
+
newTree.push(_line2);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// if it's neither the first nor the last line
|
|
84
|
+
} else {
|
|
85
|
+
var _children3 = [newChild];
|
|
86
|
+
var _line3 = createLine(_children3, lineNumber, node.properties.className);
|
|
87
|
+
newTree.push(_line3);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
lastLineBreakIndex = index;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
index++;
|
|
94
|
+
};
|
|
95
|
+
while (index < tree.length) {
|
|
96
|
+
var _ret = _loop();
|
|
97
|
+
if (_ret === "continue") continue;
|
|
98
|
+
}
|
|
99
|
+
if (lastLineBreakIndex !== tree.length - 1) {
|
|
100
|
+
var children = tree.slice(lastLineBreakIndex + 1, tree.length);
|
|
101
|
+
if (children && children.length) {
|
|
102
|
+
var lineNumber = newTree.length + startingLineNumber;
|
|
103
|
+
var line = createLine(children, lineNumber);
|
|
104
|
+
newTree.push(line);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (shouldCreateParentElementForLines) {
|
|
108
|
+
return newTree;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// If shouldCreateParentElementForLines was off, we still have a tree structure we need to flatten
|
|
112
|
+
// We have (RefractorNode | RefractorNode[])[] but need RefractorNode[]
|
|
113
|
+
// This seems like a code smell to review
|
|
114
|
+
return newTree.flat(1);
|
|
115
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import createElement from './create-element';
|
|
2
|
+
export default function createChildren(codeBidiWarningConfig) {
|
|
3
|
+
var childrenCount = 0;
|
|
4
|
+
return function (children) {
|
|
5
|
+
childrenCount += 1;
|
|
6
|
+
return children.map(function (child, i) {
|
|
7
|
+
return createElement({
|
|
8
|
+
node: child,
|
|
9
|
+
codeBidiWarningConfig: codeBidiWarningConfig,
|
|
10
|
+
key: "code-segment-".concat(childrenCount, "-").concat(i)
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
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; }
|
|
3
|
+
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) { _defineProperty(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; }
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import CodeBidiWarning from '../../../bidi-warning';
|
|
6
|
+
import codeBidiWarningDecorator from '../../../bidi-warning/bidi-warning-decorator';
|
|
7
|
+
import createChildren from './create-children';
|
|
8
|
+
function createClassNameString(classNames) {
|
|
9
|
+
return classNames ? classNames.join(' ') : '';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// NOTE: This is a function call rather than a React component because, for
|
|
13
|
+
// unknown reasons, it appears to be more performant. We tried and measured both
|
|
14
|
+
// and this stacks up better than as a memoised React component. Something to look
|
|
15
|
+
// into in the future.
|
|
16
|
+
export default function createElement(_ref) {
|
|
17
|
+
var node = _ref.node,
|
|
18
|
+
codeBidiWarningConfig = _ref.codeBidiWarningConfig,
|
|
19
|
+
key = _ref.key;
|
|
20
|
+
if (node.type === 'text') {
|
|
21
|
+
var value = node.value;
|
|
22
|
+
// occasionally a numeric value is passed when the type is text
|
|
23
|
+
var textValue = "".concat(value);
|
|
24
|
+
if (codeBidiWarningConfig.codeBidiWarnings) {
|
|
25
|
+
var decorated = codeBidiWarningDecorator(textValue, function (_ref2) {
|
|
26
|
+
var bidiCharacter = _ref2.bidiCharacter,
|
|
27
|
+
index = _ref2.index;
|
|
28
|
+
return /*#__PURE__*/React.createElement(CodeBidiWarning, {
|
|
29
|
+
bidiCharacter: bidiCharacter,
|
|
30
|
+
key: index,
|
|
31
|
+
label: codeBidiWarningConfig.codeBidiWarningLabel,
|
|
32
|
+
tooltipEnabled: codeBidiWarningConfig.codeBidiWarningTooltipEnabled
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
return decorated;
|
|
36
|
+
}
|
|
37
|
+
return textValue;
|
|
38
|
+
} else {
|
|
39
|
+
var properties = node.properties,
|
|
40
|
+
tagName = node.tagName;
|
|
41
|
+
var childrenCreator = createChildren(codeBidiWarningConfig);
|
|
42
|
+
var props = _objectSpread(_objectSpread({}, properties), {}, {
|
|
43
|
+
className: createClassNameString(properties.className)
|
|
44
|
+
});
|
|
45
|
+
var children = childrenCreator(node.children);
|
|
46
|
+
return /*#__PURE__*/React.createElement(tagName, _objectSpread({
|
|
47
|
+
key: key
|
|
48
|
+
}, props), children);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
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(_ref) {
|
|
12
|
+
var containerProps = _ref.containerProps,
|
|
13
|
+
codeTagProps = _ref.codeTagProps,
|
|
14
|
+
rows = _ref.rows,
|
|
15
|
+
codeBidiWarningConfig = _ref.codeBidiWarningConfig;
|
|
16
|
+
var renderedRows = rows.map(function (node, i) {
|
|
17
|
+
return createElement({
|
|
18
|
+
node: node,
|
|
19
|
+
codeBidiWarningConfig: codeBidiWarningConfig,
|
|
20
|
+
key: "code-segment".concat(i)
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
return /*#__PURE__*/React.createElement("span", containerProps, /*#__PURE__*/React.createElement("code", codeTagProps, renderedRows));
|
|
24
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
2
|
+
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
3
|
+
import _inherits from "@babel/runtime/helpers/inherits";
|
|
4
|
+
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
|
|
5
|
+
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
6
|
+
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); }; }
|
|
7
|
+
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; } }
|
|
8
|
+
import React from 'react';
|
|
9
|
+
// This wrapper supports the async loading of refractor and language grammars. The internal Highlight is a memo() functional component as expected
|
|
10
|
+
// eslint-disable-next-line @repo/internal/react/no-class-components
|
|
11
|
+
export var SyntaxHighlighter = /*#__PURE__*/function (_React$PureComponent) {
|
|
12
|
+
_inherits(SyntaxHighlighter, _React$PureComponent);
|
|
13
|
+
var _super = _createSuper(SyntaxHighlighter);
|
|
14
|
+
function SyntaxHighlighter() {
|
|
15
|
+
_classCallCheck(this, SyntaxHighlighter);
|
|
16
|
+
return _super.apply(this, arguments);
|
|
17
|
+
}
|
|
18
|
+
return _createClass(SyntaxHighlighter);
|
|
19
|
+
}(React.PureComponent);
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Function that receives current line number as argument and returns a
|
|
23
|
+
* line props object to be applied to each `span` wrapping code line.
|
|
24
|
+
*/
|
package/dist/esm/version.json
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
export declare const bidiCharacterRegex: RegExp;
|
|
2
|
+
/**
|
|
3
|
+
* __Code Bidi Warning Decorator__
|
|
4
|
+
*
|
|
5
|
+
* Checks the code to see if it contains any bidi characters.
|
|
6
|
+
* In case if bidi characters found - returns children with decorated
|
|
7
|
+
* bidi characters. If no bidi characters found - original text returned.
|
|
8
|
+
*/
|
|
2
9
|
export default function codeBidiWarningDecorator<DecoratorOutput>(originalText: string, decorate: (options: {
|
|
3
10
|
bidiCharacter: string;
|
|
4
11
|
index?: number;
|
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { CodeBidiWarningProps } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* __Bidi Warning__
|
|
5
|
+
*
|
|
6
|
+
* A component used to render a bidi character warning.
|
|
7
|
+
* A bidi character can be used to perform a "bidi override attack".
|
|
8
|
+
*
|
|
9
|
+
* 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
|
|
10
|
+
*/
|
|
3
11
|
export default function BidiWarning({ testId, bidiCharacter, skipChildren, tooltipEnabled, label, }: CodeBidiWarningProps): JSX.Element;
|
|
@@ -1,33 +1,29 @@
|
|
|
1
1
|
export declare type CodeBidiWarningProps = {
|
|
2
2
|
/**
|
|
3
|
-
* A
|
|
4
|
-
*
|
|
5
|
-
* serving as a hook for automated tests
|
|
3
|
+
* A unique string that appears as a data attribute `data-testid`
|
|
4
|
+
* in the rendered code. Serves as a hook for automated tests.
|
|
6
5
|
*/
|
|
7
6
|
testId?: string;
|
|
8
7
|
/**
|
|
9
|
-
* A bidi character which can be used to perform a "bidi override attack".
|
|
10
|
-
*
|
|
11
|
-
* See the following document for details.
|
|
12
|
-
*
|
|
13
|
-
* 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
|
|
8
|
+
* A bidi character which can be used to perform a "bidi override attack". See https://hello.atlassian.net/wiki/spaces/PRODSEC/pages/1347434677/PSHELP-2943+Investigate+Trojan+Source+Attack+Vulnerability#1
|
|
14
9
|
*/
|
|
15
10
|
bidiCharacter: string;
|
|
16
11
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* not work as expected.
|
|
12
|
+
* Sets whether to render tooltip with the warning or not.
|
|
13
|
+
* Intended to be disabled when used in a mobile view, such as in the editor via mobile bridge,
|
|
14
|
+
* where the tooltip could end up being cut off or otherwise not work as expected.
|
|
15
|
+
* @default true
|
|
22
16
|
*/
|
|
23
17
|
tooltipEnabled?: boolean;
|
|
24
18
|
/**
|
|
19
|
+
* Sets whether bidi character should be wrapped in decorator.
|
|
25
20
|
* Useful when wrapping the bidi character with the decoration is not achievable.
|
|
21
|
+
* @default false
|
|
26
22
|
*/
|
|
27
23
|
skipChildren?: boolean;
|
|
28
24
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
25
|
+
* Label for the bidi warning tooltip.
|
|
26
|
+
* @default "Bidirectional characters change the order that text is rendered. This could be used to obscure malicious code."
|
|
31
27
|
*/
|
|
32
28
|
label?: string;
|
|
33
29
|
};
|
|
@@ -1,37 +1,47 @@
|
|
|
1
1
|
export default function CodeBlock(__: {
|
|
2
2
|
/**
|
|
3
|
-
* The code to be formatted
|
|
3
|
+
* The code to be formatted.
|
|
4
4
|
*/
|
|
5
5
|
text: string;
|
|
6
6
|
/**
|
|
7
|
-
* A unique string that appears as a data attribute `data-testid`
|
|
8
|
-
* in the rendered code. Serves as a hook for automated tests.
|
|
7
|
+
* A unique string that appears as a data attribute `data-testid` in the rendered code. Serves as a hook for automated tests.
|
|
9
8
|
*/
|
|
10
9
|
testId?: string;
|
|
11
10
|
/**
|
|
12
|
-
*
|
|
11
|
+
* Sets whether to display code line numbers or not. Defaults to `true`
|
|
13
12
|
*/
|
|
14
13
|
showLineNumbers?: boolean;
|
|
15
14
|
/**
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
Language reference designed to be populated from `SUPPORTED_LANGUAGES` in
|
|
16
|
+
`design-system/code`. Run against language grammars from PrismJS (full list
|
|
17
|
+
available at [PrismJS documentation](https://prismjs.com/#supported-languages)).
|
|
18
|
+
|
|
19
|
+
When set to `text` will not perform highlighting. If unsupported language
|
|
20
|
+
provided - code will be treated as "text" with no highlighting.
|
|
21
|
+
|
|
22
|
+
Defaults to `text`
|
|
18
23
|
*/
|
|
19
24
|
language?: string;
|
|
20
25
|
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
Comma delimited lines to highlight.
|
|
27
|
+
|
|
28
|
+
Example uses:
|
|
29
|
+
- To highlight one line `highlight="3"`
|
|
30
|
+
- To highlight a group of lines `highlight="1-5"`
|
|
31
|
+
- To highlight multiple groups `highlight="1-5,7,10,15-20"`
|
|
27
32
|
*/
|
|
28
33
|
highlight?: string;
|
|
29
34
|
/**
|
|
30
|
-
* Screen reader text for the start of a highlighted line
|
|
35
|
+
* Screen reader text for the start of a highlighted line.
|
|
31
36
|
*/
|
|
32
37
|
highlightedStartText?: string;
|
|
33
38
|
/**
|
|
34
|
-
* Screen reader text for the end of a highlighted line
|
|
39
|
+
* Screen reader text for the end of a highlighted line.
|
|
35
40
|
*/
|
|
36
41
|
highlightedEndText?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Sets whether long lines will create a horizontally scrolling container.
|
|
44
|
+
* When set to `true`, these lines will visually wrap instead. Defaults to `false`
|
|
45
|
+
*/
|
|
46
|
+
shouldWrapLongLines?: boolean;
|
|
37
47
|
}): null;
|