more editing fun! Deleting breaks though!

master
Brian Hicks 2019-02-13 13:26:34 -06:00
parent c930b931ff
commit fdf71d15e5
3 changed files with 90 additions and 16 deletions

View File

@ -1,6 +1,7 @@
module Doc exposing (Attr, Doc, fromString, sampleDoc, toHtml)
module Doc exposing (Attr, Doc, delete, deleteSelection, fromString, insertAt, sampleDoc, toHtml)
import Html exposing (Html)
import Selection exposing (Selection)
type Doc
@ -56,3 +57,37 @@ style c attrs =
Italic :: rest ->
Html.em [] [ style c rest ]
insertAt : Int -> String -> Doc -> Doc
insertAt where_ text (Doc doc) =
let
prevAttrs =
doc
|> List.drop where_
|> List.head
|> Maybe.map Tuple.second
|> Maybe.withDefault []
prev =
List.take where_ doc
next =
List.drop where_ doc
current =
text
|> String.toList
|> List.map (\c -> ( c, prevAttrs ))
in
Doc (prev ++ current ++ next)
delete : Int -> Doc -> Doc
delete where_ (Doc doc) =
Doc (List.take (where_ - 1) doc ++ List.drop where_ doc)
deleteSelection : Selection -> Doc -> Doc
deleteSelection selection (Doc doc) =
Doc (List.take (Selection.start selection) doc ++ List.drop (Selection.end selection) doc)

View File

@ -7,17 +7,18 @@ import Html.Attributes exposing (..)
import Html.Events exposing (on)
import Json.Decode as Decode exposing (Decoder)
import Json.Encode as Encode
import Selection exposing (Selection)
type alias Model =
{ events : List Msg
{ selection : Selection
, doc : Doc
}
init : () -> ( Model, Cmd Msg )
init _ =
( { events = []
( { selection = Selection.init 0 0
, doc = Doc.sampleDoc
}
, Cmd.none
@ -42,16 +43,37 @@ type Event
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
( { model | events = msg :: model.events }
, Cmd.none
)
case msg of
Changed (InsertText string) ->
( { model | doc = Doc.insertAt (Selection.start model.selection) string model.doc }
, Cmd.none
)
Changed (ChangeSelection start end) ->
( { model | selection = Selection.init start end }
, Cmd.none
)
Changed DeleteBackward ->
( { model | doc = Doc.delete (Selection.start model.selection) model.doc }
, Cmd.none
)
Changed DeleteForward ->
( { model | doc = Doc.delete (Selection.start model.selection + 1) model.doc }
, Cmd.none
)
Pasted _ ->
-- TODO!
( model, Cmd.none )
view : Model -> Html Msg
view model =
main_
[]
[ p [] [ text (Debug.toString model.doc) ]
[ p [] [ text (Debug.toString model) ]
, node "elm-select"
[ attribute "contenteditable" "true"
, on "input" (Decode.map Changed decodeInput)
@ -63,11 +85,6 @@ view model =
]
debug : Model -> Html Msg
debug { events } =
Html.ul [] (List.map (Html.li [] << List.singleton << Html.text << Debug.toString) events)
main : Program () Model Msg
main =
Browser.document
@ -76,10 +93,7 @@ main =
, view =
\model ->
{ title = "Elm Edit"
, body =
[ view model
, debug model
]
, body = [ view model ]
}
, subscriptions = \_ -> Sub.none
}

25
src/Selection.elm Normal file
View File

@ -0,0 +1,25 @@
module Selection exposing (Selection, end, init, isPoint, start)
type Selection
= Selection Int Int
init : Int -> Int -> Selection
init start_ end_ =
Selection (min start_ end_) (max start_ end_)
start : Selection -> Int
start (Selection start_ _) =
start_
end : Selection -> Int
end (Selection _ end_) =
end_
isPoint : Selection -> Bool
isPoint (Selection start_ end_) =
start_ == end_