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