Skip to content

Commit 9ae76bd

Browse files
author
Zaydek Michels-Gualtieri
committed
Fixed several bugs, including why MemoHighlight rendered nothing
1 parent 8d9ab13 commit 9ae76bd

8 files changed

Lines changed: 198 additions & 173 deletions

File tree

src/EditorApp/EditorApp.js

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import ctrlOrCmd from "lib/Client/ctrlOrCmd"
2-
import DebouncedElementsContext from "./DebouncedElementsContext"
32
import DispatchContext from "./DispatchContext"
3+
import keyCodeFor from "lib/Client/keyCodeFor"
44
import MemoFixedBottomWYSIWYGMenu from "./MemoFixedBottomWYSIWYGMenu"
55
import MemoFixedTopPreferences from "./MemoFixedTopPreferences"
6+
import PrefsDispatchContext from "./PrefsDispatchContext"
67
import React from "react"
8+
import useKeydown from "lib/x/handlers/useKeydown"
9+
import usePreferences from "./usePreferences"
710

811
import {
912
Editor,
@@ -12,16 +15,13 @@ import {
1215

1316
const App = () => {
1417
const [state, dispatch] = useEditor()
18+
const [prefs, prefsDispatch] = usePreferences(() => state.elements)
1519

16-
// NOTE: readOnlyMode is a synthetic property of an
17-
// editor. Read-only mode can be enabled and disabled by
18-
// toggling contenteditable on the editor element.
19-
const [readOnlyMode, setReadOnlyMode] = React.useState(false)
2020
const [debouncedElements, setDebouncedElements] = React.useState(() => state.elements)
2121

2222
// Debounces elements by 50 milliseconds.
2323
React.useEffect(() => {
24-
if (!readOnlyMode) {
24+
if (!prefs.show || (prefs.show && prefs.desc === "releases")) {
2525
// No-op
2626
return
2727
}
@@ -33,20 +33,63 @@ const App = () => {
3333
}
3434
}, [
3535
state.elements,
36-
readOnlyMode,
36+
prefs.show,
37+
prefs.desc,
3738
])
3839

40+
// NOTE: prefs.readOnlyMode is a synthetic property of an
41+
// editor. Read-only mode can be enabled and disabled by
42+
// toggling contenteditable on the editor element.
43+
React.useEffect(() => {
44+
const article = document.getElementById("main-editor")
45+
article.contentEditable = !prefs.readOnlyMode
46+
}, [prefs.readOnlyMode])
47+
48+
React.useLayoutEffect(() => {
49+
if (state.show && state.desc === "markdown") {
50+
prefsDispatch({
51+
type: "UPDATE_MARKDOWN",
52+
elements: debouncedElements,
53+
})
54+
}
55+
}, [
56+
debouncedElements,
57+
state.show,
58+
state.desc,
59+
prefsDispatch,
60+
])
61+
62+
React.useLayoutEffect(() => {
63+
if (state.show && state.desc === "markup") {
64+
prefsDispatch({
65+
type: "UPDATE_MARKUP",
66+
elements: debouncedElements,
67+
})
68+
}
69+
}, [
70+
debouncedElements,
71+
state.show,
72+
state.desc,
73+
prefsDispatch,
74+
])
75+
76+
// Binds the next keydown event to hide output.
77+
useKeydown(e => {
78+
if (e.keyCode === keyCodeFor("Escape")) {
79+
prefsDispatch({
80+
type: "HIDE_ALL",
81+
})
82+
}
83+
})
84+
3985
return (
40-
<DebouncedElementsContext.Provider value={debouncedElements}>
41-
<DispatchContext.Provider value={dispatch}>
86+
<DispatchContext.Provider value={dispatch}>
87+
<PrefsDispatchContext.Provider value={prefsDispatch}>
4288

4389
<div className="px-6 py-32 flex flex-row justify-center h-full">
4490
<div className="w-full max-w-2xl h-full">
4591

46-
<MemoFixedTopPreferences
47-
readOnlyMode={readOnlyMode}
48-
setReadOnlyMode={setReadOnlyMode}
49-
/>
92+
<MemoFixedTopPreferences prefs={prefs} />
5093

5194
<div className="relative h-full">
5295
{(state.elements.length === 1 && !state.elements[0].props.children.length) && (
@@ -84,16 +127,15 @@ const App = () => {
84127
</div>
85128

86129
<MemoFixedBottomWYSIWYGMenu
87-
readOnlyMode={readOnlyMode}
88-
setReadOnlyMode={setReadOnlyMode}
130+
readOnlyMode={prefs.readOnlyMode}
89131
rangeTypes={state.rangeTypes}
90132
/>
91133

92134
</div>
93135
</div>
94136

95-
</DispatchContext.Provider>
96-
</DebouncedElementsContext.Provider>
137+
</PrefsDispatchContext.Provider>
138+
</DispatchContext.Provider>
97139
)
98140
}
99141

src/EditorApp/MemoFixedBottomWYSIWYGMenu/MemoFixedBottomWYSIWYGMenu.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ import React from "react"
33
import Transition from "lib/x/Transition"
44
import WYSIWYGMenu from "./WYSIWYGMenu"
55

6+
function areEqual(prev, next) {
7+
const ok = (
8+
prev.prefs === next.prefs &&
9+
JSONEqual(prev.rangeTypes, next.rangeTypes)
10+
)
11+
return ok
12+
}
13+
614
const MemoFixedBottomWYSIWYGMenu = React.memo(({ readOnlyMode, rangeTypes }) => (
715
<Transition
816
on={!readOnlyMode}
@@ -18,12 +26,6 @@ const MemoFixedBottomWYSIWYGMenu = React.memo(({ readOnlyMode, rangeTypes }) =>
1826
</div>
1927
</aside>
2028
</Transition>
21-
), (prev, next) => {
22-
const ok = (
23-
prev.readOnlyMode === next.readOnlyMode &&
24-
JSONEqual(prev.rangeTypes, next.rangeTypes)
25-
)
26-
return ok
27-
})
29+
), areEqual)
2830

2931
export default MemoFixedBottomWYSIWYGMenu

src/EditorApp/MemoFixedTopPreferences/MemoFixedTopPreferences.js

Lines changed: 29 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,20 @@
1-
import DebouncedElementsContext from "../DebouncedElementsContext"
2-
import keyCodeFor from "lib/Client/keyCodeFor"
31
import MemoHighlight from "lib/PrismJS/MemoHighlight"
2+
import PrefsDispatchContext from "../PrefsDispatchContext"
43
import React from "react"
54
import Releases from "./Releases"
65
import tabSize from "lib/x/tabSize"
76
import Transition from "lib/x/Transition"
8-
import useKeydown from "lib/x/handlers/useKeydown"
9-
import usePreferences from "./usePreferences"
107

118
import {
129
AbsoluteBottomLeftToolTip as TooltipL,
1310
AbsoluteBottomRightToolTip as TooltipR,
1411
} from "../Tooltips"
1512

16-
const MemoFixedTopPreferences = React.memo(({ readOnlyMode, setReadOnlyMode }) => {
17-
const debouncedElements = React.useContext(DebouncedElementsContext)
13+
const MemoFixedTopPreferences = React.memo(({ prefs }) => {
14+
const dispatch = React.useContext(PrefsDispatchContext)
1815

19-
const [state, dispatch] = usePreferences(debouncedElements)
2016
const [tooltip, setTooltip] = React.useState("")
2117

22-
React.useEffect(() => {
23-
const article = document.getElementById("main-editor")
24-
article.contentEditable = !readOnlyMode
25-
}, [readOnlyMode])
26-
27-
React.useLayoutEffect(() => {
28-
if (state.show && state.desc === "gfm") {
29-
dispatch({
30-
type: "UPDATE_GFM",
31-
elements: debouncedElements,
32-
})
33-
}
34-
}, [
35-
debouncedElements,
36-
state.show,
37-
state.desc,
38-
dispatch,
39-
])
40-
41-
React.useLayoutEffect(() => {
42-
if (state.show && state.desc === "html") {
43-
dispatch({
44-
type: "UPDATE_HTML",
45-
elements: debouncedElements,
46-
})
47-
}
48-
}, [
49-
debouncedElements,
50-
state.show,
51-
state.desc,
52-
dispatch,
53-
])
54-
55-
// Binds the next keydown event to hide output.
56-
useKeydown(e => {
57-
if (e.keyCode === keyCodeFor("Escape")) {
58-
dispatch({
59-
type: "CLOSE_ALL",
60-
})
61-
}
62-
})
63-
6418
// NOTE: Uses flex flex-col items-end because of <aside>.
6519
return (
6620
<div className="px-3 pb-8 fixed inset-0 flex flex-col items-end z-10 pointer-events-none">
@@ -72,22 +26,26 @@ const MemoFixedTopPreferences = React.memo(({ readOnlyMode, setReadOnlyMode }) =
7226

7327
<button
7428
className="p-2 relative text-gray-400 hover:text-gray-800 focus:text-gray-800 focus:outline-none transition duration-200 ease-in-out pointer-events-auto"
75-
style={{ color: readOnlyMode && "var(--gray-800)" }}
29+
style={{ color: prefs.readOnlyMode && "var(--gray-800)" }}
7630
onFocus={e => setTooltip("lock")}
7731
onBlur={e => setTooltip("")}
7832
onMouseEnter={e => setTooltip("lock")}
7933
onMouseLeave={e => setTooltip("")}
80-
onClick={e => setReadOnlyMode(!readOnlyMode)}
34+
onClick={e => {
35+
dispatch({
36+
type: "TOGGLE_READ_ONLY_MODE",
37+
})
38+
}}
8139
>
82-
{(!state.show && tooltip === "lock") && (
40+
{(!prefs.show && tooltip === "lock") && (
8341
<TooltipL>
8442
<p className="text-xs whitespace-pre text-gray-100">
85-
{!readOnlyMode ? "Enable Read-Only Mode" : "Disable Read-Only Mode"}
43+
{!prefs.readOnlyMode ? "Enable Read-Only Mode" : "Disable Read-Only Mode"}
8644
</p>
8745
</TooltipL>
8846
)}
8947
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
90-
{!readOnlyMode
48+
{!prefs.readOnlyMode
9149
? <path d="M10 2a5 5 0 00-5 5v2a2 2 0 00-2 2v5a2 2 0 002 2h10a2 2 0 002-2v-5a2 2 0 00-2-2H7V7a3 3 0 015.905-.75 1 1 0 001.937-.5A5.002 5.002 0 0010 2z" />
9250
: <path d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clipRule="evenodd" fillRule="evenodd" />
9351
}
@@ -101,7 +59,7 @@ const MemoFixedTopPreferences = React.memo(({ readOnlyMode, setReadOnlyMode }) =
10159

10260
<button
10361
className="p-2 relative text-gray-400 hover:text-gray-800 focus:text-gray-800 focus:outline-none transition duration-200 ease-in-out pointer-events-auto"
104-
style={{ color: state.show && state.desc === "releases" && "var(--gray-800)" }}
62+
style={{ color: prefs.show && prefs.desc === "releases" && "var(--gray-800)" }}
10563
onFocus={e => setTooltip("releases")}
10664
onBlur={e => setTooltip("")}
10765
onMouseEnter={e => setTooltip("releases")}
@@ -112,7 +70,7 @@ const MemoFixedTopPreferences = React.memo(({ readOnlyMode, setReadOnlyMode }) =
11270
})
11371
}}
11472
>
115-
{(!state.show && tooltip === "releases") && (
73+
{(!prefs.show && tooltip === "releases") && (
11674
<TooltipR>
11775
<p className="text-xs whitespace-pre text-gray-100">
11876
View Releases
@@ -127,18 +85,18 @@ const MemoFixedTopPreferences = React.memo(({ readOnlyMode, setReadOnlyMode }) =
12785

12886
<button
12987
className="p-2 relative text-gray-400 hover:text-gray-800 focus:text-gray-800 focus:outline-none transition duration-200 ease-in-out pointer-events-auto"
130-
style={{ color: state.show && state.desc === "gfm" && "var(--gray-800)" }}
131-
onFocus={e => setTooltip("gfm")}
88+
style={{ color: prefs.show && prefs.desc === "markdown" && "var(--gray-800)" }}
89+
onFocus={e => setTooltip("markdown")}
13290
onBlur={e => setTooltip("")}
133-
onMouseEnter={e => setTooltip("gfm")}
91+
onMouseEnter={e => setTooltip("markdown")}
13492
onMouseLeave={e => setTooltip("")}
13593
onClick={e => {
13694
dispatch({
137-
type: "TOGGLE_GFM",
95+
type: "TOGGLE_MARKDOWN",
13896
})
13997
}}
14098
>
141-
{(!state.show && tooltip === "gfm") && (
99+
{(!prefs.show && tooltip === "markdown") && (
142100
<TooltipR>
143101
<p className="text-xs whitespace-pre text-gray-100">
144102
Show GitHub Flavored Markdown
@@ -152,18 +110,18 @@ const MemoFixedTopPreferences = React.memo(({ readOnlyMode, setReadOnlyMode }) =
152110

153111
<button
154112
className="p-2 relative text-gray-400 hover:text-gray-800 focus:text-gray-800 focus:outline-none transition duration-200 ease-in-out pointer-events-auto"
155-
style={{ color: state.show && state.desc === "html" && "var(--gray-800)" }}
156-
onFocus={e => setTooltip("html")}
113+
style={{ color: prefs.show && prefs.desc === "markup" && "var(--gray-800)" }}
114+
onFocus={e => setTooltip("markup")}
157115
onBlur={e => setTooltip("")}
158-
onMouseEnter={e => setTooltip("html")}
116+
onMouseEnter={e => setTooltip("markup")}
159117
onMouseLeave={e => setTooltip("")}
160118
onClick={e => {
161119
dispatch({
162-
type: "TOGGLE_HTML",
120+
type: "TOGGLE_MARKUP",
163121
})
164122
}}
165123
>
166-
{(!state.show && tooltip === "html") && (
124+
{(!prefs.show && tooltip === "markup") && (
167125
<TooltipR>
168126
<p className="text-xs whitespace-pre text-gray-100">
169127
Show HyperText Markup Language
@@ -180,12 +138,12 @@ const MemoFixedTopPreferences = React.memo(({ readOnlyMode, setReadOnlyMode }) =
180138
</div>
181139

182140
<Transition
183-
on={state.show}
141+
on={prefs.show}
184142
from="transition duration-200 ease-in opacity-0 transform -translate-y-4 pointer-events-none"
185143
to="transition duration-200 ease-out opacity-100 transform translate-y-0 pointer-events-auto"
186144
>
187145
<aside className="w-full max-w-lg max-h-full bg-white rounded-lg shadow-hero-lg overflow-y-scroll">
188-
{state.desc === "releases" ? (
146+
{prefs.desc === "releases" ? (
189147
<div className="text-gray-800">
190148
<Releases />
191149
</div>
@@ -196,13 +154,13 @@ const MemoFixedTopPreferences = React.memo(({ readOnlyMode, setReadOnlyMode }) =
196154
...tabSize(2),
197155
// NOTE: className="break-words" does not
198156
// work as expected.
199-
fontSize: state.desc === "html" && "0.8125rem",
157+
fontSize: prefs.desc === "markup" && "0.8125rem",
200158
wordBreak: "break-word",
201159
}}
202160
>
203161
<span className="inline-block min-w-full">
204-
<MemoHighlight extension={state.desc}>
205-
{state.rendered[state.desc]}
162+
<MemoHighlight extension={prefs.desc === "markdown" && prefs.desc !== "markup" ? "gfm" : "html"}>
163+
{prefs.resolved[prefs.desc]}
206164
</MemoHighlight>
207165
</span>
208166
</div>

0 commit comments

Comments
 (0)