svg.escobar.life
A simple SVG markup editor for the web
Editor.elm (2086B)
1 module Editor exposing (editor) 2 3 import Types exposing (..) 4 import Html exposing (Html, Attribute, div, pre, code, text, textarea) 5 import Html.Attributes exposing (id, value, style, spellcheck, alt, attribute) 6 import Html.Events exposing (onInput, on) 7 import Accessibility.Landmark exposing (region) 8 import Accessibility.Widget exposing (label, hidden) 9 import Json.Decode 10 import SyntaxHighlight exposing (xml, toBlockHtml) 11 12 editor : Model -> Html Msg 13 editor model = 14 let 15 -- Indent the editor according to the order of magnitude of the number of 16 -- lines in the input file 17 indent 18 = model.image 19 |> String.lines 20 |> List.length 21 |> toFloat 22 |> logBase 10 23 |> floor 24 |> (+) 1 25 |> max 1 26 |> String.fromInt 27 |> \s -> "--indent: " ++ s ++"em;" 28 in 29 div 30 [ id "editor" 31 , region 32 , label "Text editor" 33 , attribute "style" indent 34 ] 35 [ div 36 [ hidden True, translate model.editorScroll ] 37 [ codeDisplay model ] 38 , textarea model 39 ] 40 41 textarea : Model -> Html Msg 42 textarea model = 43 Html.textarea 44 [ value model.image 45 , onInput Update 46 , onScroll Scroll 47 , spellcheck False 48 , alt "Text Editor" 49 ] [] 50 51 codeDisplay : Model -> Html Msg 52 codeDisplay model = 53 xml (if model.image == "" then placeholder else model.image) 54 |> Result.map (toBlockHtml (Just 1)) 55 |> Result.withDefault (pre [] [ code [] [ text model.image ] ]) 56 57 onScroll : ((Int, Int) -> msg) -> Attribute msg 58 onScroll f = 59 Json.Decode.map2 60 (\x -> \y -> (x, y)) 61 (Json.Decode.at [ "target", "scrollLeft" ] Json.Decode.int) 62 (Json.Decode.at [ "target", "scrollTop" ] Json.Decode.int) 63 |> Json.Decode.map f 64 |> on "scroll" 65 66 translate : (Int, Int) -> Attribute Msg 67 translate (x, y) = 68 let 69 show = String.fromInt 70 in 71 style 72 "transform" 73 ("translate(" ++ (show -x) ++ "px, " ++ (show -y) ++ "px)") 74 75 placeholder : String 76 placeholder = "<svg> ... </svg>" 77