Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support of composing events #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions elm.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"source-directories": [
"src"
],
"elm-version": "0.19.0",
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.1",
Expand All @@ -23,4 +23,4 @@
"direct": {},
"indirect": {}
}
}
}
111 changes: 98 additions & 13 deletions src/Main.elm
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ type ModifierKeyType
| Control
| Meta
| Shift
| AltGraph


type alias InputModifier =
{ alt : Bool
, control : Bool
, meta : Bool
, shift : Bool
, altgr : Bool
}


Expand Down Expand Up @@ -76,6 +78,7 @@ type Msg
| MoveRight
| NewLine
| InsertChar Char
| InsertString String
| RemoveCharBefore
| RemoveCharAfter
| Hover Hover
Expand All @@ -84,6 +87,7 @@ type Msg
| StopSelecting
| ReleaseModifierKey ModifierKeyType
| HoldModifierKey ModifierKeyType
| Focus


initModel : Model
Expand All @@ -97,14 +101,15 @@ initModel =
, meta = False
, shift = False
, alt = False
, altgr = False
}
}


init : flags -> ( Model, Cmd Msg )
init _ =
( initModel
, Dom.focus "editor"
, Dom.focus "editor_hidden_input"
|> Task.attempt (always NoOp)
)

Expand All @@ -114,23 +119,35 @@ subscriptions model =
Sub.none


compositionEndDecoder =
JD.field "data" JD.string |> JD.map (\x -> { message = InsertString x, preventDefault = False, stopPropagation = False })


focusDecoder : Decoder ( Msg, Bool )
focusDecoder =
JD.succeed ( Focus, True )


keyDecoder : KeyboardEventType -> InputModifier -> Decoder ( Msg, Bool )
keyDecoder kind withModifier =
let
alwaysPreventDefault : msg -> ( msg, Bool )
alwaysPreventDefault msg =
( msg, True )

msgDecoder : String -> Decoder Msg
msgDecoder =
case kind of
KeyUp ->
keyUpToMsg
msgDecoder : { isCompositing : Bool, key : String } -> Decoder Msg
msgDecoder jd =
case ( jd.isCompositing, kind ) of
( False, KeyUp ) ->
keyUpToMsg jd.key

( False, KeyDown ) ->
keyDownToMsg withModifier jd.key

KeyDown ->
keyDownToMsg withModifier
( True, _ ) ->
JD.succeed NoOp
in
JD.field "key" JD.string
JD.map2 (\k isc -> { key = k, isCompositing = isc }) (JD.field "key" JD.string) (JD.field "isComposing" JD.bool)
|> JD.andThen msgDecoder
|> JD.map alwaysPreventDefault

Expand All @@ -140,7 +157,7 @@ keyDownToMsg withPrefix string =
case String.uncons string of
Just ( char, "" ) ->
let
{ meta, alt, shift, control } =
{ meta, alt, shift, control, altgr } =
withPrefix
in
if meta || control then
Expand Down Expand Up @@ -184,6 +201,9 @@ keyDownToMsg withPrefix string =
"Control" ->
JD.succeed (HoldModifierKey Control)

"AltGraph" ->
JD.succeed (HoldModifierKey AltGraph)

_ ->
JD.fail "This key does nothing"

Expand All @@ -203,13 +223,22 @@ keyUpToMsg string =
"Control" ->
JD.succeed (ReleaseModifierKey Control)

"AltGraph" ->
JD.succeed (ReleaseModifierKey AltGraph)

_ ->
JD.fail "This key does nothing"


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Focus ->
( model
, Dom.focus "editor_hidden_input"
|> Task.attempt (always NoOp)
)

NoOp ->
( model, Cmd.none )

Expand Down Expand Up @@ -244,6 +273,11 @@ update msg model =
, Cmd.none
)

InsertString string ->
( insertString string model
, Cmd.none
)

RemoveCharBefore ->
( removeCharBefore model
|> sanitizeHover
Expand Down Expand Up @@ -341,6 +375,9 @@ update msg model =
Control ->
( { model | modifier = { previous | control = True } }, Cmd.none )

AltGraph ->
( { model | modifier = { previous | altgr = True } }, Cmd.none )

ReleaseModifierKey key ->
let
previous =
Expand All @@ -359,6 +396,9 @@ update msg model =
Control ->
( { model | modifier = { previous | control = False } }, Cmd.none )

AltGraph ->
( { model | modifier = { previous | altgr = False } }, Cmd.none )


hoversToPositions : Array String -> Hover -> Hover -> Maybe ( Position, Position )
hoversToPositions lines from to =
Expand Down Expand Up @@ -542,6 +582,42 @@ insertChar char ({ cursor, lines } as model) =
}


insertString : String -> Model -> Model
insertString string ({ cursor, lines } as model) =
let
{ line, column } =
cursor

lineWithCharAdded : String -> String
lineWithCharAdded content =
String.left column content
++ string
++ String.dropLeft column content

newLines : Array String
newLines =
lines
|> Array.indexedMap
(\i content ->
if i == line then
lineWithCharAdded content

else
content
)

newCursor : Position
newCursor =
{ line = line
, column = column + String.length string
}
in
{ model
| lines = newLines
, cursor = newCursor
}


removeCharBefore : Model -> Model
removeCharBefore ({ cursor, lines } as model) =
if isStartOfDocument cursor then
Expand Down Expand Up @@ -852,7 +928,7 @@ viewDebug { lines, cursor, hover, selection, modifier } =
List.foldl reducer [] (Array.toList lns)

printSuperKeys : InputModifier -> String
printSuperKeys { control, meta, alt, shift } =
printSuperKeys { control, meta, alt, shift, altgr } =
let
convert label keyTypeState =
if keyTypeState then
Expand All @@ -865,6 +941,7 @@ viewDebug { lines, cursor, hover, selection, modifier } =
, convert "meta" meta
, convert "alt" alt
, convert "shift" shift
, convert "altgr" altgr
]
|> List.filter (\s -> s /= "")
|> String.join " "
Expand Down Expand Up @@ -948,13 +1025,21 @@ viewEditor model =
, HA.style "font-size" (String.fromFloat fontSize ++ "px")
, HA.style "line-height" (String.fromFloat lineHeight ++ "px")
, HA.style "white-space" "pre"
, HE.preventDefaultOn "keydown" (keyDecoder KeyDown modifier)
, HE.preventDefaultOn "keyup" (keyDecoder KeyUp modifier)
, HA.tabindex 0
, HA.id "editor"
, HE.preventDefaultOn "click" focusDecoder
]
[ viewLineNumbers model
, viewContent model
, H.div [ HA.attribute "style" "overflow:hidden; height:0; outline: none; position: fixed; top:0" ]
[ H.input
[ HA.id "editor_hidden_input"
, HE.custom "compositionend" compositionEndDecoder
, HE.preventDefaultOn "keydown" (keyDecoder KeyDown modifier)
, HE.preventDefaultOn "keyup" (keyDecoder KeyUp modifier)
]
[]
]
]


Expand Down