module Editor exposing (editor) import Types exposing (..) import Html exposing (Html, Attribute, div, pre, code, text, textarea) import Html.Attributes exposing (id, value, style, spellcheck, alt, attribute) import Html.Events exposing (onInput, on) import Accessibility.Landmark exposing (region) import Accessibility.Widget exposing (label, hidden) import Json.Decode import SyntaxHighlight exposing (xml, toBlockHtml) editor : Model -> Html Msg editor model = let -- Indent the editor according to the order of magnitude of the number of -- lines in the input file indent = model.image |> String.lines |> List.length |> toFloat |> logBase 10 |> floor |> (+) 1 |> max 1 |> String.fromInt |> \s -> "--indent: " ++ s ++"em;" in div [ id "editor" , region , label "Text editor" , attribute "style" indent ] [ div [ hidden True, translate model.editorScroll ] [ codeDisplay model ] , textarea model ] textarea : Model -> Html Msg textarea model = Html.textarea [ value model.image , onInput Update , onScroll Scroll , spellcheck False , alt "Text Editor" ] [] codeDisplay : Model -> Html Msg codeDisplay model = xml (if model.image == "" then placeholder else model.image) |> Result.map (toBlockHtml (Just 1)) |> Result.withDefault (pre [] [ code [] [ text model.image ] ]) onScroll : ((Int, Int) -> msg) -> Attribute msg onScroll f = Json.Decode.map2 (\x -> \y -> (x, y)) (Json.Decode.at [ "target", "scrollLeft" ] Json.Decode.int) (Json.Decode.at [ "target", "scrollTop" ] Json.Decode.int) |> Json.Decode.map f |> on "scroll" translate : (Int, Int) -> Attribute Msg translate (x, y) = let show = String.fromInt in style "transform" ("translate(" ++ (show -x) ++ "px, " ++ (show -y) ++ "px)") placeholder : String placeholder = " ... "