Skip to content

Commit b940964

Browse files
authored
Key property (#30)
1 parent a84dce4 commit b940964

File tree

7 files changed

+30
-12
lines changed

7 files changed

+30
-12
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ _site/
1818
.jekyll-metadata
1919

2020
scratchpad.*
21+
scratchpadloader.*
2122

2223
.cache
2324

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"example-counters": "parcel build examples/NoEffects/Counters/counters.js -d examples/NoEffects/Counters/dist",
2323
"example-dice": "parcel build examples/EffectList/Dice/dice.js -d examples/EffectList/Dice/dist",
2424
"example-todo": "parcel build examples/EffectList/Todo/todo.js -d examples/EffectList/Todo/dist",
25-
"scratch": "parcel build test/scratchpad.js -d test/dist",
25+
"scratchpad": "parcel watch test/scratchpadloader.js -d test/dist",
2626
"webchat": "npm run example-webchat && node examples/Effectful/Webchat/dist/webchat-server.js",
2727
"server-side-rendering": "npm run example-server-side-rendering && node examples/EffectList/ServerSideRendering/dist/server-side-rendering-server.js",
2828
"build-examples": "npm run example-affjax-list && npm run example-webchat && npm run example-webchat && npm run example-affjax && npm run example-counter && npm run example-counters && npm run example-dice && npm run example-todo",

src/Flame/HTML/Attribute.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
module Flame.HTML.Attribute(module Exported) where
33

44
import Flame.HTML.Attribute.Internal (class ToClassList, ToBooleanAttribute, ToIntAttribute, ToNumberAttribute, ToStringAttribute,
5-
accentHeight, accept, acceptCharset, accessKey, accumulate, action, additive, align, alignmentBaseline, alt, ascent, autocomplete, autofocus, autoplay, azimuth, baseFrequency, baseProfile, baselineShift, begin, bias, calcMode, charset, checked, class', clipPathAttr, clipPathUnits, clipRule, color, colorInterpolation, colorInterpolationFilters, colorProfileAttr, colorRendering, cols, colspan, content, contentEditable, contentScriptType, contentStyleType, contextmenu, controls, coords, createAttribute, createAttributeName, createAttributeType, createProperty, cursorAttr, cx, cy, d, datetime, default, diffuseConstant, dir, direction, disabled, display, divisor, dominantBaseline, download, downloadAs, draggable, dropzone, dur, dx, dy, edgeMode, elevation, enctype, end, externalResourcesRequired, fill, fillOpacity, fillRule, filterAttr, filterUnits, floodColor, floodOpacity, fontFamily, fontSize, fontSizeAdjust, fontStretch, fontStyle, fontVariant, fontWeight, for, fr, from, fx, fy, gradientTransform, gradientUnits, headers, height, hidden, href, hreflang, id, imageRendering, in', in2, isMap, itemprop, k1, k2, k3, k4, kernelMatrix, kernelUnitLength, kerning, keySplines, keyTimes, kind, lang, lengthAdjust, letterSpacing, lightingColor, limitingConeAngle, list, local, loop, manifest, markerEnd, markerHeight, markerMid, markerStart, markerUnits, markerWidth, maskAttr, maskContentUnits, maskUnits, max, maxlength, media, method, min, minlength, mode, multiple, name, noValidate, numOctaves, opacity, operator, order, overflow, overlinePosition, overlineThickness, paintOrder, pathLength, pattern, patternContentUnits, patternTransform, patternUnits, ping, placeholder, pointerEvents, points, pointsAtX, pointsAtY, pointsAtZ, poster, preload, preserveAlpha, preserveAspectRatio, primitiveUnits, pubdate, r, radius, readOnly, refX, refY, rel, repeatCount, repeatDur, required, requiredFeatures, restart, result, reversed, rows, rowspan, rx, ry, sandbox, scale, scope, seed, selected, shape, shapeRendering, size, specularConstant, specularExponent, spellcheck, src, srcdoc, srclang, start, stdDeviation, step, stitchTiles, stopColor, stopOpacity, strikethroughPosition, strikethroughThickness, stroke, strokeDasharray, strokeDashoffset, strokeLinecap, strokeLinejoin, strokeMiterlimit, strokeOpacity, strokeWidth, style, styleAttr, surfaceScale, tabindex, target, targetX, targetY, textAnchor, textDecoration, textLength, textRendering, title, to, transform, type', underlinePosition, underlineThickness, useMap, value, values, vectorEffect, version, viewBox, visibility, width, wordSpacing, wrap, writingMode, x, x1, x2, xChannelSelector, y, y1, y2, yChannelSelector, innerHTML) as Exported
5+
accentHeight, accept, acceptCharset, accessKey, accumulate, action, additive, align, alignmentBaseline, alt, ascent, autocomplete, autofocus, autoplay, azimuth, baseFrequency, baseProfile, baselineShift, begin, bias, calcMode, charset, checked, class', clipPathAttr, clipPathUnits, clipRule, color, colorInterpolation, colorInterpolationFilters, colorProfileAttr, colorRendering, cols, colspan, content, contentEditable, contentScriptType, contentStyleType, contextmenu, controls, coords, createAttribute, createAttributeName, createAttributeType, createProperty, cursorAttr, cx, cy, d, datetime, default, diffuseConstant, dir, direction, disabled, display, divisor, dominantBaseline, download, downloadAs, draggable, dropzone, dur, dx, dy, edgeMode, elevation, enctype, end, externalResourcesRequired, fill, fillOpacity, fillRule, filterAttr, filterUnits, floodColor, floodOpacity, fontFamily, fontSize, fontSizeAdjust, fontStretch, fontStyle, fontVariant, fontWeight, for, fr, from, fx, fy, gradientTransform, gradientUnits, headers, height, hidden, href, hreflang, id, imageRendering, in', in2, isMap, itemprop, k1, k2, k3, k4, kernelMatrix, kernelUnitLength, kerning, key, keySplines, keyTimes, kind, lang, lengthAdjust, letterSpacing, lightingColor, limitingConeAngle, list, local, loop, manifest, markerEnd, markerHeight, markerMid, markerStart, markerUnits, markerWidth, maskAttr, maskContentUnits, maskUnits, max, maxlength, media, method, min, minlength, mode, multiple, name, noValidate, numOctaves, opacity, operator, order, overflow, overlinePosition, overlineThickness, paintOrder, pathLength, pattern, patternContentUnits, patternTransform, patternUnits, ping, placeholder, pointerEvents, points, pointsAtX, pointsAtY, pointsAtZ, poster, preload, preserveAlpha, preserveAspectRatio, primitiveUnits, pubdate, r, radius, readOnly, refX, refY, rel, repeatCount, repeatDur, required, requiredFeatures, restart, result, reversed, rows, rowspan, rx, ry, sandbox, scale, scope, seed, selected, shape, shapeRendering, size, specularConstant, specularExponent, spellcheck, src, srcdoc, srclang, start, stdDeviation, step, stitchTiles, stopColor, stopOpacity, strikethroughPosition, strikethroughThickness, stroke, strokeDasharray, strokeDashoffset, strokeLinecap, strokeLinejoin, strokeMiterlimit, strokeOpacity, strokeWidth, style, styleAttr, surfaceScale, tabindex, target, targetX, targetY, textAnchor, textDecoration, textLength, textRendering, title, to, transform, type', underlinePosition, underlineThickness, useMap, value, values, vectorEffect, version, viewBox, visibility, width, wordSpacing, wrap, writingMode, x, x1, x2, xChannelSelector, y, y1, y2, yChannelSelector, innerHTML) as Exported
66
import Flame.HTML.Event (EventName, ToEvent, ToRawEvent, ToMaybeEvent, ToSpecialEvent, createEvent, createEventMessage, createRawEvent, onBlur, onBlur', onCheck, onClick, onClick', onChange, onChange', onContextmenu, onContextmenu', onDblclick, onDblclick', onDrag, onDrag', onDragend, onDragend', onDragenter, onDragenter', onDragleave, onDragleave', onDragover, onDragover', onDragstart, onDragstart', onDrop, onDrop', onError, onError', onFocus, onFocus', onFocusin, onFocusin', onFocusout, onFocusout', onInput, onInput', onKeydown, onKeydown', onKeypress, onKeypress', onKeyup, onKeyup', onMousedown, onMousedown', onMouseenter, onMouseenter', onMouseleave, onMouseleave', onMousemove, onMousemove', onMouseout, onMouseout', onMouseover, onMouseover', onMouseup, onMouseup', onReset, onReset', onScroll, onScroll', onSelect, onSelect', onSubmit, onSubmit', onWheel, onWheel') as Exported

src/Flame/HTML/Attribute/Internal.purs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
-- | Definition of HTML attributes
2-
module Flame.HTML.Attribute.Internal (class ToClassList, ToBooleanAttribute, ToIntAttribute, ToNumberAttribute, ToStringAttribute, accentHeight, accept, acceptCharset, accessKey, accumulate, action, additive, align, alignmentBaseline, alt, ascent, autocomplete, autofocus, autoplay, azimuth, baseFrequency, baseProfile, baselineShift, begin, bias, calcMode, charset, checked, class', clipPathAttr, clipPathUnits, clipRule, color, colorInterpolation, colorInterpolationFilters, colorProfileAttr, colorRendering, cols, colspan, content, contentEditable, contentScriptType, contentStyleType, contextmenu, controls, coords, createAttribute, createAttributeName, createAttributeType, createProperty, cursorAttr, cx, cy, d, datetime, default, diffuseConstant, dir, direction, disabled, display, divisor, dominantBaseline, download, downloadAs, draggable, dropzone, dur, dx, dy, edgeMode, elevation, enctype, end, externalResourcesRequired, fill, fillOpacity, fillRule, filterAttr, filterUnits, floodColor, floodOpacity, fontFamily, fontSize, fontSizeAdjust, fontStretch, fontStyle, fontVariant, fontWeight, for, fr, from, fx, fy, gradientTransform, gradientUnits, headers, height, hidden, href, hreflang, id, imageRendering, in', in2, isMap, itemprop, k1, k2, k3, k4, kernelMatrix, kernelUnitLength, kerning, keySplines, keyTimes, kind, lang, lengthAdjust, letterSpacing, lightingColor, limitingConeAngle, list, local, loop, manifest, markerEnd, markerHeight, markerMid, markerStart, markerUnits, markerWidth, maskAttr, maskContentUnits, maskUnits, max, maxlength, media, method, min, minlength, mode, multiple, name, noValidate, numOctaves, opacity, operator, order, overflow, overlinePosition, overlineThickness, paintOrder, pathLength, pattern, patternContentUnits, patternTransform, patternUnits, ping, placeholder, pointerEvents, points, pointsAtX, pointsAtY, pointsAtZ, poster, preload, preserveAlpha, preserveAspectRatio, primitiveUnits, pubdate, r, radius, readOnly, refX, refY, rel, repeatCount, repeatDur, required, requiredFeatures, restart, result, reversed, rows, rowspan, rx, ry, sandbox, scale, scope, seed, selected, shape, shapeRendering, size, specularConstant, specularExponent, spellcheck, src, srcdoc, srclang, start, stdDeviation, step, stitchTiles, stopColor, stopOpacity, strikethroughPosition, strikethroughThickness, stroke, strokeDasharray, strokeDashoffset, strokeLinecap, strokeLinejoin, strokeMiterlimit, strokeOpacity, strokeWidth, style, styleAttr, surfaceScale, tabindex, target, targetX, targetY, textAnchor, textDecoration, textLength, textRendering, title, to, transform, type', underlinePosition, underlineThickness, useMap, value, values, vectorEffect, version, viewBox, visibility, width, wordSpacing, wrap, writingMode, x, x1, x2, xChannelSelector, y, y1, y2, yChannelSelector, innerHTML) where
2+
module Flame.HTML.Attribute.Internal (class ToClassList, ToBooleanAttribute, ToIntAttribute, ToNumberAttribute, ToStringAttribute, accentHeight, accept, acceptCharset, accessKey, accumulate, action, additive, align, alignmentBaseline, alt, ascent, autocomplete, autofocus, autoplay, azimuth, baseFrequency, baseProfile, baselineShift, begin, bias, calcMode, charset, checked, class', clipPathAttr, clipPathUnits, clipRule, color, colorInterpolation, colorInterpolationFilters, colorProfileAttr, colorRendering, cols, colspan, content, contentEditable, contentScriptType, contentStyleType, contextmenu, controls, coords, createAttribute, createAttributeName, createAttributeType, createProperty, cursorAttr, cx, cy, d, datetime, default, diffuseConstant, dir, direction, disabled, display, divisor, dominantBaseline, download, downloadAs, draggable, dropzone, dur, dx, dy, edgeMode, elevation, enctype, end, externalResourcesRequired, fill, fillOpacity, fillRule, filterAttr, filterUnits, floodColor, floodOpacity, fontFamily, fontSize, fontSizeAdjust, fontStretch, fontStyle, fontVariant, fontWeight, for, fr, from, fx, fy, gradientTransform, gradientUnits, headers, height, hidden, href, hreflang, id, imageRendering, in', in2, isMap, itemprop, k1, k2, k3, k4, kernelMatrix, kernelUnitLength, kerning, key, keySplines, keyTimes, kind, lang, lengthAdjust, letterSpacing, lightingColor, limitingConeAngle, list, local, loop, manifest, markerEnd, markerHeight, markerMid, markerStart, markerUnits, markerWidth, maskAttr, maskContentUnits, maskUnits, max, maxlength, media, method, min, minlength, mode, multiple, name, noValidate, numOctaves, opacity, operator, order, overflow, overlinePosition, overlineThickness, paintOrder, pathLength, pattern, patternContentUnits, patternTransform, patternUnits, ping, placeholder, pointerEvents, points, pointsAtX, pointsAtY, pointsAtZ, poster, preload, preserveAlpha, preserveAspectRatio, primitiveUnits, pubdate, r, radius, readOnly, refX, refY, rel, repeatCount, repeatDur, required, requiredFeatures, restart, result, reversed, rows, rowspan, rx, ry, sandbox, scale, scope, seed, selected, shape, shapeRendering, size, specularConstant, specularExponent, spellcheck, src, srcdoc, srclang, start, stdDeviation, step, stitchTiles, stopColor, stopOpacity, strikethroughPosition, strikethroughThickness, stroke, strokeDasharray, strokeDashoffset, strokeLinecap, strokeLinejoin, strokeMiterlimit, strokeOpacity, strokeWidth, style, styleAttr, surfaceScale, tabindex, target, targetX, targetY, textAnchor, textDecoration, textLength, textRendering, title, to, transform, type', underlinePosition, underlineThickness, useMap, value, values, vectorEffect, version, viewBox, visibility, width, wordSpacing, wrap, writingMode, x, x1, x2, xChannelSelector, y, y1, y2, yChannelSelector, innerHTML) where
33

44
import Data.Array as DA
55
import Data.Either as DE
@@ -472,6 +472,9 @@ kernelUnitLength = createAttribute "kernelUnitLength"
472472
kerning :: ToStringAttribute
473473
kerning = createAttribute "kerning"
474474

475+
key :: ToStringAttribute
476+
key = Key
477+
475478
keySplines :: ToStringAttribute
476479
keySplines = createAttribute "keySplines"
477480

src/Flame/Renderer/Renderer.purs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import Data.Foldable as DF
1515
import Data.Function.Uncurried (Fn1, Fn2, Fn3, runFn3)
1616
import Data.Function.Uncurried as DFU
1717
import Data.Maybe (Maybe(..))
18+
import Data.Nullable as DN
1819
import Effect (Effect)
1920
import Effect.Uncurried (EffectFn2)
2021
import Effect.Uncurried as EU
@@ -92,16 +93,16 @@ render oldVNode updater element = do
9293
patch oldVNode vNode
9394
pure vNode
9495

95-
-- could we make this keyed (key : string | number) somehow?
9696
-- | Transforms an `Html` into a `VNode`
9797
toVNode :: forall message. (message -> Effect Unit) -> Html message -> VNode
9898
toVNode updater (Text value) = text value
9999
toVNode updater (Node tag nodeData children) = h tag vNodeData $ map (toVNode updater) children
100-
where toVNodeData { properties, attributes, events, hooks } = {
100+
where toVNodeData { key, properties, attributes, events, hooks } = {
101101
attrs: attributes,
102102
props: properties,
103103
on: toVNodeEvents events,
104-
hook: hooks
104+
hook: hooks,
105+
key
105106
}
106107

107108
handleRawEvent handler event = do
@@ -112,10 +113,17 @@ toVNode updater (Node tag nodeData children) = h tag vNodeData $ map (toVNode up
112113

113114
unions record@{ properties, attributes, events, hooks } =
114115
case _ of
116+
Key value -> record { key = DN.notNull value }
115117
Property name value -> record { properties = FO.insert name value properties }
116118
Attribute name value -> record { attributes = FO.insert name value attributes }
117119
Event name message -> record { events = FO.insert name (const (updater message)) events }
118120
RawEvent name handler -> record { events = FO.insert name (handleRawEvent handler) events }
119121
Hook name fn -> record { hooks = FO.insert name fn hooks }
120122

121-
vNodeData = toVNodeData $ DF.foldl unions { properties: FO.empty, attributes: FO.empty, events: FO.empty, hooks: FO.empty } nodeData
123+
vNodeData = toVNodeData $ DF.foldl unions {
124+
key: DN.null,
125+
properties: FO.empty,
126+
attributes: FO.empty,
127+
events: FO.empty,
128+
hooks: FO.empty
129+
} nodeData

src/Flame/Types.purs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Prelude
66
import Data.Array as DA
77
import Data.Foldable as DF
88
import Data.Maybe (Maybe)
9+
import Data.Nullable (Nullable)
910
import Data.Tuple (Tuple(..))
1011
import Effect (Effect)
1112
import Foreign (Foreign)
@@ -22,6 +23,7 @@ type VNodeData = {
2223
-- we need attrs mainly for svg
2324
attrs :: Object String,
2425
props :: Object String,
26+
key :: Nullable String,
2527
on :: VNodeEvents,
2628
hook :: Object Foreign
2729
}
@@ -50,7 +52,7 @@ type PreApplication model message = App model message (
5052
-- | A native HTML element
5153
type DOMElement = WDE.Element
5254

53-
type ToNodeData message = forall b. message -> NodeData b
55+
type ToNodeData value = forall message. value -> NodeData message
5456

5557
type Tag = String
5658

@@ -84,6 +86,7 @@ isNonEventData = DA.filter case _ of
8486
--snabbom has support for style and class node data but I dont think it is worth it
8587
data NodeData message =
8688
Attribute String String |
89+
Key String |
8790
Property String String |
8891
Event String message |
8992
RawEvent String (Event -> Effect (Maybe message)) |

test/Main.purs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@ foreign import enterPressedEvent :: Effect Event
5858
foreign import errorEvent :: Effect Event
5959
foreign import offlineEvent :: Effect Event
6060

61-
62-
6361
main :: Effect Unit
6462
main =
6563
runTest do
@@ -154,6 +152,11 @@ main =
154152
html' <- liftEffect $ FRS.render html
155153
TUA.equal """<html><head><title>title</title></head><body><main><button>-</button><br>Test<button>+</button><hr><div><div><span><a>here</a></span></div></div></main></body></html>""" html'
156154

155+
test "key data property is not part of the dom" do
156+
let html = HE.div (HA.key "23") "oi"
157+
html' <- liftEffect $ FRS.render html
158+
TUA.equal """<div>oi</div>""" html'
159+
157160
test "nested elements with attributes" do
158161
let html = HE.html [HA.lang "en"] [
159162
HE.head_ [HE.title "title"],
@@ -206,7 +209,7 @@ main =
206209
TUA.equal """(Node div [(Property id 1)] [(Text T)])""" $ show $ html
207210
test "element with childs" do
208211
let html = HE.div_ [HE.div_ [HE.br]]
209-
TUA.equal """(Node div [] [(Node div [] [(Node br [] [])])])""" $ show $ html
212+
TUA.equal """(Node div [] [(Node div [] [(Node br [] [])])])""" $ show $ html
210213
suite "eq" do
211214
test "simple element" do
212215
TUA.equal' "equal html" (HE.div [HA.id "1"] [HE.text "T"]) (HE.div [HA.id "1"] [HE.text "T"])
@@ -215,7 +218,7 @@ main =
215218
TUA.equal' "equal html" (HE.div [HA.id "1", HA.onClick unit] [HE.text "T"]) (HE.div [HA.id "1"] [HE.text "T"])
216219
test "property order does not matter" do
217220
TUA.assert "should equal" $
218-
(HE.div [HA.class' "test", HA.id "1"] [HE.text "T"]) == (HE.div [HA.id "1", HA.class' "test"] [HE.text "T"])
221+
(HE.div [HA.class' "test", HA.id "1"] [HE.text "T"]) == (HE.div [HA.id "1", HA.class' "test"] [HE.text "T"])
219222
test "child order does matter" do
220223
TUA.assert "should not equal" $
221224
(HE.div_ [HE.text "T", HE.br]) /= (HE.div_ [HE.br, HE.text "T"])

0 commit comments

Comments
 (0)