Skip to content

Commit

Permalink
Move toggleWordWrap to helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
danielbrodin committed Oct 28, 2019
1 parent 9114858 commit 2b1d4fc
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 61 deletions.
67 changes: 8 additions & 59 deletions src/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import * as React from 'react';
import TextareaAutosize from 'react-autosize-textarea';
import { useMeasure } from './hooks/useMeasure';
import { useOnClickOutside } from './hooks/useOnClickOutside';
import { getWordAtPosition, getRowAtPosition, isCtrlCmd } from './helpers';
import {
getWordAtPosition,
getRowAtPosition,
isCtrlCmd,
toggleWordWrap,
} from './helpers';

type TextAreaProps = Omit<React.HTMLProps<HTMLTextAreaElement>, 'onChange'>;

Expand Down Expand Up @@ -62,62 +67,6 @@ type Action =
| BoldAction
| ItalicAction;

export function toggleWordWrap(
el: HTMLTextAreaElement,
value: string
): EditorData {
const caretStartingPosition: number = el.selectionStart;
const caretEndingPosition: number = el.selectionEnd;
const hasSelection: boolean = caretStartingPosition !== caretEndingPosition;
const [word, startPosition, endPosition] = getWordAtPosition(
el.value,
caretStartingPosition,
caretEndingPosition
);

const firstChars = word.substr(0, value.length);
const lastChars = word.substr(-value.length);
const beforeWord = el.value.substr(0, startPosition);
const afterWord = el.value.substr(endPosition, el.value.length);

if (firstChars !== value || lastChars !== value) {
el.value = `${beforeWord}${value}${word}${value}${afterWord}`;

if (hasSelection) {
el.setSelectionRange(
caretStartingPosition,
caretEndingPosition + value.length * 2
);
} else {
el.setSelectionRange(
caretStartingPosition + value.length,
caretEndingPosition + value.length
);
}

return getEditorData(el);
} else {
const updatedWord = word.substr(
value.length,
word.length - value.length * 2
);
el.value = `${beforeWord}${updatedWord}${afterWord}`;
if (hasSelection) {
el.setSelectionRange(
caretStartingPosition,
caretEndingPosition - value.length * 2
);
} else {
el.setSelectionRange(
caretStartingPosition - value.length,
caretEndingPosition - value.length
);
}

return getEditorData(el);
}
}

function getEditorData(
el: HTMLTextAreaElement,
insertStart?: string,
Expand Down Expand Up @@ -216,14 +165,14 @@ function reducer(state: State, action: Action) {
return {
...state,
editor: {
...toggleWordWrap(action.payload, '**'),
...getEditorData(toggleWordWrap(action.payload, '**')),
},
};
case 'ToggleItalic':
return {
...state,
editor: {
...toggleWordWrap(action.payload, '_'),
...getEditorData(toggleWordWrap(action.payload, '_')),
},
};
default:
Expand Down
54 changes: 54 additions & 0 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,57 @@ export function isCtrlCmd(event: KeyboardEvent): boolean {

return (isMacLike && event.metaKey) || (!isMacLike && event.ctrlKey);
}

export function toggleWordWrap(
el: HTMLTextAreaElement,
value: string
): HTMLTextAreaElement {
const caretStartingPosition: number = el.selectionStart;
const caretEndingPosition: number = el.selectionEnd;
const hasSelection: boolean = caretStartingPosition !== caretEndingPosition;
const [word, startPosition, endPosition] = getWordAtPosition(
el.value,
caretStartingPosition,
caretEndingPosition
);

const firstChars = word.substr(0, value.length);
const lastChars = word.substr(-value.length);
const beforeWord = el.value.substr(0, startPosition);
const afterWord = el.value.substr(endPosition, el.value.length);

if (firstChars !== value || lastChars !== value) {
el.value = `${beforeWord}${value}${word}${value}${afterWord}`;

if (hasSelection) {
el.setSelectionRange(
caretStartingPosition,
caretEndingPosition + value.length * 2
);
} else {
el.setSelectionRange(
caretStartingPosition + value.length,
caretEndingPosition + value.length
);
}
} else {
const updatedWord = word.substr(
value.length,
word.length - value.length * 2
);
el.value = `${beforeWord}${updatedWord}${afterWord}`;
if (hasSelection) {
el.setSelectionRange(
caretStartingPosition,
caretEndingPosition - value.length * 2
);
} else {
el.setSelectionRange(
caretStartingPosition - value.length,
caretEndingPosition - value.length
);
}
}

return el;
}
2 changes: 1 addition & 1 deletion test/helpers.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getWordAtPosition, getRowAtPosition } from '../src/helpers';

describe('getWordAtPosition', () => {
it('Returns the correct word att said position', () => {
it('Returns the correct word at said position', () => {
const words = ['lorem', 'ipsum', 'dolor'];
const position = Math.round(words[0].length + words[1].length / 2);
const [word, start, end] = getWordAtPosition(words.join(' '), position);
Expand Down
2 changes: 1 addition & 1 deletion test/toggleWordWrap.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';
import { render } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import { Editor } from '../src';
import { toggleWordWrap } from '../src';
import { toggleWordWrap } from '../src/helpers';

describe('toggleWordWrap', () => {
it('Wraps the word with no selection', async () => {
Expand Down

0 comments on commit 2b1d4fc

Please sign in to comment.