@atlaskit/editor-core 191.0.8 → 191.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/afm-cc/tsconfig.json +3 -3
  3. package/dist/cjs/plugins/index.js +0 -7
  4. package/dist/cjs/presets/universal.js +2 -1
  5. package/dist/cjs/ui/Appearance/Comment/Comment.js +6 -3
  6. package/dist/cjs/ui/Appearance/Comment/Toolbar.js +19 -6
  7. package/dist/cjs/ui/Appearance/FullPage/FullPageToolbar.js +1 -1
  8. package/dist/cjs/ui/ContentStyles/index.js +1 -1
  9. package/dist/cjs/version-wrapper.js +1 -1
  10. package/dist/es2019/plugins/index.js +0 -1
  11. package/dist/es2019/presets/universal.js +2 -1
  12. package/dist/es2019/ui/Appearance/Comment/Comment.js +6 -3
  13. package/dist/es2019/ui/Appearance/Comment/Toolbar.js +38 -6
  14. package/dist/es2019/ui/Appearance/FullPage/FullPageToolbar.js +1 -1
  15. package/dist/es2019/ui/ContentStyles/index.js +1 -1
  16. package/dist/es2019/version-wrapper.js +1 -1
  17. package/dist/esm/plugins/index.js +0 -1
  18. package/dist/esm/presets/universal.js +2 -1
  19. package/dist/esm/ui/Appearance/Comment/Comment.js +6 -3
  20. package/dist/esm/ui/Appearance/Comment/Toolbar.js +19 -6
  21. package/dist/esm/ui/Appearance/FullPage/FullPageToolbar.js +1 -1
  22. package/dist/esm/ui/ContentStyles/index.js +1 -1
  23. package/dist/esm/version-wrapper.js +1 -1
  24. package/dist/types/plugins/index.d.ts +0 -1
  25. package/dist/types/types/editor-props.d.ts +1 -1
  26. package/dist/types/ui/Appearance/Comment/Toolbar.d.ts +2 -1
  27. package/dist/types-ts4.5/plugins/index.d.ts +0 -1
  28. package/dist/types-ts4.5/types/editor-props.d.ts +1 -1
  29. package/dist/types-ts4.5/ui/Appearance/Comment/Toolbar.d.ts +2 -1
  30. package/package.json +6 -10
  31. package/dist/cjs/plugins/find-replace/FindReplaceToolbarButtonWithState.js +0 -166
  32. package/dist/cjs/plugins/find-replace/actions.js +0 -19
  33. package/dist/cjs/plugins/find-replace/commands-with-analytics.js +0 -101
  34. package/dist/cjs/plugins/find-replace/commands.js +0 -255
  35. package/dist/cjs/plugins/find-replace/index.js +0 -94
  36. package/dist/cjs/plugins/find-replace/keymap.js +0 -24
  37. package/dist/cjs/plugins/find-replace/plugin-key.js +0 -8
  38. package/dist/cjs/plugins/find-replace/plugin.js +0 -138
  39. package/dist/cjs/plugins/find-replace/reducer.js +0 -61
  40. package/dist/cjs/plugins/find-replace/styles.js +0 -16
  41. package/dist/cjs/plugins/find-replace/types.js +0 -5
  42. package/dist/cjs/plugins/find-replace/ui/Find.js +0 -308
  43. package/dist/cjs/plugins/find-replace/ui/FindReplace.js +0 -103
  44. package/dist/cjs/plugins/find-replace/ui/FindReplaceToolbarButton.js +0 -132
  45. package/dist/cjs/plugins/find-replace/ui/FindReplaceTooltipButton.js +0 -76
  46. package/dist/cjs/plugins/find-replace/ui/Replace.js +0 -174
  47. package/dist/cjs/plugins/find-replace/ui/styles.js +0 -44
  48. package/dist/cjs/plugins/find-replace/utils/batch-decorations.js +0 -310
  49. package/dist/cjs/plugins/find-replace/utils/commands.js +0 -16
  50. package/dist/cjs/plugins/find-replace/utils/index.js +0 -290
  51. package/dist/cjs/utils/array.js +0 -13
  52. package/dist/es2019/plugins/find-replace/FindReplaceToolbarButtonWithState.js +0 -153
  53. package/dist/es2019/plugins/find-replace/actions.js +0 -13
  54. package/dist/es2019/plugins/find-replace/commands-with-analytics.js +0 -72
  55. package/dist/es2019/plugins/find-replace/commands.js +0 -240
  56. package/dist/es2019/plugins/find-replace/index.js +0 -89
  57. package/dist/es2019/plugins/find-replace/keymap.js +0 -16
  58. package/dist/es2019/plugins/find-replace/plugin-key.js +0 -2
  59. package/dist/es2019/plugins/find-replace/plugin.js +0 -117
  60. package/dist/es2019/plugins/find-replace/reducer.js +0 -56
  61. package/dist/es2019/plugins/find-replace/styles.js +0 -17
  62. package/dist/es2019/plugins/find-replace/types.js +0 -1
  63. package/dist/es2019/plugins/find-replace/ui/Find.js +0 -284
  64. package/dist/es2019/plugins/find-replace/ui/FindReplace.js +0 -78
  65. package/dist/es2019/plugins/find-replace/ui/FindReplaceToolbarButton.js +0 -122
  66. package/dist/es2019/plugins/find-replace/ui/FindReplaceTooltipButton.js +0 -50
  67. package/dist/es2019/plugins/find-replace/ui/Replace.js +0 -152
  68. package/dist/es2019/plugins/find-replace/ui/styles.js +0 -48
  69. package/dist/es2019/plugins/find-replace/utils/batch-decorations.js +0 -189
  70. package/dist/es2019/plugins/find-replace/utils/commands.js +0 -6
  71. package/dist/es2019/plugins/find-replace/utils/index.js +0 -249
  72. package/dist/es2019/utils/array.js +0 -3
  73. package/dist/esm/plugins/find-replace/FindReplaceToolbarButtonWithState.js +0 -157
  74. package/dist/esm/plugins/find-replace/actions.js +0 -13
  75. package/dist/esm/plugins/find-replace/commands-with-analytics.js +0 -95
  76. package/dist/esm/plugins/find-replace/commands.js +0 -248
  77. package/dist/esm/plugins/find-replace/index.js +0 -87
  78. package/dist/esm/plugins/find-replace/keymap.js +0 -18
  79. package/dist/esm/plugins/find-replace/plugin-key.js +0 -2
  80. package/dist/esm/plugins/find-replace/plugin.js +0 -133
  81. package/dist/esm/plugins/find-replace/reducer.js +0 -54
  82. package/dist/esm/plugins/find-replace/styles.js +0 -10
  83. package/dist/esm/plugins/find-replace/types.js +0 -1
  84. package/dist/esm/plugins/find-replace/ui/Find.js +0 -302
  85. package/dist/esm/plugins/find-replace/ui/FindReplace.js +0 -97
  86. package/dist/esm/plugins/find-replace/ui/FindReplaceToolbarButton.js +0 -126
  87. package/dist/esm/plugins/find-replace/ui/FindReplaceTooltipButton.js +0 -69
  88. package/dist/esm/plugins/find-replace/ui/Replace.js +0 -168
  89. package/dist/esm/plugins/find-replace/ui/styles.js +0 -37
  90. package/dist/esm/plugins/find-replace/utils/batch-decorations.js +0 -304
  91. package/dist/esm/plugins/find-replace/utils/commands.js +0 -10
  92. package/dist/esm/plugins/find-replace/utils/index.js +0 -280
  93. package/dist/esm/utils/array.js +0 -7
  94. package/dist/types/plugins/find-replace/FindReplaceToolbarButtonWithState.d.ts +0 -4
  95. package/dist/types/plugins/find-replace/actions.d.ts +0 -64
  96. package/dist/types/plugins/find-replace/commands-with-analytics.d.ts +0 -27
  97. package/dist/types/plugins/find-replace/commands.d.ts +0 -12
  98. package/dist/types/plugins/find-replace/index.d.ts +0 -3
  99. package/dist/types/plugins/find-replace/keymap.d.ts +0 -4
  100. package/dist/types/plugins/find-replace/plugin-key.d.ts +0 -3
  101. package/dist/types/plugins/find-replace/plugin.d.ts +0 -6
  102. package/dist/types/plugins/find-replace/reducer.d.ts +0 -4
  103. package/dist/types/plugins/find-replace/styles.d.ts +0 -3
  104. package/dist/types/plugins/find-replace/types.d.ts +0 -79
  105. package/dist/types/plugins/find-replace/ui/Find.d.ts +0 -71
  106. package/dist/types/plugins/find-replace/ui/FindReplace.d.ts +0 -43
  107. package/dist/types/plugins/find-replace/ui/FindReplaceToolbarButton.d.ts +0 -21
  108. package/dist/types/plugins/find-replace/ui/FindReplaceTooltipButton.d.ts +0 -18
  109. package/dist/types/plugins/find-replace/ui/Replace.d.ts +0 -27
  110. package/dist/types/plugins/find-replace/ui/styles.d.ts +0 -6
  111. package/dist/types/plugins/find-replace/utils/batch-decorations.d.ts +0 -36
  112. package/dist/types/plugins/find-replace/utils/commands.d.ts +0 -2
  113. package/dist/types/plugins/find-replace/utils/index.d.ts +0 -49
  114. package/dist/types/utils/array.d.ts +0 -1
  115. package/dist/types-ts4.5/plugins/find-replace/FindReplaceToolbarButtonWithState.d.ts +0 -4
  116. package/dist/types-ts4.5/plugins/find-replace/actions.d.ts +0 -64
  117. package/dist/types-ts4.5/plugins/find-replace/commands-with-analytics.d.ts +0 -27
  118. package/dist/types-ts4.5/plugins/find-replace/commands.d.ts +0 -12
  119. package/dist/types-ts4.5/plugins/find-replace/index.d.ts +0 -3
  120. package/dist/types-ts4.5/plugins/find-replace/keymap.d.ts +0 -4
  121. package/dist/types-ts4.5/plugins/find-replace/plugin-key.d.ts +0 -3
  122. package/dist/types-ts4.5/plugins/find-replace/plugin.d.ts +0 -6
  123. package/dist/types-ts4.5/plugins/find-replace/reducer.d.ts +0 -4
  124. package/dist/types-ts4.5/plugins/find-replace/styles.d.ts +0 -3
  125. package/dist/types-ts4.5/plugins/find-replace/types.d.ts +0 -79
  126. package/dist/types-ts4.5/plugins/find-replace/ui/Find.d.ts +0 -71
  127. package/dist/types-ts4.5/plugins/find-replace/ui/FindReplace.d.ts +0 -43
  128. package/dist/types-ts4.5/plugins/find-replace/ui/FindReplaceToolbarButton.d.ts +0 -21
  129. package/dist/types-ts4.5/plugins/find-replace/ui/FindReplaceTooltipButton.d.ts +0 -18
  130. package/dist/types-ts4.5/plugins/find-replace/ui/Replace.d.ts +0 -27
  131. package/dist/types-ts4.5/plugins/find-replace/ui/styles.d.ts +0 -6
  132. package/dist/types-ts4.5/plugins/find-replace/utils/batch-decorations.d.ts +0 -36
  133. package/dist/types-ts4.5/plugins/find-replace/utils/commands.d.ts +0 -2
  134. package/dist/types-ts4.5/plugins/find-replace/utils/index.d.ts +0 -49
  135. package/dist/types-ts4.5/utils/array.d.ts +0 -1
@@ -1,50 +0,0 @@
1
- import _extends from "@babel/runtime/helpers/extends";
2
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
- import React from 'react';
4
- import Tooltip from '@atlaskit/tooltip';
5
- import { ToolTipContent, findKeymapByDescription } from '@atlaskit/editor-common/keymaps';
6
- import Button from '@atlaskit/button/standard-button';
7
- export class FindReplaceTooltipButton extends React.PureComponent {
8
- constructor(...args) {
9
- super(...args);
10
- _defineProperty(this, "buttonRef", /*#__PURE__*/React.createRef());
11
- _defineProperty(this, "handleClick", () => {
12
- this.props.onClick(this.buttonRef);
13
- });
14
- }
15
- render() {
16
- const {
17
- title,
18
- icon,
19
- keymapDescription,
20
- disabled,
21
- isPressed
22
- } = this.props;
23
- const pressedProps = {
24
- ...(typeof isPressed === 'boolean' && {
25
- 'aria-pressed': isPressed
26
- })
27
- };
28
- return /*#__PURE__*/React.createElement(Tooltip, {
29
- content: /*#__PURE__*/React.createElement(ToolTipContent, {
30
- description: title,
31
- keymap: findKeymapByDescription(keymapDescription)
32
- }),
33
- hideTooltipOnClick: true,
34
- position: 'top'
35
- }, /*#__PURE__*/React.createElement(Button, _extends({
36
- label: title,
37
- appearance: "subtle",
38
- testId: title,
39
- ref: this.buttonRef,
40
- iconBefore: icon,
41
- isDisabled: disabled,
42
- onClick: this.handleClick,
43
- isSelected: isPressed,
44
- shouldFitContainer: true
45
- }, pressedProps)));
46
- }
47
- }
48
- _defineProperty(FindReplaceTooltipButton, "defaultProps", {
49
- keymapDescription: 'no-keymap'
50
- });
@@ -1,152 +0,0 @@
1
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- /** @jsx jsx */
3
- import React from 'react';
4
- import { jsx } from '@emotion/react';
5
- import Button from '@atlaskit/button/standard-button';
6
- import { defineMessages, injectIntl } from 'react-intl-next';
7
- import Textfield from '@atlaskit/textfield';
8
- import { sectionWrapperStyles, replaceSectionButtonStyles } from './styles';
9
- import { EVENT_TYPE, ACTION, ACTION_SUBJECT, TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
10
- const messages = defineMessages({
11
- replaceWith: {
12
- id: 'fabric.editor.replaceWith',
13
- defaultMessage: 'Replace with',
14
- description: 'The value that will replace the word or phrase that was searched for'
15
- },
16
- replace: {
17
- id: 'fabric.editor.replace',
18
- defaultMessage: 'Replace',
19
- description: 'Replace only the currently selected instance of the word or phrase'
20
- },
21
- replaceAll: {
22
- id: 'fabric.editor.replaceAll',
23
- defaultMessage: 'Replace all',
24
- description: 'Replace all instances of the word or phrase throughout the entire document'
25
- }
26
- });
27
- class Replace extends React.PureComponent {
28
- constructor(props) {
29
- super(props);
30
- _defineProperty(this, "replaceTextfieldRef", /*#__PURE__*/React.createRef());
31
- _defineProperty(this, "skipWhileComposing", fn => {
32
- if (this.state.isComposing) {
33
- return;
34
- }
35
- fn();
36
- });
37
- _defineProperty(this, "handleReplaceClick", () => this.skipWhileComposing(() => {
38
- this.props.onReplace({
39
- triggerMethod: TRIGGER_METHOD.BUTTON,
40
- replaceText: this.state.replaceText
41
- });
42
- }));
43
- _defineProperty(this, "handleReplaceChange", event => this.skipWhileComposing(() => {
44
- this.updateReplaceValue(event.target.value);
45
- }));
46
- _defineProperty(this, "updateReplaceValue", replaceText => {
47
- const {
48
- dispatchAnalyticsEvent
49
- } = this.props;
50
- if (dispatchAnalyticsEvent) {
51
- dispatchAnalyticsEvent({
52
- eventType: EVENT_TYPE.TRACK,
53
- action: ACTION.CHANGED_REPLACEMENT_TEXT,
54
- actionSubject: ACTION_SUBJECT.FIND_REPLACE_DIALOG
55
- });
56
- }
57
- this.setState({
58
- replaceText
59
- });
60
- });
61
- _defineProperty(this, "handleReplaceKeyDown", event => this.skipWhileComposing(() => {
62
- if (event.key === 'Enter') {
63
- this.props.onReplace({
64
- triggerMethod: TRIGGER_METHOD.KEYBOARD,
65
- replaceText: this.state.replaceText
66
- });
67
- } else if (event.key === 'ArrowUp') {
68
- // we want to move focus between find & replace texfields when user hits up/down arrows
69
- this.props.onArrowUp();
70
- }
71
- }));
72
- _defineProperty(this, "handleReplaceAllClick", () => this.skipWhileComposing(() => {
73
- this.props.onReplaceAll({
74
- replaceText: this.state.replaceText
75
- });
76
- }));
77
- _defineProperty(this, "handleCompositionStart", () => {
78
- this.setState({
79
- isComposing: true
80
- });
81
- });
82
- _defineProperty(this, "handleCompositionEnd", event => {
83
- this.setState({
84
- isComposing: false
85
- });
86
- // type for React.CompositionEvent doesn't set type for target correctly
87
- this.updateReplaceValue(event.target.value);
88
- });
89
- const {
90
- replaceText: _replaceText,
91
- intl: {
92
- formatMessage
93
- }
94
- } = props;
95
- this.state = {
96
- replaceText: _replaceText || '',
97
- isComposing: false
98
- };
99
- this.replaceWith = formatMessage(messages.replaceWith);
100
- this.replace = formatMessage(messages.replace);
101
- this.replaceAll = formatMessage(messages.replaceAll);
102
- }
103
- componentDidMount() {
104
- this.props.onReplaceTextfieldRefSet(this.replaceTextfieldRef);
105
- }
106
- componentDidUpdate({
107
- replaceText: prevReplaceText
108
- }) {
109
- const {
110
- replaceText
111
- } = this.props;
112
- if (replaceText && replaceText !== prevReplaceText) {
113
- this.setState({
114
- replaceText,
115
- isComposing: false
116
- });
117
- }
118
- }
119
- render() {
120
- const {
121
- replaceText
122
- } = this.state;
123
- const {
124
- canReplace
125
- } = this.props;
126
- return jsx("div", {
127
- css: sectionWrapperStyles
128
- }, jsx(Textfield, {
129
- name: "replace",
130
- appearance: "none",
131
- placeholder: this.replaceWith,
132
- defaultValue: replaceText,
133
- ref: this.replaceTextfieldRef,
134
- autoComplete: "off",
135
- onChange: this.handleReplaceChange,
136
- onKeyDown: this.handleReplaceKeyDown,
137
- onCompositionStart: this.handleCompositionStart,
138
- onCompositionEnd: this.handleCompositionEnd
139
- }), jsx(Button, {
140
- css: replaceSectionButtonStyles,
141
- testId: this.replace,
142
- onClick: this.handleReplaceClick,
143
- isDisabled: !canReplace
144
- }, this.replace), jsx(Button, {
145
- css: replaceSectionButtonStyles,
146
- testId: this.replaceAll,
147
- onClick: this.handleReplaceAllClick,
148
- isDisabled: !canReplace
149
- }, this.replaceAll));
150
- }
151
- }
152
- export default injectIntl(Replace);
@@ -1,48 +0,0 @@
1
- /** @jsx jsx */
2
- import { css } from '@emotion/react';
3
- import { N60, N30A } from '@atlaskit/theme/colors';
4
- import { relativeFontSizeToBase16 } from '@atlaskit/editor-shared-styles';
5
- export const replaceSectionButtonStyles = css({
6
- marginLeft: "var(--ds-space-050, 4px)"
7
- });
8
- export const ruleStyles = css({
9
- width: '100%',
10
- border: 'none',
11
- backgroundColor: `${`var(--ds-border, ${N30A})`}`,
12
- margin: `${"var(--ds-space-050, 4px)"} 0px`,
13
- height: '1px',
14
- borderRadius: '1px'
15
- });
16
- export const wrapperStyles = css({
17
- display: 'flex',
18
- flexDirection: 'column',
19
- '> *:not(#replace-hr-element)': {
20
- margin: `0px ${"var(--ds-space-050, 4px)"}`
21
- }
22
- });
23
- export const sectionWrapperStyles = css`
24
- display: flex;
25
-
26
- & > * {
27
- display: inline-flex;
28
- height: 32px;
29
- flex: 0 0 auto;
30
- }
31
-
32
- & > [data-ds--text-field--container] {
33
- display: flex;
34
- flex: 1 1 auto;
35
- }
36
- `;
37
- export const countStyles = css({
38
- color: `${`var(--ds-text-subtlest, ${N60})`}`,
39
- fontSize: `${relativeFontSizeToBase16(12)}`,
40
- flex: '0 0 auto',
41
- justifyContent: 'center',
42
- alignItems: 'center',
43
- marginLeft: "var(--ds-space-050, 4px)",
44
- marginRight: "var(--ds-space-100, 8px)"
45
- });
46
- export const countWrapperStyles = css({
47
- alignItems: 'center'
48
- });
@@ -1,189 +0,0 @@
1
- import { createDecorations, findDecorationFromMatch } from './index';
2
- import { getPluginState } from '../plugin';
3
-
4
- // max number of decorations to apply at once
5
- const batchIncrement = 100;
6
- // position range to apply decorations between before alternating above or below viewport
7
- const posIncrement = 2000;
8
- /**
9
- * Provides support for applying search match highlight decorations in batches
10
- */
11
- class BatchDecorations {
12
- stop() {
13
- if (this.rafId) {
14
- cancelAnimationFrame(this.rafId);
15
- }
16
- }
17
-
18
- /**
19
- * Applies the decorations needed for the current search results
20
- * It does so async, splitting them up into batches to help with performance
21
- */
22
- async applyAllSearchDecorations(editorView, containerElement, addDecorations, removeDecorations) {
23
- this.stop();
24
- this.addDecorations = addDecorations;
25
- this.removeDecorations = removeDecorations;
26
- if (!containerElement) {
27
- return;
28
- }
29
- const pmElement = containerElement.querySelector('.ProseMirror');
30
- if (!pmElement) {
31
- return;
32
- }
33
- const positions = this.calcDecorationPositions(editorView, containerElement, pmElement);
34
- const {
35
- startPos,
36
- endPos,
37
- viewportStartPos,
38
- viewportEndPos
39
- } = positions;
40
- let dir = 0;
41
- let before = viewportStartPos;
42
- let after = viewportEndPos - posIncrement;
43
- await this.updateDecorationsBetween(editorView, viewportStartPos, viewportEndPos);
44
- while (before > startPos || after < endPos) {
45
- if (dir++ % 2 === 0 && before > startPos || after >= endPos) {
46
- const diff = before - startPos;
47
- before = Math.max(before - posIncrement, startPos);
48
- await this.updateDecorationsBetween(editorView, before, before + Math.min(diff, posIncrement));
49
- } else {
50
- after = Math.min(after + posIncrement, endPos);
51
- await this.updateDecorationsBetween(editorView, after, Math.min(after + posIncrement, endPos));
52
- }
53
- }
54
- }
55
- async updateDecorationsBetween(editorView, startPos, endPos) {
56
- await this.removeDecorationsBetween(editorView, startPos, endPos);
57
- await this.addDecorationsBetween(editorView, startPos, endPos);
58
- }
59
- async addDecorationsBetween(editorView, startPos, endPos) {
60
- const {
61
- selection
62
- } = editorView.state;
63
- const {
64
- matches,
65
- decorationSet
66
- } = getPluginState(editorView.state);
67
- if (matches.length === 0) {
68
- return;
69
- }
70
- const matchesBetween = matches.filter(m => m.start >= startPos && (endPos === undefined || m.start < endPos));
71
- const selectionMatch = matches.find(match => match.start >= selection.from);
72
- const selectionIndex = matchesBetween.findIndex(match => match === selectionMatch);
73
- return await this.batchRequests(counter => {
74
- let matchesToDecorate = matchesBetween.slice(counter, counter + batchIncrement);
75
- if (matchesToDecorate.length === 0) {
76
- return false;
77
- }
78
- let useSelectionIndex = selectionIndex >= counter && selectionIndex < counter + batchIncrement;
79
- if (selectionMatch && useSelectionIndex) {
80
- const selectionMatchDecoration = findDecorationFromMatch(decorationSet, selectionMatch);
81
- if (selectionMatchDecoration) {
82
- matchesToDecorate.splice(selectionIndex % batchIncrement, 1);
83
- useSelectionIndex = false;
84
- }
85
- }
86
- if (this.addDecorations) {
87
- this.addDecorations(createDecorations(useSelectionIndex ? selectionIndex % batchIncrement : -1, matchesToDecorate));
88
- }
89
- }, {
90
- increment: batchIncrement,
91
- until: matchesBetween.length
92
- });
93
- }
94
- async removeDecorationsBetween(editorView, startPos, endPos) {
95
- const {
96
- decorationSet
97
- } = getPluginState(editorView.state);
98
- const decorations = decorationSet.find(startPos, endPos);
99
- if (decorations.length === 0) {
100
- return;
101
- }
102
- return await this.batchRequests(counter => {
103
- let decorationsToRemove = decorations.slice(counter, counter + batchIncrement);
104
- if (decorationsToRemove.length === 0) {
105
- return false;
106
- }
107
- // only get those decorations whose from >= startPos
108
- for (let i = 0; i < decorationsToRemove.length; i++) {
109
- if (decorationsToRemove[i].from >= startPos) {
110
- break;
111
- }
112
- decorationsToRemove = decorationsToRemove.slice(1);
113
- }
114
- if (this.removeDecorations) {
115
- this.removeDecorations(decorationsToRemove);
116
- }
117
- }, {
118
- increment: batchIncrement,
119
- until: decorations.length
120
- });
121
- }
122
-
123
- /**
124
- * Calculates Prosemirror start and end positions we want to apply the decorations
125
- * between
126
- * Also calculates the positions the are the start and end of the user's viewport
127
- * so we can apply decorations there first and work outwards
128
- */
129
- calcDecorationPositions(editorView, containerElement, pmElement) {
130
- const containerRect = containerElement.getBoundingClientRect();
131
- const pmRect = pmElement.getBoundingClientRect();
132
- const viewportStartPos = this.getStartPos(editorView, 0, pmRect.left);
133
- const viewportEndPos = this.getEndPos(editorView, containerRect.top + containerRect.height, pmRect.left);
134
- return {
135
- viewportStartPos,
136
- viewportEndPos,
137
- startPos: 1,
138
- endPos: editorView.state.doc.nodeSize
139
- };
140
- }
141
- getStartPos(editorView, y, x) {
142
- const startPos = editorView.posAtCoords({
143
- top: y,
144
- left: x
145
- });
146
- return startPos ? startPos.pos : 1;
147
- }
148
- getEndPos(editorView, y, x) {
149
- const maxPos = editorView.state.doc.nodeSize;
150
- const endPos = editorView.posAtCoords({
151
- top: y,
152
- left: x
153
- });
154
- return endPos ? endPos.pos : maxPos;
155
- }
156
-
157
- /**
158
- * Util to batch function calls by animation frames
159
- * A counter will start at 0 and increment by provided value until reaches limit
160
- * Passed in fn receives the counter as a param, return false to skip waiting
161
- * for the animation frame for the next call
162
- */
163
- batchRequests(fn, opts) {
164
- let counter = 0;
165
- const {
166
- increment,
167
- until
168
- } = opts;
169
- return new Promise(resolve => {
170
- const batchedFn = () => {
171
- let result = fn(counter);
172
- while (result === false && counter < until) {
173
- counter += increment;
174
- result = fn(counter);
175
- }
176
- if (counter < until) {
177
- counter += increment;
178
- this.rafId = requestAnimationFrame(batchedFn);
179
- } else {
180
- this.rafId = undefined;
181
- resolve();
182
- }
183
- };
184
- this.rafId = requestAnimationFrame(batchedFn);
185
- });
186
- }
187
- }
188
- const batchDecorations = new BatchDecorations();
189
- export default batchDecorations;
@@ -1,6 +0,0 @@
1
- export const withScrollIntoView = command => (state, dispatch, view) => command(state, tr => {
2
- tr.scrollIntoView();
3
- if (dispatch) {
4
- dispatch(tr);
5
- }
6
- }, view);
@@ -1,249 +0,0 @@
1
- import { Decoration } from '@atlaskit/editor-prosemirror/view';
2
- import { TextSelection } from '@atlaskit/editor-prosemirror/state';
3
- import { selectedSearchMatchClass, searchMatchClass } from '../styles';
4
- export function getSelectedText(selection) {
5
- let text = '';
6
- const selectedContent = selection.content().content;
7
- for (let i = 0; i < selectedContent.childCount; i++) {
8
- text += selectedContent.child(i).textContent;
9
- }
10
- return text;
11
- }
12
- export const createDecorations = (selectedIndex, matches) => matches.map(({
13
- start,
14
- end
15
- }, i) => createDecoration(start, end, i === selectedIndex));
16
- export const createDecoration = (start, end, isSelected) => {
17
- let className = searchMatchClass;
18
- if (isSelected) {
19
- className += ` ${selectedSearchMatchClass}`;
20
- }
21
- return Decoration.inline(start, end, {
22
- class: className
23
- });
24
- };
25
- export function findMatches(content, searchText, shouldMatchCase, contentIndex = 0) {
26
- let matches = [];
27
- const searchTextLength = searchText.length;
28
- let textGrouping = null;
29
- const collectMatch = textGrouping => {
30
- if (!textGrouping) {
31
- return;
32
- }
33
- let {
34
- text,
35
- pos: relativePos
36
- } = textGrouping;
37
- const pos = contentIndex + relativePos;
38
- if (!shouldMatchCase) {
39
- searchText = searchText.toLowerCase();
40
- text = text.toLowerCase();
41
- }
42
- let index = text.indexOf(searchText);
43
- while (index !== -1) {
44
- // Find the next substring from the end of the first, so that they don't overlap
45
- const end = index + searchTextLength;
46
- // Add the substring index to the position of the node
47
- matches.push({
48
- start: pos + index,
49
- end: pos + end
50
- });
51
- index = text.indexOf(searchText, end);
52
- }
53
- };
54
- if (searchTextLength > 0) {
55
- content.descendants((node, pos) => {
56
- if (node.isText) {
57
- if (textGrouping === null) {
58
- textGrouping = {
59
- text: node.text,
60
- pos
61
- };
62
- } else {
63
- textGrouping.text = textGrouping.text + node.text;
64
- }
65
- } else {
66
- collectMatch(textGrouping);
67
- textGrouping = null;
68
- }
69
- });
70
- // if there's a dangling text grouping and no non-text node to trigger collectMatch, manually collectMatch
71
- if (textGrouping) {
72
- collectMatch(textGrouping);
73
- }
74
- }
75
- return matches;
76
- }
77
-
78
- /**
79
- * Finds index of first item in matches array that comes after user's cursor pos.
80
- * If `backward` is `true`, finds index of first item that comes before instead.
81
- */
82
- export function findSearchIndex(selectionPos, matches, backward = false) {
83
- if (backward) {
84
- let matchIndex = matches.findIndex(match => match.start >= selectionPos) - 1;
85
- if (matchIndex < 0) {
86
- matchIndex = matches.length - 1; // wrap around from the end
87
- }
88
-
89
- return matchIndex;
90
- }
91
- return Math.max(matches.findIndex(match => match.start >= selectionPos), 0);
92
- }
93
- export const nextIndex = (currentIndex, total) => (currentIndex + 1) % total;
94
- export const prevIndex = (currentIndex, total) => (currentIndex - 1 + total) % total;
95
- export const getSelectionForMatch = (selection, doc, index, matches, offset = 0) => {
96
- if (matches[index]) {
97
- return TextSelection.create(doc, matches[index].start + offset);
98
- }
99
- return selection;
100
- };
101
- export const findDecorationFromMatch = (decorationSet, match) => {
102
- if (!match) {
103
- return;
104
- }
105
- const decorations = decorationSet.find(match.start, match.end);
106
- return decorations.length ? decorations.find(
107
- // decorationSet.find() returns any decorations that touch the specifided
108
- // positions, but we want to be stricter
109
- decoration => decoration.from === match.start && decoration.to === match.end) : undefined;
110
- };
111
- export const removeDecorationsFromSet = (decorationSet, decorationsToRemove, doc) => {
112
- const prevDecorations = decorationSet.find();
113
-
114
- // it is essential that we copy the decorations otherwise in some rare cases
115
- // prosemirror-view will update our decorationsToRemove array to contain nulls
116
- // instead of Decorations which ruins our check for lost decorations below
117
- decorationSet = decorationSet.remove(decorationsToRemove.map(decoration =>
118
- // copy exists but isn't on the type definition
119
- decoration.copy(decoration.from, decoration.to)));
120
- const newDecorations = decorationSet.find();
121
-
122
- // there is a bug in prosemirror-view where it can't cope with deleting inline
123
- // decorations from a set in some cases (where there are multiple levels of nested
124
- // children arrays), and it deletes more decorations than it should
125
- // todo: ticket link
126
- const lostDecorations = findLostAdjacentDecorations(decorationsToRemove, prevDecorations, newDecorations);
127
- if (lostDecorations.length > 0) {
128
- decorationSet = decorationSet.add(doc, lostDecorations);
129
- }
130
- return decorationSet;
131
- };
132
- export const removeMatchesFromSet = (decorationSet, matches, doc) => {
133
- const decorationsToRemove = matches.filter(match => !!match).map(match => findDecorationFromMatch(decorationSet, match));
134
- decorationsToRemove.forEach(decoration => {
135
- if (decoration) {
136
- decorationSet = removeDecorationsFromSet(decorationSet, [decoration], doc);
137
- }
138
- });
139
- return decorationSet;
140
- };
141
-
142
- /**
143
- * Finds decorations in prevDecorations that are not in newDecorations or decorationsToRemove
144
- * These decorations have been lost by Prosemirror during an over eager decoration removal
145
- * We need to be smart to cope with thousands of decorations without crashing everything
146
- */
147
- export const findLostAdjacentDecorations = (decorationsToRemove, prevDecorations, newDecorations) => {
148
- let lostDecorations = [];
149
- if (prevDecorations.length - decorationsToRemove.length > newDecorations.length) {
150
- const position = decorationsToRemove.length > 0 ? decorationsToRemove[0].from : 0;
151
- const prevDecorationsStartIdx = findIndexBeforePosition(prevDecorations, position);
152
- const newDecorationsStartIdx = findIndexBeforePosition(newDecorations, position);
153
- const startIdx = Math.min(prevDecorationsStartIdx, newDecorationsStartIdx);
154
- const prevDecorationsToCheck = prevDecorations.slice(startIdx);
155
- const newDecorationsToCheck = newDecorations.slice(startIdx);
156
- const uniqueInPrev = [];
157
- const numToFind = prevDecorationsToCheck.length - newDecorationsToCheck.length;
158
- let foundAll = false;
159
- let newDecorationsIdxOffset = 0;
160
- for (let i = 0; i < prevDecorationsToCheck.length; i++) {
161
- const prevDecoration = prevDecorationsToCheck[i];
162
- // this was a legit removal, skip and continue
163
- if (decorationsToRemove.find(decoration => decoration.from === prevDecoration.from)) {
164
- newDecorationsIdxOffset -= 1;
165
- continue;
166
- }
167
- let j = i + newDecorationsIdxOffset;
168
-
169
- // this is a lost decoration
170
- if (j >= newDecorationsToCheck.length) {
171
- uniqueInPrev.push(prevDecoration);
172
- if (uniqueInPrev.length === numToFind) {
173
- foundAll = true;
174
- }
175
- }
176
- for (; j < newDecorationsToCheck.length; j++) {
177
- const newDecoration = newDecorationsToCheck[j];
178
-
179
- // decoration found in both arrays, skip and continue
180
- if (prevDecoration.from === newDecoration.from) {
181
- break;
182
- }
183
-
184
- // this is a lost decoration
185
- if (newDecoration.from > prevDecoration.from || j === newDecorationsToCheck.length - 1) {
186
- uniqueInPrev.push(prevDecoration);
187
- newDecorationsIdxOffset -= 1;
188
- if (uniqueInPrev.length === numToFind) {
189
- foundAll = true;
190
- }
191
- break;
192
- }
193
- }
194
- if (foundAll) {
195
- break;
196
- }
197
- }
198
-
199
- // make sure we ignore any that we wanted to delete
200
- lostDecorations = uniqueInPrev.filter(decoration => !decorationsToRemove.find(decorationToRemove => decoration.from === decorationToRemove.from));
201
- }
202
- return lostDecorations;
203
- };
204
-
205
- /**
206
- * Searches through array in bumps of 100 to return the index of the first
207
- * decoration whose 'from' value is before or equal to the position
208
- */
209
- export const findIndexBeforePosition = (items, position) => {
210
- // jump in batches to cope with arrays with thousands of decorations
211
- const increment = 100;
212
- let index = 0;
213
- for (let i = items.length - 1; i >= 0; i -= increment) {
214
- if (items[i].from < position) {
215
- // now we have found the 100 range, we can narrow it down to exact index
216
- index = i;
217
- for (let j = i; j <= items.length - 1; j++) {
218
- if (items[j].from <= position) {
219
- index = j;
220
- } else {
221
- break;
222
- }
223
- }
224
- break;
225
- }
226
- if (i < 100 && i > 0) {
227
- i = 100;
228
- }
229
- }
230
- return index;
231
- };
232
-
233
- /**
234
- * Determines whether a find/replace text Match will be changed as a result
235
- * of a Step modification to the document. This is evaluated by checking
236
- * both mapped and unmapped versions of the Step as in different cases the
237
- * matches will match.
238
- *
239
- * **Note:** Match state received here is after step has been applied.
240
- */
241
- export const isMatchAffectedByStep = (match, step, tr) => {
242
- const {
243
- from,
244
- to,
245
- slice
246
- } = step;
247
- const sliceSize = slice.content.size;
248
- return from + sliceSize >= match.start && to - sliceSize <= match.end || tr.mapping.map(from) + sliceSize >= match.start && tr.mapping.map(to) - sliceSize <= match.end;
249
- };
@@ -1,3 +0,0 @@
1
- export function findUniqueItemsIn(findIn, checkWith, comparator) {
2
- return findIn.filter(firstItem => checkWith.findIndex(secondItem => comparator ? comparator(firstItem, secondItem) : firstItem === secondItem) === -1);
3
- }