support update callback setting selection instead of caret
This commit is contained in:
parent
037ac29c57
commit
2ea556e0b4
3 changed files with 40 additions and 10 deletions
|
@ -20,7 +20,7 @@ import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import EditorModel from '../../../editor/model';
|
import EditorModel from '../../../editor/model';
|
||||||
import HistoryManager from '../../../editor/history';
|
import HistoryManager from '../../../editor/history';
|
||||||
import {setCaretPosition} from '../../../editor/caret';
|
import {setSelection} from '../../../editor/caret';
|
||||||
import {
|
import {
|
||||||
formatRangeAsQuote,
|
formatRangeAsQuote,
|
||||||
formatRangeAsCode,
|
formatRangeAsCode,
|
||||||
|
@ -115,11 +115,11 @@ export default class BasicMessageEditor extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateEditorState = (caret, inputType, diff) => {
|
_updateEditorState = (selection, inputType, diff) => {
|
||||||
renderModel(this._editorRef, this.props.model);
|
renderModel(this._editorRef, this.props.model);
|
||||||
if (caret) {
|
if (selection) { // set the caret/selection
|
||||||
try {
|
try {
|
||||||
setCaretPosition(this._editorRef, this.props.model, caret);
|
setSelection(this._editorRef, this.props.model, selection);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ export default class BasicMessageEditor extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.setState({autoComplete: this.props.model.autoComplete});
|
this.setState({autoComplete: this.props.model.autoComplete});
|
||||||
this.historyManager.tryPush(this.props.model, caret, inputType, diff);
|
this.historyManager.tryPush(this.props.model, selection, inputType, diff);
|
||||||
TypingStore.sharedInstance().setSelfTyping(this.props.room.roomId, !this.props.model.isEmpty);
|
TypingStore.sharedInstance().setSelfTyping(this.props.room.roomId, !this.props.model.isEmpty);
|
||||||
|
|
||||||
if (this.props.onChange) {
|
if (this.props.onChange) {
|
||||||
|
|
|
@ -16,12 +16,39 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {needsCaretNodeBefore, needsCaretNodeAfter} from "./render";
|
import {needsCaretNodeBefore, needsCaretNodeAfter} from "./render";
|
||||||
|
import Range from "./range";
|
||||||
|
|
||||||
|
export function setSelection(editor, model, selection) {
|
||||||
|
if (selection instanceof Range) {
|
||||||
|
setDocumentRangeSelection(editor, model, selection);
|
||||||
|
} else {
|
||||||
|
setCaretPosition(editor, model, selection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDocumentRangeSelection(editor, model, range) {
|
||||||
|
const sel = document.getSelection();
|
||||||
|
sel.removeAllRanges();
|
||||||
|
const selectionRange = document.createRange();
|
||||||
|
const start = getNodeAndOffsetForPosition(editor, model, range.start);
|
||||||
|
selectionRange.setStart(start.node, start.offset);
|
||||||
|
const end = getNodeAndOffsetForPosition(editor, model, range.end);
|
||||||
|
selectionRange.setEnd(end.node, end.offset);
|
||||||
|
sel.addRange(selectionRange);
|
||||||
|
}
|
||||||
|
|
||||||
export function setCaretPosition(editor, model, caretPosition) {
|
export function setCaretPosition(editor, model, caretPosition) {
|
||||||
const sel = document.getSelection();
|
const sel = document.getSelection();
|
||||||
sel.removeAllRanges();
|
sel.removeAllRanges();
|
||||||
const range = document.createRange();
|
const range = document.createRange();
|
||||||
const {offset, lineIndex, nodeIndex} = getLineAndNodePosition(model, caretPosition);
|
const {node, offset} = getNodeAndOffsetForPosition(editor, model, caretPosition);
|
||||||
|
range.setStart(node, offset);
|
||||||
|
range.collapse(true);
|
||||||
|
sel.addRange(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNodeAndOffsetForPosition(editor, model, position) {
|
||||||
|
const {offset, lineIndex, nodeIndex} = getLineAndNodePosition(model, position);
|
||||||
const lineNode = editor.childNodes[lineIndex];
|
const lineNode = editor.childNodes[lineIndex];
|
||||||
|
|
||||||
let focusNode;
|
let focusNode;
|
||||||
|
@ -35,9 +62,7 @@ export function setCaretPosition(editor, model, caretPosition) {
|
||||||
focusNode = focusNode.firstChild;
|
focusNode = focusNode.firstChild;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
range.setStart(focusNode, offset);
|
return {node: focusNode, offset};
|
||||||
range.collapse(true);
|
|
||||||
sel.addRange(range);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLineAndNodePosition(model, caretPosition) {
|
export function getLineAndNodePosition(model, caretPosition) {
|
||||||
|
|
|
@ -433,7 +433,12 @@ export default class EditorModel {
|
||||||
*/
|
*/
|
||||||
transform(callback) {
|
transform(callback) {
|
||||||
const pos = callback();
|
const pos = callback();
|
||||||
const acPromise = this._setActivePart(pos, true);
|
let acPromise = null;
|
||||||
|
if (!(pos instanceof Range)) {
|
||||||
|
acPromise = this._setActivePart(pos, true);
|
||||||
|
} else {
|
||||||
|
acPromise = Promise.resolve();
|
||||||
|
}
|
||||||
this._updateCallback(pos);
|
this._updateCallback(pos);
|
||||||
return acPromise;
|
return acPromise;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue