@seafile/sea-email-editor 0.0.1

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 (266) hide show
  1. package/README.md +1 -0
  2. package/dist/assets/icons/align-center.svg +1 -0
  3. package/dist/assets/icons/align-left.svg +1 -0
  4. package/dist/assets/icons/align-right.svg +1 -0
  5. package/dist/assets/icons/arrow-down.svg +1 -0
  6. package/dist/assets/icons/arrow-right.svg +1 -0
  7. package/dist/assets/icons/arrow-up.svg +1 -0
  8. package/dist/assets/icons/bold.svg +1 -0
  9. package/dist/assets/icons/callout-color.svg +1 -0
  10. package/dist/assets/icons/check-mark-option.svg +3 -0
  11. package/dist/assets/icons/check-square.svg +1 -0
  12. package/dist/assets/icons/clear-format.svg +1 -0
  13. package/dist/assets/icons/close.svg +3 -0
  14. package/dist/assets/icons/code-block.svg +1 -0
  15. package/dist/assets/icons/image.svg +1 -0
  16. package/dist/assets/icons/inline-code.svg +1 -0
  17. package/dist/assets/icons/insert.svg +1 -0
  18. package/dist/assets/icons/italic.svg +1 -0
  19. package/dist/assets/icons/link.svg +1 -0
  20. package/dist/assets/icons/more.svg +1 -0
  21. package/dist/assets/icons/ol.svg +1 -0
  22. package/dist/assets/icons/quote.svg +1 -0
  23. package/dist/assets/icons/rename.svg +4 -0
  24. package/dist/assets/icons/strikethrough.svg +1 -0
  25. package/dist/assets/icons/table.svg +1 -0
  26. package/dist/assets/icons/ul.svg +1 -0
  27. package/dist/assets/icons/underline.svg +1 -0
  28. package/dist/assets/icons/unlink.svg +1 -0
  29. package/dist/components/browser-tip/index.css +18 -0
  30. package/dist/components/browser-tip/index.js +28 -0
  31. package/dist/components/centered-loading.js +23 -0
  32. package/dist/components/icon/index.css +7 -0
  33. package/dist/components/icon/index.js +30 -0
  34. package/dist/components/icon-button/index.css +33 -0
  35. package/dist/components/icon-button/index.js +71 -0
  36. package/dist/components/index.js +92 -0
  37. package/dist/components/loading/index.css +54 -0
  38. package/dist/components/loading/index.js +15 -0
  39. package/dist/components/modal/index.css +0 -0
  40. package/dist/components/modal/index.js +27 -0
  41. package/dist/components/modal-header/index.css +22 -0
  42. package/dist/components/modal-header/index.js +36 -0
  43. package/dist/components/option/index.css +20 -0
  44. package/dist/components/option/index.js +39 -0
  45. package/dist/components/options-editor/container/index.css +49 -0
  46. package/dist/components/options-editor/container/index.js +122 -0
  47. package/dist/components/options-editor/index.css +26 -0
  48. package/dist/components/options-editor/index.js +70 -0
  49. package/dist/components/options-editor/options/index.css +5 -0
  50. package/dist/components/options-editor/options/index.js +138 -0
  51. package/dist/components/options-editor/options/option/index.css +54 -0
  52. package/dist/components/options-editor/options/option/index.js +138 -0
  53. package/dist/components/popover/index.js +85 -0
  54. package/dist/components/popover/utils.js +76 -0
  55. package/dist/components/search-input/index.css +52 -0
  56. package/dist/components/search-input/index.js +148 -0
  57. package/dist/components/selector-display/index.css +86 -0
  58. package/dist/components/selector-display/index.js +66 -0
  59. package/dist/components/toolbar/index.js +20 -0
  60. package/dist/components/toolbar/toolbar-group/index.css +13 -0
  61. package/dist/components/toolbar/toolbar-group/index.js +22 -0
  62. package/dist/components/toolbar/toolbar-item/index.css +3 -0
  63. package/dist/components/toolbar/toolbar-item/index.js +53 -0
  64. package/dist/components/tooltip/index.css +68 -0
  65. package/dist/components/tooltip/index.js +46 -0
  66. package/dist/components/tooltip/shortcut-key/index.css +7 -0
  67. package/dist/components/tooltip/shortcut-key/index.js +20 -0
  68. package/dist/constants/event-types.js +25 -0
  69. package/dist/constants/index.js +40 -0
  70. package/dist/constants/key-codes.js +104 -0
  71. package/dist/editor/index.css +44 -0
  72. package/dist/editor/index.js +50 -0
  73. package/dist/editor/main/index.css +19 -0
  74. package/dist/editor/main/index.js +166 -0
  75. package/dist/editor/with-props-editor.js +20 -0
  76. package/dist/extension/commons/dropdown-menu-item/index.css +52 -0
  77. package/dist/extension/commons/dropdown-menu-item/index.js +62 -0
  78. package/dist/extension/commons/index.js +5 -0
  79. package/dist/extension/commons/insert-element-dialog/index.js +91 -0
  80. package/dist/extension/commons/menu/index.js +3 -0
  81. package/dist/extension/commons/menu/menu-drop-down.js +98 -0
  82. package/dist/extension/commons/menu-shortcut-indicator/index.js +24 -0
  83. package/dist/extension/commons/menu-shortcut-indicator/style.css +18 -0
  84. package/dist/extension/constants/element-default-style.js +78 -0
  85. package/dist/extension/constants/element-types.js +33 -0
  86. package/dist/extension/constants/index.js +63 -0
  87. package/dist/extension/constants/keyboard.js +33 -0
  88. package/dist/extension/constants/menus-config.js +142 -0
  89. package/dist/extension/core/index.js +38 -0
  90. package/dist/extension/core/queries/index.js +507 -0
  91. package/dist/extension/core/transforms/focus-editor.js +18 -0
  92. package/dist/extension/core/transforms/index.js +49 -0
  93. package/dist/extension/core/transforms/move-children.js +35 -0
  94. package/dist/extension/core/transforms/remove-node-children.js +19 -0
  95. package/dist/extension/core/transforms/replace-node-children.js +24 -0
  96. package/dist/extension/core/utils/index.js +120 -0
  97. package/dist/extension/event-transfer/get-event-transfer.js +38 -0
  98. package/dist/extension/event-transfer/set-event-transfer.js +36 -0
  99. package/dist/extension/highlight/index.js +20 -0
  100. package/dist/extension/highlight/normalize-tokens.js +94 -0
  101. package/dist/extension/highlight/prismjs.js +27 -0
  102. package/dist/extension/highlight/set-node-decorations.js +81 -0
  103. package/dist/extension/highlight/use-highlight.js +20 -0
  104. package/dist/extension/index.js +67 -0
  105. package/dist/extension/plugins/blockquote/helpers.js +68 -0
  106. package/dist/extension/plugins/blockquote/index.js +18 -0
  107. package/dist/extension/plugins/blockquote/menu/index.js +35 -0
  108. package/dist/extension/plugins/blockquote/plugin.js +154 -0
  109. package/dist/extension/plugins/blockquote/render-elem.js +29 -0
  110. package/dist/extension/plugins/check-list/helper.js +34 -0
  111. package/dist/extension/plugins/check-list/index.js +19 -0
  112. package/dist/extension/plugins/check-list/menu/index.js +39 -0
  113. package/dist/extension/plugins/check-list/plugin.js +92 -0
  114. package/dist/extension/plugins/check-list/render-elem.js +61 -0
  115. package/dist/extension/plugins/clear-format/helpers.js +51 -0
  116. package/dist/extension/plugins/clear-format/menu/index.js +35 -0
  117. package/dist/extension/plugins/code-block/helpers.js +140 -0
  118. package/dist/extension/plugins/code-block/index.js +20 -0
  119. package/dist/extension/plugins/code-block/menu/index.js +59 -0
  120. package/dist/extension/plugins/code-block/plugin.js +288 -0
  121. package/dist/extension/plugins/code-block/render-elem/constant.js +22 -0
  122. package/dist/extension/plugins/code-block/render-elem/index.js +89 -0
  123. package/dist/extension/plugins/code-block/render-elem/language-selector/index.css +18 -0
  124. package/dist/extension/plugins/code-block/render-elem/language-selector/index.js +38 -0
  125. package/dist/extension/plugins/formula/formula.css +22 -0
  126. package/dist/extension/plugins/formula/helper.js +80 -0
  127. package/dist/extension/plugins/formula/index.js +19 -0
  128. package/dist/extension/plugins/formula/menu/formula-modal.js +98 -0
  129. package/dist/extension/plugins/formula/menu/index.js +35 -0
  130. package/dist/extension/plugins/formula/plugin.js +22 -0
  131. package/dist/extension/plugins/formula/render-elem.js +64 -0
  132. package/dist/extension/plugins/header/helper.js +55 -0
  133. package/dist/extension/plugins/header/index.js +19 -0
  134. package/dist/extension/plugins/header/menu/index.js +72 -0
  135. package/dist/extension/plugins/header/plugin.js +155 -0
  136. package/dist/extension/plugins/header/render-elem.js +39 -0
  137. package/dist/extension/plugins/html/index.js +13 -0
  138. package/dist/extension/plugins/html/plugin.js +69 -0
  139. package/dist/extension/plugins/image/helper.js +131 -0
  140. package/dist/extension/plugins/image/index.js +19 -0
  141. package/dist/extension/plugins/image/menu/image-menu-dialog.js +92 -0
  142. package/dist/extension/plugins/image/menu/index.css +3 -0
  143. package/dist/extension/plugins/image/menu/index.js +103 -0
  144. package/dist/extension/plugins/image/plugin.js +56 -0
  145. package/dist/extension/plugins/image/render-element/image-previewer.js +89 -0
  146. package/dist/extension/plugins/image/render-element/index.js +141 -0
  147. package/dist/extension/plugins/image/render-element/style.css +68 -0
  148. package/dist/extension/plugins/index.js +116 -0
  149. package/dist/extension/plugins/link/helper.js +258 -0
  150. package/dist/extension/plugins/link/index.js +19 -0
  151. package/dist/extension/plugins/link/menu/index.js +92 -0
  152. package/dist/extension/plugins/link/menu/link-modal.js +169 -0
  153. package/dist/extension/plugins/link/plugin.js +172 -0
  154. package/dist/extension/plugins/link/render-elem/index.css +12 -0
  155. package/dist/extension/plugins/link/render-elem/index.js +103 -0
  156. package/dist/extension/plugins/link/render-elem/link-op-menu/index.css +33 -0
  157. package/dist/extension/plugins/link/render-elem/link-op-menu/index.js +89 -0
  158. package/dist/extension/plugins/list/constant.js +8 -0
  159. package/dist/extension/plugins/list/helpers.js +102 -0
  160. package/dist/extension/plugins/list/index.js +19 -0
  161. package/dist/extension/plugins/list/menu/index.js +41 -0
  162. package/dist/extension/plugins/list/plugin/index.js +80 -0
  163. package/dist/extension/plugins/list/plugin/insert-break-list.js +29 -0
  164. package/dist/extension/plugins/list/plugin/insert-fragment-list.js +179 -0
  165. package/dist/extension/plugins/list/plugin/normalize-list.js +79 -0
  166. package/dist/extension/plugins/list/plugin/on-tab-handle.js +63 -0
  167. package/dist/extension/plugins/list/plugin/shortcut.js +69 -0
  168. package/dist/extension/plugins/list/queries/index.js +52 -0
  169. package/dist/extension/plugins/list/render-elem/index.js +68 -0
  170. package/dist/extension/plugins/list/transforms/index.js +75 -0
  171. package/dist/extension/plugins/list/transforms/insert-list-item.js +98 -0
  172. package/dist/extension/plugins/list/transforms/move-list-item-down.js +50 -0
  173. package/dist/extension/plugins/list/transforms/move-list-item-up.js +124 -0
  174. package/dist/extension/plugins/list/transforms/move-list-items-to-list.js +63 -0
  175. package/dist/extension/plugins/list/transforms/move-list-items.js +73 -0
  176. package/dist/extension/plugins/list/transforms/normalize-list-item.js +110 -0
  177. package/dist/extension/plugins/list/transforms/normalize-nested-list.js +38 -0
  178. package/dist/extension/plugins/list/transforms/remove-first-list-item.js +24 -0
  179. package/dist/extension/plugins/list/transforms/transforms-to-list.js +131 -0
  180. package/dist/extension/plugins/list/transforms/unwrap-list.js +48 -0
  181. package/dist/extension/plugins/markdown/index.js +12 -0
  182. package/dist/extension/plugins/markdown/plugin.js +257 -0
  183. package/dist/extension/plugins/node-id/constants.js +24 -0
  184. package/dist/extension/plugins/node-id/helpers.js +78 -0
  185. package/dist/extension/plugins/node-id/index.js +12 -0
  186. package/dist/extension/plugins/node-id/with-node-id.js +37 -0
  187. package/dist/extension/plugins/p/helper.js +17 -0
  188. package/dist/extension/plugins/p/index.js +17 -0
  189. package/dist/extension/plugins/p/plugin.js +141 -0
  190. package/dist/extension/plugins/p/render-elem.js +29 -0
  191. package/dist/extension/plugins/paragraph/helper.js +17 -0
  192. package/dist/extension/plugins/paragraph/index.js +17 -0
  193. package/dist/extension/plugins/paragraph/plugin.js +141 -0
  194. package/dist/extension/plugins/paragraph/render-elem.js +29 -0
  195. package/dist/extension/plugins/table/constant.js +24 -0
  196. package/dist/extension/plugins/table/context-menu/horizontal-align-popover/index.css +3 -0
  197. package/dist/extension/plugins/table/context-menu/horizontal-align-popover/index.js +64 -0
  198. package/dist/extension/plugins/table/context-menu/index.css +13 -0
  199. package/dist/extension/plugins/table/context-menu/index.js +152 -0
  200. package/dist/extension/plugins/table/context-menu/insert-table-element/index.css +27 -0
  201. package/dist/extension/plugins/table/context-menu/insert-table-element/index.js +113 -0
  202. package/dist/extension/plugins/table/helper.js +333 -0
  203. package/dist/extension/plugins/table/index.js +21 -0
  204. package/dist/extension/plugins/table/menu/index.js +61 -0
  205. package/dist/extension/plugins/table/menu/table-operator.js +97 -0
  206. package/dist/extension/plugins/table/menu/table-size-selector/index.css +27 -0
  207. package/dist/extension/plugins/table/menu/table-size-selector/index.js +98 -0
  208. package/dist/extension/plugins/table/model.js +102 -0
  209. package/dist/extension/plugins/table/plugin.js +351 -0
  210. package/dist/extension/plugins/table/render-elem/index.css +64 -0
  211. package/dist/extension/plugins/table/render-elem/index.js +252 -0
  212. package/dist/extension/plugins/table/table-operations.js +323 -0
  213. package/dist/extension/plugins/text-style/helpers.js +57 -0
  214. package/dist/extension/plugins/text-style/index.js +17 -0
  215. package/dist/extension/plugins/text-style/menu/index.js +37 -0
  216. package/dist/extension/plugins/text-style/plugin.js +38 -0
  217. package/dist/extension/plugins/text-style/render-elem.js +63 -0
  218. package/dist/extension/render/render-element.js +115 -0
  219. package/dist/extension/render/render-leaf.js +22 -0
  220. package/dist/extension/toolbar/index.css +16 -0
  221. package/dist/extension/toolbar/index.js +89 -0
  222. package/dist/extension/toolbar/insert-toolbar.js +78 -0
  223. package/dist/hooks/use-attachments.js +38 -0
  224. package/dist/hooks/use-container-style.js +50 -0
  225. package/dist/hooks/use-mathjax.js +46 -0
  226. package/dist/hooks/use-scroll-context.js +20 -0
  227. package/dist/hooks/use-selection-update.js +20 -0
  228. package/dist/hooks/user-link-click.js +52 -0
  229. package/dist/index.js +9 -0
  230. package/dist/intl/ReactIntlUniversal.js +310 -0
  231. package/dist/intl/constants.js +21 -0
  232. package/dist/intl/index.js +33 -0
  233. package/dist/locale/index.js +11 -0
  234. package/dist/locale/lang/en.json +83 -0
  235. package/dist/slate-convert/html-to-slate/constants.js +146 -0
  236. package/dist/slate-convert/html-to-slate/helper.js +106 -0
  237. package/dist/slate-convert/html-to-slate/index.js +138 -0
  238. package/dist/slate-convert/html-to-slate/rules/blockquote.js +26 -0
  239. package/dist/slate-convert/html-to-slate/rules/br.js +29 -0
  240. package/dist/slate-convert/html-to-slate/rules/check-list.js +29 -0
  241. package/dist/slate-convert/html-to-slate/rules/code-block.js +95 -0
  242. package/dist/slate-convert/html-to-slate/rules/header.js +26 -0
  243. package/dist/slate-convert/html-to-slate/rules/image.js +31 -0
  244. package/dist/slate-convert/html-to-slate/rules/index.js +20 -0
  245. package/dist/slate-convert/html-to-slate/rules/link.js +31 -0
  246. package/dist/slate-convert/html-to-slate/rules/list.js +74 -0
  247. package/dist/slate-convert/html-to-slate/rules/p.js +37 -0
  248. package/dist/slate-convert/html-to-slate/rules/paragraph.js +37 -0
  249. package/dist/slate-convert/html-to-slate/rules/table.js +64 -0
  250. package/dist/slate-convert/html-to-slate/rules/text.js +71 -0
  251. package/dist/slate-convert/index.js +20 -0
  252. package/dist/slate-convert/slate-to-html/index.js +143 -0
  253. package/dist/utils/common.js +46 -0
  254. package/dist/utils/deserialize-html.js +219 -0
  255. package/dist/utils/dom-utils.js +57 -0
  256. package/dist/utils/dom.js +133 -0
  257. package/dist/utils/event-bus.js +40 -0
  258. package/dist/utils/event-handler.js +44 -0
  259. package/dist/utils/get-browser-Info.js +35 -0
  260. package/dist/utils/hotkey.js +45 -0
  261. package/dist/utils/is-punctuation-mark.js +50 -0
  262. package/dist/utils/object-utils.js +56 -0
  263. package/dist/utils/search.js +20 -0
  264. package/dist/utils/translate.js +18 -0
  265. package/dist/utils/type-detection.js +42 -0
  266. package/package.json +177 -0
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ var _reactstrap = require("reactstrap");
10
+ var _constants = require("@/constants");
11
+ var _components = require("../../../../components");
12
+ var _helper = require("../helper");
13
+ var _jsxRuntime = require("react/jsx-runtime");
14
+ const LinkModal = _ref => {
15
+ let {
16
+ editor,
17
+ onCloseModal,
18
+ linkTitle,
19
+ linkUrl
20
+ } = _ref;
21
+ const [formData, setFormData] = (0, _react.useState)({
22
+ linkUrl: linkUrl !== null && linkUrl !== void 0 ? linkUrl : '',
23
+ linkTitle: linkTitle !== null && linkTitle !== void 0 ? linkTitle : ''
24
+ });
25
+ const [validatorErrorMessage, setValidatorErrorMessage] = (0, _react.useState)({
26
+ linkUrl: '',
27
+ linkTitle: ''
28
+ });
29
+ const linkAddressRef = (0, _react.useRef)(null);
30
+ const isSubmitDisabled = (0, _react.useMemo)(() => {
31
+ const isFormDataEmpty = Object.values(formData).some(value => value.length === 0);
32
+ if (isFormDataEmpty) return true;
33
+ const isValidatorErrorMessage = Object.values(validatorErrorMessage).some(value => value.length > 0);
34
+ if (isValidatorErrorMessage) return true;
35
+ return false;
36
+ }, [formData, validatorErrorMessage]);
37
+ const onOpened = (0, _react.useCallback)(() => {
38
+ var _linkAddressRef$curre;
39
+ (_linkAddressRef$curre = linkAddressRef.current) === null || _linkAddressRef$curre === void 0 ? void 0 : _linkAddressRef$curre.focus();
40
+ }, []);
41
+
42
+ /**
43
+ * @param {String} formItemName form item name
44
+ * @param {String} formItemValue form item value
45
+ * @returns if validate passed, return Promise.resolve(); else return Promise.reject(error message);
46
+ */
47
+ const validateFormData = (0, _react.useCallback)((formItemName, formItemValue) => {
48
+ if (formItemName === 'linkUrl') {
49
+ if (formItemValue.length === 0) return Promise.reject('Link address required');
50
+ // When entering a URL in the dialog box, the validity is not checked.
51
+ // if (!isUrl(formItemValue)) return Promise.reject('Link_address_invalid');
52
+ }
53
+ if (formItemName === 'linkTitle') {
54
+ if (!formItemValue.length) return Promise.reject('Link title required');
55
+ if (!formItemValue.trim().length) return Promise.reject('Blank title not allowed');
56
+ }
57
+ return Promise.resolve();
58
+ }, []);
59
+ const preProcessBeforeOnchange = (0, _react.useCallback)((formItemName, formItemValue) => {
60
+ if (formItemName === 'linkUrl') {
61
+ return formItemValue.trim();
62
+ }
63
+ return formItemValue;
64
+ }, []);
65
+ const onFormValueChange = (0, _react.useCallback)(e => {
66
+ const formItemName = e.target.name;
67
+ let formItemValue = e.target.value;
68
+ // pre-process form item value
69
+ formItemValue = preProcessBeforeOnchange(formItemName, formItemValue);
70
+ validateFormData(formItemName, formItemValue).then(() => setValidatorErrorMessage({
71
+ ...validatorErrorMessage,
72
+ [formItemName]: ''
73
+ }), errMsg => setValidatorErrorMessage({
74
+ ...validatorErrorMessage,
75
+ [formItemName]: errMsg
76
+ }));
77
+ setFormData({
78
+ ...formData,
79
+ [formItemName]: formItemValue
80
+ });
81
+ }, [formData, preProcessBeforeOnchange, validateFormData, validatorErrorMessage]);
82
+ const onSubmit = (0, _react.useCallback)(e => {
83
+ // re-validate form data before submit
84
+ Object.entries(formData).forEach(_ref2 => {
85
+ let [key, value] = _ref2;
86
+ return validateFormData(key, value).catch(errMsg => setValidatorErrorMessage(prev => ({
87
+ ...prev,
88
+ [key]: errMsg
89
+ })));
90
+ });
91
+ if (!isSubmitDisabled) {
92
+ const isLinkActive = (0, _helper.isLinkType)(editor);
93
+ isLinkActive ? (0, _helper.updateLink)(editor, formData.linkUrl, formData.linkTitle) : (0, _helper.insertLink)({
94
+ editor,
95
+ url: formData.linkUrl,
96
+ title: formData.linkTitle
97
+ });
98
+ onCloseModal();
99
+ }
100
+ e.preventDefault();
101
+ e.stopPropagation();
102
+ }, [editor, formData, isSubmitDisabled, onCloseModal, validateFormData]);
103
+ const onKeydown = (0, _react.useCallback)(e => {
104
+ if (e.key === 'Enter') {
105
+ onSubmit(e);
106
+ }
107
+ }, [onSubmit]);
108
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.Modal, {
109
+ isOpen: true,
110
+ toggle: onCloseModal,
111
+ onOpened: onOpened,
112
+ zIndex: 1100,
113
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ModalHeader, {
114
+ toggle: onCloseModal,
115
+ children: (0, _constants.gettext)('Insert link')
116
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactstrap.ModalBody, {
117
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactstrap.Form, {
118
+ onChange: onFormValueChange,
119
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactstrap.FormGroup, {
120
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactstrap.Label, {
121
+ for: "linkUrl",
122
+ children: (0, _constants.gettext)('Link address')
123
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactstrap.Input, {
124
+ onKeyDown: onKeydown
125
+ // `onChange={() => void 0}` to fix reactstrap error which need `onChange` when `value` setteled, (`onChange` has been listened at `<Form>` )
126
+ ,
127
+ onChange: () => void 0,
128
+ value: formData.linkUrl,
129
+ invalid: !!validatorErrorMessage.linkUrl,
130
+ name: "linkUrl",
131
+ innerRef: linkAddressRef,
132
+ type: "url",
133
+ id: "linkUrl"
134
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactstrap.FormFeedback, {
135
+ children: (0, _constants.gettext)(validatorErrorMessage.linkUrl)
136
+ })]
137
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactstrap.FormGroup, {
138
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactstrap.Label, {
139
+ for: "linkTitle",
140
+ children: (0, _constants.gettext)('Link title')
141
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactstrap.Input, {
142
+ onKeyDown: onKeydown
143
+ // `onChange={() => void 0}` to fix reactstrap error which need `onChange` when `value` setteled, (`onChange` has been listened at `<Form>` )
144
+ ,
145
+ onChange: () => void 0,
146
+ value: formData.linkTitle,
147
+ invalid: !!validatorErrorMessage.linkTitle,
148
+ name: "linkTitle",
149
+ id: "linkTitle"
150
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactstrap.FormFeedback, {
151
+ children: (0, _constants.gettext)(validatorErrorMessage.linkTitle)
152
+ })]
153
+ })]
154
+ })
155
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactstrap.ModalFooter, {
156
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactstrap.Button, {
157
+ onClick: onCloseModal,
158
+ color: "secondary",
159
+ children: (0, _constants.gettext)('Cancel')
160
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactstrap.Button, {
161
+ onClick: onSubmit,
162
+ disabled: isSubmitDisabled,
163
+ color: "primary",
164
+ children: (0, _constants.gettext)('Add link')
165
+ })]
166
+ })]
167
+ });
168
+ };
169
+ var _default = exports.default = LinkModal;
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _slate = require("slate");
9
+ var _slugid = _interopRequireDefault(require("slugid"));
10
+ var _queries = require("../../core/queries");
11
+ var _helper = require("./helper");
12
+ var _elementTypes = require("../../constants/element-types");
13
+ var _constants = require("../../constants");
14
+ var _eventTypes = require("../../../constants/event-types");
15
+ var _common = require("../../../utils/common");
16
+ var _focusEditor = require("../../core/transforms/focus-editor");
17
+ var _helper2 = require("../image/helper");
18
+ var _isHotkey = _interopRequireDefault(require("is-hotkey"));
19
+ var _eventBus = _interopRequireDefault(require("../../../utils/event-bus"));
20
+ const withLink = editor => {
21
+ const {
22
+ isInline,
23
+ insertBreak,
24
+ deleteBackward,
25
+ insertText,
26
+ normalizeNode,
27
+ insertData,
28
+ onHotKeyDown
29
+ } = editor;
30
+ const newEditor = editor;
31
+
32
+ // Rewrite isInline
33
+ newEditor.isInline = elem => {
34
+ const {
35
+ type
36
+ } = elem;
37
+ if (type === _elementTypes.LINK) {
38
+ return true;
39
+ }
40
+ return isInline(elem);
41
+ };
42
+ newEditor.insertBreak = () => {
43
+ const [selectedElement, path] = _slate.Editor.parent(editor, editor.selection);
44
+ if (selectedElement.type === _elementTypes.LINK) {
45
+ const endPoint = _slate.Range.end(editor.selection);
46
+ const [selectedLeaf] = _slate.Editor.node(editor, endPoint);
47
+ if (selectedLeaf.text.length === endPoint.offset) {
48
+ if (_slate.Range.isExpanded(editor.selection)) {
49
+ _slate.Transforms.delete(editor);
50
+ } else {
51
+ _slate.Transforms.select(editor, {
52
+ path: _slate.Path.next(path),
53
+ offset: 0
54
+ });
55
+ }
56
+ }
57
+ }
58
+ insertBreak();
59
+ };
60
+
61
+ // ! bug: insertFragment will insert the same character twice in LinkNode, so we need to delete the first character
62
+ newEditor.insertText = text => {
63
+ const isCollapsed = _slate.Range.isCollapsed(editor.selection);
64
+ const path = _slate.Editor.path(editor, editor.selection);
65
+ const isLinkNode = (0, _queries.getSelectedNodeByType)(editor, _elementTypes.LINK);
66
+ const isFocusAtLinkEnd = _slate.Editor.isEnd(editor, editor.selection.focus, path);
67
+ if (isCollapsed && isLinkNode && isFocusAtLinkEnd) {
68
+ _slate.Editor.insertFragment(newEditor, [{
69
+ id: _slugid.default.nice(),
70
+ text: text
71
+ }]);
72
+ return;
73
+ }
74
+ return insertText(text);
75
+ };
76
+ newEditor.insertData = data => {
77
+ // Paste link content
78
+ const text = data.getData('text/plain');
79
+ if ((0, _common.isUrl)(text) && !(0, _common.isImage)(text)) {
80
+ const link = (0, _helper.generateLinkNode)(text, text);
81
+ _slate.Editor.insertFragment(newEditor, [link], {
82
+ select: true
83
+ });
84
+ return;
85
+ } else if ((0, _common.isUrl)(text) && (0, _common.isImage)(text)) {
86
+ (0, _helper2.insertImage)(newEditor, text);
87
+ return;
88
+ }
89
+ insertData(data);
90
+ };
91
+ newEditor.deleteBackward = unit => {
92
+ const {
93
+ selection
94
+ } = newEditor;
95
+ if (!selection) return deleteBackward(unit);
96
+ // Delete link node
97
+ const isDeletingLinkNode = (0, _helper.isLinkType)(editor);
98
+ if (isDeletingLinkNode) {
99
+ const linkNodeInfo = (0, _helper.getLinkInfo)(editor);
100
+ if (linkNodeInfo && linkNodeInfo.linkTitle.length === 1) {
101
+ const next = _slate.Editor.next(editor);
102
+ const nextPath = _slate.Path.next(linkNodeInfo.path);
103
+ const nextNode = _slate.Editor.node(editor, nextPath);
104
+ (0, _focusEditor.focusEditor)(editor, next[1]);
105
+ _slate.Transforms.select(editor, nextNode[1]);
106
+ _slate.Transforms.delete(newEditor, {
107
+ at: linkNodeInfo.path
108
+ });
109
+ return;
110
+ }
111
+ }
112
+ return deleteBackward(unit);
113
+ };
114
+
115
+ // Add 'mod+k' shortcut Key
116
+ newEditor.onHotKeyDown = e => {
117
+ if ((0, _isHotkey.default)('mod+k', e)) {
118
+ e.preventDefault();
119
+ const {
120
+ selection
121
+ } = newEditor;
122
+ const isCollapsed = _slate.Range.isCollapsed(selection);
123
+ const eventBus = _eventBus.default.getInstance();
124
+ if (isCollapsed) {
125
+ eventBus.dispatch(_eventTypes.INTERNAL_EVENTS.INSERT_ELEMENT, {
126
+ type: _constants.ElementTypes.LINK,
127
+ editor
128
+ });
129
+ } else {
130
+ const [firstSelectedNode, ...restNodes] = (0, _queries.getSelectedElems)(newEditor);
131
+ if (!firstSelectedNode) return; // If not select any node, return
132
+ // If firstNode has child nods, recursively check if every child node contains a text node
133
+ const hasTextNode = node => {
134
+ if (_slate.Text.isText(node)) return true;
135
+ if (node.children && node.children.length > 0) {
136
+ return node.children.some(hasTextNode);
137
+ }
138
+ };
139
+ const isSelectTextNodes = hasTextNode(firstSelectedNode);
140
+ if (!isSelectTextNodes) return;
141
+ const linkTitle = window.getSelection().toString();
142
+ eventBus.dispatch(_eventTypes.INTERNAL_EVENTS.INSERT_ELEMENT, {
143
+ type: _constants.ElementTypes.LINK,
144
+ editor: newEditor,
145
+ linkTitle: linkTitle
146
+ });
147
+ }
148
+ }
149
+ return onHotKeyDown && onHotKeyDown(e);
150
+ };
151
+
152
+ // Rewrite normalizeNode
153
+ newEditor.normalizeNode = _ref => {
154
+ let [node, path] = _ref;
155
+ const type = (0, _queries.getNodeType)(node);
156
+ if (type !== _elementTypes.LINK) {
157
+ // If the type is not link, perform default normalizeNode
158
+ return normalizeNode([node, path]);
159
+ }
160
+
161
+ // If the link is empty, delete it
162
+ const str = _slate.Node.string(node);
163
+ if (str === '') {
164
+ return _slate.Transforms.removeNodes(newEditor, {
165
+ at: path
166
+ });
167
+ }
168
+ return normalizeNode([node, path]);
169
+ };
170
+ return newEditor;
171
+ };
172
+ var _default = exports.default = withLink;
@@ -0,0 +1,12 @@
1
+ .sea-email-virtual-link {
2
+ color: #eb8205;
3
+ }
4
+
5
+ .sea-email-virtual-link:hover {
6
+ text-decoration: underline;
7
+ text-underline-position: under;
8
+ }
9
+
10
+ .sea-email-virtual-link.selected {
11
+ background-color: #e5e5e5;
12
+ }
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+ var _react = _interopRequireWildcard(require("react"));
10
+ var _classnames = _interopRequireDefault(require("classnames"));
11
+ var _slateReact = require("slate-react");
12
+ var _linkOpMenu = _interopRequireDefault(require("./link-op-menu"));
13
+ var _helper = require("../helper");
14
+ var _eventBus = _interopRequireDefault(require("../../../../utils/event-bus"));
15
+ var _eventTypes = require("../../../../constants/event-types");
16
+ var _constants = require("../../../constants");
17
+ require("./index.css");
18
+ var _jsxRuntime = require("react/jsx-runtime");
19
+ /* eslint-disable react-hooks/rules-of-hooks */
20
+
21
+ const renderLink = (_ref, editor) => {
22
+ let {
23
+ attributes,
24
+ children,
25
+ element,
26
+ option
27
+ } = _ref;
28
+ const [isShowPopover, setIsShowPopover] = (0, _react.useState)(false);
29
+ const [popoverPosition, setPopoverPosition] = (0, _react.useState)({
30
+ top: 0,
31
+ left: 0
32
+ });
33
+ const isReadonly = (0, _slateReact.useReadOnly)();
34
+
35
+ // eslint-disable-next-line react-hooks/exhaustive-deps
36
+ const isLinkActive = (0, _react.useMemo)(() => (0, _helper.isLinkType)(editor), [editor.selection]);
37
+ const onClosePopover = (0, _react.useCallback)(e => {
38
+ unregisterClickEvent();
39
+ setIsShowPopover(false);
40
+ // eslint-disable-next-line react-hooks/exhaustive-deps
41
+ }, [setPopoverPosition]);
42
+ const registerClickEvent = (0, _react.useCallback)(() => {
43
+ window.addEventListener('click', onClosePopover);
44
+ }, [onClosePopover]);
45
+ const unregisterClickEvent = (0, _react.useCallback)(() => {
46
+ window.removeEventListener('click', onClosePopover);
47
+ }, [onClosePopover]);
48
+ const onLinkClick = (0, _react.useCallback)(e => {
49
+ e.stopPropagation();
50
+ const eventBus = _eventBus.default.getInstance();
51
+ if (isReadonly) {
52
+ eventBus.dispatch(_eventTypes.EXTERNAL_EVENTS.ON_LINK_CLICK, e, editor._id);
53
+ return;
54
+ }
55
+ // Only one popover can be open at the same time, close other popover and update new popover controller function.
56
+ eventBus.dispatch(_eventTypes.INTERNAL_EVENTS.ON_CLOSE_LINK_POPOVER);
57
+ eventBus.subscribe(_eventTypes.INTERNAL_EVENTS.ON_CLOSE_LINK_POPOVER, () => setIsShowPopover(false));
58
+ const linkInfo = (0, _helper.getLinkInfo)(editor);
59
+ if (!linkInfo) return;
60
+ const {
61
+ top,
62
+ left,
63
+ width
64
+ } = e.target.getBoundingClientRect();
65
+ const popoverTop = top - 42;
66
+ const popoverLeft = left - 140 / 2 + width / 2;
67
+ setPopoverPosition({
68
+ top: popoverTop,
69
+ left: popoverLeft
70
+ });
71
+ setIsShowPopover(true);
72
+ registerClickEvent();
73
+ }, [editor, isReadonly, registerClickEvent]);
74
+ const onHrefClick = (0, _react.useCallback)(e => {
75
+ e.preventDefault();
76
+ }, []);
77
+ const url = (0, _helper.getElementHref)(element);
78
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
79
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
80
+ onClick: onLinkClick,
81
+ "data-url": url,
82
+ ...attributes,
83
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("a", {
84
+ href: url,
85
+ className: (0, _classnames.default)('sea-email-virtual-link', element.className, {
86
+ selected: isShowPopover
87
+ }),
88
+ style: {
89
+ ...(_constants.ELEMENT_DEFAULT_STYLE[element.type] || {}),
90
+ ...((element === null || element === void 0 ? void 0 : element.style) || {})
91
+ },
92
+ onClick: onHrefClick,
93
+ children: children
94
+ })
95
+ }), isLinkActive && isShowPopover && /*#__PURE__*/(0, _jsxRuntime.jsx)(_linkOpMenu.default, {
96
+ popoverPosition: popoverPosition,
97
+ linkUrl: url,
98
+ editor: editor,
99
+ onClosePopover: onClosePopover
100
+ })]
101
+ });
102
+ };
103
+ var _default = exports.default = renderLink;
@@ -0,0 +1,33 @@
1
+ .sea-email-link-op-menu {
2
+ height: 36px;
3
+ padding: 7px 8px;
4
+ display: flex;
5
+ position: absolute;
6
+ background-color: #fff;
7
+ border: 1px solid #e5e5e5;
8
+ border-radius: 3px;
9
+ box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08);
10
+ z-index: 1999;
11
+ }
12
+
13
+ .sea-email-link-op-menu-link {
14
+ font-size: 12px;
15
+ color: #212529;
16
+ padding: 0 5px;
17
+ line-height: 20px;
18
+ }
19
+
20
+ .sea-email-link-op-menu-link:hover {
21
+ color: #212529;
22
+ text-decoration: none;
23
+ background: #f1f1f1;
24
+ cursor: pointer;
25
+ }
26
+
27
+ .sea-email-link-op-icons {
28
+ margin-left: 8px;
29
+ border-left: 1px solid #e5e5e5;
30
+ display: flex;
31
+ gap: 8px;
32
+ padding-left: 8px;
33
+ }
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+ var _react = _interopRequireWildcard(require("react"));
10
+ var _reactDom = require("react-dom");
11
+ var _constants = require("@/constants");
12
+ var _eventBus = _interopRequireDefault(require("../../../../../utils/event-bus"));
13
+ var _helper = require("../../helper");
14
+ var _eventTypes = require("../../../../../constants/event-types");
15
+ var _components = require("../../../../../components");
16
+ require("./index.css");
17
+ var _jsxRuntime = require("react/jsx-runtime");
18
+ const LinkOpMenu = _ref => {
19
+ let {
20
+ linkUrl,
21
+ onClosePopover,
22
+ popoverPosition,
23
+ editor
24
+ } = _ref;
25
+ (0, _react.useEffect)(() => {
26
+ return () => {
27
+ // unregister click event before unmount
28
+ onClosePopover();
29
+ };
30
+ }, [onClosePopover]);
31
+ const onLinkClick = (0, _react.useCallback)(event => {
32
+ const eventBus = _eventBus.default.getInstance();
33
+ eventBus.dispatch(_eventTypes.EXTERNAL_EVENTS.ON_LINK_CLICK, event, editor._id);
34
+ onClosePopover();
35
+ }, [editor, onClosePopover]);
36
+ const onUnwrapLink = (0, _react.useCallback)(e => {
37
+ e.stopPropagation();
38
+ (0, _helper.unWrapLinkNode)(editor);
39
+ }, [editor]);
40
+ const onEditLink = (0, _react.useCallback)(e => {
41
+ e.stopPropagation();
42
+ const linkNode = (0, _helper.getLinkInfo)(editor);
43
+ if (!linkNode) {
44
+ onClosePopover();
45
+ return;
46
+ }
47
+ const {
48
+ linkTitle,
49
+ linkUrl
50
+ } = linkNode;
51
+ const eventBus = _eventBus.default.getInstance();
52
+ eventBus.dispatch(_eventTypes.INTERNAL_EVENTS.ON_OPEN_LINK_MODAL, {
53
+ linkTitle,
54
+ linkUrl
55
+ });
56
+ onClosePopover();
57
+ }, [editor, onClosePopover]);
58
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
59
+ children: /*#__PURE__*/(0, _reactDom.createPortal)(/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
60
+ id: "link-op-menu",
61
+ className: "sea-email-link-op-menu",
62
+ style: popoverPosition,
63
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
64
+ "data-url": linkUrl,
65
+ onClick: onLinkClick,
66
+ className: "sea-email-link-op-menu-link",
67
+ children: (0, _constants.gettext)('Open link')
68
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
69
+ className: "sea-email-link-op-icons",
70
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_components.IconButton, {
71
+ icon: "rename",
72
+ onClick: onEditLink,
73
+ size: {
74
+ btn: 20,
75
+ icon: 12
76
+ }
77
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.IconButton, {
78
+ icon: "unlink",
79
+ onClick: onUnwrapLink,
80
+ size: {
81
+ btn: 20,
82
+ icon: 12
83
+ }
84
+ })]
85
+ })]
86
+ }), document.body)
87
+ });
88
+ };
89
+ var _default = exports.default = LinkOpMenu;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.LIST_TYPES = void 0;
7
+ var _elementTypes = require("../../constants/element-types");
8
+ const LIST_TYPES = exports.LIST_TYPES = [_elementTypes.ORDERED_LIST, _elementTypes.UNORDERED_LIST];
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.setListType = exports.isMenuDisabled = exports.getBeforeText = exports.getActiveListType = void 0;
7
+ var _slate = require("slate");
8
+ var _elementTypes = require("../../constants/element-types");
9
+ var _constant = require("./constant");
10
+ var _transforms = require("./transforms");
11
+ const isMenuDisabled = (editor, readonly) => {
12
+ if (readonly || !editor.selection) return true;
13
+ // Match disable node
14
+ const [matchedDisabledNode] = _slate.Editor.nodes(editor, {
15
+ match: node => {
16
+ if (!_slate.Element.isElement(node)) return false;
17
+ const isVoidOrBlock = _slate.Editor.isVoid(editor, node) && _slate.Editor.isBlock(editor, node);
18
+ if (isVoidOrBlock) return true;
19
+ const disabledNodeTypes = [_elementTypes.CODE_LINE, _elementTypes.CODE_BLOCK, _elementTypes.TABLE, _elementTypes.CHECK_LIST_ITEM];
20
+ const isDisabledNode = disabledNodeTypes.includes(node.type);
21
+ if (isDisabledNode) return true;
22
+ return false;
23
+ }
24
+ });
25
+ if (matchedDisabledNode) return true;
26
+ return false;
27
+ };
28
+
29
+ /**
30
+ * @returns {ORDERED_LIST | UNORDERED_LIST | undefined} Return the list type of the selected list
31
+ */
32
+ exports.isMenuDisabled = isMenuDisabled;
33
+ const getActiveListType = editor => {
34
+ const {
35
+ selection
36
+ } = editor;
37
+ if (!selection) return;
38
+ let selectedListNodeEntry;
39
+ if (_slate.Range.isCollapsed(selection)) {
40
+ const [nodeEntry] = _slate.Editor.nodes(editor, {
41
+ match: node => _constant.LIST_TYPES.includes(node.type),
42
+ mode: 'lowest'
43
+ });
44
+ selectedListNodeEntry = nodeEntry;
45
+ } else {
46
+ const {
47
+ anchor,
48
+ focus
49
+ } = selection;
50
+ const commonNodeEntry = _slate.Node.common(editor, anchor.path, focus.path);
51
+ // Select condition:
52
+ // 1. Select in one list
53
+ // 2. Select in one list item
54
+ // 3. Select in one line
55
+ if (_constant.LIST_TYPES.includes(commonNodeEntry[0].type)) {
56
+ // Select in one list
57
+ selectedListNodeEntry = commonNodeEntry;
58
+ } else if (commonNodeEntry[0].type === _elementTypes.LIST_ITEM) {
59
+ // Select in one list item
60
+ selectedListNodeEntry = _slate.Editor.parent(editor, commonNodeEntry[1]);
61
+ } else if (_slate.Text.isText(commonNodeEntry[0])) {
62
+ // Select in one line
63
+ const [nodeEntry] = _slate.Editor.nodes(editor, {
64
+ at: commonNodeEntry[1],
65
+ match: node => _constant.LIST_TYPES.includes(node.type),
66
+ mode: 'lowest'
67
+ });
68
+ selectedListNodeEntry = nodeEntry;
69
+ }
70
+ }
71
+ return selectedListNodeEntry && selectedListNodeEntry[0].type;
72
+ };
73
+ exports.getActiveListType = getActiveListType;
74
+ const setListType = (editor, type) => {
75
+ (0, _transforms.transformsToList)(editor, type);
76
+ };
77
+ exports.setListType = setListType;
78
+ const getBeforeText = editor => {
79
+ const {
80
+ selection
81
+ } = editor;
82
+ if (selection == null) return {
83
+ beforeText: '',
84
+ range: null
85
+ };
86
+ const {
87
+ anchor
88
+ } = selection;
89
+ // Find the near text node above the current text
90
+ const [, aboveNodePath] = _slate.Editor.above(editor);
91
+ const aboveNodeStartPoint = _slate.Editor.start(editor, aboveNodePath); // The starting position of the text node
92
+ const range = {
93
+ anchor,
94
+ focus: aboveNodeStartPoint
95
+ };
96
+ const beforeText = _slate.Editor.string(editor, range) || '';
97
+ return {
98
+ beforeText,
99
+ range
100
+ };
101
+ };
102
+ exports.getBeforeText = getBeforeText;