chromium/third_party/blink/perf_tests/speedometer21/resources/todomvc/functional-prog-examples/elm/Todo/Task.elm

module Todo.Task exposing (..)

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Json.Decode
import String


-- MODEL


type alias Model =
    { description : String
    , completed : Bool
    , edits : Maybe String
    , id : Int
    }


init : String -> Int -> Model
init desc id =
    { description = desc
    , completed = False
    , edits = Nothing
    , id = id
    }



-- UPDATE


type Msg
    = Focus String
    | Edit String
    | Cancel
    | Commit
    | Completed Bool
    | Delete


update : Msg -> Model -> Maybe Model
update msg model =
    case msg of
        Focus elementId ->
            Just { model | edits = Just model.description }

        Edit description ->
            Just { model | edits = Just description }

        Cancel ->
            Just { model | edits = Nothing }

        Commit ->
            case model.edits of
                Nothing ->
                    Just model

                Just rawDescription ->
                    let
                        description =
                            String.trim rawDescription
                    in
                        if String.isEmpty description then
                            Nothing
                        else
                            Just
                                { model
                                    | edits = Nothing
                                    , description = description
                                }

        Completed bool ->
            Just { model | completed = bool }

        Delete ->
            Nothing



-- VIEW


view : Model -> Html Msg
view model =
    let
        className =
            (if model.completed then
                "completed "
             else
                ""
            )
                ++ case model.edits of
                    Just _ ->
                        "editing"

                    Nothing ->
                        ""

        description =
            Maybe.withDefault model.description model.edits

        elementId =
            "todo-" ++ toString model.id
    in
        li
            [ class className ]
            [ div
                [ class "view" ]
                [ input
                    [ class "toggle"
                    , type' "checkbox"
                    , checked model.completed
                    , onClick (Completed (not model.completed))
                    ]
                    []
                , label
                    [ onDoubleClick (Focus elementId) ]
                    [ text description ]
                , button
                    [ class "destroy"
                    , onClick Delete
                    ]
                    []
                ]
            , input
                [ class "edit"
                , value description
                , name "title"
                , id (elementId)
                , onInput Edit
                , onBlur Commit
                , onFinish Commit Cancel
                ]
                []
            ]


onFinish : msg -> msg -> Attribute msg
onFinish enterMessage escapeMessage =
    let
        select key =
            case key of
                13 ->
                    enterMessage

                _ ->
                    -- Not a 'finish' key, such as ENTER or ESCAPE
                    escapeMessage
    in
        on "keydown" (Json.Decode.map select keyCode)