Skip to content

Commit

Permalink
Combine Provider.Keydown and Provider.Keyup into `Provider.Keyboa…
Browse files Browse the repository at this point in the history
…rd` (#663)
  • Loading branch information
farism committed Sep 17, 2023
1 parent cc407e7 commit 168ce02
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 64 deletions.
57 changes: 57 additions & 0 deletions core/source/Provider/Keyboard.mint
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* Represents a subscription for `Provider.Keyboard` */
record Provider.Keyboard.Subscription {
downs : Function(Html.Event, Promise(Void)),
ups : Function(Html.Event, Promise(Void))
}

/* A provider for global keyboard events. */
provider Provider.Keyboard : Provider.Keyboard.Subscription {
/* The listener unsubscribe functions. */
state listeners : Maybe(Tuple(Function(Void), Function(Void))) = Maybe::Nothing

/* Updates the provider. */
fun update : Promise(Void) {
if Array.isEmpty(subscriptions) {
Maybe.map(
listeners,
(methods : Tuple(Function(Void), Function(Void))) {
let {keydownListener, keyupListener} =
methods

keydownListener()
keyupListener()
})

next { listeners: Maybe::Nothing }
} else {
case listeners {
Maybe::Nothing =>
next
{
listeners:
Maybe::Just(
{
Window.addEventListener(
"keydown",
true,
(event : Html.Event) {
for subscription of subscriptions {
subscription.downs(event)
}
}),
Window.addEventListener(
"keyup",
true,
(event : Html.Event) {
for subscription of subscriptions {
subscription.ups(event)
}
})
})
}

=> next { }
}
}
}
}
32 changes: 0 additions & 32 deletions core/source/Provider/Keydown.mint

This file was deleted.

32 changes: 0 additions & 32 deletions core/source/Provider/Keyup.mint

This file was deleted.

30 changes: 30 additions & 0 deletions core/source/Test/Html.mint
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,36 @@ module Test.Html {
`
}

/* Triggers a keydown event with the specified key on the element that matches the given selector. */
fun triggerKeyDown (
context : Test.Context(Dom.Element),
selector : String,
key : String
) : Test.Context(Dom.Element) {
`
#{context}.step((element) => {
const event = new KeyboardEvent('keydown', { key: #{key} });
element.querySelector(#{selector}).dispatchEvent(event)
return element
})
`
}

/* Triggers a keyup event with the specified key on the element that matches the given selector. */
fun triggerKeyUp (
context : Test.Context(Dom.Element),
selector : String,
key : String
) : Test.Context(Dom.Element) {
`
#{context}.step((element) => {
const event = new KeyboardEvent('keyup', { key: #{key} });
element.querySelector(#{selector}).dispatchEvent(event)
return element
})
`
}

/* Asserts the text of the element that matches the given selector. */
fun assertTextOf (
context : Test.Context(Dom.Element),
Expand Down
41 changes: 41 additions & 0 deletions core/tests/tests/Provider/Keyboard.mint
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
component Test.Provider.Keyboard {
state downs : Number = 0
state ups : Number = 0

use Provider.Keyboard {
downs: (event : Html.Event) : Promise(Void) { next { downs: downs + 1 } },
ups: (event : Html.Event) : Promise(Void) { next { ups: ups + 1 } }
}

fun render : Html {
<div>
<downs>
<{ Number.toString(downs) }>
</downs>

<ups>
<{ Number.toString(ups) }>
</ups>
</div>
}
}

suite "Provider.Keyboard.downs" {
test "calls downs on keydown" {
<Test.Provider.Keyboard/>
|> Test.Html.start()
|> Test.Html.assertTextOf("downs", "0")
|> Test.Html.triggerKeyDown("div", "A")
|> Test.Html.assertTextOf("downs", "1")
}
}

suite "Provider.Keyboard.ups" {
test "calls ups on keyup" {
<Test.Provider.Keyboard/>
|> Test.Html.start()
|> Test.Html.assertTextOf("ups", "0")
|> Test.Html.triggerKeyUp("div", "A")
|> Test.Html.assertTextOf("ups", "1")
}
}

0 comments on commit 168ce02

Please sign in to comment.