@atlaskit/renderer 98.0.0 → 100.0.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 +28 -0
- package/dist/cjs/react/hooks/use-bidi-warnings.js +45 -0
- package/dist/cjs/react/hooks/use-in-viewport.js +63 -0
- package/dist/cjs/react/index.js +5 -2
- package/dist/cjs/react/nodes/codeBlock/codeBlock.js +49 -0
- package/dist/cjs/react/nodes/codeBlock/components/codeBlockContainer.js +55 -0
- package/dist/cjs/react/nodes/codeBlock/components/lightWeightCodeBlock.js +82 -0
- package/dist/cjs/react/nodes/codeBlock/windowedCodeBlock.js +103 -0
- package/dist/cjs/react/nodes/codeBlockCopyButton.js +24 -27
- package/dist/cjs/react/nodes/heading.js +15 -18
- package/dist/cjs/react/nodes/index.js +34 -5
- package/dist/cjs/react/nodes/layoutColumn.js +7 -2
- package/dist/cjs/react/utils/clipboard.js +24 -0
- package/dist/cjs/ui/Renderer/index.js +12 -7
- package/dist/cjs/ui/Renderer/style.js +4 -2
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/react/hooks/use-bidi-warnings.js +28 -0
- package/dist/es2019/react/hooks/use-in-viewport.js +25 -0
- package/dist/es2019/react/index.js +5 -2
- package/dist/es2019/react/nodes/codeBlock/codeBlock.js +33 -0
- package/dist/es2019/react/nodes/codeBlock/components/codeBlockContainer.js +44 -0
- package/dist/es2019/react/nodes/codeBlock/components/lightWeightCodeBlock.js +58 -0
- package/dist/es2019/react/nodes/codeBlock/windowedCodeBlock.js +58 -0
- package/dist/es2019/react/nodes/codeBlockCopyButton.js +24 -28
- package/dist/es2019/react/nodes/heading.js +16 -20
- package/dist/es2019/react/nodes/index.js +22 -5
- package/dist/es2019/react/nodes/layoutColumn.js +7 -3
- package/dist/es2019/react/utils/clipboard.js +9 -0
- package/dist/es2019/ui/Renderer/index.js +9 -4
- package/dist/es2019/ui/Renderer/style.js +3 -0
- package/dist/es2019/version.json +1 -1
- package/dist/esm/react/hooks/use-bidi-warnings.js +29 -0
- package/dist/esm/react/hooks/use-in-viewport.js +51 -0
- package/dist/esm/react/index.js +5 -2
- package/dist/esm/react/nodes/codeBlock/codeBlock.js +32 -0
- package/dist/esm/react/nodes/codeBlock/components/codeBlockContainer.js +40 -0
- package/dist/esm/react/nodes/codeBlock/components/lightWeightCodeBlock.js +57 -0
- package/dist/esm/react/nodes/codeBlock/windowedCodeBlock.js +80 -0
- package/dist/esm/react/nodes/codeBlockCopyButton.js +24 -27
- package/dist/esm/react/nodes/heading.js +15 -18
- package/dist/esm/react/nodes/index.js +33 -5
- package/dist/esm/react/nodes/layoutColumn.js +8 -3
- package/dist/esm/react/utils/clipboard.js +15 -0
- package/dist/esm/ui/Renderer/index.js +12 -6
- package/dist/esm/ui/Renderer/style.js +3 -2
- package/dist/esm/version.json +1 -1
- package/dist/types/react/hooks/use-bidi-warnings.d.ts +10 -0
- package/dist/types/react/hooks/use-in-viewport.d.ts +5 -0
- package/dist/types/react/index.d.ts +5 -1
- package/dist/types/react/nodes/{codeBlock.d.ts → codeBlock/codeBlock.d.ts} +1 -1
- package/dist/types/react/nodes/codeBlock/components/codeBlockContainer.d.ts +12 -0
- package/dist/types/react/nodes/codeBlock/components/lightWeightCodeBlock.d.ts +9 -0
- package/dist/types/react/nodes/codeBlock/windowedCodeBlock.d.ts +4 -0
- package/dist/types/react/nodes/index.d.ts +8 -5
- package/dist/types/react/utils/clipboard.d.ts +1 -0
- package/dist/types/ui/Renderer/types.d.ts +4 -0
- package/dist/types/ui/renderer-props.d.ts +2 -1
- package/package.json +16 -15
- package/report.api.md +590 -119
- package/dist/cjs/react/nodes/codeBlock.js +0 -74
- package/dist/cjs/react/nodes/copy-text-provider.js +0 -174
- package/dist/es2019/react/nodes/codeBlock.js +0 -59
- package/dist/es2019/react/nodes/copy-text-provider.js +0 -93
- package/dist/esm/react/nodes/codeBlock.js +0 -55
- package/dist/esm/react/nodes/copy-text-provider.js +0 -140
- package/dist/types/react/nodes/copy-text-provider.d.ts +0 -20
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
/** @jsx jsx */
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { jsx } from '@emotion/react';
|
|
4
|
-
import { WidthProvider, clearNextSiblingMarginTopStyle } from '@atlaskit/editor-common/ui';
|
|
3
|
+
import { jsx, css } from '@emotion/react';
|
|
4
|
+
import { WidthProvider, clearNextSiblingMarginTopStyle, clearNextSiblingBlockMarkMarginTopStyle } from '@atlaskit/editor-common/ui';
|
|
5
|
+
const layoutColumnClearMarginTopStyles = css`
|
|
6
|
+
${clearNextSiblingMarginTopStyle}
|
|
7
|
+
${clearNextSiblingBlockMarkMarginTopStyle}
|
|
8
|
+
`;
|
|
5
9
|
export default function LayoutSection(props) {
|
|
6
10
|
return jsx("div", {
|
|
7
11
|
"data-layout-column": true,
|
|
@@ -10,6 +14,6 @@ export default function LayoutSection(props) {
|
|
|
10
14
|
flexBasis: `${props.width}%`
|
|
11
15
|
}
|
|
12
16
|
}, jsx(WidthProvider, null, jsx("div", {
|
|
13
|
-
css:
|
|
17
|
+
css: layoutColumnClearMarginTopStyles
|
|
14
18
|
}), props.children));
|
|
15
19
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const copyTextToClipboard = text => new Promise((resolve, reject) => {
|
|
2
|
+
const isApiSupported = !!navigator.clipboard && typeof navigator.clipboard.writeText === 'function';
|
|
3
|
+
|
|
4
|
+
if (isApiSupported) {
|
|
5
|
+
navigator.clipboard.writeText(text).then(() => resolve(), e => reject(e));
|
|
6
|
+
} else {
|
|
7
|
+
reject('Clipboard API is not supported');
|
|
8
|
+
}
|
|
9
|
+
});
|
|
@@ -21,7 +21,6 @@ import { TruncatedWrapper } from './truncated-wrapper';
|
|
|
21
21
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '../../analytics/enums';
|
|
22
22
|
import { PLATFORM, MODE } from '../../analytics/events';
|
|
23
23
|
import AnalyticsContext from '../../analytics/analyticsContext';
|
|
24
|
-
import { CopyTextProvider } from '../../react/nodes/copy-text-provider';
|
|
25
24
|
import { Provider as SmartCardStorageProvider } from '../SmartCardStorage';
|
|
26
25
|
import { name, version } from '../../version.json';
|
|
27
26
|
import { BreakoutSSRInlineScript } from './breakout-ssr';
|
|
@@ -179,6 +178,9 @@ export class Renderer extends PureComponent {
|
|
|
179
178
|
annotationProvider
|
|
180
179
|
} = props;
|
|
181
180
|
const allowAnnotationsDraftMode = Boolean(annotationProvider && annotationProvider.inlineComment && annotationProvider.inlineComment.allowDraftMode);
|
|
181
|
+
const {
|
|
182
|
+
featureFlags
|
|
183
|
+
} = this.featureFlags(props.featureFlags);
|
|
182
184
|
return {
|
|
183
185
|
providers: this.providerFactory,
|
|
184
186
|
eventHandlers: props.eventHandlers,
|
|
@@ -206,7 +208,10 @@ export class Renderer extends PureComponent {
|
|
|
206
208
|
allowCustomPanels: props.allowCustomPanels,
|
|
207
209
|
allowAnnotations: props.allowAnnotations,
|
|
208
210
|
allowSelectAllTrap: props.allowSelectAllTrap,
|
|
209
|
-
allowPlaceholderText: props.allowPlaceholderText
|
|
211
|
+
allowPlaceholderText: props.allowPlaceholderText,
|
|
212
|
+
nodeComponents: props.nodeComponents,
|
|
213
|
+
// does not currently support SSR, should not be enabled in environments where Renderer is SSR-ed
|
|
214
|
+
allowWindowedCodeBlock: featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.allowWindowedCodeBlock
|
|
210
215
|
};
|
|
211
216
|
}
|
|
212
217
|
|
|
@@ -289,7 +294,7 @@ export class Renderer extends PureComponent {
|
|
|
289
294
|
|
|
290
295
|
const rendererOutput = jsx(RendererContextProvider, {
|
|
291
296
|
value: this.featureFlags(this.props.featureFlags)
|
|
292
|
-
}, jsx(
|
|
297
|
+
}, jsx(ActiveHeaderIdProvider, {
|
|
293
298
|
value: getActiveHeadingId(allowHeadingAnchorLinks)
|
|
294
299
|
}, jsx(AnalyticsContext.Provider, {
|
|
295
300
|
value: {
|
|
@@ -309,7 +314,7 @@ export class Renderer extends PureComponent {
|
|
|
309
314
|
doc: pmDoc,
|
|
310
315
|
schema: schema,
|
|
311
316
|
onAnalyticsEvent: this.fireAnalyticsEvent
|
|
312
|
-
}, result))))))
|
|
317
|
+
}, result))))));
|
|
313
318
|
let rendererResult = truncated ? jsx(TruncatedWrapper, {
|
|
314
319
|
height: maxHeight,
|
|
315
320
|
fadeHeight: fadeOutHeight
|
|
@@ -10,6 +10,7 @@ import { editorFontSize, blockNodesVerticalMargin, akEditorTableToolbar, akEdito
|
|
|
10
10
|
import { RendererCssClassName } from '../../consts';
|
|
11
11
|
import { HeadingAnchorWrapperClassName } from '../../react/nodes/heading-anchor';
|
|
12
12
|
import { shadowObserverClassNames } from '@atlaskit/editor-common/ui';
|
|
13
|
+
import { getLightWeightCodeBlockStylesForRootRendererStyleSheet } from '../../react/nodes/codeBlock/components/lightWeightCodeBlock';
|
|
13
14
|
export const FullPagePadding = 32;
|
|
14
15
|
|
|
15
16
|
const getLineHeight = fontCode => headingSizesImport[fontCode].lineHeight / headingSizesImport[fontCode].size;
|
|
@@ -661,6 +662,8 @@ export const rendererStyles = wrapperProps => theme => {
|
|
|
661
662
|
}
|
|
662
663
|
}
|
|
663
664
|
|
|
665
|
+
${getLightWeightCodeBlockStylesForRootRendererStyleSheet()}
|
|
666
|
+
|
|
664
667
|
${columnLayoutSharedStyle};
|
|
665
668
|
& [data-layout-section] {
|
|
666
669
|
margin-top: ${gridSize() * 2.5}px;
|
package/dist/es2019/version.json
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useIntl } from 'react-intl-next';
|
|
3
|
+
import CodeBidiWarning from '@atlaskit/code/bidi-warning';
|
|
4
|
+
import { codeBidiWarningMessages } from '@atlaskit/editor-common/messages';
|
|
5
|
+
import codeBidiWarningDecorator from '@atlaskit/code/bidi-warning-decorator';
|
|
6
|
+
export var useBidiWarnings = function useBidiWarnings(_ref) {
|
|
7
|
+
var _ref$enableWarningToo = _ref.enableWarningTooltip,
|
|
8
|
+
enableWarningTooltip = _ref$enableWarningToo === void 0 ? true : _ref$enableWarningToo;
|
|
9
|
+
var intl = useIntl();
|
|
10
|
+
var warningLabel = intl.formatMessage(codeBidiWarningMessages.label);
|
|
11
|
+
|
|
12
|
+
var renderBidiWarnings = function renderBidiWarnings(text) {
|
|
13
|
+
return codeBidiWarningDecorator(text, function (_ref2) {
|
|
14
|
+
var bidiCharacter = _ref2.bidiCharacter,
|
|
15
|
+
index = _ref2.index;
|
|
16
|
+
return /*#__PURE__*/React.createElement(CodeBidiWarning, {
|
|
17
|
+
bidiCharacter: bidiCharacter,
|
|
18
|
+
key: index,
|
|
19
|
+
label: warningLabel,
|
|
20
|
+
tooltipEnabled: enableWarningTooltip
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
renderBidiWarnings: renderBidiWarnings,
|
|
27
|
+
warningLabel: warningLabel
|
|
28
|
+
};
|
|
29
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
|
|
3
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
4
|
+
|
|
5
|
+
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); }
|
|
6
|
+
|
|
7
|
+
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; }
|
|
8
|
+
|
|
9
|
+
import { useEffect, useRef, useState } from 'react';
|
|
10
|
+
export var useInViewport = function useInViewport() {
|
|
11
|
+
var trackingRef = useRef(null);
|
|
12
|
+
|
|
13
|
+
var _useState = useState(false),
|
|
14
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
15
|
+
isInViewport = _useState2[0],
|
|
16
|
+
setIsInViewport = _useState2[1];
|
|
17
|
+
|
|
18
|
+
useEffect(function () {
|
|
19
|
+
if (!trackingRef || !(trackingRef !== null && trackingRef !== void 0 && trackingRef.current)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var target = trackingRef.current;
|
|
24
|
+
var observer = new IntersectionObserver(function (entries) {
|
|
25
|
+
var _iterator = _createForOfIteratorHelper(entries),
|
|
26
|
+
_step;
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
30
|
+
var entry = _step.value;
|
|
31
|
+
|
|
32
|
+
if (entry.isIntersecting) {
|
|
33
|
+
setIsInViewport(true);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
} catch (err) {
|
|
37
|
+
_iterator.e(err);
|
|
38
|
+
} finally {
|
|
39
|
+
_iterator.f();
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
observer.observe(target);
|
|
43
|
+
return function () {
|
|
44
|
+
return observer.disconnect();
|
|
45
|
+
};
|
|
46
|
+
}, [trackingRef]);
|
|
47
|
+
return {
|
|
48
|
+
isInViewport: isInViewport,
|
|
49
|
+
trackingRef: trackingRef
|
|
50
|
+
};
|
|
51
|
+
};
|
package/dist/esm/react/index.js
CHANGED
|
@@ -76,8 +76,9 @@ var ReactSerializer = /*#__PURE__*/function () {
|
|
|
76
76
|
var nodeKey = "".concat(node.type.name, "__").concat(_this.startPos);
|
|
77
77
|
|
|
78
78
|
var serializedContent = _this.serializeFragment(node.content, _this.getNodeProps(node, parentInfo), toReact(node, {
|
|
79
|
-
allowSelectAllTrap: _this.allowSelectAllTrap
|
|
80
|
-
|
|
79
|
+
allowSelectAllTrap: _this.allowSelectAllTrap,
|
|
80
|
+
allowWindowedCodeBlock: _this.allowWindowedCodeBlock
|
|
81
|
+
}, _this.nodeComponents), nodeKey, {
|
|
81
82
|
parentIsIncompleteTask: parentIsIncompleteTask,
|
|
82
83
|
path: [].concat(_toConsumableArray(currentPath), [node]),
|
|
83
84
|
pos: _this.startPos
|
|
@@ -194,6 +195,8 @@ var ReactSerializer = /*#__PURE__*/function () {
|
|
|
194
195
|
this.media = init.media;
|
|
195
196
|
this.smartLinks = init.smartLinks;
|
|
196
197
|
this.allowSelectAllTrap = init.allowSelectAllTrap;
|
|
198
|
+
this.nodeComponents = init.nodeComponents;
|
|
199
|
+
this.allowWindowedCodeBlock = init.allowWindowedCodeBlock;
|
|
197
200
|
}
|
|
198
201
|
|
|
199
202
|
_createClass(ReactSerializer, [{
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { jsx } from '@emotion/react';
|
|
3
|
+
import { injectIntl } from 'react-intl-next';
|
|
4
|
+
import { CodeBlockSharedCssClassName } from '@atlaskit/editor-common/styles';
|
|
5
|
+
import { CodeBlock as AkCodeBlock } from '@atlaskit/code';
|
|
6
|
+
import { codeBidiWarningMessages } from '@atlaskit/editor-common/messages';
|
|
7
|
+
import { useFeatureFlags } from '../../../use-feature-flags';
|
|
8
|
+
import CodeBlockContainer from './components/codeBlockContainer';
|
|
9
|
+
|
|
10
|
+
function CodeBlock(props) {
|
|
11
|
+
var text = props.text,
|
|
12
|
+
language = props.language,
|
|
13
|
+
_props$allowCopyToCli = props.allowCopyToClipboard,
|
|
14
|
+
allowCopyToClipboard = _props$allowCopyToCli === void 0 ? false : _props$allowCopyToCli,
|
|
15
|
+
codeBidiWarningTooltipEnabled = props.codeBidiWarningTooltipEnabled;
|
|
16
|
+
var featureFlags = useFeatureFlags();
|
|
17
|
+
var codeBidiWarningLabel = props.intl.formatMessage(codeBidiWarningMessages.label);
|
|
18
|
+
var className = [CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER, props.className].join(' ');
|
|
19
|
+
return jsx(CodeBlockContainer, {
|
|
20
|
+
text: text,
|
|
21
|
+
className: className,
|
|
22
|
+
allowCopyToClipboard: allowCopyToClipboard
|
|
23
|
+
}, jsx(AkCodeBlock, {
|
|
24
|
+
language: language,
|
|
25
|
+
text: text,
|
|
26
|
+
codeBidiWarnings: featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.codeBidiWarnings,
|
|
27
|
+
codeBidiWarningLabel: codeBidiWarningLabel,
|
|
28
|
+
codeBidiWarningTooltipEnabled: codeBidiWarningTooltipEnabled
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default injectIntl(CodeBlock);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
|
|
2
|
+
|
|
3
|
+
var _templateObject;
|
|
4
|
+
|
|
5
|
+
/** @jsx jsx */
|
|
6
|
+
import { jsx, css } from '@emotion/react';
|
|
7
|
+
import { overflowShadow, relativeFontSizeToBase16 } from '@atlaskit/editor-shared-styles';
|
|
8
|
+
import { N20, DN50 } from '@atlaskit/theme/colors';
|
|
9
|
+
import { themed } from '@atlaskit/theme/components';
|
|
10
|
+
import { fontSize, gridSize } from '@atlaskit/theme/constants';
|
|
11
|
+
import { CodeBlockSharedCssClassName } from '@atlaskit/editor-common/styles';
|
|
12
|
+
import CopyButton from '../../codeBlockCopyButton';
|
|
13
|
+
|
|
14
|
+
// TODO: Quality ticket https://product-fabric.atlassian.net/browse/DSP-4118
|
|
15
|
+
|
|
16
|
+
/* eslint-disable @atlaskit/design-system/ensure-design-token-usage */
|
|
17
|
+
var codeBlockStyleOverrides = function codeBlockStyleOverrides(props) {
|
|
18
|
+
return css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n tab-size: 4;\n ", " {\n font-size: ", ";\n line-height: 1.5rem;\n background-image: ", ";\n background-attachment: local, scroll, scroll;\n background-position: 100% 0, 100% 0, 0 0;\n }\n "])), CodeBlockSharedCssClassName.DS_CODEBLOCK, relativeFontSizeToBase16(fontSize()), overflowShadow({
|
|
19
|
+
background: themed({
|
|
20
|
+
light: N20,
|
|
21
|
+
dark: DN50
|
|
22
|
+
})(props),
|
|
23
|
+
width: "".concat(gridSize(), "px")
|
|
24
|
+
}));
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
var CodeBlockContainer = function CodeBlockContainer(_ref) {
|
|
28
|
+
var text = _ref.text,
|
|
29
|
+
className = _ref.className,
|
|
30
|
+
allowCopyToClipboard = _ref.allowCopyToClipboard,
|
|
31
|
+
children = _ref.children;
|
|
32
|
+
return jsx("div", {
|
|
33
|
+
className: className,
|
|
34
|
+
css: codeBlockStyleOverrides
|
|
35
|
+
}, allowCopyToClipboard ? jsx(CopyButton, {
|
|
36
|
+
content: text
|
|
37
|
+
}) : null, children);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export default CodeBlockContainer;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
|
|
2
|
+
|
|
3
|
+
var _templateObject, _templateObject2;
|
|
4
|
+
|
|
5
|
+
/** @jsx jsx */
|
|
6
|
+
import React, { forwardRef, useMemo } from 'react';
|
|
7
|
+
import { css, jsx, useTheme } from '@emotion/react';
|
|
8
|
+
import { blockNodesVerticalMargin } from '@atlaskit/editor-shared-styles';
|
|
9
|
+
import { codeBlockSharedStyles, CodeBlockSharedCssClassName } from '@atlaskit/editor-common/styles';
|
|
10
|
+
import { useBidiWarnings } from '../../../hooks/use-bidi-warnings';
|
|
11
|
+
import { RendererCssClassName } from '../../../../consts';
|
|
12
|
+
var lightWeightCodeBlockStyles = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n .", " {\n cursor: text;\n }\n"])), CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER);
|
|
13
|
+
export var LightWeightCodeBlockCssClassName = {
|
|
14
|
+
CONTAINER: 'light-weight-code-block'
|
|
15
|
+
};
|
|
16
|
+
export var getLightWeightCodeBlockStylesForRootRendererStyleSheet = function getLightWeightCodeBlockStylesForRootRendererStyleSheet() {
|
|
17
|
+
// We overwrite the rule that clears margin-top for first nested codeblocks, as
|
|
18
|
+
// our lightweight codeblock dom structure will always nest the codeblock inside
|
|
19
|
+
// an extra container div which would constantly be targeted. Now, top-level
|
|
20
|
+
// lightweight codeblock containers will not be targeted.
|
|
21
|
+
// NOTE: This must be added after other .code-block styles in the root
|
|
22
|
+
// Renderer stylesheet.
|
|
23
|
+
return css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n .", "\n > .", "\n .", " {\n margin-top: ", ";\n }\n "])), RendererCssClassName.DOCUMENT, LightWeightCodeBlockCssClassName.CONTAINER, CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER, blockNodesVerticalMargin);
|
|
24
|
+
};
|
|
25
|
+
var LightWeightCodeBlock = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
26
|
+
var text = _ref.text,
|
|
27
|
+
_ref$codeBidiWarningT = _ref.codeBidiWarningTooltipEnabled,
|
|
28
|
+
codeBidiWarningTooltipEnabled = _ref$codeBidiWarningT === void 0 ? true : _ref$codeBidiWarningT,
|
|
29
|
+
className = _ref.className;
|
|
30
|
+
var theme = useTheme();
|
|
31
|
+
var textRows = useMemo(function () {
|
|
32
|
+
return (text !== null && text !== void 0 ? text : '').split('\n');
|
|
33
|
+
}, [text]);
|
|
34
|
+
|
|
35
|
+
var _useBidiWarnings = useBidiWarnings({
|
|
36
|
+
enableWarningTooltip: codeBidiWarningTooltipEnabled
|
|
37
|
+
}),
|
|
38
|
+
renderBidiWarnings = _useBidiWarnings.renderBidiWarnings;
|
|
39
|
+
|
|
40
|
+
var classNames = [LightWeightCodeBlockCssClassName.CONTAINER, className].join(' ');
|
|
41
|
+
return jsx("div", {
|
|
42
|
+
className: classNames,
|
|
43
|
+
ref: ref,
|
|
44
|
+
css: [codeBlockSharedStyles(theme), lightWeightCodeBlockStyles]
|
|
45
|
+
}, jsx("div", {
|
|
46
|
+
className: CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER
|
|
47
|
+
}, jsx("div", {
|
|
48
|
+
className: CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER
|
|
49
|
+
}, textRows.map(function (_, index) {
|
|
50
|
+
return jsx("span", {
|
|
51
|
+
key: index
|
|
52
|
+
});
|
|
53
|
+
})), jsx("div", {
|
|
54
|
+
className: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT
|
|
55
|
+
}, jsx("code", null, renderBidiWarnings(text)))));
|
|
56
|
+
});
|
|
57
|
+
export default LightWeightCodeBlock;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
3
|
+
|
|
4
|
+
/** @jsx jsx */
|
|
5
|
+
import { Fragment, memo } from 'react';
|
|
6
|
+
import { lazy, Suspense } from 'react';
|
|
7
|
+
import { jsx } from '@emotion/react';
|
|
8
|
+
import { CodeBlockSharedCssClassName } from '@atlaskit/editor-common/styles';
|
|
9
|
+
import { useFeatureFlags } from '../../../use-feature-flags';
|
|
10
|
+
import { useInViewport } from '../../hooks/use-in-viewport';
|
|
11
|
+
import { useBidiWarnings } from '../../hooks/use-bidi-warnings';
|
|
12
|
+
import LightWeightCodeBlock from './components/lightWeightCodeBlock';
|
|
13
|
+
import CodeBlockContainer from './components/codeBlockContainer';
|
|
14
|
+
var LazyAkCodeBlock = /*#__PURE__*/lazy( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
15
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
16
|
+
while (1) {
|
|
17
|
+
switch (_context.prev = _context.next) {
|
|
18
|
+
case 0:
|
|
19
|
+
return _context.abrupt("return", import(
|
|
20
|
+
/* webpackChunkName: "@atlaskit-internal_renderer-codeBlock" */
|
|
21
|
+
'@atlaskit/code/block'));
|
|
22
|
+
|
|
23
|
+
case 1:
|
|
24
|
+
case "end":
|
|
25
|
+
return _context.stop();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}, _callee);
|
|
29
|
+
})));
|
|
30
|
+
|
|
31
|
+
var joinWithSpaces = function joinWithSpaces() {
|
|
32
|
+
for (var _len = arguments.length, strs = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
33
|
+
strs[_key] = arguments[_key];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return strs.join(' ');
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
var MemoizedLightWeightCodeBlock = /*#__PURE__*/memo(LightWeightCodeBlock);
|
|
40
|
+
|
|
41
|
+
var WindowedCodeBlock = function WindowedCodeBlock(_ref2) {
|
|
42
|
+
var text = _ref2.text,
|
|
43
|
+
language = _ref2.language,
|
|
44
|
+
allowCopyToClipboard = _ref2.allowCopyToClipboard,
|
|
45
|
+
codeBidiWarningTooltipEnabled = _ref2.codeBidiWarningTooltipEnabled,
|
|
46
|
+
rootClassName = _ref2.className;
|
|
47
|
+
var featureFlags = useFeatureFlags();
|
|
48
|
+
|
|
49
|
+
var _useBidiWarnings = useBidiWarnings({
|
|
50
|
+
enableWarningTooltip: codeBidiWarningTooltipEnabled
|
|
51
|
+
}),
|
|
52
|
+
warningLabel = _useBidiWarnings.warningLabel;
|
|
53
|
+
|
|
54
|
+
var _useInViewport = useInViewport(),
|
|
55
|
+
isInViewport = _useInViewport.isInViewport,
|
|
56
|
+
trackingRef = _useInViewport.trackingRef;
|
|
57
|
+
|
|
58
|
+
var className = joinWithSpaces(CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER, rootClassName);
|
|
59
|
+
var memoizedLightWeightCodeBlock = jsx(MemoizedLightWeightCodeBlock, {
|
|
60
|
+
ref: trackingRef,
|
|
61
|
+
text: text,
|
|
62
|
+
codeBidiWarningTooltipEnabled: codeBidiWarningTooltipEnabled,
|
|
63
|
+
className: rootClassName
|
|
64
|
+
});
|
|
65
|
+
return isInViewport ? jsx(Fragment, null, jsx(Suspense, {
|
|
66
|
+
fallback: memoizedLightWeightCodeBlock
|
|
67
|
+
}, jsx(CodeBlockContainer, {
|
|
68
|
+
className: className,
|
|
69
|
+
text: text,
|
|
70
|
+
allowCopyToClipboard: allowCopyToClipboard
|
|
71
|
+
}, jsx(LazyAkCodeBlock, {
|
|
72
|
+
language: language,
|
|
73
|
+
text: text,
|
|
74
|
+
codeBidiWarnings: featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.codeBidiWarnings,
|
|
75
|
+
codeBidiWarningLabel: warningLabel,
|
|
76
|
+
codeBidiWarningTooltipEnabled: codeBidiWarningTooltipEnabled
|
|
77
|
+
})))) : memoizedLightWeightCodeBlock;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export default WindowedCodeBlock;
|
|
@@ -11,7 +11,7 @@ import Tooltip from '@atlaskit/tooltip';
|
|
|
11
11
|
import Button from '@atlaskit/button/custom-theme-button';
|
|
12
12
|
import CopyIcon from '@atlaskit/icon/glyph/copy';
|
|
13
13
|
import { N20, N30, N700 } from '@atlaskit/theme/colors';
|
|
14
|
-
import {
|
|
14
|
+
import { copyTextToClipboard } from '../utils/clipboard';
|
|
15
15
|
import { codeBlockCopyButtonMessages } from '../../messages';
|
|
16
16
|
import { token } from '@atlaskit/tokens';
|
|
17
17
|
var copyButtonWrapperStyles = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: flex;\n position: sticky;\n justify-content: flex-end;\n top: 0;\n\n button {\n position: absolute;\n display: flex;\n justify-content: center;\n height: 32px;\n width: 32px;\n right: 6px;\n top: 4px;\n padding: 2px;\n opacity: 0;\n transition: opacity 0.2s ease 0s;\n border: 2px solid ", ";\n border-radius: 4px;\n background-color: ", ";\n color: ", ";\n }\n\n button:hover {\n background-color: ", ";\n }\n\n button.clicked {\n background-color: ", ";\n color: ", " !important;\n }\n"])), token('color.border.inverse', '#fff'), token('color.background.neutral.subtle', N20), token('color.icon', 'rgb(66, 82, 110)'), token('color.background.neutral.hovered', N30), token('color.background.neutral.bold.pressed', N700), token('color.icon.inverse', '#fff'));
|
|
@@ -35,32 +35,29 @@ var CopyButton = function CopyButton(_ref) {
|
|
|
35
35
|
setClassName('copy-to-clipboard');
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
return jsx(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
}))));
|
|
63
|
-
});
|
|
38
|
+
return jsx("span", {
|
|
39
|
+
css: copyButtonWrapperStyles
|
|
40
|
+
}, jsx(Tooltip, {
|
|
41
|
+
content: tooltip,
|
|
42
|
+
hideTooltipOnClick: false,
|
|
43
|
+
position: "top"
|
|
44
|
+
}, jsx("div", {
|
|
45
|
+
onMouseLeave: onMouseLeave
|
|
46
|
+
}, jsx(Button, {
|
|
47
|
+
className: className,
|
|
48
|
+
"aria-label": tooltip,
|
|
49
|
+
spacing: "compact",
|
|
50
|
+
appearance: "subtle",
|
|
51
|
+
"aria-haspopup": true,
|
|
52
|
+
iconBefore: jsx(CopyIcon, {
|
|
53
|
+
label: tooltip
|
|
54
|
+
}),
|
|
55
|
+
onClick: function onClick() {
|
|
56
|
+
copyTextToClipboard(content);
|
|
57
|
+
setTooltip(intl.formatMessage(codeBlockCopyButtonMessages.copiedCodeToClipboard));
|
|
58
|
+
setClassName('copy-to-clipboard clicked');
|
|
59
|
+
}
|
|
60
|
+
}))));
|
|
64
61
|
};
|
|
65
62
|
|
|
66
63
|
export default injectIntl(CopyButton);
|
|
@@ -3,7 +3,7 @@ import React from 'react';
|
|
|
3
3
|
import HeadingAnchor from './heading-anchor';
|
|
4
4
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '../../analytics/enums';
|
|
5
5
|
import AnalyticsContext from '../../analytics/analyticsContext';
|
|
6
|
-
import {
|
|
6
|
+
import { copyTextToClipboard } from '../utils/clipboard';
|
|
7
7
|
|
|
8
8
|
var getCurrentUrlWithHash = function getCurrentUrlWithHash() {
|
|
9
9
|
var hash = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
@@ -43,23 +43,20 @@ function Heading(props) {
|
|
|
43
43
|
var headingIdToUse = invisible ? undefined : headingId;
|
|
44
44
|
return /*#__PURE__*/React.createElement(HX, _extends({
|
|
45
45
|
id: headingIdToUse
|
|
46
|
-
}, dataAttributes), /*#__PURE__*/React.createElement(React.Fragment, null, showAnchorLink && isRightAligned ? WrapChildTextInSpan(props.children) : props.children, showAnchorLink && /*#__PURE__*/React.createElement(
|
|
47
|
-
var
|
|
48
|
-
return
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return copyTextToClipboard(getCurrentUrlWithHash(headingId));
|
|
61
|
-
}
|
|
62
|
-
});
|
|
46
|
+
}, dataAttributes), /*#__PURE__*/React.createElement(React.Fragment, null, showAnchorLink && isRightAligned ? WrapChildTextInSpan(props.children) : props.children, showAnchorLink && headingId && /*#__PURE__*/React.createElement(AnalyticsContext.Consumer, null, function (_ref) {
|
|
47
|
+
var fireAnalyticsEvent = _ref.fireAnalyticsEvent;
|
|
48
|
+
return /*#__PURE__*/React.createElement(HeadingAnchor, {
|
|
49
|
+
enableNestedHeaderLinks: enableNestedHeaderLinks,
|
|
50
|
+
level: props.level,
|
|
51
|
+
onCopyText: function onCopyText() {
|
|
52
|
+
fireAnalyticsEvent({
|
|
53
|
+
action: ACTION.CLICKED,
|
|
54
|
+
actionSubject: ACTION_SUBJECT.BUTTON,
|
|
55
|
+
actionSubjectId: ACTION_SUBJECT_ID.HEADING_ANCHOR_LINK,
|
|
56
|
+
eventType: EVENT_TYPE.UI
|
|
57
|
+
});
|
|
58
|
+
return copyTextToClipboard(getCurrentUrlWithHash(headingId));
|
|
59
|
+
}
|
|
63
60
|
});
|
|
64
61
|
})));
|
|
65
62
|
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
|
|
3
|
+
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; }
|
|
4
|
+
|
|
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
|
+
|
|
1
7
|
import Loadable from 'react-loadable';
|
|
2
8
|
import Blockquote from './blockquote';
|
|
3
9
|
import BodiedExtension from './bodiedExtension';
|
|
@@ -20,11 +26,23 @@ import { TableCell, TableHeader } from './tableCell';
|
|
|
20
26
|
import TableRow from './tableRow';
|
|
21
27
|
import UnknownBlock from './unknownBlock';
|
|
22
28
|
import { UnsupportedBlock, UnsupportedInline } from '@atlaskit/editor-common/ui';
|
|
29
|
+
var WindowedCodeBlock = Loadable({
|
|
30
|
+
loader: function loader() {
|
|
31
|
+
return import(
|
|
32
|
+
/* webpackChunkName: "@atlaskit-internal_renderer-node_WindowedCodeBlock" */
|
|
33
|
+
'./codeBlock/windowedCodeBlock').then(function (mod) {
|
|
34
|
+
return mod.default;
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
loading: function loading() {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
23
41
|
var CodeBlock = Loadable({
|
|
24
42
|
loader: function loader() {
|
|
25
43
|
return import(
|
|
26
44
|
/* webpackChunkName: "@atlaskit-internal_renderer-node_CodeBlock" */
|
|
27
|
-
'./codeBlock').then(function (mod) {
|
|
45
|
+
'./codeBlock/codeBlock').then(function (mod) {
|
|
28
46
|
return mod.default;
|
|
29
47
|
});
|
|
30
48
|
},
|
|
@@ -241,7 +259,6 @@ export var nodeToReact = {
|
|
|
241
259
|
bulletList: BulletList,
|
|
242
260
|
blockCard: BlockCard,
|
|
243
261
|
caption: Caption,
|
|
244
|
-
codeBlock: CodeBlock,
|
|
245
262
|
date: Date,
|
|
246
263
|
decisionItem: DecisionItem,
|
|
247
264
|
decisionList: DecisionList,
|
|
@@ -280,12 +297,23 @@ export var nodeToReact = {
|
|
|
280
297
|
nestedExpand: Expand,
|
|
281
298
|
embedCard: EmbedCard
|
|
282
299
|
};
|
|
283
|
-
export var toReact = function toReact(node, flags) {
|
|
300
|
+
export var toReact = function toReact(node, flags, nodeComponents) {
|
|
284
301
|
if (node.type.name === 'doc' && (flags === null || flags === void 0 ? void 0 : flags.allowSelectAllTrap) === true) {
|
|
285
302
|
return DocWithSelectAllTrap;
|
|
286
303
|
}
|
|
287
304
|
|
|
288
|
-
|
|
305
|
+
if (node.type.name === 'codeBlock') {
|
|
306
|
+
if ((flags === null || flags === void 0 ? void 0 : flags.allowWindowedCodeBlock) === true) {
|
|
307
|
+
return WindowedCodeBlock;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return CodeBlock;
|
|
311
|
+
} // Allowing custom components to override those provided in nodeToReact
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
var nodes = _objectSpread(_objectSpread({}, nodeToReact), nodeComponents);
|
|
315
|
+
|
|
316
|
+
return nodes[node.type.name];
|
|
289
317
|
};
|
|
290
318
|
|
|
291
319
|
/*
|
|
@@ -422,4 +450,4 @@ var isEmojiBlock = function isEmojiBlock(pnode) {
|
|
|
422
450
|
return emojiCount > 0;
|
|
423
451
|
};
|
|
424
452
|
|
|
425
|
-
export { Blockquote, BodiedExtension, BulletList, BlockCard, Caption, CodeBlock, Date, DecisionItem, DecisionList, Doc, DocWithSelectAllTrap, Emoji, Extension, Expand, HardBreak, Heading, ListItem, InlineCard, InlineExtension, LayoutSection, LayoutColumn, Media, MediaGroup, MediaInline, MediaSingle, Mention, OrderedList, Panel, Paragraph, Placeholder, Rule, Status, TaskItem, TaskList, Table, TableCell, TableRow, UnknownBlock, EmbedCard };
|
|
453
|
+
export { Blockquote, BodiedExtension, BulletList, BlockCard, Caption, CodeBlock, WindowedCodeBlock, Date, DecisionItem, DecisionList, Doc, DocWithSelectAllTrap, Emoji, Extension, Expand, HardBreak, Heading, ListItem, InlineCard, InlineExtension, LayoutSection, LayoutColumn, Media, MediaGroup, MediaInline, MediaSingle, Mention, OrderedList, Panel, Paragraph, Placeholder, Rule, Status, TaskItem, TaskList, Table, TableCell, TableRow, UnknownBlock, EmbedCard };
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
|
|
2
|
+
|
|
3
|
+
var _templateObject;
|
|
4
|
+
|
|
1
5
|
/** @jsx jsx */
|
|
2
6
|
import React from 'react';
|
|
3
|
-
import { jsx } from '@emotion/react';
|
|
4
|
-
import { WidthProvider, clearNextSiblingMarginTopStyle } from '@atlaskit/editor-common/ui';
|
|
7
|
+
import { jsx, css } from '@emotion/react';
|
|
8
|
+
import { WidthProvider, clearNextSiblingMarginTopStyle, clearNextSiblingBlockMarkMarginTopStyle } from '@atlaskit/editor-common/ui';
|
|
9
|
+
var layoutColumnClearMarginTopStyles = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n ", "\n ", "\n"])), clearNextSiblingMarginTopStyle, clearNextSiblingBlockMarkMarginTopStyle);
|
|
5
10
|
export default function LayoutSection(props) {
|
|
6
11
|
return jsx("div", {
|
|
7
12
|
"data-layout-column": true,
|
|
@@ -10,6 +15,6 @@ export default function LayoutSection(props) {
|
|
|
10
15
|
flexBasis: "".concat(props.width, "%")
|
|
11
16
|
}
|
|
12
17
|
}, jsx(WidthProvider, null, jsx("div", {
|
|
13
|
-
css:
|
|
18
|
+
css: layoutColumnClearMarginTopStyles
|
|
14
19
|
}), props.children));
|
|
15
20
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export var copyTextToClipboard = function copyTextToClipboard(text) {
|
|
2
|
+
return new Promise(function (resolve, reject) {
|
|
3
|
+
var isApiSupported = !!navigator.clipboard && typeof navigator.clipboard.writeText === 'function';
|
|
4
|
+
|
|
5
|
+
if (isApiSupported) {
|
|
6
|
+
navigator.clipboard.writeText(text).then(function () {
|
|
7
|
+
return resolve();
|
|
8
|
+
}, function (e) {
|
|
9
|
+
return reject(e);
|
|
10
|
+
});
|
|
11
|
+
} else {
|
|
12
|
+
reject('Clipboard API is not supported');
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
};
|