mirror of
https://github.com/strapi/strapi.git
synced 2025-09-23 23:38:15 +00:00
Fix offsets
This commit is contained in:
parent
1047a5bdda
commit
1b82aa0940
@ -15,19 +15,18 @@ export function getBlockStyle(block) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this could be improved
|
|
||||||
export function getInnerText(style) {
|
export function getInnerText(style) {
|
||||||
let innerText;
|
let innerText;
|
||||||
|
|
||||||
switch (style) {
|
switch (style) {
|
||||||
case 'BOLD':
|
case 'BOLD':
|
||||||
innerText = '**text in bold**';
|
innerText = '**bold text**';
|
||||||
break;
|
break;
|
||||||
case 'ITALIC':
|
case 'ITALIC':
|
||||||
innerText = '*text in italic*';
|
innerText = '*italic text*';
|
||||||
break;
|
break;
|
||||||
case 'UNDERLINE':
|
case 'UNDERLINE':
|
||||||
innerText = '__text underlined__';
|
innerText = '__underlined text__';
|
||||||
break;
|
break;
|
||||||
case 'LINK':
|
case 'LINK':
|
||||||
innerText = '[text](link)';
|
innerText = '[text](link)';
|
||||||
@ -51,3 +50,19 @@ export function getOffSets(selection) {
|
|||||||
start: selection.getStartOffset(),
|
start: selection.getStartOffset(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getTheFocusOffsetToAdd
|
||||||
|
* @param {[type]} style [description]
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function getFocusOffset(style) {
|
||||||
|
switch (style) {
|
||||||
|
case 'BOLD':
|
||||||
|
return 11;
|
||||||
|
case 'ITALIC':
|
||||||
|
return 12;
|
||||||
|
default:
|
||||||
|
return 17;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -17,7 +17,7 @@ import {
|
|||||||
} from 'draft-js';
|
} from 'draft-js';
|
||||||
import { List } from 'immutable';
|
import { List } from 'immutable';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { isEmpty, isNaN, last, replace, trimStart, trimEnd, words } from 'lodash';
|
import { isEmpty, isNaN, last, replace, words } from 'lodash';
|
||||||
import cn from 'classnames';
|
import cn from 'classnames';
|
||||||
import Controls from 'components/WysiwygInlineControls';
|
import Controls from 'components/WysiwygInlineControls';
|
||||||
import Drop from 'components/WysiwygDropUpload';
|
import Drop from 'components/WysiwygDropUpload';
|
||||||
@ -25,8 +25,8 @@ import Select from 'components/InputSelect';
|
|||||||
import WysiwygBottomControls from 'components/WysiwygBottomControls';
|
import WysiwygBottomControls from 'components/WysiwygBottomControls';
|
||||||
import WysiwygEditor from 'components/WysiwygEditor';
|
import WysiwygEditor from 'components/WysiwygEditor';
|
||||||
import request from 'utils/request';
|
import request from 'utils/request';
|
||||||
import { END_REPLACER, NEW_CONTROLS, SELECT_OPTIONS, START_REPLACER } from './constants';
|
import { NEW_CONTROLS, SELECT_OPTIONS } from './constants';
|
||||||
import { getBlockStyle, getInnerText, getOffSets } from './helpers';
|
import { getBlockStyle, getFocusOffset, getInnerText, getOffSets } from './helpers';
|
||||||
import styles from './styles.scss';
|
import styles from './styles.scss';
|
||||||
|
|
||||||
/* eslint-disable react/jsx-handler-names */
|
/* eslint-disable react/jsx-handler-names */
|
||||||
@ -131,41 +131,40 @@ class Wysiwyg extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addEntity = (text, style) => {
|
addEntity = (text, style) => {
|
||||||
const editorState = this.state.editorState;
|
const editorState = this.getEditorState();
|
||||||
const currentContent = editorState.getCurrentContent();
|
const selectedText = this.getSelectedText();
|
||||||
// Get the selected text
|
|
||||||
const selection = editorState.getSelection();
|
// Don't handle selection
|
||||||
const anchorKey = selection.getAnchorKey();
|
if (selectedText !== '') {
|
||||||
const currentContentBlock = currentContent.getBlockForKey(anchorKey);
|
const textWithEntity = Modifier.replaceText(editorState.getCurrentContent(), this.getSelection(), replace(text, 'innerText', selectedText));
|
||||||
// Range of the text we want to replace
|
const newEditorState = EditorState.push(editorState, textWithEntity, 'insert-characters');
|
||||||
const { start, end } = getOffSets(selection);
|
|
||||||
// Retrieve the selected text
|
return this.setState({
|
||||||
const selectedText = currentContentBlock.getText().slice(start, end);
|
editorState: EditorState.moveFocusToEnd(newEditorState),
|
||||||
const innerText = selectedText === '' ? getInnerText(style) : replace(text, 'innerText', selectedText);
|
}, () => {
|
||||||
const trimedStart = trimStart(innerText, START_REPLACER).length;
|
this.focus();
|
||||||
const trimedEnd = trimEnd(innerText, END_REPLACER).length;
|
});
|
||||||
// Set the correct offset
|
}
|
||||||
const focusOffset = start === end ? trimedEnd : start + trimedEnd;
|
|
||||||
const anchorOffset = start + innerText.length - trimedStart;
|
const cursorPosition = getOffSets(this.getSelection()).start;
|
||||||
// Merge the old selection with the new one so the editorState is updated
|
const focusOffsetToAdd = getFocusOffset(style);
|
||||||
const updateSelection = selection.merge({
|
const textWithEntity = Modifier.replaceText(editorState.getCurrentContent(), this.getSelection(), getInnerText(style));
|
||||||
|
const anchorOffsetToAdd = style === 'ITALIC' ? 1 : 2;
|
||||||
|
const anchorOffset = cursorPosition + anchorOffsetToAdd;
|
||||||
|
const focusOffset = cursorPosition + focusOffsetToAdd;
|
||||||
|
const updatedSelection = this.getSelection().merge({
|
||||||
anchorOffset,
|
anchorOffset,
|
||||||
focusOffset,
|
focusOffset,
|
||||||
});
|
});
|
||||||
// Dynamically add some content to the one selected
|
const newEditorState = EditorState.push(editorState, textWithEntity, 'insert-character');
|
||||||
const textWithEntity = Modifier.replaceText(currentContent, selection, innerText);
|
|
||||||
// Push the new content to the editorState
|
return this.setState({
|
||||||
const newEditorState = EditorState.push(editorState, textWithEntity, 'insert-characters');
|
editorState: EditorState.forceSelection(newEditorState, updatedSelection),
|
||||||
// SetState and force focus
|
|
||||||
this.setState({
|
|
||||||
editorState: EditorState.forceSelection(newEditorState, updateSelection),
|
|
||||||
headerValue: '',
|
|
||||||
}, () => {
|
|
||||||
this.focus();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addOlBlock = () => {
|
addOlBlock = () => {
|
||||||
|
// NOTE need to check if this line is really necessary
|
||||||
const previousBlockKey = last(Object.keys(this.getCurrentBlockMap()));
|
const previousBlockKey = last(Object.keys(this.getCurrentBlockMap()));
|
||||||
const previousContent = this.getEditorState().getCurrentContent().getBlockForKey(previousBlockKey).getText();
|
const previousContent = this.getEditorState().getCurrentContent().getBlockForKey(previousBlockKey).getText();
|
||||||
const number = previousContent ? parseInt(previousContent.split('.')[0], 10) : 0;
|
const number = previousContent ? parseInt(previousContent.split('.')[0], 10) : 0;
|
||||||
@ -325,16 +324,6 @@ class Wysiwyg extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange = (editorState) => {
|
|
||||||
// Update the state and force the focus
|
|
||||||
this.setState({ editorState }, () => { this.focus(); });
|
|
||||||
this.props.onChange({ target: {
|
|
||||||
value: editorState.getCurrentContent().getPlainText(),
|
|
||||||
name: this.props.name,
|
|
||||||
type: 'textarea',
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
|
|
||||||
mapKeyToEditorCommand = (e) => {
|
mapKeyToEditorCommand = (e) => {
|
||||||
if (e.keyCode === 9 /* TAB */) {
|
if (e.keyCode === 9 /* TAB */) {
|
||||||
const newEditorState = RichUtils.onTab(
|
const newEditorState = RichUtils.onTab(
|
||||||
@ -351,6 +340,16 @@ class Wysiwyg extends React.Component {
|
|||||||
return getDefaultKeyBinding(e);
|
return getDefaultKeyBinding(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onChange = (editorState) => {
|
||||||
|
// Update the state and force the focus
|
||||||
|
this.setState({ editorState }, () => { this.focus(); });
|
||||||
|
this.props.onChange({ target: {
|
||||||
|
value: editorState.getCurrentContent().getPlainText(),
|
||||||
|
name: this.props.name,
|
||||||
|
type: 'textarea',
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: this need to be changed to preview markdown
|
// NOTE: this need to be changed to preview markdown
|
||||||
previewHTML = () => {
|
previewHTML = () => {
|
||||||
const blocksFromHTML = convertFromHTML(this.props.value);
|
const blocksFromHTML = convertFromHTML(this.props.value);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user