From 4e3ecd8336e1bfba0595158e7fcf39ed131b212a Mon Sep 17 00:00:00 2001 From: Zaydek Michels-Gualtieri Date: Fri, 26 Jun 2020 06:59:19 +0900 Subject: [PATCH] Finished extracting backspace --- src/Editor/Iterators/index.js | 4 +-- src/Editor/backspace/backspace.js | 18 +++++----- src/Editor/backspace/dropCursors.js | 54 ++++++++++------------------- src/Editor/useEditor.js | 17 ++++----- 4 files changed, 34 insertions(+), 59 deletions(-) diff --git a/src/Editor/Iterators/index.js b/src/Editor/Iterators/index.js index 45c8aef..49bb966 100644 --- a/src/Editor/Iterators/index.js +++ b/src/Editor/Iterators/index.js @@ -1,7 +1,7 @@ import * as emojiTrie from "emoji-trie" import * as UTF8 from "lib/encoding/UTF8" -// Right-to-left (RTL) iterator; returns a substring. +// Right-to-left iterator; returns a substring. export const RTL = { rune(str) { // return emojiTrie.atEnd(str)?.emoji || UTF8.atEnd(str) @@ -70,7 +70,7 @@ export const RTL = { }, } -// Left-to-right (LTR) iterator; returns a substring. +// Left-to-right iterator; returns a substring. export const LTR = { rune(str) { // return emojiTrie.atStart(str)?.emoji || UTF8.atStart(str) diff --git a/src/Editor/backspace/backspace.js b/src/Editor/backspace/backspace.js index 6342268..55077b9 100644 --- a/src/Editor/backspace/backspace.js +++ b/src/Editor/backspace/backspace.js @@ -7,7 +7,7 @@ import must from "lib/must" // Returns the next right-to-left cursor for a boundary. function nextRTLCursor(elements, { ...rtl }, boundary) { const y = must(elements.findIndex(each => each.key === rtl.key)) - const substr = Spans.textContent(elements[y].props.children).slice(0, rtl.offset) + const textContent = Spans.textContent(elements[y].props.children) if (!rtl.offset && y) { Object.assign(rtl, { key: elements[y - 1].key, @@ -15,26 +15,24 @@ function nextRTLCursor(elements, { ...rtl }, boundary) { }) return rtl } - // const runes = Iterators.RTL[boundary](substr) // DEBUG - // rtl.offset -= runes.length // DEBUG - rtl.offset -= Iterators.RTL[boundary](substr).length + const substr = Iterators.RTL[boundary](textContent.slice(0, rtl.offset)) + rtl.offset -= substr.length return rtl } // Returns the next left-to-right cursor for a boundary. function nextLTRCursor(elements, { ...ltr }, boundary) { const y = must(elements.findIndex(each => each.key === ltr.key)) - const substr = Spans.textContent(elements[y].props.children).slice(ltr.offset) - if (ltr.offset === substr.length && y + 1 < elements.length) { + const textContent = Spans.textContent(elements[y].props.children) + if (ltr.offset === textContent.length && y + 1 < elements.length) { Object.assign(ltr, { key: elements[y + 1].key, - offset: Spans.textContent(elements[y + 1].props.children).length, + offset: 0, }) return ltr } - // const runes = Iterators.LTR[boundary](substr) // DEBUG - // ltr.offset += runes.length // DEBUG - ltr.offset += Iterators.LTR[boundary](substr).length + const substr = Iterators.LTR[boundary](textContent.slice(ltr.offset)) + ltr.offset += substr.length return ltr } diff --git a/src/Editor/backspace/dropCursors.js b/src/Editor/backspace/dropCursors.js index cb33d4b..3ff6617 100644 --- a/src/Editor/backspace/dropCursors.js +++ b/src/Editor/backspace/dropCursors.js @@ -3,37 +3,14 @@ import * as Spans from "../Spans" import JSONClone from "lib/JSONClone" import must from "lib/must" -// // Returns the span and character offsets for an array of -// // spans at an offset. -// function computeSpanOffsets(spans, offset) { -// const offsets = { -// span: 0, -// char: 0, -// } -// -// let x = 0 -// for (; x < spans.length; x++) { -// const children = spans[x].props.children -// if (offset - children.length <= 0) { -// Object.assign(offsets, { -// span: x, -// char: offset, -// }) -// return offsets -// } -// offset -= children.length -// } -// return null -// } - // Returns the span and character offsets for an array of // spans at an offset. -function computeSpanOffsets(spans, offset) { +function Span_offsets(spans, offset) { // TODO let x = 0 for (; x < spans.length; x++) { const children = spans[x].props.children if (offset - children.length <= 0) { - return { span: x, char: offset } + return [x, offset] } offset -= children.length } @@ -43,16 +20,16 @@ function computeSpanOffsets(spans, offset) { // Drops a number of characters from an array of spans at an // offset. Returns the number of characters dropped. function dropChars(spans, offset, nchars) { - const offsets = must(computeSpanOffsets(spans, offset)) - if (nchars > offsets.char) { - nchars = offsets.char + const offsets = must(Span_offsets(spans, offset)) + if (nchars > offsets[1]) { + nchars = offsets[1] } - spans[offsets.span].props.children = ( - spans[offsets.span].props.children.slice(0, offsets.char - nchars) + - spans[offsets.span].props.children.slice(offsets.char) + spans[offsets[0]].props.children = ( + spans[offsets[0]].props.children.slice(0, offsets[1] - nchars) + + spans[offsets[0]].props.children.slice(offsets[1]) ) - if (!spans[offsets.span].props.children) { - spans.splice(offsets.span, 1) + if (!spans[offsets[0]].props.children) { + spans.splice(offsets[0], 1) } Spans.defer(spans) return nchars @@ -61,11 +38,16 @@ function dropChars(spans, offset, nchars) { // Counts the number of characters between the offsets of a // set of cursors. function nchars(cursors) { - const nchars = 0 + let nchars = 0 if (cursors[0].key === cursors[1].key) { - return cursors[1].offset - cursors[0].offset + // Hello, [world]! + nchars = cursors[1].offset - cursors[0].offset + } else { + // Hello, world! + // [Hello, world]! + nchars = cursors[1].offset } - return cursors[1].offset + return nchars } // Drops the characters between a set of cursors. diff --git a/src/Editor/useEditor.js b/src/Editor/useEditor.js index e23c38a..a00adbc 100644 --- a/src/Editor/useEditor.js +++ b/src/Editor/useEditor.js @@ -1,6 +1,6 @@ import * as Cursors from "./Cursors" import * as Elements from "./Elements" -import backspaceHandler from "./backspace" +import backspace from "./backspace" import must from "lib/must" import newHashID from "lib/newHashID" import React from "react" @@ -106,32 +106,27 @@ const methods = state => ({ // }, backspaceRTLRune() { - const { elements, cursors } = state - const collapsed = backspaceHandler(elements, cursors, "rtl", "rune") + const collapsed = backspace(state.elements, state.cursors, "rtl", "rune") this.select(collapsed) this.render() }, backspaceRTLWord() { - const { elements, cursors } = state - const collapsed = backspaceHandler(elements, cursors, "rtl", "word") + const collapsed = backspace(state.elements, state.cursors, "rtl", "word") this.select(collapsed) this.render() }, backspaceRTLLine() { - const { elements, cursors } = state - const collapsed = backspaceHandler(elements, cursors, "rtl", "line") + const collapsed = backspace(state.elements, state.cursors, "rtl", "line") this.select(collapsed) this.render() }, backspaceLTRRune() { - const { elements, cursors } = state - const collapsed = backspaceHandler(elements, cursors, "ltr", "rune") + const collapsed = backspace(state.elements, state.cursors, "ltr", "rune") this.select(collapsed) this.render() }, backspaceLTRWord() { - const { elements, cursors } = state - const collapsed = backspaceHandler(elements, cursors, "ltr", "word") + const collapsed = backspace(state.elements, state.cursors, "ltr", "word") this.select(collapsed) this.render() },