@atlaskit/editor-plugin-code-bidi-warning 2.1.4 → 3.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 +53 -0
- package/dist/cjs/pm-plugins/codeBidiWarningDomSpec.js +32 -0
- package/dist/cjs/pm-plugins/main.js +11 -5
- package/dist/cjs/pm-plugins/vanilla-plugin-factory.js +103 -0
- package/dist/es2019/pm-plugins/codeBidiWarningDomSpec.js +26 -0
- package/dist/es2019/pm-plugins/main.js +9 -3
- package/dist/es2019/pm-plugins/vanilla-plugin-factory.js +92 -0
- package/dist/esm/pm-plugins/codeBidiWarningDomSpec.js +25 -0
- package/dist/esm/pm-plugins/main.js +11 -5
- package/dist/esm/pm-plugins/vanilla-plugin-factory.js +95 -0
- package/dist/types/pm-plugins/codeBidiWarningDomSpec.d.ts +2 -0
- package/dist/types/pm-plugins/vanilla-plugin-factory.d.ts +12 -0
- package/dist/types-ts4.5/pm-plugins/codeBidiWarningDomSpec.d.ts +2 -0
- package/dist/types-ts4.5/pm-plugins/vanilla-plugin-factory.d.ts +12 -0
- package/package.json +8 -4
- /package/dist/cjs/pm-plugins/{plugin-factory.js → react-plugin-factory.js} +0 -0
- /package/dist/es2019/pm-plugins/{plugin-factory.js → react-plugin-factory.js} +0 -0
- /package/dist/esm/pm-plugins/{plugin-factory.js → react-plugin-factory.js} +0 -0
- /package/dist/types/pm-plugins/{plugin-factory.d.ts → react-plugin-factory.d.ts} +0 -0
- /package/dist/types-ts4.5/pm-plugins/{plugin-factory.d.ts → react-plugin-factory.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-code-bidi-warning
|
|
2
2
|
|
|
3
|
+
## 3.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#181024](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/181024)
|
|
8
|
+
[`8e80c487ca307`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/8e80c487ca307) - ##
|
|
9
|
+
Make `@atlaskit/editor-common` a peer dependency
|
|
10
|
+
|
|
11
|
+
**WHAT:** `@atlaskit/editor-common` has been moved from `dependencies` to `peerDependencies` in
|
|
12
|
+
all editor plugin packages.
|
|
13
|
+
|
|
14
|
+
**WHY:** This change ensures that only a single version of `@atlaskit/editor-common` is used in
|
|
15
|
+
consuming applications, preventing issues caused by multiple versions of singleton libraries (such
|
|
16
|
+
as context mismatches or duplicated state). This is especially important for packages that rely on
|
|
17
|
+
shared context or singletons.
|
|
18
|
+
|
|
19
|
+
**HOW TO ADJUST:**
|
|
20
|
+
|
|
21
|
+
- Consumers must now explicitly install `@atlaskit/editor-common` in their own project if they use
|
|
22
|
+
any of these editor plugins.
|
|
23
|
+
- Ensure the version you install matches the version required by the plugins.
|
|
24
|
+
- You can use the
|
|
25
|
+
[`check-peer-dependencies`](https://www.npmjs.com/package/check-peer-dependencies) package to
|
|
26
|
+
verify that all required peer dependencies are installed and compatible.
|
|
27
|
+
- Example install command:
|
|
28
|
+
```
|
|
29
|
+
npm install @atlaskit/editor-common
|
|
30
|
+
```
|
|
31
|
+
or
|
|
32
|
+
```
|
|
33
|
+
yarn add @atlaskit/editor-common
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Note:** This is a breaking change. If `@atlaskit/editor-common` is not installed at the
|
|
37
|
+
application level, you may see errors or unexpected behavior.
|
|
38
|
+
|
|
39
|
+
### Patch Changes
|
|
40
|
+
|
|
41
|
+
- Updated dependencies
|
|
42
|
+
|
|
43
|
+
## 2.2.0
|
|
44
|
+
|
|
45
|
+
### Minor Changes
|
|
46
|
+
|
|
47
|
+
- [#180500](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/180500)
|
|
48
|
+
[`411796e8a55c6`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/411796e8a55c6) -
|
|
49
|
+
[ux] Move code-bidi-warning plugin widget to be a vanilla-DOM implementation, instead of react, to
|
|
50
|
+
fix memory leaks.
|
|
51
|
+
|
|
52
|
+
### Patch Changes
|
|
53
|
+
|
|
54
|
+
- Updated dependencies
|
|
55
|
+
|
|
3
56
|
## 2.1.4
|
|
4
57
|
|
|
5
58
|
### Patch Changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.getCodeBidiWarningDomSpec = getCodeBidiWarningDomSpec;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
|
+
function getCodeBidiWarningDomSpec(bidiCharacter, codeBidiWarningLabel, tooltipEnabled) {
|
|
10
|
+
var _bidiCharacter$codePo;
|
|
11
|
+
var bidiCharacterCode = "U+".concat((_bidiCharacter$codePo = bidiCharacter.codePointAt(0)) === null || _bidiCharacter$codePo === void 0 || (_bidiCharacter$codePo = _bidiCharacter$codePo.toString(16)) === null || _bidiCharacter$codePo === void 0 ? void 0 : _bidiCharacter$codePo.toUpperCase());
|
|
12
|
+
return ['span', {
|
|
13
|
+
'data-prosemirror-node-name': 'code-bidi-warning',
|
|
14
|
+
dir: 'ltr'
|
|
15
|
+
},
|
|
16
|
+
// Code Bidi Warning Decorator
|
|
17
|
+
['span', {
|
|
18
|
+
'data-bidi-component': 'code-bidi-warning-decorator',
|
|
19
|
+
'data-testid': 'code-bidi-warning-decorator',
|
|
20
|
+
'data-bidi-character-code': bidiCharacterCode,
|
|
21
|
+
role: 'mark'
|
|
22
|
+
},
|
|
23
|
+
// Mark the < and > characters as visually hidden for screen readers
|
|
24
|
+
['span', {
|
|
25
|
+
'aria-hidden': 'true'
|
|
26
|
+
}, '<'], bidiCharacterCode, ['span', {
|
|
27
|
+
'aria-hidden': 'true'
|
|
28
|
+
}, '>']]].concat((0, _toConsumableArray2.default)(tooltipEnabled ? [['span', {
|
|
29
|
+
'data-bidi-component': 'code-bidi-warning-tooltip',
|
|
30
|
+
role: 'tooltip'
|
|
31
|
+
}, codeBidiWarningLabel]] : []));
|
|
32
|
+
}
|
|
@@ -6,8 +6,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.createPlugin = void 0;
|
|
7
7
|
var _messages = require("@atlaskit/editor-common/messages");
|
|
8
8
|
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
9
|
-
var
|
|
9
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
10
10
|
var _pluginKey = require("./plugin-key");
|
|
11
|
+
var _reactPluginFactory = require("./react-plugin-factory");
|
|
12
|
+
var _vanillaPluginFactory = require("./vanilla-plugin-factory");
|
|
11
13
|
var createPlugin = exports.createPlugin = function createPlugin(_ref, _ref2) {
|
|
12
14
|
var dispatch = _ref.dispatch,
|
|
13
15
|
getIntl = _ref.getIntl,
|
|
@@ -15,14 +17,18 @@ var createPlugin = exports.createPlugin = function createPlugin(_ref, _ref2) {
|
|
|
15
17
|
var appearance = _ref2.appearance;
|
|
16
18
|
var intl = getIntl();
|
|
17
19
|
var codeBidiWarningLabel = intl.formatMessage(_messages.codeBidiWarningMessages.label);
|
|
18
|
-
var
|
|
19
|
-
createPluginState =
|
|
20
|
-
getPluginState =
|
|
20
|
+
var _ref3 = (0, _platformFeatureFlags.fg)('platform_editor_vanilla_codebidi_warning') ? (0, _vanillaPluginFactory.pluginFactoryCreator)() : (0, _reactPluginFactory.pluginFactoryCreator)(nodeViewPortalProviderAPI),
|
|
21
|
+
createPluginState = _ref3.createPluginState,
|
|
22
|
+
getPluginState = _ref3.getPluginState;
|
|
21
23
|
return new _safePlugin.SafePlugin({
|
|
22
24
|
key: _pluginKey.codeBidiWarningPluginKey,
|
|
23
25
|
state: createPluginState(dispatch, function (state) {
|
|
24
26
|
return {
|
|
25
|
-
decorationSet: (0,
|
|
27
|
+
decorationSet: (0, _platformFeatureFlags.fg)('platform_editor_vanilla_codebidi_warning') ? (0, _vanillaPluginFactory.createBidiWarningsDecorationSetFromDoc)({
|
|
28
|
+
doc: state.doc,
|
|
29
|
+
codeBidiWarningLabel: codeBidiWarningLabel,
|
|
30
|
+
tooltipEnabled: true
|
|
31
|
+
}) : (0, _reactPluginFactory.createBidiWarningsDecorationSetFromDoc)({
|
|
26
32
|
doc: state.doc,
|
|
27
33
|
codeBidiWarningLabel: codeBidiWarningLabel,
|
|
28
34
|
tooltipEnabled: true,
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.createBidiWarningsDecorationSetFromDoc = createBidiWarningsDecorationSetFromDoc;
|
|
8
|
+
exports.pluginFactoryCreator = void 0;
|
|
9
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
10
|
+
var _bidiWarningDecorator = _interopRequireDefault(require("@atlaskit/code/bidi-warning-decorator"));
|
|
11
|
+
var _utils = require("@atlaskit/editor-common/utils");
|
|
12
|
+
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
13
|
+
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
14
|
+
var _codeBidiWarningDomSpec = require("./codeBidiWarningDomSpec");
|
|
15
|
+
var _pluginKey = require("./plugin-key");
|
|
16
|
+
var _reducer = _interopRequireDefault(require("./reducer"));
|
|
17
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
18
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
19
|
+
var pluginFactoryCreator = exports.pluginFactoryCreator = function pluginFactoryCreator() {
|
|
20
|
+
return (0, _utils.pluginFactory)(_pluginKey.codeBidiWarningPluginKey, _reducer.default, {
|
|
21
|
+
onDocChanged: function onDocChanged(tr, pluginState) {
|
|
22
|
+
if (!tr.steps.find(_utils.stepHasSlice)) {
|
|
23
|
+
return pluginState;
|
|
24
|
+
}
|
|
25
|
+
var newBidiWarningsDecorationSet = createBidiWarningsDecorationSetFromDoc({
|
|
26
|
+
doc: tr.doc,
|
|
27
|
+
codeBidiWarningLabel: pluginState.codeBidiWarningLabel,
|
|
28
|
+
tooltipEnabled: pluginState.tooltipEnabled
|
|
29
|
+
});
|
|
30
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
31
|
+
decorationSet: newBidiWarningsDecorationSet
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
function createBidiWarningsDecorationSetFromDoc(_ref) {
|
|
37
|
+
var doc = _ref.doc,
|
|
38
|
+
codeBidiWarningLabel = _ref.codeBidiWarningLabel,
|
|
39
|
+
tooltipEnabled = _ref.tooltipEnabled;
|
|
40
|
+
var bidiCharactersAndTheirPositions = [];
|
|
41
|
+
doc.descendants(function (node, pos) {
|
|
42
|
+
var isTextWithCodeMark = node.type.name === 'text' && node.marks && node.marks.some(function (mark) {
|
|
43
|
+
return mark.type.name === 'code';
|
|
44
|
+
});
|
|
45
|
+
if (isTextWithCodeMark) {
|
|
46
|
+
(0, _bidiWarningDecorator.default)(node.textContent, function (_ref2) {
|
|
47
|
+
var bidiCharacter = _ref2.bidiCharacter,
|
|
48
|
+
index = _ref2.index;
|
|
49
|
+
bidiCharactersAndTheirPositions.push({
|
|
50
|
+
// Ignored via go/ees005
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
52
|
+
position: pos + index,
|
|
53
|
+
bidiCharacter: bidiCharacter
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
var isCodeBlock = node.type.name === 'codeBlock';
|
|
59
|
+
if (isCodeBlock) {
|
|
60
|
+
(0, _bidiWarningDecorator.default)(node.textContent, function (_ref3) {
|
|
61
|
+
var bidiCharacter = _ref3.bidiCharacter,
|
|
62
|
+
index = _ref3.index;
|
|
63
|
+
bidiCharactersAndTheirPositions.push({
|
|
64
|
+
// Ignored via go/ees005
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
66
|
+
position: pos + index + 1,
|
|
67
|
+
bidiCharacter: bidiCharacter
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Bidi characters are not expected to commonly appear in code snippets, so recreating the decoration set
|
|
74
|
+
// for documents rather than reusing existing decorations seems a reasonable performance/complexity tradeoff.
|
|
75
|
+
|
|
76
|
+
if (bidiCharactersAndTheirPositions.length === 0) {
|
|
77
|
+
return _view.DecorationSet.empty;
|
|
78
|
+
}
|
|
79
|
+
var newBidiWarningsDecorationSet = _view.DecorationSet.create(doc, bidiCharactersAndTheirPositions.map(function (_ref4) {
|
|
80
|
+
var position = _ref4.position,
|
|
81
|
+
bidiCharacter = _ref4.bidiCharacter;
|
|
82
|
+
return _view.Decoration.widget(position, function (el) {
|
|
83
|
+
return renderDOM(bidiCharacter, codeBidiWarningLabel, tooltipEnabled);
|
|
84
|
+
}, {
|
|
85
|
+
destroy: function destroy(el) {
|
|
86
|
+
if (!(el instanceof HTMLElement)) {
|
|
87
|
+
throw new Error('Code Bidi Warning DOM spec did not return an HTMLElement');
|
|
88
|
+
}
|
|
89
|
+
el.remove();
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}));
|
|
93
|
+
return newBidiWarningsDecorationSet;
|
|
94
|
+
}
|
|
95
|
+
function renderDOM(bidiCharacter, codeBidiWarningLabel, tooltipEnabled) {
|
|
96
|
+
var spec = (0, _codeBidiWarningDomSpec.getCodeBidiWarningDomSpec)(bidiCharacter, codeBidiWarningLabel, tooltipEnabled);
|
|
97
|
+
var _DOMSerializer$render = _model.DOMSerializer.renderSpec(document, spec),
|
|
98
|
+
dom = _DOMSerializer$render.dom;
|
|
99
|
+
if (!(dom instanceof HTMLElement)) {
|
|
100
|
+
throw new Error('Code Bidi Warning DOM spec did not return an HTMLElement');
|
|
101
|
+
}
|
|
102
|
+
return dom;
|
|
103
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function getCodeBidiWarningDomSpec(bidiCharacter, codeBidiWarningLabel, tooltipEnabled) {
|
|
2
|
+
var _bidiCharacter$codePo, _bidiCharacter$codePo2;
|
|
3
|
+
const bidiCharacterCode = `U+${(_bidiCharacter$codePo = bidiCharacter.codePointAt(0)) === null || _bidiCharacter$codePo === void 0 ? void 0 : (_bidiCharacter$codePo2 = _bidiCharacter$codePo.toString(16)) === null || _bidiCharacter$codePo2 === void 0 ? void 0 : _bidiCharacter$codePo2.toUpperCase()}`;
|
|
4
|
+
return ['span', {
|
|
5
|
+
'data-prosemirror-node-name': 'code-bidi-warning',
|
|
6
|
+
dir: 'ltr'
|
|
7
|
+
},
|
|
8
|
+
// Code Bidi Warning Decorator
|
|
9
|
+
['span', {
|
|
10
|
+
'data-bidi-component': 'code-bidi-warning-decorator',
|
|
11
|
+
'data-testid': 'code-bidi-warning-decorator',
|
|
12
|
+
'data-bidi-character-code': bidiCharacterCode,
|
|
13
|
+
role: 'mark'
|
|
14
|
+
},
|
|
15
|
+
// Mark the < and > characters as visually hidden for screen readers
|
|
16
|
+
['span', {
|
|
17
|
+
'aria-hidden': 'true'
|
|
18
|
+
}, '<'], bidiCharacterCode, ['span', {
|
|
19
|
+
'aria-hidden': 'true'
|
|
20
|
+
}, '>']],
|
|
21
|
+
// Code Bidi Warning Tooltip
|
|
22
|
+
...(tooltipEnabled ? [['span', {
|
|
23
|
+
'data-bidi-component': 'code-bidi-warning-tooltip',
|
|
24
|
+
role: 'tooltip'
|
|
25
|
+
}, codeBidiWarningLabel]] : [])];
|
|
26
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { codeBidiWarningMessages } from '@atlaskit/editor-common/messages';
|
|
2
2
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
|
-
import {
|
|
3
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
4
4
|
import { codeBidiWarningPluginKey } from './plugin-key';
|
|
5
|
+
import { createBidiWarningsDecorationSetFromDoc as reactCreateBidiWarningsDecorationSetFromDoc, pluginFactoryCreator as reactPluginFactoryCreator } from './react-plugin-factory';
|
|
6
|
+
import { createBidiWarningsDecorationSetFromDoc as vanillaCreateBidiWarningsDecorationSetFromDoc, pluginFactoryCreator as vanillaPluginFactoryCreator } from './vanilla-plugin-factory';
|
|
5
7
|
export const createPlugin = ({
|
|
6
8
|
dispatch,
|
|
7
9
|
getIntl,
|
|
@@ -14,12 +16,16 @@ export const createPlugin = ({
|
|
|
14
16
|
const {
|
|
15
17
|
createPluginState,
|
|
16
18
|
getPluginState
|
|
17
|
-
} =
|
|
19
|
+
} = fg('platform_editor_vanilla_codebidi_warning') ? vanillaPluginFactoryCreator() : reactPluginFactoryCreator(nodeViewPortalProviderAPI);
|
|
18
20
|
return new SafePlugin({
|
|
19
21
|
key: codeBidiWarningPluginKey,
|
|
20
22
|
state: createPluginState(dispatch, state => {
|
|
21
23
|
return {
|
|
22
|
-
decorationSet:
|
|
24
|
+
decorationSet: fg('platform_editor_vanilla_codebidi_warning') ? vanillaCreateBidiWarningsDecorationSetFromDoc({
|
|
25
|
+
doc: state.doc,
|
|
26
|
+
codeBidiWarningLabel,
|
|
27
|
+
tooltipEnabled: true
|
|
28
|
+
}) : reactCreateBidiWarningsDecorationSetFromDoc({
|
|
23
29
|
doc: state.doc,
|
|
24
30
|
codeBidiWarningLabel,
|
|
25
31
|
tooltipEnabled: true,
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import codeBidiWarningDecorator from '@atlaskit/code/bidi-warning-decorator';
|
|
2
|
+
import { pluginFactory, stepHasSlice } from '@atlaskit/editor-common/utils';
|
|
3
|
+
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
4
|
+
import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
5
|
+
import { getCodeBidiWarningDomSpec } from './codeBidiWarningDomSpec';
|
|
6
|
+
import { codeBidiWarningPluginKey } from './plugin-key';
|
|
7
|
+
import reducer from './reducer';
|
|
8
|
+
export const pluginFactoryCreator = () => pluginFactory(codeBidiWarningPluginKey, reducer, {
|
|
9
|
+
onDocChanged: (tr, pluginState) => {
|
|
10
|
+
if (!tr.steps.find(stepHasSlice)) {
|
|
11
|
+
return pluginState;
|
|
12
|
+
}
|
|
13
|
+
const newBidiWarningsDecorationSet = createBidiWarningsDecorationSetFromDoc({
|
|
14
|
+
doc: tr.doc,
|
|
15
|
+
codeBidiWarningLabel: pluginState.codeBidiWarningLabel,
|
|
16
|
+
tooltipEnabled: pluginState.tooltipEnabled
|
|
17
|
+
});
|
|
18
|
+
return {
|
|
19
|
+
...pluginState,
|
|
20
|
+
decorationSet: newBidiWarningsDecorationSet
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
export function createBidiWarningsDecorationSetFromDoc({
|
|
25
|
+
doc,
|
|
26
|
+
codeBidiWarningLabel,
|
|
27
|
+
tooltipEnabled
|
|
28
|
+
}) {
|
|
29
|
+
const bidiCharactersAndTheirPositions = [];
|
|
30
|
+
doc.descendants((node, pos) => {
|
|
31
|
+
const isTextWithCodeMark = node.type.name === 'text' && node.marks && node.marks.some(mark => mark.type.name === 'code');
|
|
32
|
+
if (isTextWithCodeMark) {
|
|
33
|
+
codeBidiWarningDecorator(node.textContent, ({
|
|
34
|
+
bidiCharacter,
|
|
35
|
+
index
|
|
36
|
+
}) => {
|
|
37
|
+
bidiCharactersAndTheirPositions.push({
|
|
38
|
+
// Ignored via go/ees005
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
40
|
+
position: pos + index,
|
|
41
|
+
bidiCharacter
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
const isCodeBlock = node.type.name === 'codeBlock';
|
|
47
|
+
if (isCodeBlock) {
|
|
48
|
+
codeBidiWarningDecorator(node.textContent, ({
|
|
49
|
+
bidiCharacter,
|
|
50
|
+
index
|
|
51
|
+
}) => {
|
|
52
|
+
bidiCharactersAndTheirPositions.push({
|
|
53
|
+
// Ignored via go/ees005
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
55
|
+
position: pos + index + 1,
|
|
56
|
+
bidiCharacter
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Bidi characters are not expected to commonly appear in code snippets, so recreating the decoration set
|
|
63
|
+
// for documents rather than reusing existing decorations seems a reasonable performance/complexity tradeoff.
|
|
64
|
+
|
|
65
|
+
if (bidiCharactersAndTheirPositions.length === 0) {
|
|
66
|
+
return DecorationSet.empty;
|
|
67
|
+
}
|
|
68
|
+
const newBidiWarningsDecorationSet = DecorationSet.create(doc, bidiCharactersAndTheirPositions.map(({
|
|
69
|
+
position,
|
|
70
|
+
bidiCharacter
|
|
71
|
+
}) => {
|
|
72
|
+
return Decoration.widget(position, el => renderDOM(bidiCharacter, codeBidiWarningLabel, tooltipEnabled), {
|
|
73
|
+
destroy: el => {
|
|
74
|
+
if (!(el instanceof HTMLElement)) {
|
|
75
|
+
throw new Error('Code Bidi Warning DOM spec did not return an HTMLElement');
|
|
76
|
+
}
|
|
77
|
+
el.remove();
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}));
|
|
81
|
+
return newBidiWarningsDecorationSet;
|
|
82
|
+
}
|
|
83
|
+
function renderDOM(bidiCharacter, codeBidiWarningLabel, tooltipEnabled) {
|
|
84
|
+
const spec = getCodeBidiWarningDomSpec(bidiCharacter, codeBidiWarningLabel, tooltipEnabled);
|
|
85
|
+
const {
|
|
86
|
+
dom
|
|
87
|
+
} = DOMSerializer.renderSpec(document, spec);
|
|
88
|
+
if (!(dom instanceof HTMLElement)) {
|
|
89
|
+
throw new Error('Code Bidi Warning DOM spec did not return an HTMLElement');
|
|
90
|
+
}
|
|
91
|
+
return dom;
|
|
92
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
export function getCodeBidiWarningDomSpec(bidiCharacter, codeBidiWarningLabel, tooltipEnabled) {
|
|
3
|
+
var _bidiCharacter$codePo;
|
|
4
|
+
var bidiCharacterCode = "U+".concat((_bidiCharacter$codePo = bidiCharacter.codePointAt(0)) === null || _bidiCharacter$codePo === void 0 || (_bidiCharacter$codePo = _bidiCharacter$codePo.toString(16)) === null || _bidiCharacter$codePo === void 0 ? void 0 : _bidiCharacter$codePo.toUpperCase());
|
|
5
|
+
return ['span', {
|
|
6
|
+
'data-prosemirror-node-name': 'code-bidi-warning',
|
|
7
|
+
dir: 'ltr'
|
|
8
|
+
},
|
|
9
|
+
// Code Bidi Warning Decorator
|
|
10
|
+
['span', {
|
|
11
|
+
'data-bidi-component': 'code-bidi-warning-decorator',
|
|
12
|
+
'data-testid': 'code-bidi-warning-decorator',
|
|
13
|
+
'data-bidi-character-code': bidiCharacterCode,
|
|
14
|
+
role: 'mark'
|
|
15
|
+
},
|
|
16
|
+
// Mark the < and > characters as visually hidden for screen readers
|
|
17
|
+
['span', {
|
|
18
|
+
'aria-hidden': 'true'
|
|
19
|
+
}, '<'], bidiCharacterCode, ['span', {
|
|
20
|
+
'aria-hidden': 'true'
|
|
21
|
+
}, '>']]].concat(_toConsumableArray(tooltipEnabled ? [['span', {
|
|
22
|
+
'data-bidi-component': 'code-bidi-warning-tooltip',
|
|
23
|
+
role: 'tooltip'
|
|
24
|
+
}, codeBidiWarningLabel]] : []));
|
|
25
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { codeBidiWarningMessages } from '@atlaskit/editor-common/messages';
|
|
2
2
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
|
-
import {
|
|
3
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
4
4
|
import { codeBidiWarningPluginKey } from './plugin-key';
|
|
5
|
+
import { createBidiWarningsDecorationSetFromDoc as reactCreateBidiWarningsDecorationSetFromDoc, pluginFactoryCreator as reactPluginFactoryCreator } from './react-plugin-factory';
|
|
6
|
+
import { createBidiWarningsDecorationSetFromDoc as vanillaCreateBidiWarningsDecorationSetFromDoc, pluginFactoryCreator as vanillaPluginFactoryCreator } from './vanilla-plugin-factory';
|
|
5
7
|
export var createPlugin = function createPlugin(_ref, _ref2) {
|
|
6
8
|
var dispatch = _ref.dispatch,
|
|
7
9
|
getIntl = _ref.getIntl,
|
|
@@ -9,14 +11,18 @@ export var createPlugin = function createPlugin(_ref, _ref2) {
|
|
|
9
11
|
var appearance = _ref2.appearance;
|
|
10
12
|
var intl = getIntl();
|
|
11
13
|
var codeBidiWarningLabel = intl.formatMessage(codeBidiWarningMessages.label);
|
|
12
|
-
var
|
|
13
|
-
createPluginState =
|
|
14
|
-
getPluginState =
|
|
14
|
+
var _ref3 = fg('platform_editor_vanilla_codebidi_warning') ? vanillaPluginFactoryCreator() : reactPluginFactoryCreator(nodeViewPortalProviderAPI),
|
|
15
|
+
createPluginState = _ref3.createPluginState,
|
|
16
|
+
getPluginState = _ref3.getPluginState;
|
|
15
17
|
return new SafePlugin({
|
|
16
18
|
key: codeBidiWarningPluginKey,
|
|
17
19
|
state: createPluginState(dispatch, function (state) {
|
|
18
20
|
return {
|
|
19
|
-
decorationSet:
|
|
21
|
+
decorationSet: fg('platform_editor_vanilla_codebidi_warning') ? vanillaCreateBidiWarningsDecorationSetFromDoc({
|
|
22
|
+
doc: state.doc,
|
|
23
|
+
codeBidiWarningLabel: codeBidiWarningLabel,
|
|
24
|
+
tooltipEnabled: true
|
|
25
|
+
}) : reactCreateBidiWarningsDecorationSetFromDoc({
|
|
20
26
|
doc: state.doc,
|
|
21
27
|
codeBidiWarningLabel: codeBidiWarningLabel,
|
|
22
28
|
tooltipEnabled: true,
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
import codeBidiWarningDecorator from '@atlaskit/code/bidi-warning-decorator';
|
|
5
|
+
import { pluginFactory, stepHasSlice } from '@atlaskit/editor-common/utils';
|
|
6
|
+
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
7
|
+
import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
8
|
+
import { getCodeBidiWarningDomSpec } from './codeBidiWarningDomSpec';
|
|
9
|
+
import { codeBidiWarningPluginKey } from './plugin-key';
|
|
10
|
+
import reducer from './reducer';
|
|
11
|
+
export var pluginFactoryCreator = function pluginFactoryCreator() {
|
|
12
|
+
return pluginFactory(codeBidiWarningPluginKey, reducer, {
|
|
13
|
+
onDocChanged: function onDocChanged(tr, pluginState) {
|
|
14
|
+
if (!tr.steps.find(stepHasSlice)) {
|
|
15
|
+
return pluginState;
|
|
16
|
+
}
|
|
17
|
+
var newBidiWarningsDecorationSet = createBidiWarningsDecorationSetFromDoc({
|
|
18
|
+
doc: tr.doc,
|
|
19
|
+
codeBidiWarningLabel: pluginState.codeBidiWarningLabel,
|
|
20
|
+
tooltipEnabled: pluginState.tooltipEnabled
|
|
21
|
+
});
|
|
22
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
23
|
+
decorationSet: newBidiWarningsDecorationSet
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
export function createBidiWarningsDecorationSetFromDoc(_ref) {
|
|
29
|
+
var doc = _ref.doc,
|
|
30
|
+
codeBidiWarningLabel = _ref.codeBidiWarningLabel,
|
|
31
|
+
tooltipEnabled = _ref.tooltipEnabled;
|
|
32
|
+
var bidiCharactersAndTheirPositions = [];
|
|
33
|
+
doc.descendants(function (node, pos) {
|
|
34
|
+
var isTextWithCodeMark = node.type.name === 'text' && node.marks && node.marks.some(function (mark) {
|
|
35
|
+
return mark.type.name === 'code';
|
|
36
|
+
});
|
|
37
|
+
if (isTextWithCodeMark) {
|
|
38
|
+
codeBidiWarningDecorator(node.textContent, function (_ref2) {
|
|
39
|
+
var bidiCharacter = _ref2.bidiCharacter,
|
|
40
|
+
index = _ref2.index;
|
|
41
|
+
bidiCharactersAndTheirPositions.push({
|
|
42
|
+
// Ignored via go/ees005
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
44
|
+
position: pos + index,
|
|
45
|
+
bidiCharacter: bidiCharacter
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
var isCodeBlock = node.type.name === 'codeBlock';
|
|
51
|
+
if (isCodeBlock) {
|
|
52
|
+
codeBidiWarningDecorator(node.textContent, function (_ref3) {
|
|
53
|
+
var bidiCharacter = _ref3.bidiCharacter,
|
|
54
|
+
index = _ref3.index;
|
|
55
|
+
bidiCharactersAndTheirPositions.push({
|
|
56
|
+
// Ignored via go/ees005
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
58
|
+
position: pos + index + 1,
|
|
59
|
+
bidiCharacter: bidiCharacter
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Bidi characters are not expected to commonly appear in code snippets, so recreating the decoration set
|
|
66
|
+
// for documents rather than reusing existing decorations seems a reasonable performance/complexity tradeoff.
|
|
67
|
+
|
|
68
|
+
if (bidiCharactersAndTheirPositions.length === 0) {
|
|
69
|
+
return DecorationSet.empty;
|
|
70
|
+
}
|
|
71
|
+
var newBidiWarningsDecorationSet = DecorationSet.create(doc, bidiCharactersAndTheirPositions.map(function (_ref4) {
|
|
72
|
+
var position = _ref4.position,
|
|
73
|
+
bidiCharacter = _ref4.bidiCharacter;
|
|
74
|
+
return Decoration.widget(position, function (el) {
|
|
75
|
+
return renderDOM(bidiCharacter, codeBidiWarningLabel, tooltipEnabled);
|
|
76
|
+
}, {
|
|
77
|
+
destroy: function destroy(el) {
|
|
78
|
+
if (!(el instanceof HTMLElement)) {
|
|
79
|
+
throw new Error('Code Bidi Warning DOM spec did not return an HTMLElement');
|
|
80
|
+
}
|
|
81
|
+
el.remove();
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}));
|
|
85
|
+
return newBidiWarningsDecorationSet;
|
|
86
|
+
}
|
|
87
|
+
function renderDOM(bidiCharacter, codeBidiWarningLabel, tooltipEnabled) {
|
|
88
|
+
var spec = getCodeBidiWarningDomSpec(bidiCharacter, codeBidiWarningLabel, tooltipEnabled);
|
|
89
|
+
var _DOMSerializer$render = DOMSerializer.renderSpec(document, spec),
|
|
90
|
+
dom = _DOMSerializer$render.dom;
|
|
91
|
+
if (!(dom instanceof HTMLElement)) {
|
|
92
|
+
throw new Error('Code Bidi Warning DOM spec did not return an HTMLElement');
|
|
93
|
+
}
|
|
94
|
+
return dom;
|
|
95
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Node as PmNode } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
3
|
+
export declare const pluginFactoryCreator: () => {
|
|
4
|
+
createPluginState: (dispatch: import("@atlaskit/editor-common/event-dispatcher").Dispatch, initialState: import("./types").CodeBidiWarningPluginState | ((state: import("prosemirror-state").EditorState) => import("./types").CodeBidiWarningPluginState)) => import("prosemirror-state").SafeStateField<import("./types").CodeBidiWarningPluginState>;
|
|
5
|
+
createCommand: <A = unknown>(action: A | ((state: Readonly<import("prosemirror-state").EditorState>) => false | A), transform?: ((tr: import("prosemirror-state").Transaction, state: import("prosemirror-state").EditorState) => import("prosemirror-state").Transaction) | undefined) => import("@atlaskit/editor-common/types").Command;
|
|
6
|
+
getPluginState: (state: import("prosemirror-state").EditorState) => import("./types").CodeBidiWarningPluginState;
|
|
7
|
+
};
|
|
8
|
+
export declare function createBidiWarningsDecorationSetFromDoc({ doc, codeBidiWarningLabel, tooltipEnabled, }: {
|
|
9
|
+
doc: PmNode;
|
|
10
|
+
codeBidiWarningLabel: string;
|
|
11
|
+
tooltipEnabled: boolean;
|
|
12
|
+
}): DecorationSet;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Node as PmNode } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
3
|
+
export declare const pluginFactoryCreator: () => {
|
|
4
|
+
createPluginState: (dispatch: import("@atlaskit/editor-common/event-dispatcher").Dispatch, initialState: import("./types").CodeBidiWarningPluginState | ((state: import("prosemirror-state").EditorState) => import("./types").CodeBidiWarningPluginState)) => import("prosemirror-state").SafeStateField<import("./types").CodeBidiWarningPluginState>;
|
|
5
|
+
createCommand: <A = unknown>(action: A | ((state: Readonly<import("prosemirror-state").EditorState>) => false | A), transform?: ((tr: import("prosemirror-state").Transaction, state: import("prosemirror-state").EditorState) => import("prosemirror-state").Transaction) | undefined) => import("@atlaskit/editor-common/types").Command;
|
|
6
|
+
getPluginState: (state: import("prosemirror-state").EditorState) => import("./types").CodeBidiWarningPluginState;
|
|
7
|
+
};
|
|
8
|
+
export declare function createBidiWarningsDecorationSetFromDoc({ doc, codeBidiWarningLabel, tooltipEnabled, }: {
|
|
9
|
+
doc: PmNode;
|
|
10
|
+
codeBidiWarningLabel: string;
|
|
11
|
+
tooltipEnabled: boolean;
|
|
12
|
+
}): DecorationSet;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-code-bidi-warning",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Code bidi warning plugin for @atlaskit/editor-core.",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -9,8 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"atlassian": {
|
|
11
11
|
"team": "Editor: Core Experiences",
|
|
12
|
-
"singleton": true
|
|
13
|
-
"runReact18": true
|
|
12
|
+
"singleton": true
|
|
14
13
|
},
|
|
15
14
|
"repository": "https://bitbucket.org/atlassian/atlassian-frontend-mirror",
|
|
16
15
|
"main": "dist/cjs/index.js",
|
|
@@ -32,13 +31,13 @@
|
|
|
32
31
|
},
|
|
33
32
|
"dependencies": {
|
|
34
33
|
"@atlaskit/code": "^17.2.0",
|
|
35
|
-
"@atlaskit/editor-common": "^107.0.0",
|
|
36
34
|
"@atlaskit/editor-prosemirror": "7.0.0",
|
|
37
35
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
38
36
|
"@babel/runtime": "^7.0.0",
|
|
39
37
|
"uuid": "^3.1.0"
|
|
40
38
|
},
|
|
41
39
|
"peerDependencies": {
|
|
40
|
+
"@atlaskit/editor-common": "^107.6.0",
|
|
42
41
|
"react": "^18.2.0",
|
|
43
42
|
"react-dom": "^18.2.0"
|
|
44
43
|
},
|
|
@@ -86,5 +85,10 @@
|
|
|
86
85
|
"import-no-extraneous-disable-for-examples-and-docs"
|
|
87
86
|
]
|
|
88
87
|
}
|
|
88
|
+
},
|
|
89
|
+
"platform-feature-flags": {
|
|
90
|
+
"platform_editor_vanilla_codebidi_warning": {
|
|
91
|
+
"type": "boolean"
|
|
92
|
+
}
|
|
89
93
|
}
|
|
90
94
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|