on master help sign in
Get --output=index.html working again

Need to go through again later and make it prettier though.

commitc368061e0c99175402dae46a91584b1d503ee106 authorEvan Czaplicki <evancz@users.noreply.github.com> dateMon 2 Apr 2018, 12:35 (9 years ago) parent695c9d6
6 files changed+118−32
builder/src/Generate/Html.hs+61 builder/src/Generate/Output.hs+36−22 compiler/src/Elm/Compiler/Objects.hs+1 compiler/src/Generate/JavaScript.hs+18−9 elm.cabal+1 ui/terminal/src/Develop/StaticFiles/Build.hs+1−1
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
3131import qualified File.Crawl as Crawl
3232import qualified File.IO as IO
3333import qualified Generate.Functions as Functions
34+import qualified Generate.Html as Html
3435import qualified Reporting.Task as Task
3536import qualified Stuff.Paths as Paths
3637import Terminal.Args (Parser(..), suggestFiles)
@@ -63,31 +64,40 @@ generate options summary graph@(Crawl.Graph args _ _ _ _) =
6364
6465
6566generateMonolith :: 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 =
6768 do let pkg = Project.getName project
68− let roots = map (Module.Canonical pkg) names
69+ let roots = map (Module.Canonical pkg) rootNames
6970 objectGraph <- organize summary graph
7071 case Obj.generate debug target ifaces objectGraph roots of
71− Nothing ->
72+ Obj.None ->
7273 return ()
7374
74− Just builder ->
75+ Obj.Some name names builder ->
7576 let
7677 monolith =
7778 "(function(scope){\n'use strict';"
7879 <> Functions.functions <> builder <> "}(this));"
7980 in
8081 liftIO $
81− case output_ of
82− Nothing ->
83− IO.writeBuilder "elm.js" monolith
82+ case maybeOutput of
83+ Nothing ->
84+ IO.writeBuilder "elm.js" monolith
8485
85− Just None ->
86− return ()
86+ Just None ->
87+ return ()
8788
88− Just (Custom maybeDir fileName) ->
89− do path <- safeCustomPath maybeDir fileName
90− IO.writeBuilder path monolith
89+ Just (JavaScript maybeDir fileName) ->
90+ do path <- toWritablePath maybeDir fileName
91+ IO.writeBuilder path monolith
92+
93+ Just (Html maybeDir fileName) ->
94+ case names of
95+ [] ->
96+ do path <- toWritablePath maybeDir fileName
97+ IO.writeBuilder path (Html.sandwich name monolith)
98+
99+ _:_ ->
100+ return ()
91101
92102
93103
@@ -141,12 +151,13 @@ loadPackageObj ( name, (version,_) ) =
141151
142152data Output
143153 = None
144− | Custom (Maybe FilePath) FilePath
154+ | Html (Maybe FilePath) FilePath
155+ | JavaScript (Maybe FilePath) FilePath
145156
146157
147−safeCustomPath :: Maybe FilePath -> FilePath -> IO FilePath
148−safeCustomPath maybeDirectory fileName =
149− case maybeDirectory of
158+toWritablePath :: Maybe FilePath -> FilePath -> IO FilePath
159+toWritablePath maybeDir fileName =
160+ case maybeDir of
150161 Nothing ->
151162 do return fileName
152163
@@ -175,24 +186,27 @@ parseOutput string =
175186 if string == "/dev/null" || string == "NUL" || string == "$null" then
176187 Just None
177188
178− else if FP.takeExtension string == ".js" then
179− toCustom string
189+ else if FP.takeExtension string == ".html" && length string > 5 then
190+ splitOutput Html string
191+
192+ else if FP.takeExtension string == ".js" && length string > 3 then
193+ splitOutput JavaScript string
180194
181195 else
182196 Nothing
183197
184198
185−toCustom :: String -> Maybe Output
186−toCustom string =
199+splitOutput :: (Maybe FilePath -> FilePath -> Output) -> String -> Maybe Output
200+splitOutput toOutput string =
187201 case FP.splitPath string of
188202 [] ->
189203 Nothing
190204
191205 [name] ->
192− Just $ Custom Nothing name
206+ Just $ toOutput Nothing name
193207
194208 segments ->
195− Just $ Custom (Just (FP.joinPath (init segments))) (last segments)
209+ Just $ toOutput (Just (FP.joinPath (init segments))) (last segments)
196210
197211
198212exampleOutput :: String -> IO [String]
compiler/src/Elm/Compiler/Objects.hs+1
@@ -2,6 +2,7 @@
22module Elm.Compiler.Objects
33 ( Name.Target(..)
44 , JS.Mode(..)
5+ , JS.Output(..)
56 , JS.generate
67 , JS.generateForRepl
78 , Opt.Graph
compiler/src/Generate/JavaScript.hs+18−9
@@ -1,6 +1,7 @@
11{-# LANGUAGE OverloadedStrings #-}
22module Generate.JavaScript
33 ( Mode(..)
4+ , Output(..)
45 , generate
56 , generateForRepl
67 )
@@ -39,20 +40,28 @@ import qualified Reporting.Helpers as H
3940data Mode = Debug | Prod
4041
4142
42−generate :: Mode -> Name.Target -> I.Interfaces -> Opt.Graph -> [ModuleName.Canonical] -> Maybe B.Builder
43+data Output
44+ = None
45+ | Some N.Name [N.Name] B.Builder
46+
47+
48+generate :: Mode -> Name.Target -> I.Interfaces -> Opt.Graph -> [ModuleName.Canonical] -> Output
4349generate mode target interfaces (Opt.Graph mains graph fields) roots =
4450 let
4551 rootSet = Set.fromList roots
4652 rootMap = Map.restrictKeys mains rootSet
4753 in
48− if Map.null rootMap then
49− Nothing
50− else
51− let
52− realMode = toRealMode mode target fields
53− state = Map.foldrWithKey (addMain realMode graph) emptyState rootMap
54− in
55− Just $ stateToBuilder state <> toMainExports realMode interfaces rootMap
54+ case map ModuleName._module (Map.keys rootMap) of
55+ [] ->
56+ None
57+
58+ name:names ->
59+ let
60+ realMode = toRealMode mode target fields
61+ state = Map.foldrWithKey (addMain realMode graph) emptyState rootMap
62+ builder = stateToBuilder state <> toMainExports realMode interfaces rootMap
63+ in
64+ Some name names builder
5665
5766
5867addMain :: Name.Mode -> Graph -> ModuleName.Canonical -> main -> State -> State
elm.cabal+1
@@ -107,6 +107,7 @@ Executable elm
107107 File.Header,
108108 File.Plan,
109109 Generate.Functions,
110+ Generate.Html,
110111 Generate.Output,
111112 Reporting.Exit,
112113 Reporting.Exit.Assets,
ui/terminal/src/Develop/StaticFiles/Build.hs+1−1
@@ -53,7 +53,7 @@ compile =
5353options :: Output.Options
5454options =
5555 Output.Options Obj.Prod Obj.Client $
56− Just (Output.Custom Nothing tempFileName)
56+ Just (Output.JavaScript Nothing tempFileName)
5757
5858
5959tempFileName :: FilePath