mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-20 15:27:45 +03:00
virtual-dom: create a Patch tag union
This commit is contained in:
parent
0cf9ba647c
commit
823aaa2c52
@ -1,12 +1,15 @@
|
||||
hosted Effect
|
||||
exposes [
|
||||
Effect,
|
||||
NodeId,
|
||||
EventHandlerId,
|
||||
TagName,
|
||||
AttrType,
|
||||
EventType,
|
||||
after,
|
||||
always,
|
||||
map,
|
||||
NodeId,
|
||||
EventHandlerId,
|
||||
eventHandlerId,
|
||||
createElement,
|
||||
createTextNode,
|
||||
updateTextNode,
|
||||
@ -24,22 +27,21 @@ hosted Effect
|
||||
imports []
|
||||
generates Effect with [after, always, map]
|
||||
|
||||
# TODO: private type
|
||||
# TODO: private types
|
||||
NodeId : Nat
|
||||
|
||||
EventHandlerId := Nat
|
||||
eventHandlerId = \id -> @EventHandlerId id
|
||||
EventHandlerId : Nat
|
||||
|
||||
# TODO: make these tag unions to avoid encoding/decoding standard names
|
||||
# but for now, this is much easier to code and debug!
|
||||
TagName : Str
|
||||
AttrType : Str
|
||||
EventType : Str
|
||||
|
||||
## createElement tagName
|
||||
createElement : TagName -> Effect NodeId
|
||||
createElement : NodeId, TagName -> Effect {}
|
||||
|
||||
## createTextNode content
|
||||
createTextNode : Str -> Effect NodeId
|
||||
createTextNode : NodeId, Str -> Effect {}
|
||||
|
||||
## updateTextNode content
|
||||
updateTextNode : NodeId, Str -> Effect {}
|
||||
|
@ -515,7 +515,8 @@ createSubTree = \previousEffects, node ->
|
||||
{ newHandlers, renderedNodes } <- previousEffects |> Effect.after
|
||||
when node is
|
||||
Element name size attrs children ->
|
||||
nodeIndex <- Effect.createElement name |> Effect.after
|
||||
nodeIndex = 0 # TODO: temporary hacks
|
||||
_ <- Effect.createElement nodeIndex name |> Effect.after
|
||||
{ style, newHandlers: newHandlersAttrs, renderedAttrs, effects: attrEffects } =
|
||||
List.walk attrs { nodeIndex, style: "", newHandlers, renderedAttrs: [], effects: Effect.always {} } addAttribute
|
||||
|
||||
@ -533,10 +534,9 @@ createSubTree = \previousEffects, node ->
|
||||
}
|
||||
|
||||
Text content ->
|
||||
Effect.createTextNode content
|
||||
|> Effect.map \nodeIndex ->
|
||||
|
||||
{ newHandlers, renderedNodes: List.append renderedNodes (RenderedText nodeIndex content) }
|
||||
nodeIndex = 0 # TODO: temporary hacks
|
||||
_ <- Effect.createTextNode nodeIndex content |> Effect.after
|
||||
Effect.always { newHandlers, renderedNodes: List.append renderedNodes (RenderedText nodeIndex content) }
|
||||
|
||||
None -> Effect.always { newHandlers, renderedNodes: List.append renderedNodes RenderedNone }
|
||||
|
||||
|
43
examples/virtual-dom-wip/platform/Html/Patch.roc
Normal file
43
examples/virtual-dom-wip/platform/Html/Patch.roc
Normal file
@ -0,0 +1,43 @@
|
||||
interface Html.Patch
|
||||
exposes [
|
||||
Patch,
|
||||
]
|
||||
imports [
|
||||
Effect.{
|
||||
Effect,
|
||||
NodeId,
|
||||
EventHandlerId,
|
||||
TagName,
|
||||
AttrType,
|
||||
EventType,
|
||||
},
|
||||
]
|
||||
|
||||
Patch : [
|
||||
CreateElement NodeId TagName,
|
||||
CreateTextNode NodeId Str,
|
||||
UpdateTextNode NodeId Str,
|
||||
AppendChild NodeId NodeId,
|
||||
RemoveNode NodeId,
|
||||
SetAttribute NodeId AttrType Str,
|
||||
RemoveAttribute NodeId AttrType,
|
||||
SetProperty NodeId Str (List U8),
|
||||
RemoveProperty NodeId Str,
|
||||
SetListener NodeId EventType EventHandlerId,
|
||||
RemoveListener NodeId EventType,
|
||||
]
|
||||
|
||||
apply : Patch -> Effect {}
|
||||
apply = \patch ->
|
||||
when patch is
|
||||
CreateElement nodeId tagName -> Effect.createElement nodeId tagName
|
||||
CreateTextNode nodeId content -> Effect.createTextNode nodeId content
|
||||
UpdateTextNode content -> Effect.updateTextNode content
|
||||
AppendChild parentId childId -> Effect.appendChild parentId childId
|
||||
RemoveNode id -> Effect.removeNode id
|
||||
SetAttribute nodeId attrName value -> Effect.setAttribute nodeId attrName value
|
||||
RemoveAttribute nodeId attrName -> Effect.removeAttribute nodeId attrName
|
||||
SetProperty nodeId propName json -> Effect.setProperty nodeId propName json
|
||||
RemoveProperty nodeId propName -> Effect.removeProperty nodeId propName
|
||||
SetListener nodeId eventType handlerId -> Effect.setListener nodeId eventType handlerId
|
||||
RemoveListener nodeId eventType -> Effect.removeListener nodeId eventType
|
@ -30,20 +30,22 @@ const roc_init = async (initData, wasmUrl) => {
|
||||
const effects = {
|
||||
/**
|
||||
* @param {number} tagAddr
|
||||
* @param {number} id
|
||||
*/
|
||||
createElement: (tagAddr) => {
|
||||
createElement: (tagAddr, id) => {
|
||||
const tagName = decodeRocStr(tagAddr);
|
||||
const node = document.createElement(tagName);
|
||||
return insertNode(node);
|
||||
nodes[id] = node;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {number} contentAddr
|
||||
* @param {number} id
|
||||
*/
|
||||
createTextNode: (contentAddr) => {
|
||||
createTextNode: (contentAddr, id) => {
|
||||
const content = decodeRocStr(contentAddr);
|
||||
const node = document.createTextNode(content);
|
||||
return insertNode(node);
|
||||
nodes[id] = node;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -239,18 +241,6 @@ const roc_init = async (initData, wasmUrl) => {
|
||||
return utf8Decoder.decode(bytes);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
*/
|
||||
const insertNode = (node) => {
|
||||
let i = 0;
|
||||
for (; i < nodes.length; i++) {
|
||||
if (!nodes[i]) break;
|
||||
}
|
||||
nodes[i] = node;
|
||||
return i;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {CyclicStructureAccessor} accessor
|
||||
* @param {any} structure
|
||||
|
Loading…
Reference in New Issue
Block a user