@atlaskit/editor-plugin-text-formatting 0.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 (140) hide show
  1. package/.eslintrc.js +7 -0
  2. package/CHANGELOG.md +1 -0
  3. package/LICENSE.md +13 -0
  4. package/README.md +9 -0
  5. package/dist/cjs/actions.js +188 -0
  6. package/dist/cjs/commands/clear-formatting.js +111 -0
  7. package/dist/cjs/commands/text-formatting.js +143 -0
  8. package/dist/cjs/commands/transform-to-code.js +68 -0
  9. package/dist/cjs/index.js +12 -0
  10. package/dist/cjs/plugin.js +133 -0
  11. package/dist/cjs/pm-plugins/clear-formatting-keymap.js +21 -0
  12. package/dist/cjs/pm-plugins/clear-formatting.js +36 -0
  13. package/dist/cjs/pm-plugins/cursor.js +55 -0
  14. package/dist/cjs/pm-plugins/input-rule.js +274 -0
  15. package/dist/cjs/pm-plugins/keymap.js +52 -0
  16. package/dist/cjs/pm-plugins/main.js +113 -0
  17. package/dist/cjs/pm-plugins/plugin-key.js +9 -0
  18. package/dist/cjs/pm-plugins/smart-input-rule.js +176 -0
  19. package/dist/cjs/ui/Toolbar/constants.js +19 -0
  20. package/dist/cjs/ui/Toolbar/dropdown-menu.js +86 -0
  21. package/dist/cjs/ui/Toolbar/hooks/clear-formatting-icon.js +55 -0
  22. package/dist/cjs/ui/Toolbar/hooks/formatting-icons.js +227 -0
  23. package/dist/cjs/ui/Toolbar/hooks/menu-state.js +23 -0
  24. package/dist/cjs/ui/Toolbar/hooks/responsive-toolbar-buttons.js +60 -0
  25. package/dist/cjs/ui/Toolbar/index.js +183 -0
  26. package/dist/cjs/ui/Toolbar/more-button.js +42 -0
  27. package/dist/cjs/ui/Toolbar/single-toolbar-buttons.js +49 -0
  28. package/dist/cjs/ui/Toolbar/types.js +17 -0
  29. package/dist/cjs/utils/cell-selection.js +12 -0
  30. package/dist/cjs/utils.js +86 -0
  31. package/dist/cjs/version.json +5 -0
  32. package/dist/es2019/actions.js +161 -0
  33. package/dist/es2019/commands/clear-formatting.js +105 -0
  34. package/dist/es2019/commands/text-formatting.js +144 -0
  35. package/dist/es2019/commands/transform-to-code.js +71 -0
  36. package/dist/es2019/index.js +1 -0
  37. package/dist/es2019/plugin.js +124 -0
  38. package/dist/es2019/pm-plugins/clear-formatting-keymap.js +10 -0
  39. package/dist/es2019/pm-plugins/clear-formatting.js +26 -0
  40. package/dist/es2019/pm-plugins/cursor.js +52 -0
  41. package/dist/es2019/pm-plugins/input-rule.js +242 -0
  42. package/dist/es2019/pm-plugins/keymap.js +43 -0
  43. package/dist/es2019/pm-plugins/main.js +110 -0
  44. package/dist/es2019/pm-plugins/plugin-key.js +2 -0
  45. package/dist/es2019/pm-plugins/smart-input-rule.js +155 -0
  46. package/dist/es2019/ui/Toolbar/constants.js +20 -0
  47. package/dist/es2019/ui/Toolbar/dropdown-menu.js +66 -0
  48. package/dist/es2019/ui/Toolbar/hooks/clear-formatting-icon.js +44 -0
  49. package/dist/es2019/ui/Toolbar/hooks/formatting-icons.js +212 -0
  50. package/dist/es2019/ui/Toolbar/hooks/menu-state.js +11 -0
  51. package/dist/es2019/ui/Toolbar/hooks/responsive-toolbar-buttons.js +48 -0
  52. package/dist/es2019/ui/Toolbar/index.js +168 -0
  53. package/dist/es2019/ui/Toolbar/more-button.js +34 -0
  54. package/dist/es2019/ui/Toolbar/single-toolbar-buttons.js +39 -0
  55. package/dist/es2019/ui/Toolbar/types.js +10 -0
  56. package/dist/es2019/utils/cell-selection.js +5 -0
  57. package/dist/es2019/utils.js +74 -0
  58. package/dist/es2019/version.json +5 -0
  59. package/dist/esm/actions.js +168 -0
  60. package/dist/esm/commands/clear-formatting.js +101 -0
  61. package/dist/esm/commands/text-formatting.js +134 -0
  62. package/dist/esm/commands/transform-to-code.js +61 -0
  63. package/dist/esm/index.js +1 -0
  64. package/dist/esm/plugin.js +125 -0
  65. package/dist/esm/pm-plugins/clear-formatting-keymap.js +10 -0
  66. package/dist/esm/pm-plugins/clear-formatting.js +28 -0
  67. package/dist/esm/pm-plugins/cursor.js +48 -0
  68. package/dist/esm/pm-plugins/input-rule.js +257 -0
  69. package/dist/esm/pm-plugins/keymap.js +43 -0
  70. package/dist/esm/pm-plugins/main.js +99 -0
  71. package/dist/esm/pm-plugins/plugin-key.js +2 -0
  72. package/dist/esm/pm-plugins/smart-input-rule.js +169 -0
  73. package/dist/esm/ui/Toolbar/constants.js +8 -0
  74. package/dist/esm/ui/Toolbar/dropdown-menu.js +75 -0
  75. package/dist/esm/ui/Toolbar/hooks/clear-formatting-icon.js +47 -0
  76. package/dist/esm/ui/Toolbar/hooks/formatting-icons.js +215 -0
  77. package/dist/esm/ui/Toolbar/hooks/menu-state.js +15 -0
  78. package/dist/esm/ui/Toolbar/hooks/responsive-toolbar-buttons.js +50 -0
  79. package/dist/esm/ui/Toolbar/index.js +174 -0
  80. package/dist/esm/ui/Toolbar/more-button.js +33 -0
  81. package/dist/esm/ui/Toolbar/single-toolbar-buttons.js +38 -0
  82. package/dist/esm/ui/Toolbar/types.js +10 -0
  83. package/dist/esm/utils/cell-selection.js +5 -0
  84. package/dist/esm/utils.js +75 -0
  85. package/dist/esm/version.json +5 -0
  86. package/dist/types/actions.d.ts +22 -0
  87. package/dist/types/commands/clear-formatting.d.ts +6 -0
  88. package/dist/types/commands/text-formatting.d.ts +5 -0
  89. package/dist/types/commands/transform-to-code.d.ts +2 -0
  90. package/dist/types/index.d.ts +3 -0
  91. package/dist/types/plugin.d.ts +17 -0
  92. package/dist/types/pm-plugins/clear-formatting-keymap.d.ts +4 -0
  93. package/dist/types/pm-plugins/clear-formatting.d.ts +8 -0
  94. package/dist/types/pm-plugins/cursor.d.ts +3 -0
  95. package/dist/types/pm-plugins/input-rule.d.ts +23 -0
  96. package/dist/types/pm-plugins/keymap.d.ts +4 -0
  97. package/dist/types/pm-plugins/main.d.ts +7 -0
  98. package/dist/types/pm-plugins/plugin-key.d.ts +3 -0
  99. package/dist/types/pm-plugins/smart-input-rule.d.ts +3 -0
  100. package/dist/types/ui/Toolbar/constants.d.ts +6 -0
  101. package/dist/types/ui/Toolbar/dropdown-menu.d.ts +15 -0
  102. package/dist/types/ui/Toolbar/hooks/clear-formatting-icon.d.ts +7 -0
  103. package/dist/types/ui/Toolbar/hooks/formatting-icons.d.ts +14 -0
  104. package/dist/types/ui/Toolbar/hooks/menu-state.d.ts +1 -0
  105. package/dist/types/ui/Toolbar/hooks/responsive-toolbar-buttons.d.ts +20 -0
  106. package/dist/types/ui/Toolbar/index.d.ts +25 -0
  107. package/dist/types/ui/Toolbar/more-button.d.ts +14 -0
  108. package/dist/types/ui/Toolbar/single-toolbar-buttons.d.ts +10 -0
  109. package/dist/types/ui/Toolbar/types.d.ts +32 -0
  110. package/dist/types/utils/cell-selection.d.ts +3 -0
  111. package/dist/types/utils.d.ts +11 -0
  112. package/dist/types-ts4.5/actions.d.ts +22 -0
  113. package/dist/types-ts4.5/commands/clear-formatting.d.ts +6 -0
  114. package/dist/types-ts4.5/commands/text-formatting.d.ts +5 -0
  115. package/dist/types-ts4.5/commands/transform-to-code.d.ts +2 -0
  116. package/dist/types-ts4.5/index.d.ts +3 -0
  117. package/dist/types-ts4.5/plugin.d.ts +19 -0
  118. package/dist/types-ts4.5/pm-plugins/clear-formatting-keymap.d.ts +4 -0
  119. package/dist/types-ts4.5/pm-plugins/clear-formatting.d.ts +8 -0
  120. package/dist/types-ts4.5/pm-plugins/cursor.d.ts +3 -0
  121. package/dist/types-ts4.5/pm-plugins/input-rule.d.ts +23 -0
  122. package/dist/types-ts4.5/pm-plugins/keymap.d.ts +4 -0
  123. package/dist/types-ts4.5/pm-plugins/main.d.ts +7 -0
  124. package/dist/types-ts4.5/pm-plugins/plugin-key.d.ts +3 -0
  125. package/dist/types-ts4.5/pm-plugins/smart-input-rule.d.ts +3 -0
  126. package/dist/types-ts4.5/ui/Toolbar/constants.d.ts +6 -0
  127. package/dist/types-ts4.5/ui/Toolbar/dropdown-menu.d.ts +15 -0
  128. package/dist/types-ts4.5/ui/Toolbar/hooks/clear-formatting-icon.d.ts +7 -0
  129. package/dist/types-ts4.5/ui/Toolbar/hooks/formatting-icons.d.ts +14 -0
  130. package/dist/types-ts4.5/ui/Toolbar/hooks/menu-state.d.ts +5 -0
  131. package/dist/types-ts4.5/ui/Toolbar/hooks/responsive-toolbar-buttons.d.ts +20 -0
  132. package/dist/types-ts4.5/ui/Toolbar/index.d.ts +25 -0
  133. package/dist/types-ts4.5/ui/Toolbar/more-button.d.ts +14 -0
  134. package/dist/types-ts4.5/ui/Toolbar/single-toolbar-buttons.d.ts +10 -0
  135. package/dist/types-ts4.5/ui/Toolbar/types.d.ts +32 -0
  136. package/dist/types-ts4.5/utils/cell-selection.d.ts +3 -0
  137. package/dist/types-ts4.5/utils.d.ts +11 -0
  138. package/package.json +93 -0
  139. package/report.api.md +66 -0
  140. package/tmp/api-report-tmp.d.ts +39 -0
@@ -0,0 +1,168 @@
1
+ /** @jsx jsx */
2
+ import { useEffect, useMemo, useState } from 'react';
3
+ import { jsx } from '@emotion/react';
4
+ import { injectIntl } from 'react-intl-next';
5
+ import { usePreviousState } from '@atlaskit/editor-common/hooks';
6
+ import { toolbarMessages } from '@atlaskit/editor-common/messages';
7
+ import { buttonGroupStyle, separatorStyles, wrapperStyle } from '@atlaskit/editor-common/styles';
8
+ import { Announcer } from '@atlaskit/editor-common/ui';
9
+ import { compareItemsArrays, isArrayContainsContent } from '../../utils';
10
+ import { FormattingTextDropdownMenu } from './dropdown-menu';
11
+ import { useClearIcon } from './hooks/clear-formatting-icon';
12
+ import { useFormattingIcons, useHasFormattingActived } from './hooks/formatting-icons';
13
+ import { useResponsiveIconTypeMenu, useResponsiveToolbarButtons } from './hooks/responsive-toolbar-buttons';
14
+ import { MoreButton } from './more-button';
15
+ import { SingleToolbarButtons } from './single-toolbar-buttons';
16
+ const ToolbarFormatting = ({
17
+ shouldUseResponsiveToolbar,
18
+ popupsMountPoint,
19
+ popupsBoundariesElement,
20
+ popupsScrollableElement,
21
+ editorView,
22
+ toolbarSize,
23
+ isReducedSpacing,
24
+ isToolbarDisabled,
25
+ intl,
26
+ editorAnalyticsAPI
27
+ }) => {
28
+ var _usePreviousState;
29
+ const editorState = useMemo(() => editorView.state, [editorView.state]);
30
+ const [message, setMessage] = useState('');
31
+ const defaultIcons = useFormattingIcons({
32
+ editorState,
33
+ intl,
34
+ isToolbarDisabled,
35
+ editorAnalyticsAPI
36
+ });
37
+ const clearIcon = useClearIcon({
38
+ editorState,
39
+ intl,
40
+ editorAnalyticsAPI
41
+ });
42
+ const menuIconTypeList = useResponsiveIconTypeMenu({
43
+ toolbarSize,
44
+ responsivenessEnabled: shouldUseResponsiveToolbar
45
+ });
46
+ const hasFormattingActive = useHasFormattingActived({
47
+ editorState: editorView.state,
48
+ iconTypeList: menuIconTypeList
49
+ });
50
+ const {
51
+ dropdownItems,
52
+ singleItems
53
+ } = useResponsiveToolbarButtons({
54
+ icons: defaultIcons,
55
+ toolbarSize,
56
+ responsivenessEnabled: shouldUseResponsiveToolbar
57
+ });
58
+ const clearFormattingStatus = intl.formatMessage(toolbarMessages.textFormattingOff);
59
+ const superscriptOffSubscriptOnStatus = intl.formatMessage(toolbarMessages.superscriptOffSubscriptOn);
60
+ const subscriptOffSuperscriptOnStatus = intl.formatMessage(toolbarMessages.subscriptOffSuperscriptOn);
61
+ const activeItems = [...dropdownItems, ...singleItems].filter(item => item.isActive);
62
+ const prevActiveItems = (_usePreviousState = usePreviousState(activeItems)) !== null && _usePreviousState !== void 0 ? _usePreviousState : [];
63
+ const fromSuperscriptToSubscript = isArrayContainsContent(activeItems, 'Subscript') && isArrayContainsContent(prevActiveItems, 'Superscript');
64
+ const fromSubscriptToSuperscript = isArrayContainsContent(activeItems, 'Superscript') && isArrayContainsContent(prevActiveItems, 'Subscript');
65
+ let comparedItems;
66
+ let screenReaderMessage = '';
67
+ if (prevActiveItems && activeItems.length > prevActiveItems.length) {
68
+ comparedItems = compareItemsArrays(activeItems, prevActiveItems);
69
+ screenReaderMessage = intl.formatMessage(toolbarMessages.on, {
70
+ formattingType: comparedItems[0].content
71
+ });
72
+ } else {
73
+ comparedItems = compareItemsArrays(prevActiveItems, activeItems);
74
+ if (comparedItems && comparedItems.length) {
75
+ var _activeItems$;
76
+ screenReaderMessage = intl.formatMessage(toolbarMessages.off, {
77
+ formattingType: comparedItems[0].content
78
+ });
79
+ if (((_activeItems$ = activeItems[0]) === null || _activeItems$ === void 0 ? void 0 : _activeItems$.content) === 'Code') {
80
+ screenReaderMessage = intl.formatMessage(toolbarMessages.codeOn, {
81
+ textFormattingOff: (prevActiveItems === null || prevActiveItems === void 0 ? void 0 : prevActiveItems.length) > 1 ? clearFormattingStatus : screenReaderMessage
82
+ });
83
+ }
84
+ if (fromSuperscriptToSubscript) {
85
+ screenReaderMessage = superscriptOffSubscriptOnStatus;
86
+ }
87
+ if (fromSubscriptToSuperscript) {
88
+ screenReaderMessage = subscriptOffSuperscriptOnStatus;
89
+ }
90
+ }
91
+ }
92
+
93
+ // handle 'Clear formatting' status for screen readers
94
+ if (!(activeItems !== null && activeItems !== void 0 && activeItems.length) && (prevActiveItems === null || prevActiveItems === void 0 ? void 0 : prevActiveItems.length) > 1) {
95
+ screenReaderMessage = clearFormattingStatus;
96
+ }
97
+ const items = useMemo(() => {
98
+ if (!clearIcon) {
99
+ return dropdownItems;
100
+ }
101
+ return [...dropdownItems, clearIcon];
102
+ }, [clearIcon, dropdownItems]);
103
+ const moreFormattingButtonLabel = intl.formatMessage(toolbarMessages.moreFormatting);
104
+ useEffect(() => {
105
+ if (screenReaderMessage) {
106
+ setMessage(screenReaderMessage);
107
+ }
108
+ }, [screenReaderMessage]);
109
+ return (
110
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
111
+ jsx("span", {
112
+ css: buttonGroupStyle
113
+ }, message && jsx(Announcer, {
114
+ ariaLive: "assertive",
115
+ text: message,
116
+ ariaRelevant: "additions",
117
+ delay: 250
118
+ }), jsx(SingleToolbarButtons, {
119
+ items: singleItems,
120
+ editorView: editorView,
121
+ isReducedSpacing: isReducedSpacing
122
+ }), jsx("span", {
123
+ css: wrapperStyle
124
+ }, isToolbarDisabled ? jsx("div", null, jsx(MoreButton, {
125
+ label: moreFormattingButtonLabel,
126
+ isReducedSpacing: isReducedSpacing,
127
+ isDisabled: true,
128
+ isSelected: false,
129
+ "aria-expanded": undefined,
130
+ "aria-pressed": undefined
131
+ })) : jsx(FormattingTextDropdownMenu, {
132
+ popupsMountPoint: popupsMountPoint,
133
+ popupsBoundariesElement: popupsBoundariesElement,
134
+ popupsScrollableElement: popupsScrollableElement,
135
+ editorView: editorView,
136
+ isReducedSpacing: isReducedSpacing,
137
+ moreButtonLabel: moreFormattingButtonLabel,
138
+ hasFormattingActive: hasFormattingActive,
139
+ items: items
140
+ }), jsx("span", {
141
+ css: separatorStyles
142
+ })))
143
+ );
144
+ };
145
+ const Toolbar = ({
146
+ popupsMountPoint,
147
+ popupsScrollableElement,
148
+ toolbarSize,
149
+ isReducedSpacing,
150
+ editorView,
151
+ isToolbarDisabled,
152
+ shouldUseResponsiveToolbar,
153
+ intl,
154
+ editorAnalyticsAPI
155
+ }) => {
156
+ return jsx(ToolbarFormatting, {
157
+ popupsMountPoint: popupsMountPoint,
158
+ popupsScrollableElement: popupsScrollableElement,
159
+ toolbarSize: toolbarSize,
160
+ isReducedSpacing: isReducedSpacing,
161
+ editorView: editorView,
162
+ isToolbarDisabled: isToolbarDisabled,
163
+ shouldUseResponsiveToolbar: shouldUseResponsiveToolbar,
164
+ intl: intl,
165
+ editorAnalyticsAPI: editorAnalyticsAPI
166
+ });
167
+ };
168
+ export default injectIntl(Toolbar);
@@ -0,0 +1,34 @@
1
+ /** @jsx jsx */
2
+ import React from 'react';
3
+ import { jsx } from '@emotion/react';
4
+ import { triggerWrapperStyles } from '@atlaskit/editor-common/styles';
5
+ import { ToolbarButton } from '@atlaskit/editor-common/ui-menu';
6
+ import MoreIcon from '@atlaskit/icon/glyph/editor/more';
7
+ export const MoreButton = /*#__PURE__*/React.memo(({
8
+ label,
9
+ 'aria-expanded': ariaExpanded,
10
+ isReducedSpacing,
11
+ isSelected,
12
+ isDisabled,
13
+ onClick,
14
+ onKeyDown
15
+ }) => {
16
+ return jsx(ToolbarButton, {
17
+ disabled: isDisabled,
18
+ selected: isSelected,
19
+ onClick: onClick,
20
+ onKeyDown: onKeyDown,
21
+ spacing: isReducedSpacing ? 'none' : 'default',
22
+ title: label,
23
+ iconBefore:
24
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
25
+ jsx("div", {
26
+ css: triggerWrapperStyles
27
+ }, jsx(MoreIcon, {
28
+ label: ""
29
+ })),
30
+ "aria-expanded": ariaExpanded,
31
+ "aria-label": label,
32
+ "aria-haspopup": true
33
+ });
34
+ });
@@ -0,0 +1,39 @@
1
+ /** @jsx jsx */
2
+ import React, { useCallback } from 'react';
3
+ import { jsx } from '@emotion/react';
4
+ import { buttonGroupStyle } from '@atlaskit/editor-common/styles';
5
+ import { ToolbarButton } from '@atlaskit/editor-common/ui-menu';
6
+ export const SingleToolbarButtons = /*#__PURE__*/React.memo(({
7
+ items,
8
+ isReducedSpacing,
9
+ editorView
10
+ }) => {
11
+ const onClick = useCallback(command => {
12
+ return () => {
13
+ command(editorView.state, editorView.dispatch);
14
+ return false;
15
+ };
16
+ }, [editorView.state, editorView.dispatch]);
17
+ return (
18
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
19
+ jsx("span", {
20
+ css: buttonGroupStyle
21
+ }, items.map(item => {
22
+ var _item$ariaLabel;
23
+ return jsx(ToolbarButton, {
24
+ key: item.key,
25
+ testId: `editor-toolbar__${String(item.content)}`,
26
+ buttonId: item.buttonId,
27
+ spacing: isReducedSpacing ? 'none' : 'default',
28
+ onClick: onClick(item.command),
29
+ selected: item.isActive,
30
+ disabled: item.isDisabled,
31
+ title: item.tooltipElement,
32
+ iconBefore: item.iconElement,
33
+ "aria-pressed": item.isActive,
34
+ "aria-label": (_item$ariaLabel = item['aria-label']) !== null && _item$ariaLabel !== void 0 ? _item$ariaLabel : String(item.content),
35
+ "aria-keyshortcuts": item['aria-keyshortcuts']
36
+ });
37
+ }))
38
+ );
39
+ });
@@ -0,0 +1,10 @@
1
+ export let IconTypes = /*#__PURE__*/function (IconTypes) {
2
+ IconTypes["strong"] = "strong";
3
+ IconTypes["em"] = "em";
4
+ IconTypes["underline"] = "underline";
5
+ IconTypes["strike"] = "strike";
6
+ IconTypes["code"] = "code";
7
+ IconTypes["subscript"] = "subscript";
8
+ IconTypes["superscript"] = "superscript";
9
+ return IconTypes;
10
+ }({});
@@ -0,0 +1,5 @@
1
+ export const cellSelectionNodesBetween = (selection, doc, f, startPos) => {
2
+ selection.forEachCell((cell, cellPos) => {
3
+ doc.nodesBetween(cellPos, cellPos + cell.nodeSize, f, startPos);
4
+ });
5
+ };
@@ -0,0 +1,74 @@
1
+ import { anyMarkActive } from '@atlaskit/editor-common/mark';
2
+ import { FORMATTING_MARK_TYPES, FORMATTING_NODE_TYPES } from './commands/clear-formatting';
3
+ export const hasCode = (state, pos) => {
4
+ const {
5
+ code
6
+ } = state.schema.marks;
7
+ const node = pos >= 0 && state.doc.nodeAt(pos);
8
+ if (node) {
9
+ return !!node.marks.filter(mark => mark.type === code).length;
10
+ }
11
+ return false;
12
+ };
13
+
14
+ /**
15
+ * Determine if a mark (with specific attribute values) exists anywhere in the selection.
16
+ */
17
+ export const markActive = (state, mark) => {
18
+ const {
19
+ from,
20
+ to,
21
+ empty
22
+ } = state.selection;
23
+ // When the selection is empty, only the active marks apply.
24
+ if (empty) {
25
+ return !!mark.isInSet(state.tr.storedMarks || state.selection.$from.marks());
26
+ }
27
+ // For a non-collapsed selection, the marks on the nodes matter.
28
+ let found = false;
29
+ state.doc.nodesBetween(from, to, node => {
30
+ found = found || mark.isInSet(node.marks);
31
+ });
32
+ return found;
33
+ };
34
+ const blockStylingIsPresent = state => {
35
+ let {
36
+ from,
37
+ to
38
+ } = state.selection;
39
+ let isBlockStyling = false;
40
+ state.doc.nodesBetween(from, to, node => {
41
+ if (FORMATTING_NODE_TYPES.indexOf(node.type.name) !== -1) {
42
+ isBlockStyling = true;
43
+ return false;
44
+ }
45
+ return true;
46
+ });
47
+ return isBlockStyling;
48
+ };
49
+ const marksArePresent = state => {
50
+ const activeMarkTypes = FORMATTING_MARK_TYPES.filter(mark => {
51
+ if (!!state.schema.marks[mark]) {
52
+ const {
53
+ $from,
54
+ empty
55
+ } = state.selection;
56
+ const {
57
+ marks
58
+ } = state.schema;
59
+ if (empty) {
60
+ return !!marks[mark].isInSet(state.storedMarks || $from.marks());
61
+ }
62
+ return anyMarkActive(state, marks[mark]);
63
+ }
64
+ return false;
65
+ });
66
+ return activeMarkTypes.length > 0;
67
+ };
68
+ export const checkFormattingIsPresent = state => {
69
+ return marksArePresent(state) || blockStylingIsPresent(state);
70
+ };
71
+ export const compareItemsArrays = (items, prevItems) => {
72
+ return items && items.filter(item => !prevItems.includes(item));
73
+ };
74
+ export const isArrayContainsContent = (items, content) => items.filter(item => item.content === content).length > 0;
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "@atlaskit/editor-plugin-text-formatting",
3
+ "version": "0.1.0",
4
+ "sideEffects": false
5
+ }
@@ -0,0 +1,168 @@
1
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
2
+ import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
3
+ import { toggleMark } from '@atlaskit/editor-common/mark';
4
+ export var toggleEm = function toggleEm() {
5
+ return function (state, dispatch) {
6
+ var em = state.schema.marks.em;
7
+ if (em) {
8
+ return toggleMark(em)(state, dispatch);
9
+ }
10
+ return false;
11
+ };
12
+ };
13
+ export var toggleEmWithAnalytics = function toggleEmWithAnalytics(editorAnalyticsAPI) {
14
+ return function (_ref) {
15
+ var inputMethod = _ref.inputMethod;
16
+ return withAnalytics(editorAnalyticsAPI, {
17
+ action: ACTION.FORMATTED,
18
+ actionSubject: ACTION_SUBJECT.TEXT,
19
+ eventType: EVENT_TYPE.TRACK,
20
+ actionSubjectId: ACTION_SUBJECT_ID.FORMAT_ITALIC,
21
+ attributes: {
22
+ inputMethod: inputMethod
23
+ }
24
+ })(toggleEm());
25
+ };
26
+ };
27
+ export var toggleStrike = function toggleStrike() {
28
+ return function (state, dispatch) {
29
+ var strike = state.schema.marks.strike;
30
+ if (strike) {
31
+ return toggleMark(strike)(state, dispatch);
32
+ }
33
+ return false;
34
+ };
35
+ };
36
+ export var toggleStrikeWithAnalytics = function toggleStrikeWithAnalytics(editorAnalyticsAPI) {
37
+ return function (_ref2) {
38
+ var inputMethod = _ref2.inputMethod;
39
+ return withAnalytics(editorAnalyticsAPI, {
40
+ action: ACTION.FORMATTED,
41
+ actionSubject: ACTION_SUBJECT.TEXT,
42
+ eventType: EVENT_TYPE.TRACK,
43
+ actionSubjectId: ACTION_SUBJECT_ID.FORMAT_STRIKE,
44
+ attributes: {
45
+ inputMethod: inputMethod
46
+ }
47
+ })(toggleStrike());
48
+ };
49
+ };
50
+ export var toggleStrong = function toggleStrong() {
51
+ return function (state, dispatch) {
52
+ var strong = state.schema.marks.strong;
53
+ if (strong) {
54
+ return toggleMark(strong)(state, dispatch);
55
+ }
56
+ return false;
57
+ };
58
+ };
59
+ export var toggleStrongWithAnalytics = function toggleStrongWithAnalytics(editorAnalyticsAPI) {
60
+ return function (_ref3) {
61
+ var inputMethod = _ref3.inputMethod;
62
+ return withAnalytics(editorAnalyticsAPI, {
63
+ action: ACTION.FORMATTED,
64
+ actionSubject: ACTION_SUBJECT.TEXT,
65
+ eventType: EVENT_TYPE.TRACK,
66
+ actionSubjectId: ACTION_SUBJECT_ID.FORMAT_STRONG,
67
+ attributes: {
68
+ inputMethod: inputMethod
69
+ }
70
+ })(toggleStrong());
71
+ };
72
+ };
73
+ export var toggleUnderline = function toggleUnderline() {
74
+ return function (state, dispatch) {
75
+ var underline = state.schema.marks.underline;
76
+ if (underline) {
77
+ return toggleMark(underline)(state, dispatch);
78
+ }
79
+ return false;
80
+ };
81
+ };
82
+ export var toggleUnderlineWithAnalytics = function toggleUnderlineWithAnalytics(editorAnalyticsAPI) {
83
+ return function (_ref4) {
84
+ var inputMethod = _ref4.inputMethod;
85
+ return withAnalytics(editorAnalyticsAPI, {
86
+ action: ACTION.FORMATTED,
87
+ actionSubject: ACTION_SUBJECT.TEXT,
88
+ eventType: EVENT_TYPE.TRACK,
89
+ actionSubjectId: ACTION_SUBJECT_ID.FORMAT_UNDERLINE,
90
+ attributes: {
91
+ inputMethod: inputMethod
92
+ }
93
+ })(toggleUnderline());
94
+ };
95
+ };
96
+ export var toggleSuperscript = function toggleSuperscript() {
97
+ return function (state, dispatch) {
98
+ var subsup = state.schema.marks.subsup;
99
+ if (subsup) {
100
+ return toggleMark(subsup, {
101
+ type: 'sup'
102
+ })(state, dispatch);
103
+ }
104
+ return false;
105
+ };
106
+ };
107
+ export var toggleSuperscriptWithAnalytics = function toggleSuperscriptWithAnalytics(editorAnalyticsAPI) {
108
+ return function (_ref5) {
109
+ var inputMethod = _ref5.inputMethod;
110
+ return withAnalytics(editorAnalyticsAPI, {
111
+ action: ACTION.FORMATTED,
112
+ actionSubject: ACTION_SUBJECT.TEXT,
113
+ eventType: EVENT_TYPE.TRACK,
114
+ actionSubjectId: ACTION_SUBJECT_ID.FORMAT_SUPER,
115
+ attributes: {
116
+ inputMethod: inputMethod
117
+ }
118
+ })(toggleSuperscript());
119
+ };
120
+ };
121
+ export var toggleSubscript = function toggleSubscript() {
122
+ return function (state, dispatch) {
123
+ var subsup = state.schema.marks.subsup;
124
+ if (subsup) {
125
+ return toggleMark(subsup, {
126
+ type: 'sub'
127
+ })(state, dispatch);
128
+ }
129
+ return false;
130
+ };
131
+ };
132
+ export var toggleSubscriptWithAnalytics = function toggleSubscriptWithAnalytics(editorAnalyticsAPI) {
133
+ return function (_ref6) {
134
+ var inputMethod = _ref6.inputMethod;
135
+ return withAnalytics(editorAnalyticsAPI, {
136
+ action: ACTION.FORMATTED,
137
+ actionSubject: ACTION_SUBJECT.TEXT,
138
+ eventType: EVENT_TYPE.TRACK,
139
+ actionSubjectId: ACTION_SUBJECT_ID.FORMAT_SUB,
140
+ attributes: {
141
+ inputMethod: inputMethod
142
+ }
143
+ })(toggleSubscript());
144
+ };
145
+ };
146
+ export var toggleCode = function toggleCode() {
147
+ return function (state, dispatch) {
148
+ var code = state.schema.marks.code;
149
+ if (code) {
150
+ return toggleMark(code)(state, dispatch);
151
+ }
152
+ return false;
153
+ };
154
+ };
155
+ export var toggleCodeWithAnalytics = function toggleCodeWithAnalytics(editorAnalyticsAPI) {
156
+ return function (_ref7) {
157
+ var inputMethod = _ref7.inputMethod;
158
+ return withAnalytics(editorAnalyticsAPI, {
159
+ action: ACTION.FORMATTED,
160
+ actionSubject: ACTION_SUBJECT.TEXT,
161
+ eventType: EVENT_TYPE.TRACK,
162
+ actionSubjectId: ACTION_SUBJECT_ID.FORMAT_CODE,
163
+ attributes: {
164
+ inputMethod: inputMethod
165
+ }
166
+ })(toggleCode());
167
+ };
168
+ };
@@ -0,0 +1,101 @@
1
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
2
+ import { liftTarget } from '@atlaskit/editor-prosemirror/transform';
3
+ import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
4
+ import { cellSelectionNodesBetween } from '../utils/cell-selection';
5
+ export var FORMATTING_NODE_TYPES = ['heading', 'blockquote'];
6
+ export var FORMATTING_MARK_TYPES = ['em', 'code', 'strike', 'strong', 'underline', 'textColor', 'subsup'];
7
+ var formatTypes = {
8
+ em: ACTION_SUBJECT_ID.FORMAT_ITALIC,
9
+ code: ACTION_SUBJECT_ID.FORMAT_CODE,
10
+ strike: ACTION_SUBJECT_ID.FORMAT_STRIKE,
11
+ strong: ACTION_SUBJECT_ID.FORMAT_STRONG,
12
+ underline: ACTION_SUBJECT_ID.FORMAT_UNDERLINE,
13
+ textColor: ACTION_SUBJECT_ID.FORMAT_COLOR,
14
+ subsup: 'subsup'
15
+ };
16
+ export function clearFormattingWithAnalytics(inputMethod, editorAnalyticsAPI) {
17
+ return clearFormatting(inputMethod, editorAnalyticsAPI);
18
+ }
19
+ function clearNodeFormattingOnSelection(state, tr, formattedNodeType, nodeName, formattingCleared) {
20
+ return function (node, pos) {
21
+ if (node.type === formattedNodeType) {
22
+ if (formattedNodeType.isTextblock) {
23
+ tr.setNodeMarkup(pos, state.schema.nodes.paragraph);
24
+ formattingCleared.push(nodeName);
25
+ return false;
26
+ } else {
27
+ // In case of panel or blockquote
28
+ var fromPos = tr.doc.resolve(pos + 1);
29
+ var toPos = tr.doc.resolve(pos + node.nodeSize - 1);
30
+ var nodeRange = fromPos.blockRange(toPos);
31
+ if (nodeRange) {
32
+ var targetLiftDepth = liftTarget(nodeRange);
33
+ if (targetLiftDepth || targetLiftDepth === 0) {
34
+ formattingCleared.push(nodeName);
35
+ tr.lift(nodeRange, targetLiftDepth);
36
+ }
37
+ }
38
+ }
39
+ }
40
+ return true;
41
+ };
42
+ }
43
+ export function clearFormatting(inputMethod, editorAnalyticsAPI) {
44
+ return function (state, dispatch) {
45
+ var tr = state.tr;
46
+ var formattingCleared = [];
47
+ FORMATTING_MARK_TYPES.forEach(function (mark) {
48
+ var _tr$selection = tr.selection,
49
+ from = _tr$selection.from,
50
+ to = _tr$selection.to;
51
+ var markType = state.schema.marks[mark];
52
+ if (!markType) {
53
+ return;
54
+ }
55
+ if (tr.selection instanceof CellSelection) {
56
+ cellSelectionNodesBetween(tr.selection, tr.doc, function (node, pos) {
57
+ var isTableCell = node.type === state.schema.nodes.tableCell || node.type === state.schema.nodes.tableHeader;
58
+ if (!isTableCell) {
59
+ return true;
60
+ }
61
+ if (tr.doc.rangeHasMark(pos, pos + node.nodeSize, markType)) {
62
+ formattingCleared.push(formatTypes[mark]);
63
+ tr.removeMark(pos, pos + node.nodeSize, markType);
64
+ }
65
+ return false;
66
+ });
67
+ } else if (tr.doc.rangeHasMark(from, to, markType)) {
68
+ formattingCleared.push(formatTypes[mark]);
69
+ tr.removeMark(from, to, markType);
70
+ }
71
+ });
72
+ FORMATTING_NODE_TYPES.forEach(function (nodeName) {
73
+ var formattedNodeType = state.schema.nodes[nodeName];
74
+ var _tr$selection2 = tr.selection,
75
+ $from = _tr$selection2.$from,
76
+ $to = _tr$selection2.$to;
77
+ if (tr.selection instanceof CellSelection) {
78
+ cellSelectionNodesBetween(tr.selection, tr.doc, clearNodeFormattingOnSelection(state, tr, formattedNodeType, nodeName, formattingCleared));
79
+ } else {
80
+ tr.doc.nodesBetween($from.pos, $to.pos, clearNodeFormattingOnSelection(state, tr, formattedNodeType, nodeName, formattingCleared));
81
+ }
82
+ });
83
+ tr.setStoredMarks([]);
84
+ if (formattingCleared.length && inputMethod) {
85
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent({
86
+ action: ACTION.FORMATTED,
87
+ eventType: EVENT_TYPE.TRACK,
88
+ actionSubject: ACTION_SUBJECT.TEXT,
89
+ actionSubjectId: ACTION_SUBJECT_ID.FORMAT_CLEAR,
90
+ attributes: {
91
+ inputMethod: inputMethod,
92
+ formattingCleared: formattingCleared
93
+ }
94
+ })(tr);
95
+ }
96
+ if (dispatch) {
97
+ dispatch(tr);
98
+ }
99
+ return true;
100
+ };
101
+ }