on master help sign in
Minor bug fixes for foreign imports/exports. Update changelog
882a381evancz
elm/changelog.txt+31−4
@@ -1,17 +1,44 @@
1+
1Release 0.3.5
2Release 0.3.5
2=============
3=============
3
4
4* Add JavaScript event interface. Allows Elm to import and export JS values
5* Add JavaScript event interface. Allows Elm to import and export JS values
5 and events. This makes it possible to import and export Elements, so users
6 and events. This makes it possible to import and export Elements, so users
6 can use JS techniques and libraries if necessary.
7 can use JS techniques and libraries if necessary.
8+
7* Add new flags to help with JavaScript event interface.
9* Add new flags to help with JavaScript event interface.
10+
11+* Add three built-in event listeners (elm_title, elm_log, elm_redirect) that
12+ make it possible to make some common/simple imperative actions without
13+ having to worry about writing the JS yourself. For example:
14+ foreign export jsevent "elm_title"
15+ title :: Signal JSString
16+ will update the page's title to the current value of the title signal.
17+ Empty strings are ignored. "elm_redirect" and "elm_log" events work much
18+ the same way, except that "elm_log" does not skip empty strings.
19+
8* Add new Signal functions:
20* Add new Signal functions:
9− count :: Signal a -> Signal Int
21+ count :: Signal a -> Signal Int
10− keepIf :: a -> (a -> Bool) -> Signal a -> Signal a
22+ keepIf :: (a -> Bool) -> a -> Signal a -> Signal a
23+ dropIf :: (a -> Bool) -> a -> Signal a -> Signal a
24+ keepWhen :: Signal Bool -> a -> Signal a -> Signal a
11− dropIf :: a -> (a -> Bool) -> Signal a -> Signal a
25+ dropWhen :: Signal Bool -> a -> Signal a -> Signal a
12 dropRepeats :: Signal a -> Signal a
26 dropRepeats :: Signal a -> Signal a
13 The keep and drop functions make it possible to filter events, which
27 The keep and drop functions make it possible to filter events, which
14− was not possible in prior releases.
28+ was not possible in prior releases. More documentation:
29+ http://elm-lang.org/docs/Signal/Signal.elm
30+
31+* Add examples of JS event interface and new signal functions:
32+ https://github.com/evancz/Elm/tree/master/Examples/elm-js
33+
34+* Use more compressed format for strings. Should make strings 10-12 times
35+ more space efficient than in previous releases. Anecdotal evidence:
36+ Elm's home page is now 70% of its previous size.
37+
38+* Add new function to Data.List:
39+ last :: [a] -> a
40+
41+* Fix parenthesization bug with binary operators.
15
42
16
43
17
44
elm/elm-runtime-0.3.5.js+26−7
@@ -255,6 +255,17 @@ var Value = function(){
255 }
255 }
256 return v[2];
256 return v[2];
257 }
257 }
258+ function last(v) {
259+ if (v[0] !== "Cons") {
260+ throw "Error: 'last' only accepts lists of length greater than one.";
261+ }
262+ var out = v[1];
263+ while (v[0] === "Cons") {
264+ out = v[1];
265+ v = v[2];
266+ }
267+ return out;
268+ }
258 function map(f) {
269 function map(f) {
259 return function(xs) {
270 return function(xs) {
260 if (xs[0] === "Nil") { return xs; }
271 if (xs[0] === "Nil") { return xs; }
@@ -634,6 +645,7 @@ var Value = function(){
634 }
645 }
635 return {head:head,
646 return {head:head,
636 tail:tail,
647 tail:tail,
648+ last:last,
637 map:map,
649 map:map,
638 foldl:foldl,
650 foldl:foldl,
639 foldr:foldr,
651 foldr:foldr,
@@ -713,6 +725,7 @@ var Maybe = function() {
713 };
725 };
714}();
726}();
715
727
728+/*
716var String = function() {
729var String = function() {
717
730
718 function append(s1) { return function(s2) {
731 function append(s1) { return function(s2) {
@@ -784,16 +797,14 @@ var String = function() {
784 concatMap : concatMap,
797 concatMap : concatMap,
785 forall : forall,
798 forall : forall,
786 exists : exists,
799 exists : exists,
787− /*
788− filter : filter,
800+ //filter : filter,
789− take:,
801+ //take:,
790− drop:,
802+ //drop:,
791− */
792 toText : Value.toText,
803 toText : Value.toText,
793 properEscape : Value.properEscape
804 properEscape : Value.properEscape
794 };
805 };
795}();
806}();
796−
807+*/
797return {String: {toText:Value.toText, properEscape:Value.properEscape},
808return {String: {toText:Value.toText, properEscape:Value.properEscape},
798 Char:Char,
809 Char:Char,
799 Maybe:Maybe,
810 Maybe:Maybe,
@@ -1910,7 +1921,8 @@ var Signal = function() {
1910 button:button};
1921 button:button};
1911 }();
1922 }();
1912
1923
1924+ return {addListener:addListener,
1913− return {Mouse:Mouse,
1925+ Mouse:Mouse,
1914 Keyboard:Keyboard,
1926 Keyboard:Keyboard,
1915 Time:Time,
1927 Time:Time,
1916 Window:Window,
1928 Window:Window,
@@ -1992,6 +2004,7 @@ var Prelude = function() {
1992 filter : Data.List.filter,
2004 filter : Data.List.filter,
1993 head : Data.List.head,
2005 head : Data.List.head,
1994 tail : Data.List.tail,
2006 tail : Data.List.tail,
2007+ last : Data.List.last,
1995 length : Data.List.length,
2008 length : Data.List.length,
1996 reverse : Data.List.reverse,
2009 reverse : Data.List.reverse,
1997 foldr : Data.List.foldr,
2010 foldr : Data.List.foldr,
@@ -2028,6 +2041,12 @@ var Prelude = function() {
2028}();
2041}();
2029var eq = Value.eq;
2042var eq = Value.eq;
2030
2043
2044+Signal.addListener(document, 'elm_log', function(e) { console.log(e.value); });
2045+Signal.addListener(document, 'elm_title', function(e) { document.title = e.value; });
2046+Signal.addListener(document, 'elm_redirect', function(e) {
2047+ if (e.value.length > 0) { window.location = e.value; }
2048+ });
2049+
2031var includeGlobal = this;
2050var includeGlobal = this;
2032(function() {
2051(function() {
2033 var include = function(library) {
2052 var include = function(library) {
elm/src/Gen/CompileToJS.hs+5−5
@@ -61,15 +61,15 @@ jsModule (Module names exports imports defs foreigns) =
61 (concatMap importEvent i, concatMap exportEvent e)
61 (concatMap importEvent i, concatMap exportEvent e)
62
62
63importEvent (js,base,elm,_) =
63importEvent (js,base,elm,_) =
64− concat [ "var " ++ elm ++ " = Elm.Input(" ++ toJS base ++ ");"
64+ concat [ "\nvar " ++ elm ++ " = Elm.Input(" ++ toJS base ++ ");"
65− , "Signal.addListener(document, '" ++ js
65+ , "\nSignal.addListener(document, '" ++ js
66 , "', function(e) { Dispatcher.notify(" ++ elm
66 , "', function(e) { Dispatcher.notify(" ++ elm
67 , ".id, e.value); });" ]
67 , ".id, e.value); });" ]
68exportEvent (js,elm,_) =
68exportEvent (js,elm,_) =
69− concat [ "lift (function(v) { var e = document.createEvent('Event');"
69+ concat [ "\nlift(function(v) { var e = document.createEvent('Event');"
70 , "e.initEvent('" ++ js ++ "', true, true);"
70 , "e.initEvent('" ++ js ++ "', true, true);"
71 , "e.value = v;"
71 , "e.value = v;"
72− , "document.dispatchEvent(e); return v; })(" ++ elm ++ ")"
72+ , "document.dispatchEvent(e); return v; })(" ++ elm ++ ");"
73 ]
73 ]
74
74
75jsImport (modul, how) =
75jsImport (modul, how) =
@@ -158,6 +158,6 @@ binop (o:p) e1 e2
158 "." -> jsFunc "x" . ret $ e1 ++ parens (e2 ++ parens "x")
158 "." -> jsFunc "x" . ret $ e1 ++ parens (e2 ++ parens "x")
159 "==" -> "eq(" ++ e1 ++ "," ++ e2 ++ ")"
159 "==" -> "eq(" ++ e1 ++ "," ++ e2 ++ ")"
160 "/=" -> "not(eq(" ++ e1 ++ "," ++ e2 ++ "))"
160 "/=" -> "not(eq(" ++ e1 ++ "," ++ e2 ++ "))"
161− _ -> e1 ++ (o:p) ++ e2
161+ _ -> parens (e1 ++ (o:p) ++ e2)
162
162
163append e1 e2 = "Value.append" ++ parens (e1 ++ "," ++ e2)
163append e1 e2 = "Value.append" ++ parens (e1 ++ "," ++ e2)
elm/src/Initialize.hs+1
@@ -10,6 +10,7 @@ import Unify
10import Rename
10import Rename
11import Optimize
11import Optimize
12
12
13+
13initialize str = do
14initialize str = do
14 (Module name ex im defs (ims,exs), tipes) <- parseProgram str
15 (Module name ex im defs (ims,exs), tipes) <- parseProgram str
15 let (Let ds _) = rename . Let defs $ Var "_"
16 let (Let ds _) = rename . Let defs $ Var "_"
elm/src/Parse/ParseForeign.hs+3−2
@@ -9,6 +9,7 @@ import Ast
9import ParseLib
9import ParseLib
10import ParseExpr (term)
10import ParseExpr (term)
11import ParseTypes
11import ParseTypes
12+import Types (signalOf)
12
13
13
14
14foreignDefs = do
15foreignDefs = do
@@ -28,7 +29,7 @@ exportEvent = do
28 tipe <- typeExpr
29 tipe <- typeExpr
29 case tipe of
30 case tipe of
30 ADTPT "Signal" [pt] ->
31 ADTPT "Signal" [pt] ->
31− either fail (return . (,,) js elm) (toForeignType pt)
32+ either fail (return . (,,) js elm . signalOf) (toForeignType pt)
32 _ -> fail "When exporting events, the exported value must be a Signal."
33 _ -> fail "When exporting events, the exported value must be a Signal."
33
34
34importEvent = do
35importEvent = do
@@ -41,7 +42,7 @@ importEvent = do
41 tipe <- typeExpr
42 tipe <- typeExpr
42 case tipe of
43 case tipe of
43 ADTPT "Signal" [pt] ->
44 ADTPT "Signal" [pt] ->
44− either fail (return . (,,,) js base elm) (toForeignType pt)
45+ either fail (return . (,,,) js base elm . signalOf) (toForeignType pt)
45 _ -> fail "When importing events, the imported value must be a Signal."
46 _ -> fail "When importing events, the imported value must be a Signal."
46
47
47
48
elm/src/Parse/ParseTypes.hs+1−1
@@ -99,4 +99,4 @@ toForeignType (VarPT x@(c:_))
99 | otherwise = Left $ "'" ++ x ++ "' is not an exportable type. Only JSTypes are exportable."
99 | otherwise = Left $ "'" ++ x ++ "' is not an exportable type. Only JSTypes are exportable."
100
100
101isJsStructure name = name == "JSArray" || isTuple
101isJsStructure name = name == "JSArray" || isTuple
102− where isTuple = "JSTuple" == take 7 name && name `elem` map show [2..5]
102+ where isTuple = "JSTuple" == take 7 name && drop 7 name `elem` map show [2..5]
elm/src/Types/Hints.hs+7−1
@@ -56,7 +56,7 @@ casts =
56 , "castBoolToJSBool" -: BoolT ==> jsBool
56 , "castBoolToJSBool" -: BoolT ==> jsBool
57 , "castJSNumberToInt" -: jsNumber ==> IntT
57 , "castJSNumberToInt" -: jsNumber ==> IntT
58 , "castIntToJSNumber" -: IntT ==> jsNumber
58 , "castIntToJSNumber" -: IntT ==> jsNumber
59− , "castJSElementToElement" -: jsElement ==> element
59+ , "castJSElementToElement" -: IntT ==> IntT ==> jsElement ==> element
60 , "castElementToJSElement" -: element ==> jsElement
60 , "castElementToJSElement" -: element ==> jsElement
61 , "castJSStringToString" -: jsString ==> string
61 , "castJSStringToString" -: jsString ==> string
62 , "castStringToJSString" -: string ==> jsString
62 , "castStringToJSString" -: string ==> jsString
@@ -92,6 +92,12 @@ signals = sequence
92 , do [a,b] <- vars 2
92 , do [a,b] <- vars 2
93 "foldp" -:: (a ==> b ==> b) ==> b ==> signalOf a ==> signalOf b
93 "foldp" -:: (a ==> b ==> b) ==> b ==> signalOf a ==> signalOf b
94 , do a <- var ; "randomize" -:: IntT ==> IntT ==> signalOf a ==> signalOf IntT
94 , do a <- var ; "randomize" -:: IntT ==> IntT ==> signalOf a ==> signalOf IntT
95+ , do a <- var ; "count" -:: signalOf a ==> signalOf IntT
96+ , do a <- var ; "keepIf" -:: (a==>BoolT) ==> a ==> signalOf a ==> signalOf a
97+ , do a <- var ; "dropIf" -:: (a==>BoolT) ==> a ==> signalOf a ==> signalOf a
98+ , do a <- var ; "keepWhen" -:: signalOf BoolT ==>a==> signalOf a ==> signalOf a
99+ , do a <- var ; "dropWhen" -:: signalOf BoolT ==>a==> signalOf a ==> signalOf a
100+ , do a <- var ; "dropRepeats" -:: signalOf a ==> signalOf a
95 ]
101 ]
96
102
97concreteSignals =
103concreteSignals =