x-star-editor 0.3.4 → 0.3.6

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.
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  interface FileInputProps {
3
+ image?: boolean;
3
4
  onCancel: () => void;
4
5
  onOk: (data: ({
5
6
  type: 'file';
@@ -11,5 +12,5 @@ interface FileInputProps {
11
12
  description: string;
12
13
  }) => void;
13
14
  }
14
- declare const FileInput: ({ onCancel, onOk }: FileInputProps) => React.JSX.Element;
15
+ declare const FileInput: ({ image, onCancel, onOk }: FileInputProps) => React.JSX.Element;
15
16
  export default FileInput;
@@ -6,7 +6,8 @@ import { useLocale } from "../locales";
6
6
  import { prefix } from "../utils/global";
7
7
  var FileInput = function FileInput(_ref) {
8
8
  var _file$name;
9
- var onCancel = _ref.onCancel,
9
+ var image = _ref.image,
10
+ onCancel = _ref.onCancel,
10
11
  onOk = _ref.onOk;
11
12
  var _useState = useState('file'),
12
13
  _useState2 = _slicedToArray(_useState, 2),
@@ -47,6 +48,7 @@ var FileInput = function FileInput(_ref) {
47
48
  }, /*#__PURE__*/React.createElement("input", {
48
49
  className: classNames("".concat(prefix, "hidden")),
49
50
  type: "file",
51
+ accept: image ? 'image/*' : undefined,
50
52
  onChange: function onChange(e) {
51
53
  var _e$target$files;
52
54
  return setFile((_e$target$files = e.target.files) === null || _e$target$files === void 0 ? void 0 : _e$target$files[0]);
@@ -78,7 +78,7 @@ var Item = function Item(_ref) {
78
78
  return /*#__PURE__*/React.createElement("div", {
79
79
  className: classNames("".concat(prefix, "item-container"))
80
80
  }, /*#__PURE__*/React.createElement("div", {
81
- className: classNames("".concat(prefix, "item"), (_classNames = {}, _defineProperty(_classNames, "".concat(prefix, "disabled"), disabled), _defineProperty(_classNames, "".concat(prefix, "active"), tooltipOpen || popoverMount), _classNames)),
81
+ className: classNames("".concat(prefix, "item"), (_classNames = {}, _defineProperty(_classNames, "".concat(prefix, "disabled"), disabled), _defineProperty(_classNames, "".concat(prefix, "active"), popoverMount), _classNames)),
82
82
  onClick: function onClick() {
83
83
  if (!disabled) {
84
84
  setTooltipOpen(false);
@@ -315,6 +315,7 @@ export var getDefaultToolbarItemMap = function getDefaultToolbarItemMap(locale,
315
315
  tooltip: t('image'),
316
316
  popoverRender: function popoverRender(exec, close) {
317
317
  return /*#__PURE__*/React.createElement(FileInput, {
318
+ image: true,
318
319
  onCancel: close,
319
320
  onOk: function onOk(data) {
320
321
  if (data.type === 'file') {
@@ -422,7 +423,12 @@ export var getDefaultToolbarItemMap = function getDefaultToolbarItemMap(locale,
422
423
  children: /*#__PURE__*/React.createElement(SvgOrderedList, {
423
424
  className: classNames("".concat(prefix, "icon"))
424
425
  }),
425
- tooltip: t('orderedList')
426
+ tooltip: t('orderedList'),
427
+ onClick: function onClick(exec) {
428
+ return exec(toggleHandler({
429
+ type: 'orderedList'
430
+ }));
431
+ }
426
432
  },
427
433
  redo: function redo(_ref5) {
428
434
  var history = _ref5.history;
@@ -458,7 +464,12 @@ export var getDefaultToolbarItemMap = function getDefaultToolbarItemMap(locale,
458
464
  children: /*#__PURE__*/React.createElement(SvgTaskList, {
459
465
  className: classNames("".concat(prefix, "icon"))
460
466
  }),
461
- tooltip: t('taskList')
467
+ tooltip: t('taskList'),
468
+ onClick: function onClick(exec) {
469
+ return exec(toggleHandler({
470
+ type: 'taskList'
471
+ }));
472
+ }
462
473
  },
463
474
  thematicBreak: {
464
475
  children: /*#__PURE__*/React.createElement(SvgThematicBreak, {
@@ -530,14 +541,17 @@ export var getDefaultToolbarItemMap = function getDefaultToolbarItemMap(locale,
530
541
  children: /*#__PURE__*/React.createElement(SvgUnorderedList, {
531
542
  className: classNames("".concat(prefix, "icon"))
532
543
  }),
533
- tooltip: t('unorderedList')
544
+ tooltip: t('unorderedList'),
545
+ onClick: function onClick(exec) {
546
+ return exec(toggleHandler({
547
+ type: 'unorderedList'
548
+ }));
549
+ }
534
550
  }
535
551
  };
536
552
  };
537
553
  export var getDefaultToolbarItems = function getDefaultToolbarItems() {
538
- return [['heading', 'strong', 'emphasis', 'delete'], ['thematicBreak', 'blockquote' /** 'table' */], ['link', 'image', 'mermaid'], ['inlineCode', 'code', 'inlineMath', 'math'], ['undo', 'redo'],
539
- // ['orderedList', 'unorderedList', 'taskList'],
540
- ['toMarkdown', 'toHTML']
554
+ return [['heading', 'strong', 'emphasis', 'delete'], ['thematicBreak', 'blockquote' /** 'table' */], ['link', 'image', 'mermaid'], ['inlineCode', 'code', 'inlineMath', 'math'], ['orderedList', 'unorderedList', 'taskList'], ['toMarkdown', 'toHTML'], ['undo', 'redo']
541
555
  // ['help'],
542
556
  ];
543
557
  };
@@ -114,7 +114,7 @@
114
114
  background-color: rgba(230, 247, 255, 0.7);
115
115
  cursor: not-allowed;
116
116
  }
117
- .x-star-editor-toolbar .x-star-editor-item-container .x-star-editor-item.x-star-editor-active {
117
+ .x-star-editor-toolbar .x-star-editor-item-container .x-star-editor-item:hover, .x-star-editor-toolbar .x-star-editor-item-container .x-star-editor-item.x-star-editor-active {
118
118
  background-color: #cbedfd;
119
119
  }
120
120
  .x-star-editor-toolbar .x-star-editor-item-container .x-star-editor-item .x-star-editor-icon {
@@ -179,7 +179,7 @@
179
179
  .x-star-editor-editor.x-star-editor-fullscreen {
180
180
  position: fixed;
181
181
  inset: 0;
182
- z-index: 1000;
182
+ z-index: 9999;
183
183
  }
184
184
  .x-star-editor-editor.x-star-editor-fullscreen > .x-star-editor-md-editor,
185
185
  .x-star-editor-editor.x-star-editor-fullscreen > .x-star-editor-md-viewer {
@@ -237,10 +237,10 @@
237
237
  background-color: #c1def1;
238
238
  }
239
239
  .x-star-editor-md-editor > :first-child {
240
- margin-top: 1em;
240
+ margin-top: 0.5em;
241
241
  }
242
242
  .x-star-editor-md-editor > :last-child {
243
- margin-bottom: 1em;
243
+ margin-bottom: 0.5em;
244
244
  }
245
245
 
246
246
  .x-star-editor-md-viewer {
@@ -41,4 +41,5 @@ export declare const useContainer: (ref: React.RefObject<HTMLDivElement>) => {
41
41
  getOffset: (root: Node, targetNode: Node, targetOffset: number) => number;
42
42
  getSelection: () => ContainerSelection;
43
43
  setSelection: ({ anchorOffset, focusOffset }: ContainerSelection) => void;
44
+ normalizeSelection: () => void;
44
45
  };
@@ -1,5 +1,5 @@
1
1
  import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
2
- import { useEffect, useRef } from 'react';
2
+ import { useRef } from 'react';
3
3
  import { editorRender } from "./markdown";
4
4
 
5
5
  /**
@@ -294,52 +294,49 @@ export var useContainer = function useContainer(ref) {
294
294
  range.setEnd(focus.node, focus.offset);
295
295
  var rangeRect = range.getBoundingClientRect();
296
296
  var containerRect = ref.current.getBoundingClientRect();
297
- var topOffset = rangeRect.top - containerRect.top;
298
- var bottomOffset = rangeRect.bottom - containerRect.bottom;
297
+ var topOffset = Math.round(rangeRect.top - containerRect.top);
298
+ var bottomOffset = Math.round(rangeRect.bottom - containerRect.bottom);
299
299
 
300
300
  // 将光标滚动到视口内
301
- if (topOffset < 0) {
302
- ref.current.scrollTop += topOffset;
303
- } else if (bottomOffset > 0) {
304
- ref.current.scrollTop += bottomOffset;
301
+ if (topOffset < 1) {
302
+ ref.current.scrollTop += topOffset - 1;
303
+ } else if (bottomOffset > -1) {
304
+ ref.current.scrollTop += bottomOffset + 1;
305
305
  }
306
306
  };
307
307
 
308
- // 确保光标不在零宽空格后
309
- useEffect(function () {
310
- var listener = function listener() {
311
- var _ref$current, _anchorNode$nodeValue, _focusNode$nodeValue;
312
- var selection = window.getSelection();
313
- if (!selection || !selection.anchorNode || !selection.focusNode || !((_ref$current = ref.current) !== null && _ref$current !== void 0 && _ref$current.contains(selection.anchorNode))) {
314
- return;
315
- }
316
- var update = false;
317
- var anchorNode = selection.anchorNode,
318
- anchorOffset = selection.anchorOffset,
319
- focusNode = selection.focusNode,
320
- focusOffset = selection.focusOffset;
321
- if (anchorNode.nodeType === Node.TEXT_NODE && ((_anchorNode$nodeValue = anchorNode.nodeValue) === null || _anchorNode$nodeValue === void 0 ? void 0 : _anchorNode$nodeValue[anchorOffset - 1]) === "\u200B") {
322
- update = true;
323
- anchorOffset--;
324
- }
325
- if (focusNode.nodeType === Node.TEXT_NODE && ((_focusNode$nodeValue = focusNode.nodeValue) === null || _focusNode$nodeValue === void 0 ? void 0 : _focusNode$nodeValue[focusOffset - 1]) === "\u200B") {
326
- update = true;
327
- focusOffset--;
328
- }
329
- if (update) {
330
- selection.setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);
331
- }
332
- };
333
- document.addEventListener('selectionchange', listener);
334
- return function () {
335
- return document.removeEventListener('selectionchange', listener);
336
- };
337
- }, []);
308
+ /**
309
+ * 标准化容器选区,确保光标不在零宽空格后
310
+ */
311
+ var normalizeSelection = function normalizeSelection() {
312
+ var _anchorNode$nodeValue, _focusNode$nodeValue;
313
+ var selection = window.getSelection();
314
+ if (!selection || !selection.anchorNode || !selection.focusNode || !ref.current) {
315
+ return;
316
+ }
317
+ var update = false;
318
+ var anchorNode = selection.anchorNode,
319
+ anchorOffset = selection.anchorOffset,
320
+ focusNode = selection.focusNode,
321
+ focusOffset = selection.focusOffset;
322
+ if (anchorNode.nodeType === Node.TEXT_NODE && ((_anchorNode$nodeValue = anchorNode.nodeValue) === null || _anchorNode$nodeValue === void 0 ? void 0 : _anchorNode$nodeValue[anchorOffset - 1]) === "\u200B") {
323
+ update = true;
324
+ anchorOffset--;
325
+ }
326
+ if (focusNode.nodeType === Node.TEXT_NODE && ((_focusNode$nodeValue = focusNode.nodeValue) === null || _focusNode$nodeValue === void 0 ? void 0 : _focusNode$nodeValue[focusOffset - 1]) === "\u200B") {
327
+ update = true;
328
+ focusOffset--;
329
+ }
330
+ if (update) {
331
+ selection.setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);
332
+ }
333
+ };
338
334
  return useRef({
339
335
  getText: getText,
340
336
  setText: setText,
341
337
  getOffset: getOffset,
342
338
  getSelection: getSelection,
343
- setSelection: setSelection
339
+ setSelection: setSelection,
340
+ normalizeSelection: normalizeSelection
344
341
  }).current;
345
342
  };
@@ -17,7 +17,7 @@ export interface InsertAction {
17
17
  export interface ToggleAction {
18
18
  type: 'toggle';
19
19
  payload: {
20
- type: 'blockquote' | 'delete' | 'emphasis' | 'inlineCode' | 'inlineMath' | 'math' | 'strong' | 'thematicBreak';
20
+ type: 'blockquote' | 'delete' | 'emphasis' | 'inlineCode' | 'inlineMath' | 'math' | 'orderedList' | 'strong' | 'taskList' | 'thematicBreak' | 'unorderedList';
21
21
  } | {
22
22
  type: 'code';
23
23
  lang: string;
@@ -66,7 +66,7 @@ export interface SelectAction {
66
66
  selection: ContainerSelection;
67
67
  }
68
68
  type HistoryAction = UndoAction | RedoAction | BatchAction | SelectAction;
69
- export declare const useHistory: (initialSourceCode: string) => {
69
+ export declare const useHistory: (initialSourceCode: string, readOnly?: boolean) => {
70
70
  history: History;
71
71
  sourceCode: string;
72
72
  selection: ContainerSelection;
@@ -1,7 +1,7 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
2
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
3
3
  import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
4
- import { useReducer } from 'react';
4
+ import { useReducer, useRef } from 'react';
5
5
  import { createSelection, getRange } from "./container";
6
6
 
7
7
  /**
@@ -35,21 +35,26 @@ var stateReducer = function stateReducer(_ref, action) {
35
35
  var lineAfter = sourceCode.slice(lineEndOffset);
36
36
  switch (action.payload.type) {
37
37
  case 'blockquote':
38
+ case 'orderedList':
39
+ case 'taskList':
40
+ case 'unorderedList':
38
41
  {
42
+ var type = action.payload.type;
43
+ var prefixes = type === 'blockquote' ? ['>', '>'] : type === 'orderedList' ? ['\\d+\\.', '1.'] : type === 'taskList' ? ['[*+-] \\[[ x]]', '* [ ]'] : ['[*+-]', '*'];
39
44
  var lines = sourceCode.slice(lineStartOffset, lineEndOffset).split('\n');
40
45
  var values = lines.map(function (line) {
41
- return /^ {0,3}> */.test(line);
46
+ return new RegExp("^ {0,3}".concat(prefixes[0], " +")).test(line);
42
47
  });
43
48
  for (var i = 0; i < values.length; i++) {
44
49
  if (values[i]) {
45
- lines[i] = lines[i].replace(/^ {0,3}> */, '');
50
+ lines[i] = lines[i].replace(new RegExp("^ {0,3}".concat(prefixes[0], " +")), '');
46
51
  }
47
52
  }
48
53
  if (values.some(function (value) {
49
54
  return !value;
50
55
  })) {
51
56
  for (var _i = 0; _i < lines.length; _i++) {
52
- lines[_i] = "> ".concat(lines[_i]);
57
+ lines[_i] = "".concat(prefixes[1], " ").concat(lines[_i]);
53
58
  }
54
59
  }
55
60
  var _text = lines.join('\n');
@@ -76,8 +81,8 @@ var stateReducer = function stateReducer(_ref, action) {
76
81
  case 'inlineMath':
77
82
  case 'strong':
78
83
  {
79
- var type = action.payload.type;
80
- var delimiters = type === 'emphasis' ? ['*', '_'] : type === 'strong' ? ['**', '__'] : type === 'inlineCode' ? ['`'] : type === 'delete' ? ['~~'] : ['$'];
84
+ var _type = action.payload.type;
85
+ var delimiters = _type === 'emphasis' ? ['*', '_'] : _type === 'strong' ? ['**', '__'] : _type === 'inlineCode' ? ['`'] : _type === 'delete' ? ['~~'] : ['$'];
81
86
  var _text2 = sourceCode.slice(startOffset, endOffset);
82
87
  for (var _i2 = 0, _delimiters = delimiters; _i2 < _delimiters.length; _i2++) {
83
88
  var _delimiter = _delimiters[_i2];
@@ -128,12 +133,12 @@ var stateReducer = function stateReducer(_ref, action) {
128
133
  case 'link':
129
134
  {
130
135
  var _action$payload2 = action.payload,
131
- _type = _action$payload2.type,
136
+ _type2 = _action$payload2.type,
132
137
  url = _action$payload2.url,
133
138
  description = _action$payload2.description;
134
139
  return {
135
- sourceCode: "".concat(before).concat(_type === 'image' ? '!' : '', "[").concat(description, "](").concat(url, ")").concat(after),
136
- selection: createSelection(startOffset + url.length + description.length + 4 + (_type === 'image' ? 1 : 0))
140
+ sourceCode: "".concat(before).concat(_type2 === 'image' ? '!' : '', "[").concat(description, "](").concat(url, ")").concat(after),
141
+ selection: createSelection(startOffset + url.length + description.length + 4 + (_type2 === 'image' ? 1 : 0))
137
142
  };
138
143
  }
139
144
  case 'math':
@@ -268,7 +273,7 @@ var historyReducer = function historyReducer(_ref2, action) {
268
273
  }
269
274
  }
270
275
  };
271
- export var useHistory = function useHistory(initialSourceCode) {
276
+ export var useHistory = function useHistory(initialSourceCode, readOnly) {
272
277
  var _useReducer = useReducer(historyReducer, initialSourceCode, function (text) {
273
278
  var action = {
274
279
  type: 'insert',
@@ -292,10 +297,16 @@ export var useHistory = function useHistory(initialSourceCode) {
292
297
  _useReducer2 = _slicedToArray(_useReducer, 2),
293
298
  history = _useReducer2[0],
294
299
  dispatch = _useReducer2[1];
300
+ var readOnlyLatest = useRef(readOnly);
301
+ readOnlyLatest.current = readOnly;
295
302
  return {
296
303
  history: history,
297
304
  sourceCode: history.states[history.index].sourceCode,
298
305
  selection: history.selection,
299
- dispatch: dispatch
306
+ dispatch: useRef(function (action) {
307
+ if (!readOnlyLatest.current) {
308
+ dispatch(action);
309
+ }
310
+ }).current
300
311
  };
301
312
  };
@@ -25,6 +25,10 @@ export interface XStarEditorProps {
25
25
  * 初始文本
26
26
  */
27
27
  initialValue?: string;
28
+ /**
29
+ * 是否只读
30
+ */
31
+ readOnly?: XStarMdEditorProps['readOnly'];
28
32
  /**
29
33
  * 是否启用 Web Worker
30
34
  */
@@ -32,7 +36,7 @@ export interface XStarEditorProps {
32
36
  /**
33
37
  * 编辑器属性
34
38
  */
35
- editorProps?: Omit<XStarMdEditorProps, 'height' | 'locale' | 'initialValue' | 'onChange' | 'onInsertFile'>;
39
+ editorProps?: Omit<XStarMdEditorProps, 'height' | 'locale' | 'initialValue' | 'readOnly' | 'onChange' | 'onInsertFile'>;
36
40
  /**
37
41
  * 查看器属性
38
42
  */
@@ -5,6 +5,7 @@ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
5
5
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
6
6
  import classNames from 'classnames';
7
7
  import React, { useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
8
+ import { createKeybindingsHandler } from 'tinykeys';
8
9
  import SvgEditOnly from "../icons/EditOnly";
9
10
  import SvgEnterFullscreen from "../icons/EnterFullscreen";
10
11
  import SvgExitFullscreen from "../icons/ExitFullscreen";
@@ -42,6 +43,7 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
42
43
  locale = _ref2.locale,
43
44
  _ref2$initialValue = _ref2.initialValue,
44
45
  initialValue = _ref2$initialValue === void 0 ? '' : _ref2$initialValue,
46
+ readOnly = _ref2.readOnly,
45
47
  enableWebWorker = _ref2.enableWebWorker,
46
48
  editorProps = _ref2.editorProps,
47
49
  viewerProps = _ref2.viewerProps,
@@ -64,6 +66,9 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
64
66
  var _editorRef$current, _viewerRef$current;
65
67
  var editor = (_editorRef$current = editorRef.current) === null || _editorRef$current === void 0 ? void 0 : _editorRef$current.getEditorContainer();
66
68
  var viewer = (_viewerRef$current = viewerRef.current) === null || _viewerRef$current === void 0 ? void 0 : _viewerRef$current.getViewerContainer();
69
+ if (!editor || !viewer) {
70
+ return;
71
+ }
67
72
 
68
73
  /**
69
74
  * 获取两个父元素的子元素到各自父元素顶部的距离
@@ -122,7 +127,7 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
122
127
  var listener = function listener(e) {
123
128
  var ignore = ignoreNext;
124
129
  ignoreNext = false;
125
- if (ignore || !editor || !viewer) {
130
+ if (ignore) {
126
131
  return;
127
132
  }
128
133
  var _ref3 = e.currentTarget === editor ? [editor, viewer] : [viewer, editor],
@@ -135,7 +140,7 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
135
140
  toOffsetTops = _getOffsetTops2[1];
136
141
  for (var i = 0; i < fromOffsetTops.length - 1; i++) {
137
142
  if (fromOffsetTops[i] <= fromElement.scrollTop && fromElement.scrollTop < fromOffsetTops[i + 1]) {
138
- var scrollTop = (fromElement.scrollTop - fromOffsetTops[i]) / (fromOffsetTops[i + 1] - fromOffsetTops[i]) * (toOffsetTops[i + 1] - toOffsetTops[i]) + toOffsetTops[i];
143
+ var scrollTop = Math.round((fromElement.scrollTop - fromOffsetTops[i]) / (fromOffsetTops[i + 1] - fromOffsetTops[i]) * (toOffsetTops[i + 1] - toOffsetTops[i]) + toOffsetTops[i]);
139
144
  if (toElement.scrollTop !== scrollTop) {
140
145
  ignoreNext = true;
141
146
  toElement.scrollTop = scrollTop;
@@ -144,11 +149,11 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
144
149
  }
145
150
  }
146
151
  };
147
- editor === null || editor === void 0 ? void 0 : editor.addEventListener('scroll', listener);
148
- viewer === null || viewer === void 0 ? void 0 : viewer.addEventListener('scroll', listener);
152
+ editor.addEventListener('scroll', listener);
153
+ viewer.addEventListener('scroll', listener);
149
154
  return function () {
150
- editor === null || editor === void 0 ? void 0 : editor.removeEventListener('scroll', listener);
151
- viewer === null || viewer === void 0 ? void 0 : viewer.removeEventListener('scroll', listener);
155
+ editor.removeEventListener('scroll', listener);
156
+ viewer.removeEventListener('scroll', listener);
152
157
  };
153
158
  }, []);
154
159
  var _useState = useState(initialValue),
@@ -202,13 +207,25 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
202
207
  }].concat(_toConsumableArray((_editorProps$plugins = editorProps === null || editorProps === void 0 ? void 0 : editorProps.plugins) !== null && _editorProps$plugins !== void 0 ? _editorProps$plugins : []));
203
208
  }, [locale, editOnly, viewOnly, fullscreen, editorProps === null || editorProps === void 0 ? void 0 : editorProps.plugins]);
204
209
 
205
- // 防止出现两个滚动条
210
+ // 防止出现两个滚动条,按下 Esc 退出全屏
206
211
  useEffect(function () {
207
212
  if (fullscreen) {
208
213
  var overflow = document.body.style.overflow;
214
+ var listener = createKeybindingsHandler({
215
+ Escape: function Escape(e) {
216
+ e.stopImmediatePropagation();
217
+ setFullscreen(false);
218
+ }
219
+ });
209
220
  document.body.style.overflow = 'hidden';
221
+ document.addEventListener('keydown', listener, {
222
+ capture: true
223
+ });
210
224
  return function () {
211
225
  document.body.style.overflow = overflow;
226
+ document.removeEventListener('keydown', listener, {
227
+ capture: true
228
+ });
212
229
  };
213
230
  }
214
231
  }, [fullscreen]);
@@ -223,6 +240,7 @@ var XStarEditor = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
223
240
  height: height,
224
241
  locale: locale,
225
242
  initialValue: initialValue,
243
+ readOnly: viewOnly || readOnly,
226
244
  plugins: editorPlugins,
227
245
  onChange: function onChange(value) {
228
246
  setValue(value);
@@ -51,6 +51,10 @@ export interface XStarMdEditorProps {
51
51
  * 初始文本
52
52
  */
53
53
  initialValue?: string;
54
+ /**
55
+ * 是否只读
56
+ */
57
+ readOnly?: boolean;
54
58
  /**
55
59
  * 插件
56
60
  */
@@ -16,12 +16,13 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
16
16
  locale = _ref.locale,
17
17
  _ref$initialValue = _ref.initialValue,
18
18
  initialValue = _ref$initialValue === void 0 ? '' : _ref$initialValue,
19
+ readOnly = _ref.readOnly,
19
20
  plugins = _ref.plugins,
20
21
  onChange = _ref.onChange,
21
22
  onInsertFile = _ref.onInsertFile;
22
23
  var containerRef = useRef(null);
23
24
  var container = useContainer(containerRef);
24
- var _useHistory = useHistory(initialValue),
25
+ var _useHistory = useHistory(initialValue, readOnly),
25
26
  history = _useHistory.history,
26
27
  sourceCode = _useHistory.sourceCode,
27
28
  selection = _useHistory.selection,
@@ -124,6 +125,11 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
124
125
  });
125
126
  break;
126
127
  }
128
+ case 'compositionstart':
129
+ {
130
+ container.normalizeSelection();
131
+ break;
132
+ }
127
133
  }
128
134
  };
129
135
  var dragEventHandler = function dragEventHandler(e) {
@@ -183,14 +189,17 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
183
189
  }
184
190
  };
185
191
  useEffect(function () {
186
- var _containerRef$current;
192
+ var editor = containerRef.current;
193
+ if (!editor) {
194
+ return;
195
+ }
187
196
  var listener = function listener(e) {
188
197
  var targetRange = e.getTargetRanges()[0];
189
- if (!targetRange || !containerRef.current) {
198
+ if (!targetRange) {
190
199
  return;
191
200
  }
192
- var startOffset = container.getOffset(containerRef.current, targetRange.startContainer, targetRange.startOffset);
193
- var endOffset = container.getOffset(containerRef.current, targetRange.endContainer, targetRange.endOffset);
201
+ var startOffset = container.getOffset(editor, targetRange.startContainer, targetRange.startOffset);
202
+ var endOffset = container.getOffset(editor, targetRange.endContainer, targetRange.endOffset);
194
203
  var selection = createSelection(startOffset, endOffset);
195
204
  switch (e.inputType) {
196
205
  case 'insertText':
@@ -346,10 +355,9 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
346
355
  }
347
356
  }
348
357
  };
349
- (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.addEventListener('beforeinput', listener);
358
+ editor.addEventListener('beforeinput', listener);
350
359
  return function () {
351
- var _containerRef$current2;
352
- return (_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 ? void 0 : _containerRef$current2.removeEventListener('beforeinput', listener);
360
+ return editor.removeEventListener('beforeinput', listener);
353
361
  };
354
362
  }, []);
355
363
  return /*#__PURE__*/React.createElement(LocaleProvider, {
@@ -369,6 +377,7 @@ var XStarMdEditor = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
369
377
  contentEditable: true,
370
378
  onBlur: focusEventHandler,
371
379
  onCompositionEnd: compositionEventHandler,
380
+ onCompositionStart: compositionEventHandler,
372
381
  onCopy: clipboardEventHandler,
373
382
  onCut: clipboardEventHandler,
374
383
  onDragStart: dragEventHandler,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "x-star-editor",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "An editor developed by turingstar",
5
5
  "license": "MIT",
6
6
  "module": "dist/index.js",