Skip to content

Commit cfab65c

Browse files
author
Zaydek Michels-Gualtieri
committed
Added an entirely new heuristic which seems to work
1 parent e706b29 commit cfab65c

File tree

3 files changed

+91
-91
lines changed

3 files changed

+91
-91
lines changed

src/Editor/Elements/Elements.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import { Strikethrough } from "./InlineElements"
1414
// React components.
1515
function toReact(children) {
1616
if (children === null || typeof children === "string") {
17-
return !children ? null : <span>{children}</span>
17+
// return !children ? null : <span>{children}</span>
18+
return children
1819
}
1920
const components = []
2021
for (const each of children) {

src/Editor/Elements/Markdown.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function parseSyntax(syntax) {
2020
}
2121

2222
const Syntax = ({ className, ...props }) => {
23-
return <span className={`markdown ${className || ""}`.trim()} {...props} />
23+
return <span className={`markdown ${className || ""}`.trim()} {...props} data-codex-markdown />
2424
}
2525

2626
const Markdown = ({ syntax, ...props }) => {

src/Editor/useEditor.js

Lines changed: 88 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as ascii from "lib/encoding/ascii"
22
import * as posIterators from "./posIterators"
33
import LRUCache from "lib/LRUCache"
44
import parseElements from "./parser/parseElements"
5+
import parseInlineElements from "./parser/parseInlineElements"
56
import UndoManager from "lib/UndoManager"
67
import useMethods from "use-methods"
78
import uuidv4 from "uuid/v4"
@@ -361,108 +362,106 @@ const methods = state => ({
361362
console.log("parseElements", Date.now() - t)
362363

363364
if (renderOpts.rerenderIfNeeded) {
364-
// Compares whether two children are equal. Character
365-
// data is not compared in order to preserve
366-
// spellcheck highlighting.
367365

368-
// const isUndefinedOrNull = value => {
369-
// return value === undefined || value === null
370-
// }
371-
372-
const isString = value => {
373-
return typeof value === "string"
374-
}
366+
let mustRerender = true
375367

376-
const isObject = value => {
377-
const ok = (
378-
typeof value === "object" &&
379-
!Array.isArray(value)
368+
let id = ""
369+
const selection = document.getSelection()
370+
if (selection.rangeCount) {
371+
const range = selection.getRangeAt(0)
372+
mustRerender = (
373+
(range.startContainer.nodeType === Node.TEXT_NODE && range.startOffset <= 1) ||
374+
ascendToElement(range.startContainer).getAttribute("data-codex-markdown")
380375
)
381-
return ok
376+
const root = ascendToElement(range.startContainer).closest("[data-codex-editor] > *")
377+
id = root.id || root.querySelector("[id]").id
382378
}
383-
384-
const isArray = value => {
385-
const ok = (
386-
typeof value === "object" &&
387-
Array.isArray(value)
388-
)
389-
return ok
379+
if (mustRerender) {
380+
const nextElement = nextElements.find(each => each.id === id)
381+
if (nextElement) {
382+
nextElement.reactKey = uuidv4().slice(0, 8)
383+
}
390384
}
391385

392-
// const areEqualChildrenObjects = (objectA, objectB) => {
386+
// const elements = parseInlineElements(state.nodes[state.pos1.y].data)
387+
// console.log(elements)
388+
389+
// // Compares whether two children are equal. Character
390+
// // data is not compared in order to preserve
391+
// // spellcheck highlighting.
392+
// const isString = value => {
393+
// return typeof value === "string"
394+
// }
395+
// const isObject = value => {
393396
// const ok = (
394-
// objectA.type === objectB.type &&
395-
// JSON.stringify(objectA.syntax) === JSON.stringify(objectB.syntax) &&
396-
// areEqualChildren(objectA.children, objectB.children)
397+
// typeof value === "object" &&
398+
// !Array.isArray(value)
397399
// )
398400
// return ok
399401
// }
400-
401-
const areEqualChildren = (childrenA, childrenB) => {
402-
if (childrenA === null || childrenB === null) {
403-
return childrenA === childrenB
404-
}
405-
406-
if (isString(childrenA) && isString(childrenB)) {
407-
return true
408-
} else if (isObject(childrenA) && isObject(childrenB)) {
409-
const ok = (
410-
childrenA.type === childrenB.type &&
411-
JSON.stringify(childrenA.syntax) === JSON.stringify(childrenB.syntax) &&
412-
areEqualChildren(childrenA.children, childrenB.children)
413-
)
414-
return ok
415-
}
416-
417-
if (!isArray(childrenA) || !isArray(childrenB) || childrenA.length !== childrenB.length) {
418-
return false
419-
}
420-
for (let x = 0; x < childrenA.length; x++) {
421-
if (!areEqualChildren(childrenA[x], childrenB[x])) {
422-
return false
423-
}
424-
}
425-
return true
426-
}
427-
428-
// Compares whether two elements are equal. Elements
429-
// are considered to be equal if their types, ID, and
430-
// children are equal.
431-
const areEqualElements = (elementA, elementB) => {
432-
const ok = (
433-
elementA.type === elementB.type &&
434-
elementA.id === elementB.id &&
435-
JSON.stringify(elementA.syntax) === JSON.stringify(elementB.syntax) &&
436-
areEqualChildren(elementA.children, elementB.children)
437-
)
438-
return ok
439-
}
440-
let id = ""
441-
const selection = document.getSelection()
442-
if (selection.rangeCount) {
443-
const range = selection.getRangeAt(0)
444-
const root = ascendToElement(range.startContainer).closest("[data-codex-editor] > *")
445-
id = root.id || root.querySelector("[id]").id
446-
}
402+
// const isArray = value => {
403+
// const ok = (
404+
// typeof value === "object" &&
405+
// Array.isArray(value)
406+
// )
407+
// return ok
408+
// }
409+
// const areEqualChildren = (childrenA, childrenB) => {
410+
// if (childrenA === null || childrenB === null) {
411+
// return childrenA === childrenB
412+
// }
413+
// if (isString(childrenA) && isString(childrenB)) {
414+
// return true
415+
// } else if (isObject(childrenA) && isObject(childrenB)) {
416+
// const ok = (
417+
// childrenA.type === childrenB.type &&
418+
// JSON.stringify(childrenA.syntax) === JSON.stringify(childrenB.syntax) &&
419+
// areEqualChildren(childrenA.children, childrenB.children)
420+
// )
421+
// return ok
422+
// }
423+
// if (!isArray(childrenA) || !isArray(childrenB) || childrenA.length !== childrenB.length) {
424+
// return false
425+
// }
426+
// for (let x = 0; x < childrenA.length; x++) {
427+
// if (!areEqualChildren(childrenA[x], childrenB[x])) {
428+
// return false
429+
// }
430+
// }
431+
// return true
432+
// }
433+
// // Compares whether two elements are equal. Elements
434+
// // are considered to be equal if their types, ID, and
435+
// // children are equal.
436+
// const areEqualElements = (elementA, elementB) => {
437+
// const ok = (
438+
// elementA.type === elementB.type &&
439+
// elementA.id === elementB.id &&
440+
// JSON.stringify(elementA.syntax) === JSON.stringify(elementB.syntax) &&
441+
// areEqualChildren(elementA.children, elementB.children)
442+
// )
443+
// return ok
444+
// }
445+
// let id = ""
446+
// const selection = document.getSelection()
447+
// if (selection.rangeCount) {
448+
// const range = selection.getRangeAt(0)
449+
// const root = ascendToElement(range.startContainer).closest("[data-codex-editor] > *")
450+
// id = root.id || root.querySelector("[id]").id
451+
// }
452+
// const substr = state.nodes[state.pos1.y].data.slice(state.pos1.x - 2, state.pos1.x + 1)
453+
// const mustRerender = false // substr
454+
// // .split("")
455+
// // .some(each => ascii.isPunctuation(each))
456+
// const prevElement = state.elements.find(each => each.id === id)
447457
// const nextElement = nextElements.find(each => each.id === id)
448-
// if (nextElement) {
458+
// if (prevElement && nextElement) {
459+
// if (areEqualElements(prevElement, nextElement)) {
460+
// // No-op
461+
// return
462+
// }
449463
// nextElement.reactKey = uuidv4().slice(0, 8)
450464
// }
451-
452-
const substr = state.nodes[state.pos1.y].data.slice(state.pos1.x - 2, state.pos1.x + 1)
453-
const mustRerender = false // substr
454-
// .split("")
455-
// .some(each => ascii.isPunctuation(each))
456-
457-
const prevElement = state.elements.find(each => each.id === id)
458-
const nextElement = nextElements.find(each => each.id === id)
459-
if (prevElement && nextElement) {
460-
if (areEqualElements(prevElement, nextElement)) {
461-
// No-op
462-
return
463-
}
464-
nextElement.reactKey = uuidv4().slice(0, 8)
465-
}
466465
}
467466

468467
Object.assign(state, {

0 commit comments

Comments
 (0)