Lightly parse state.data
; should end up with:
-
<Any>
-
<Blockquote>
-
<Preformatted>
-
<AnyList>
-
parseAny
-
<Header>
-
<Paragraph>
-
<Break>
-
-
parseBlockquote
-
parsePreformatted
-
parseAnyList
-
So what we’re essentially doing is a breaking up the job of the parser into smaller tasks. We parse the elements based on their greediness and then pass them off to functions which resolve the actual components. The interesting aspect of all of this is that before we hand off components to the resolves, we can cache them for later reuse. Cached elements must not persist IDs.
We can even extract the parser into it’s own module;
-
parser/
-
/test
: Tests elements -
/elements
: Parses elements -
/parseElements
: Main parser
-
data=1
reactVDOM=8 // Can be optimized with a cache
ReactEditor=1
ReactDOM.render=133 // Much lower in production (<20ms or something)
syncDOM=1 // Can be micro-optimized with diffing -- we want this
syncDOMPos=11 // Can be optimized with vdom most likely
computePosRange=5 // Can be optimized with vdom most likely
So we can probably shave off 8 + 1 + 11 + 5
or ~25ms
, maybe more like 20ms
all things considered.
syncDOMPos
and computePosRange
are actually redundant. Since we’re always using syncDOMPos
, we probably can factor out computePosRange
altogether, because we’re already computing the pos
.
What is a component?
Components are UI elements that can be reused across your designs. They help you to create and manage consistent designs across projects. When we create a component, it’s actually your “parent” component and if you create a few copies from it, they are your “child” components.
What is difference between the “Parent” component and “Child” component?
You got some of your traits from your parents (DNA). When you create a “Parent” component (Figma calls it “Master” component), “Child” components will get its styles and when you apply some changes to the parent component, those changes will be applied to the “child” components too, whereas if you apply some changes to the “child” components, “parent” component will be remained unchanged.
Imagine you bought a PC, this PC has different parts including Processor (CPU), Graphic Card, Fan, Ram, Hard Drive (or SSD) and…. So when you want to build a new PC, you need to buy these parts.
- Fix numbered lists
- Can use number for
typeEnum
;NumberEnum
or equivalent - Maybe we can use
nodes
as keys? Maybe not, because we have to deal with proxies - Implement less-naive LRU cache implementation
- Not obviously faster and potentially harder to debug, not sure about this
- The complaint about using a naive implementation is that it clears entries on every pass, which seems wasteful
- Added an optional clean up function to purge the cache
- Not obviously faster and potentially harder to debug, not sure about this
Should we clear the cache when a user navigates away from the page? We just use clear. 🤔
- Would prefer to rename
reactVDOM
toelements
- We need to override previously parsed keys deeply
- Just missing lists because they’re nested and recursive
- Can we use ints for
typeEnums
?- We want strings for normal cases like
EditorApp
, but we can use numbers (ints
) everywhere else - Introduced
typeEnumArray
pattern
- We want strings for normal cases like
- Optimize pos
operations
-- can rely on VDOM and maybe evengetElementById
? In the least, we can probably cutdispatch.select
fromuseLayoutEffect
- Diff in
syncDOM
-- needed for checkboxes - Parsing lists is a little bit off
- We need to parse separate lists
- So the parser is actually fine -- it looks like the problem has to do with CSS
- Scroll handlers look off
- Scroll overflow may be confusing
- Persist readme?
- Make possible to make
font-size
smaller - Let’s try blue for
code
-
Blockquotes look a little off - Images
-
<iframe>
and<embed>
?- Can do later
-
- Scroll into view
- Implementation is slightly different for container editors and in general, but the current implementation solves for both situations by returning a
scrollingElement
- Fix
useLayoutEffect
dependencies
- Implementation is slightly different for container editors and in general, but the current implementation solves for both situations by returning a
- Better undo
- Pending Egon’s response: https://codepen.io/zaydek/pen/qBOppQe?editors=1010
- Good enough
- Drop special
pos
behavior because it’s confusing and almost never relevant - Implement
UndoManager
pattern -- need to make sure it works with Proxies, etc.
- Pending Egon’s response: https://codepen.io/zaydek/pen/qBOppQe?editors=1010
- Select-all bug (seems to exclusively affect Firefox)
- Test iOS
- General tests
- Need far more tests now
var myself = { name: 'Tom' };
// clone myself, to ensure that changing someoneElse doesn't
// mutate it.
var someoneElse = JSON.parse(JSON.stringify(myself));
myself.name = 'Thomas';
Do later:
-
Progress indicator?
-
Block-level shortcuts?
-
Quality-of-life shortcuts (e.g.
ctrl-x
) -
Monospace
- This is perfect for a pro feature
- Also custom colors
- Dark mode could be a pro feature
-
Unlimited notes
-
Custom font and stylesheet
-
HTML code
-
Scratch paper?