on master help sign in
Get --output=index.html working again
c368061Evan Czaplicki
builder/src/Generate/Html.hsnew file+61
@@ -0,0 +1,61 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+{-# LANGUAGE QuasiQuotes #-}
3+module Generate.Html
4+ ( sandwich
5+ )
6+ where
7+
8+
9+import qualified Data.ByteString.Builder as B
10+import Data.Monoid ((<>))
11+import Text.RawString.QQ (r)
12+
13+import qualified Elm.Name as N
14+
15+
16+
17+-- SANDWICH
18+
19+
20+sandwich :: N.Name -> B.Builder -> B.Builder
21+sandwich moduleName javascript =
22+ header <> javascript <> footer (N.toBuilder moduleName)
23+
24+
25+header :: B.Builder
26+header = [r|
27+<!DOCTYPE HTML>
28+<html>
29+<head>
30+ <meta charset="UTF-8">
31+</head>
32+
33+<body>
34+<div id="embed"></div>
35+<script>
36+|]
37+
38+
39+footer :: B.Builder -> B.Builder
40+footer name =
41+ "</script>\n\
42+ \<script>\n\
43+ \// It is too complicated to figure out which kind of Program you created\n\
44+ \// based on only the code. So here we check for different possibilities.\n\
45+ \//\n\
46+ \// When you embed compiled Elm into HTML yourself, you should not copy/paste\n\
47+ \// from here. Do just the part that makes sense for your application!\n\
48+ \//\n\
49+ \var app =\n\
50+ \ Elm." <> name <> ".fullscreen\n\
51+ \ ? Elm." <> name <> ".fullscreen()\n\
52+ \ :\n\
53+ \ Elm." <> name <> ".embed\n\
54+ \ ? Elm." <> name <> ".embed(document.getElementById('embed'))\n\
55+ \ :\n\
56+ \ Elm." <> name <> ".worker\n\
57+ \ ? (document.getElementById('embed').innerText = 'This is a headless program, meaning there is nothing to show here. I started the program anyway though, and you can access it as `app` in the developer console.', Elm." <> name <> ".worker())\n\
58+ \ : (document.getElementById('embed').innerText = 'I cannot figure out what kind of program this is supposed to be. Perhaps someone on Slack can help?', undefined);\n\
59+ \</script>\n\
60+ \</body>\n\
61+ \</html>"
builder/src/Generate/Output.hs+36−22
@@ -31,6 +31,7 @@ import qualified File.Args as Args
31import qualified File.Crawl as Crawl
31import qualified File.Crawl as Crawl
32import qualified File.IO as IO
32import qualified File.IO as IO
33import qualified Generate.Functions as Functions
33import qualified Generate.Functions as Functions
34+import qualified Generate.Html as Html
34import qualified Reporting.Task as Task
35import qualified Reporting.Task as Task
35import qualified Stuff.Paths as Paths
36import qualified Stuff.Paths as Paths
36import Terminal.Args (Parser(..), suggestFiles)
37import Terminal.Args (Parser(..), suggestFiles)
@@ -63,31 +64,40 @@ generate options summary graph@(Crawl.Graph args _ _ _ _) =
63
64
64
65
65generateMonolith :: Options -> Summary.Summary -> Crawl.Result -> [Module.Raw] -> Task.Task ()
66generateMonolith :: Options -> Summary.Summary -> Crawl.Result -> [Module.Raw] -> Task.Task ()
66−generateMonolith (Options debug target output_) summary@(Summary.Summary _ project _ ifaces _) graph names =
67+generateMonolith (Options debug target maybeOutput) summary@(Summary.Summary _ project _ ifaces _) graph rootNames =
67 do let pkg = Project.getName project
68 do let pkg = Project.getName project
68− let roots = map (Module.Canonical pkg) names
69+ let roots = map (Module.Canonical pkg) rootNames
69 objectGraph <- organize summary graph
70 objectGraph <- organize summary graph
70 case Obj.generate debug target ifaces objectGraph roots of
71 case Obj.generate debug target ifaces objectGraph roots of
71− Nothing ->
72+ Obj.None ->
72 return ()
73 return ()
73
74
74− Just builder ->
75+ Obj.Some name names builder ->
75 let
76 let
76 monolith =
77 monolith =
77 "(function(scope){\n'use strict';"
78 "(function(scope){\n'use strict';"
78 <> Functions.functions <> builder <> "}(this));"
79 <> Functions.functions <> builder <> "}(this));"
79 in
80 in
80 liftIO $
81 liftIO $
81− case output_ of
82+ case maybeOutput of
82− Nothing ->
83+ Nothing ->
83− IO.writeBuilder "elm.js" monolith
84+ IO.writeBuilder "elm.js" monolith
84
85
85− Just None ->
86+ Just None ->
86− return ()
87+ return ()
87
88
89+ Just (JavaScript maybeDir fileName) ->
90+ do path <- toWritablePath maybeDir fileName
91+ IO.writeBuilder path monolith
92+
88− Just (Custom maybeDir fileName) ->
93+ Just (Html maybeDir fileName) ->
94+ case names of
95+ [] ->
89− do path <- safeCustomPath maybeDir fileName
96+ do path <- toWritablePath maybeDir fileName
90− IO.writeBuilder path monolith
97+ IO.writeBuilder path (Html.sandwich name monolith)
98+
99+ _:_ ->
100+ return ()
91
101
92
102
93
103
@@ -141,12 +151,13 @@ loadPackageObj ( name, (version,_) ) =
141
151
142data Output
152data Output
143 = None
153 = None
154+ | Html (Maybe FilePath) FilePath
144− | Custom (Maybe FilePath) FilePath
155+ | JavaScript (Maybe FilePath) FilePath
145
156
146
157
147−safeCustomPath :: Maybe FilePath -> FilePath -> IO FilePath
158+toWritablePath :: Maybe FilePath -> FilePath -> IO FilePath
148−safeCustomPath maybeDirectory fileName =
159+toWritablePath maybeDir fileName =
149− case maybeDirectory of
160+ case maybeDir of
150 Nothing ->
161 Nothing ->
151 do return fileName
162 do return fileName
152
163
@@ -175,24 +186,27 @@ parseOutput string =
175 if string == "/dev/null" || string == "NUL" || string == "$null" then
186 if string == "/dev/null" || string == "NUL" || string == "$null" then
176 Just None
187 Just None
177
188
178− else if FP.takeExtension string == ".js" then
189+ else if FP.takeExtension string == ".html" && length string > 5 then
179− toCustom string
190+ splitOutput Html string
191+
192+ else if FP.takeExtension string == ".js" && length string > 3 then
193+ splitOutput JavaScript string
180
194
181 else
195 else
182 Nothing
196 Nothing
183
197
184
198
185−toCustom :: String -> Maybe Output
199+splitOutput :: (Maybe FilePath -> FilePath -> Output) -> String -> Maybe Output
186−toCustom string =
200+splitOutput toOutput string =
187 case FP.splitPath string of
201 case FP.splitPath string of
188 [] ->
202 [] ->
189 Nothing
203 Nothing
190
204
191 [name] ->
205 [name] ->
192− Just $ Custom Nothing name
206+ Just $ toOutput Nothing name
193
207
194 segments ->
208 segments ->
195− Just $ Custom (Just (FP.joinPath (init segments))) (last segments)
209+ Just $ toOutput (Just (FP.joinPath (init segments))) (last segments)
196
210
197
211
198exampleOutput :: String -> IO [String]
212exampleOutput :: String -> IO [String]
compiler/src/Elm/Compiler/Objects.hs+1
@@ -2,6 +2,7 @@
2module Elm.Compiler.Objects
2module Elm.Compiler.Objects
3 ( Name.Target(..)
3 ( Name.Target(..)
4 , JS.Mode(..)
4 , JS.Mode(..)
5+ , JS.Output(..)
5 , JS.generate
6 , JS.generate
6 , JS.generateForRepl
7 , JS.generateForRepl
7 , Opt.Graph
8 , Opt.Graph
compiler/src/Generate/JavaScript.hs+18−9
@@ -1,6 +1,7 @@
1{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
2module Generate.JavaScript
2module Generate.JavaScript
3 ( Mode(..)
3 ( Mode(..)
4+ , Output(..)
4 , generate
5 , generate
5 , generateForRepl
6 , generateForRepl
6 )
7 )
@@ -39,20 +40,28 @@ import qualified Reporting.Helpers as H
39data Mode = Debug | Prod
40data Mode = Debug | Prod
40
41
41
42
43+data Output
44+ = None
45+ | Some N.Name [N.Name] B.Builder
46+
47+
42−generate :: Mode -> Name.Target -> I.Interfaces -> Opt.Graph -> [ModuleName.Canonical] -> Maybe B.Builder
48+generate :: Mode -> Name.Target -> I.Interfaces -> Opt.Graph -> [ModuleName.Canonical] -> Output
43generate mode target interfaces (Opt.Graph mains graph fields) roots =
49generate mode target interfaces (Opt.Graph mains graph fields) roots =
44 let
50 let
45 rootSet = Set.fromList roots
51 rootSet = Set.fromList roots
46 rootMap = Map.restrictKeys mains rootSet
52 rootMap = Map.restrictKeys mains rootSet
47 in
53 in
48− if Map.null rootMap then
54+ case map ModuleName._module (Map.keys rootMap) of
49− Nothing
55+ [] ->
50− else
56+ None
57+
58+ name:names ->
51− let
59+ let
52− realMode = toRealMode mode target fields
60+ realMode = toRealMode mode target fields
53− state = Map.foldrWithKey (addMain realMode graph) emptyState rootMap
61+ state = Map.foldrWithKey (addMain realMode graph) emptyState rootMap
54− in
55− Just $ stateToBuilder state <> toMainExports realMode interfaces rootMap
62+ builder = stateToBuilder state <> toMainExports realMode interfaces rootMap
63+ in
64+ Some name names builder
56
65
57
66
58addMain :: Name.Mode -> Graph -> ModuleName.Canonical -> main -> State -> State
67addMain :: Name.Mode -> Graph -> ModuleName.Canonical -> main -> State -> State
elm.cabal+1
@@ -107,6 +107,7 @@ Executable elm
107 File.Header,
107 File.Header,
108 File.Plan,
108 File.Plan,
109 Generate.Functions,
109 Generate.Functions,
110+ Generate.Html,
110 Generate.Output,
111 Generate.Output,
111 Reporting.Exit,
112 Reporting.Exit,
112 Reporting.Exit.Assets,
113 Reporting.Exit.Assets,
ui/terminal/src/Develop/StaticFiles/Build.hs+1−1
@@ -53,7 +53,7 @@ compile =
53options :: Output.Options
53options :: Output.Options
54options =
54options =
55 Output.Options Obj.Prod Obj.Client $
55 Output.Options Obj.Prod Obj.Client $
56− Just (Output.Custom Nothing tempFileName)
56+ Just (Output.JavaScript Nothing tempFileName)
57
57
58
58
59tempFileName :: FilePath
59tempFileName :: FilePath