Skip to content

Commit

Permalink
Added a handler to disable read-only mode when DOMContentLoaded fires
Browse files Browse the repository at this point in the history
  • Loading branch information
Zaydek Michels-Gualtieri committed Jul 5, 2020
1 parent c81c072 commit 4296f52
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 227 deletions.
52 changes: 33 additions & 19 deletions src/Editor/Editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ const Editor = ({ markup, children }) => {

const [state, dispatch] = useEditor({ markup, children })

// Disables read-only mode on DOMContentLoaded.
React.useEffect(() => {
const handler = e => {
dispatch.disableReadOnlyMode()
}
document.addEventListener("DOMContentLoaded", handler)
return () => {
document.removeEventListener("DOMContentLoaded", handler)
}
}, [dispatch])

// Renders UI on state.shouldRender.
React.useLayoutEffect(
React.useCallback(() => {
// https://bugs.chromium.org/p/chromium/issues/detail?id=138439#c10
Expand All @@ -44,17 +56,19 @@ const Editor = ({ markup, children }) => {
const domRange = Range.toDOMRange(state.range)
domSelection.addRange(domRange)
} catch (error) {
console.error(error)
console.error({
range: state.range,
error,
})
}
})
}, [state, dispatch]),
[state.shouldRender],
)

// Exclusively returns a handler when the editor is
// unlocked; returns undefined when the editor is locked.
const newUnlockedHandler = handler => {
if (state.locked) {
// Exclusively returns a handler when state.readOnly=true.
const newReadWriteHandler = handler => {
if (state.readOnly) {
return undefined
}
return handler
Expand All @@ -78,19 +92,19 @@ const Editor = ({ markup, children }) => {
tabSize: 4,
}}

onFocus={newUnlockedHandler(e => {
onFocus={newReadWriteHandler(e => {
dispatch.focus()
})}

onBlur={newUnlockedHandler(e => {
onBlur={newReadWriteHandler(e => {
dispatch.blur()
})}

onPointerDown={newUnlockedHandler(e => {
onPointerDown={newReadWriteHandler(e => {
pointerdownRef.current = true
})}

onPointerMove={newUnlockedHandler(e => {
onPointerMove={newReadWriteHandler(e => {
if (!state.focused) {
pointerdownRef.current = false
return
Expand All @@ -107,13 +121,13 @@ const Editor = ({ markup, children }) => {
dispatch.select(range)
})}

onPointerUp={newUnlockedHandler(e => {
onPointerUp={newReadWriteHandler(e => {
pointerdownRef.current = false
})}

// TODO: Add COMPAT guard for select-all or prevent
// default?
onSelect={newUnlockedHandler(e => {
onSelect={newReadWriteHandler(e => {
const range = Range.compute(ref.current)
if (!range) {
// No-op
Expand All @@ -122,7 +136,7 @@ const Editor = ({ markup, children }) => {
dispatch.select(range)
})}

onKeyDown={newUnlockedHandler(e => {
onKeyDown={newReadWriteHandler(e => {
const keydownT = keydown.detectType(e)
if (keydownT) {
console.log(keydownT)
Expand Down Expand Up @@ -208,33 +222,33 @@ const Editor = ({ markup, children }) => {
}
})}

onInput={newUnlockedHandler(e => {
onInput={newReadWriteHandler(e => {
const collapsed = Range.collapse(Range.compute(ref.current)) // Takes precedence
const spans = Readers.rendered.spans(document.getElementById(collapsed[0].key))
dispatch.uncontrolledInputHandler(spans, collapsed)
})}

onCut={newUnlockedHandler(e => {
onCut={newReadWriteHandler(e => {
e.preventDefault()
// TODO: e.clipboardData.setData("text/plain", ...)
})}

onCopy={newUnlockedHandler(e => {
onCopy={newReadWriteHandler(e => {
e.preventDefault()
// TODO: e.clipboardData.setData("text/plain", ...)
})}

onPaste={newUnlockedHandler(e => {
onPaste={newReadWriteHandler(e => {
e.preventDefault()
// TODO: e.clipboardData.getData("text/plain")
})}

onDragStart={newUnlockedHandler(e => {
onDragStart={newReadWriteHandler(e => {
e.preventDefault()
})}

contentEditable={!state.locked}
suppressContentEditableWarning={!state.locked}
contentEditable={!state.readOnly}
suppressContentEditableWarning={!state.readOnly}
/>

{/* Debugger */}
Expand Down
189 changes: 0 additions & 189 deletions src/Editor/notes.js

This file was deleted.

10 changes: 3 additions & 7 deletions src/Editor/useEditor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,11 @@ import useMethods from "use-methods"
// this.select(collapsed)
// render(state)()
// },
// input(spans, collapsed) {
// const element = state.elements.find(each => each.key === collapsed[0].key)
// element.props.spans = spans
// this.select(collapsed)
// render(state)()
// },

const init = elements => ({
locked: false,
// NOTE: The DOM event "DOMContentLoaded" fires
// dispatch.enableReadOnlyMode.
readOnly: true,
elements,
focused: false,
range: {
Expand Down
19 changes: 7 additions & 12 deletions src/Editor/useEditor/methods.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import $delete from "./delete"
import applyFormat from "./applyFormat"

// TODO: Add findElementOrNode API or equivalent?
const methods = state => ({
// Locks the editor; disables future edits. Unlike blur,
// lock is expected to remove the DOM attribute
// contenteditable.
lock() {
state.locked = true
},
// Unlocks the editor; enables future edits. Unlike focus,
// unlock is expected to add the DOM attribute
// contenteditable.
unlock() {
state.locked = false
// Enables read-only mode; disables future edits.
enableReadOnlyMode() {
state.readOnly = true
},
// Disables read-only mode; enables future edits.
disableReadOnlyMode() {
state.readOnly = false
},
// Focuses the editor. When the editor is focused, editing
// operations are expected to work.
Expand Down

0 comments on commit 4296f52

Please sign in to comment.