Code Snippet: index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Main</title>
    <style>
      html,head,body { padding:0; margin:0; }
      body { font-family: calibri, helvetica, arial, sans-serif; }
    </style>
    <script src="elm.min.js" type="text/javascript">
    </script>
  </head>
  <body>
    <script type="text/javascript">
      Elm.fullscreen(
        Elm.Main,
        { queryString: window.location.search });
    </script>
  </body>
</html>

Code Snippet: Main.elm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module Main (..) where

import Html exposing (text)
import ParseModel exposing (Model,parse,update, view)
import Html exposing (Html)
import StartApp.Simple exposing (start)

main : Signal Html.Html
main =
 start
 { model = parse queryString -- 0
 , update = update
 , view = view
 }

port queryString : String

Code Snippet: src/ParseModel.elm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
module ParseModel where

import List exposing (filter,head)
import Maybe exposing (withDefault)
import String exposing (dropLeft,split,startsWith,toInt)

import Html exposing (..)
import Html.Attributes exposing (href,style)
import Html.Events exposing (onClick)
import Http exposing (url)

-- MODEL
type alias Model = Int

-- UPDATE
type Action = Increment | Decrement
update : Action -> Model -> Model
update action model =
  case action of
    Increment ->
      model + 1
    Decrement ->
      model - 1

-- VIEW
view : Signal.Address Action -> Model -> Html
view address model =
  div []
    [ button [ onClick address Decrement ] [ text "-" ]
    , state model
    , button [ onClick address Increment ] [ text "+" ]
    ]

-- INITIAL STATE
query2model : String -> String
query2model s =
  withDefault "?foo=" (Just s)
    |> dropLeft 1 -- drop '?'
    |> split "&"
    |> filter (\term -> startsWith "foo=" term)
    |> head
    |> withDefault "foo=0"
    |> dropLeft 4 -- drop 'foo='
       
parse : String -> Int
parse s =
  case query2model s |> toInt of
    Err msg -> Debug.crash msg
    Ok  val -> val
  
-- SAVE STATE
linkToApp model =
  a [ "/assets/apps/elm/counterState/index.html?foo=" ++ (toString model) |> href ]
    [ toString model |> text ]

content link =
  div [ ]
    [ text ""
    , link
    ]

state model =
  div [countStyle] [ linkToApp model |> content ]

-- CSS
countStyle : Attribute
countStyle =
  style
    [ ("font-size", "20px")
    , ("font-family", "monospace")
    , ("display", "inline-block")
    , ("width", "50px")
    , ("text-align", "center")
    ]

Build Snippet: build.bash

#!/bin/bash

# ensure latest packages are downloaded
elm-package install --yes

# only create the .js as we will rely on a custom html file (port)
elm-make Main.elm --output elm.js --yes

# make elm js as small as possible
./.misc/jsmin/jsmin < elm.js > elm.min.js

Code output:

References: