on master help sign in
Merge branch 'json' into dev
commita862b89da9cdfc77a5c98664a87c7ba162732371 authorEvan Czaplicki <info@elm-lang.org> dateThu 27 Mar 2014, 18:59 (13 years ago) parent15d87f232b7c18
19 files changed+256−433
compiler/Generate/JavaScript.hs+1−2 compiler/Generate/JavaScript/Ports.hs+14−15 compiler/Metadata/Prelude.hs+3−1 compiler/Type/ExtraChecks.hs+7−10 libraries/Graphics/Collage.elm−1 libraries/Graphics/Element.elm+10−13 libraries/JavaScript.elm−74 libraries/JavaScript/Experimental.elm+30−16 libraries/Json.elm+25−110 libraries/Native/Date.js+1−2 libraries/Native/JavaScript.js+59−91 libraries/Native/Json.js+71−58 libraries/Native/Regex.js+14−14 libraries/Native/Signal/Http.js+6−7 libraries/Native/Signal/Touch.js+3−3 libraries/Native/Signal/WebSocket.js+3−5 libraries/Native/String.js+9−9 libraries/Text.elm−1 libraries/elm_dependencies.json−1
compiler/Generate/JavaScript.hs+1−2
@@ -39,7 +39,6 @@ internalImports name =
3939 , include "_U" "_N.Utils"
4040 , include "_L" "_N.List"
4141 , include "_E" "_N.Error"
42− , include "_J" "_N.JavaScript"
4342 , varDecl "$moduleName" (string name)
4443 ]
4544
@@ -163,7 +162,7 @@ expression (A region expr) =
163162
164163 ExplicitList es ->
165164 do es' <- mapM expression es
166− return $ obj "_J.toList" <| ArrayLit () es'
165+ return $ obj "_L.fromArray" <| ArrayLit () es'
167166
168167 Data name es ->
169168 do es' <- mapM expression es
compiler/Generate/JavaScript/Ports.hs+14−15
@@ -35,17 +35,17 @@ inc tipe x =
3535 case tipe of
3636 Lambda _ _ -> error "functions should not be allowed through input ports"
3737 Var _ -> error "type variables should not be allowed through input ports"
38+
39+ Data "Json.Value" [] ->
40+ obj "Native.Json.fromJS" <| x
41+
3842 Data ctor []
39− | ctor == "Int" -> elm JSNumber
40− | ctor == "Float" -> elm JSNumber
41− | ctor == "Bool" -> elm JSBoolean
42− | ctor == "String" -> elm JSString
43− | ctor == "JavaScript.JSNumber" -> js JSNumber
44− | ctor == "JavaScript.JSBool" -> js JSBoolean
45− | ctor == "JavaScript.JSString" -> js JSString
43+ | ctor == "Int" -> from JSNumber
44+ | ctor == "Float" -> from JSNumber
45+ | ctor == "Bool" -> from JSBoolean
46+ | ctor == "String" -> from JSString
4647 where
47− elm checks = check x checks (obj ("_J.to" ++ ctor) <| x)
48− js checks = check x checks x
48+ from checks = check x checks x
4949
5050 Data ctor [t]
5151 | ctor == "Maybe.Maybe" ->
@@ -54,7 +54,7 @@ inc tipe x =
5454 (obj "Maybe.Just" <| inc t x)
5555
5656 | ctor == "_List" ->
57− check x JSArray (obj "_J.toList" <| array)
57+ check x JSArray (obj "_L.fromArray" <| array)
5858 where
5959 array = DotRef () x (var "map") <| incoming t
6060
@@ -104,10 +104,9 @@ out tipe x =
104104
105105 Var _ -> error "type variables should not be allowed through input ports"
106106 Data ctor []
107− | ctor `elem` ["Int","Float","Bool","String"] -> obj ("_J.from" ++ ctor) <| x
108− | ctor `elem` jsPrims -> x
109− where
110− jsPrims = map ("JavaScript.JS"++) ["Number","Bool","String"]
107+ | ctor `elem` ["Int","Float","Bool","String"] -> x
108+ | ctor == "Json.Value" ->
109+ obj "Native.Json.toJS" <| x
111110
112111 Data ctor [t]
113112 | ctor == "Maybe.Maybe" ->
@@ -116,7 +115,7 @@ out tipe x =
116115 (out t (DotRef () x (var "_0")))
117116
118117 | ctor == "_List" ->
119− DotRef () (obj "_J.fromList" <| x) (var "map") <| outgoing t
118+ DotRef () (obj "_L.toArray" <| x) (var "map") <| outgoing t
120119
121120 Data ctor ts
122121 | Help.isTuple ctor ->
compiler/Metadata/Prelude.hs+3−1
@@ -25,7 +25,9 @@ prelude = string ++ text ++ map (\n -> (n, Hiding [])) modules
2525 text = map ((,) "Text") [ As "Text", Hiding ["link", "color", "height"] ]
2626 string = map ((,) "String") [ As "String", Importing ["show"] ]
2727 modules = [ "Basics", "Signal", "List", "Maybe", "Time", "Color"
28− , "Graphics.Element", "Graphics.Collage", "Native.Ports" ]
28+ , "Graphics.Element", "Graphics.Collage"
29+ , "Native.Ports", "Native.Json"
30+ ]
2931
3032interfaces :: Bool -> IO Interfaces
3133interfaces noPrelude =
compiler/Type/ExtraChecks.hs+7−10
@@ -8,7 +8,6 @@ module Type.ExtraChecks (mainType, occurs, portTypes) where
88
99import Control.Applicative ((<$>),(<*>))
1010import Control.Monad.State
11−import qualified Data.List as List
1211import qualified Data.Map as Map
1312import qualified Data.Traversable as Traverse
1413import qualified Data.UnionFind.IO as UF
@@ -56,9 +55,15 @@ portTypes rules expr =
5655 isValid isTopLevel seenFunc seenSignal direction name tipe =
5756 case tipe of
5857 ST.Data ctor ts
59− | isJs ctor || isElm ctor -> mapM_ valid ts
58+ | validConstructor -> mapM_ valid ts
6059 | ctor == "Signal.Signal" -> handleSignal ts
6160 | otherwise -> err' True "an unsupported type"
61+ where
62+ primitives =
63+ ["Int","Float","String","Bool","Maybe.Maybe","_List","Json.Value"]
64+
65+ validConstructor =
66+ ctor `elem` primitives || Help.isTuple ctor
6267
6368 ST.Var _ -> err "free type variables"
6469
@@ -80,14 +85,6 @@ portTypes rules expr =
8085 isValid' = isValid False
8186 valid = isValid' seenFunc seenSignal direction name
8287
83− isJs ctor =
84− List.isPrefixOf "JavaScript." ctor
85− && length (filter (=='.') ctor) == 1
86−
87− isElm ctor =
88− ctor `elem` ["Int","Float","String","Bool","Maybe.Maybe","_List"]
89− || Help.isTuple ctor
90−
9188 handleSignal ts
9289 | seenFunc = err "functions that involve signals"
9390 | seenSignal = err "signals-of-signals"
libraries/Graphics/Collage.elm−1
@@ -38,7 +38,6 @@ import Native.Graphics.Collage
3838import Graphics.Element (Element)
3939import Color (Color, black, Gradient)
4040import Maybe (Maybe)
41−import JavaScript (JSString)
4241
4342type Form = {
4443 theta : Float,
libraries/Graphics/Element.elm+10−13
@@ -39,8 +39,6 @@ If you need more precision, you can create custom positions.
3939
4040import Basics (..)
4141import Native.Utils
42−import JavaScript as JS
43−import JavaScript (JSString)
4442import List as List
4543import Color (..)
4644import Maybe (Maybe, Just, Nothing)
@@ -51,8 +49,8 @@ type Properties = {
5149 height : Int,
5250 opacity : Float,
5351 color : Maybe Color,
54− href : JSString,
55− tag : JSString,
52+ href : String,
53+ tag : String,
5654 hover : (),
5755 click : ()
5856 }
@@ -120,21 +118,20 @@ with a link like this: `/facts-about-animals.elm#all-about-badgers`
120118-}
121119tag : String -> Element -> Element
122120tag name e = let p = e.props in
123− { element=e.element, props={p | tag <- JS.fromString name} }
121+ { element=e.element, props={p | tag <- name} }
124122
125123{-| Create an `Element` that is a hyper-link. -}
126124link : String -> Element -> Element
127125link href e = let p = e.props in
128− { element=e.element, props={p | href <- JS.fromString href} }
126+ { element=e.element, props={p | href <- href} }
129127
130−emptyStr = JS.fromString ""
131128newElement w h e =
132− { props = Properties (Native.Utils.guid ()) w h 1 Nothing emptyStr emptyStr () ()
129+ { props = Properties (Native.Utils.guid ()) w h 1 Nothing "" "" () ()
133130 , element = e
134131 }
135132
136133data ElementPrim
137− = Image ImageStyle Int Int JSString
134+ = Image ImageStyle Int Int String
138135 | Container Position Element
139136 | Flow Direction [Element]
140137 | Spacer
@@ -145,13 +142,13 @@ data ImageStyle = Plain | Fitted | Cropped (Int,Int) | Tiled
145142
146143{-| Create an image given a width, height, and image source. -}
147144image : Int -> Int -> String -> Element
148−image w h src = newElement w h (Image Plain w h (JS.fromString src))
145+image w h src = newElement w h (Image Plain w h src)
149146
150147{-| Create a fitted image given a width, height, and image source.
151148This will crop the picture to best fill the given dimensions.
152149-}
153150fittedImage : Int -> Int -> String -> Element
154−fittedImage w h src = newElement w h (Image Fitted w h (JS.fromString src))
151+fittedImage w h src = newElement w h (Image Fitted w h src)
155152
156153{-| Create a cropped image. Take a rectangle out of the picture starting
157154at the given top left coordinate. If you have a 140-by-140 image,
@@ -161,11 +158,11 @@ the following will cut a 100-by-100 square out of the middle of it.
161158-}
162159croppedImage : (Int,Int) -> Int -> Int -> String -> Element
163160croppedImage pos w h src =
164− newElement w h (Image (Cropped pos) w h (JS.fromString src))
161+ newElement w h (Image (Cropped pos) w h src)
165162
166163tiledImage : Int -> Int -> String -> Element
167164tiledImage w h src =
168− newElement w h (Image Tiled w h (JS.fromString src))
165+ newElement w h (Image Tiled w h src)
169166
170167data Three = P | Z | N
171168data Pos = Absolute Int | Relative Float
libraries/JavaScript.elmdeleted−74
@@ -1,74 +0,0 @@
1−
2−module JavaScript where
3−
4−{-|This library does basic conversions between Elm and JS values. This allows
5−the internal data structures of Elm to change and improve with no impact on JS
6−integration.
7−
8−It is intended to be imported as `import JavaScript as JS`. That way functions
9−like `JS.toInt` convert JavaScript *to* Elm integers and functions like
10−`JS.fromString` gets JavaScript *from* Elm strings.
11−
12−# Javascript to Elm
13−@docs toString, toInt, toFloat, toBool, toList
14−
15−# JavaScript from Elm
16−@docs fromString, fromInt, fromFloat, fromBool, fromList
17−-}
18−{-
19−# DOM Nodes and Elements
20−@docs toElement, fromElement
21−-}
22−
23−import Native.JavaScript
24−
25−data JSNumber = JSNumber
26−data JSBool = JSBool
27−data JSString = JSString
28−data JSArray a = JSArray a
29−data JSDomNode = JSDomNode
30−data JSObject = JSObject
31−
32−{-| Requires that the input array be uniform (all members have the same type) -}
33−toList : JSArray a -> [a]
34−toList = Native.JavaScript.toList
35−
36−toInt : JSNumber -> Int
37−toInt = Native.JavaScript.toInt
38−
39−toFloat : JSNumber -> Float
40−toFloat = Native.JavaScript.toFloat
41−
42−toBool : JSBool -> Bool
43−toBool = Native.JavaScript.toBool
44−
45−toString : JSString -> String
46−toString = Native.JavaScript.toString
47−
48−
49−{-| Produces a uniform JavaScript array with all members of the same type. -}
50−fromList : [a] -> JSArray a
51−fromList = Native.JavaScript.fromList
52−
53−fromInt : Int -> JSNumber
54−fromInt = Native.JavaScript.fromInt
55−
56−fromFloat : Float -> JSNumber
57−fromFloat = Native.JavaScript.fromFloat
58−
59−fromBool : Bool -> JSBool
60−fromBool = Native.JavaScript.fromBool
61−
62−fromString : String -> JSString
63−fromString = Native.JavaScript.fromString
64−
65−{-
66−{-| Turn an `Element` into a DOM node. -}
67−fromElement : Element -> JSDomNode
68−fromElement = Native.JavaScript.fromElement
69−
70−{-| Turn a DOM node into an `Element`. You can resize the node
71−using the normal `width` and `height` functions. -}
72−toElement : Int -> Int -> JSDomNode -> Element
73−toElement = Native.JavaScript.toElement
74−-}
libraries/JavaScript/Experimental.elm+30−16
@@ -8,34 +8,48 @@ improve as we find its key failings.
88@docs toRecord, fromRecord
99-}
1010
11−import JavaScript (JSObject)
1211import Native.JavaScript
12+import Json
13+
14+data RawObject = RawObject
1315
1416{-| Turn arbitrary JavaScript objects into Elm records.
1517Arrays are converted into lists, nested objects are allowed.
1618No `null` values or non-homogeneous arrays.
1719
18− -- OK objects
19− { student:"Steve", scores:[83,94,99,72] }
20− { errorLevel:10, critical:true }
20+ -- OK objects
21+ { student:"Steve", scores:[83,94,99,72] }
22+ { errorLevel:10, critical:true }
2123
22− -- BAD objects
23− { answer:null }
24− { info:[true,42,'what'] }
24+ -- BAD objects
25+ { answer:null }
26+ { info:[true,42,'what'] }
2527-}
26−toRecord : JSObject -> a
28+toRecord : RawObject -> a
2729toRecord = Native.JavaScript.toRecord
2830
2931{-| Turn arbitrary Elm records into JavaScript objects.
3032Lists become arrays, nested records are allowed. No ADTs.
3133
32− -- OK records
33− { student="Steve", scores=[83,94,99,72] }
34− { errorLevel=10, critical=True }
34+ -- OK records
35+ { student="Steve", scores=[83,94,99,72] }
36+ { errorLevel=10, critical=True }
37+
38+ -- BAD records
39+ { answer = Nothing }
40+ { result = Left "An error occurred" }
41+-}
42+fromRecord : a -> RawObject
43+fromRecord = Native.JavaScript.fromRecord
44+
45+{-| Turn a raw JavaScript object into a `Json.Value` as described in the
46+`Json` library.
47+-}
48+toJson : RawObject -> Json.Value
49+toJson = Native.Json.fromJS
3550
36− -- BAD records
37− { answer = Nothing }
38− { result = Left "An error occurred" }
51+{-| Turn a `Json.Value` (as described in the `Json` library) into a raw
52+JavaScript object.
3953-}
40−fromRecord : a -> JSObject
41−fromRecord = Native.JavaScript.fromRecord
54+fromJson : Json.Value -> RawObject
55+fromJson = Native.Json.toJS
libraries/Json.elm+25−110
@@ -3,132 +3,47 @@ module Json where
33
44{-| Library for working with [JSON](https://en.wikipedia.org/wiki/JSON) values.
55
6−# Json Values
7−@docs JsonValue
8−
9−# Strings
10−@docs fromString, toString
11−
12−# JS Strings
13−@docs fromJSString, toJSString
14−
15−# JS Objects
16−@docs fromJSObject, toJSObject
6+@docs Value, fromString, toString
177
188-}
199
20−import Basics (..)
2110import Dict
2211import Maybe (Maybe)
23−import JavaScript as JS
2412import Native.Json
25−import JavaScript (JSObject, JSString)
2613
27−{-| This datatype can represent all valid values that can be held in a JSON
28−object. In Elm, a proper JSON object is represented as a (Dict String JsonValue)
29−which is a mapping from strings to Json Values. -}
30−data JsonValue
14+{-| This datatype can represent all valid JSON values. A `Value` can be sent
15+through ports, and the runtime will do a conversion like this:
16+
17+ [2,'abc',null] == Array [Number 2, String "abc", Null]
18+
19+JSON is an intentional subset of JavaScript values which excludes functions.
20+This ensures that impure functions cannot sneak into Elm through ports.
21+-}
22+data Value
3123 = String String
3224 | Number Float
3325 | Boolean Bool
3426 | Null
35− | Array [JsonValue]
36− | Object (Dict.Dict String JsonValue)
37−
27+ | Array [Value]
28+ | Object (Dict.Dict String Value)
3829
39−-- String Converters
4030
41−{-| Convert a `JsonValue` into a prettified string.
31+{-| Convert a `Value` into a prettified string.
4232The first argument is a separator token (e.g. \" \", \"\\n\", etc.) that will
43−be used for indentation in the prettified string version of the JSON. -}
44−toString : String -> JsonValue -> String
45−toString sep v = JS.toString (Native.Json.toJSString sep v)
33+be used for indentation in the prettified string version of the JSON.
4634
47−{-| Convert a proper JSON object into a JavaScript string.
48−Note that the type JSString seen here is not the same as the type constructor
49−JsonString used elsewhere in this module. -}
50−toJSString : String -> JsonValue -> JSString
51−toJSString = Native.Json.toJSString
35+ toString "" Null == "null"
36+ toString "" (Number 4.0) == "4.0"
37+-}
38+toString : String -> Value -> String
39+toString sep value = Native.Json.toString sep value
5240
5341{-| Parse a string representation of a proper JSON object into
54−its Elm representation. -}
55−fromString : String -> Maybe JsonValue
56−fromString s = Native.Json.fromJSString (JS.fromString s)
57−
58−{-| Parse a JavaScript string representation of a proper JSON object into
59−its Elm representation. -}
60−fromJSString : JSString -> Maybe JsonValue
61−fromJSString = Native.Json.fromJSString
62−
63−{-| Convert a JS object into a `JsonValue`. -}
64−fromJSObject : JSObject -> JsonValue
65−fromJSObject = Native.Json.fromJSObject
42+its Elm representation.
6643
67−{-| Convert a `JsonValue` into a `JSObject`. Paired with the
68−[`JavaScript.Experimental` library](/docs/JavaScript/Experimental.elm),
69−This lets you convert strings into Elm records:
70−
71− import JavaScript.Experimental as JS
72−
73− stringToRecord str =
74− case fromString str of
75− Just jsonValue -> Just (JS.toRecord (toJSObject jsonValue))
76− Nothing -> Nothing
44+ fromString "null" == Just Null
45+ fromString "[true,3]" == Just (Array [Boolean True, Number 3])
46+ fromString "{'abc':4}" == Just (Object (Dict.fromList [("abc", Number 4)]))
7747-}
78−toJSObject : JsonValue -> JSObject
79−toJSObject = Native.Json.toJSObject
80−
81− {-- Extract Elm values from Json values
82−
83− string : JsonValue -> String
84− string v = case v of { String s -> s ; _ -> "" }
85−
86− number : JsonValue -> Float
87− number v = case v of { Number n -> n ; _ -> 0 }
88−
89− boolean : JsonValue -> Bool
90− boolean v = case v of { Boolean b -> b ; _ -> False }
91−
92− array : JsonValue -> [JsonValue]
93− array v = case v of { Array a -> a ; _ -> [] }
94−
95− object : JsonValue -> Dict String JsonValue
96− object v = case v of { Object o -> o ; _ -> Dict.empty }
97−
98−
99− -- Extract Elm values from dictionaries of Json values
100−
101− {-| Find a value in a Json Object using the passed get function. If the key is
102− not found, this returns the given default/base value. -}
103− find get base =
104− let f key dict =
105− case Dict.lookup key dict of
106− Nothing -> base
107− Just v -> get v
108− in f
109−
110− {-| Find a string value in an Elm Json object. If the key is not found or the
111− value found is not a string, this returns the empty string. -}
112− findString : String -> Object -> String
113− findString = find string ""
114−
115− {-| Find a number value in an Elm Json object. If the key is not found or the
116− value found is not a number, this returns 0 -}
117− findNumber : String -> Object -> Float
118− findNumber = find number 0
119−
120− {-| Find a boolean value in an Elm Json object. If the key is not found or the
121− value found is not a boolean, this returns the False. -}
122− findBoolean : String -> Object -> Bool
123− findBoolean = find boolean False
124−
125− {-| Find an array value in an Elm Json object. If the key is not found or the
126− value found is not an array, this returns an empty list. -}
127− findArray : String -> Object -> [JsonValue]
128− findArray = find array []
129−
130− {-| Find an object value in an Elm Json object. If the key is not found or the
131− value found is not an object, this returns an empty object. -}
132− findObject : String -> Object -> Object
133− findObject = find object Dict.empty
134− --}
48+fromString : String -> Maybe Value
49+fromString str = Native.Json.fromString str
libraries/Native/Date.js+1−2
@@ -4,12 +4,11 @@ Elm.Native.Date.make = function(elm) {
44 elm.Native.Date = elm.Native.Date || {};
55 if (elm.Native.Date.values) return elm.Native.Date.values;
66
7− var JS = Elm.JavaScript.make(elm);
87 var Maybe = Elm.Maybe.make(elm);
98
109 function dateNow() { return new window.Date; }
1110 function readDate(str) {
12− var d = new window.Date(JS.fromString(str));
11+ var d = new window.Date(str);
1312 if (isNaN(d.getTime())) return Maybe.Nothing;
1413 return Maybe.Just(d);
1514 }
libraries/Native/JavaScript.js+59−91
@@ -1,100 +1,68 @@
11Elm.Native.JavaScript = {};
22Elm.Native.JavaScript.make = function(elm) {
3− elm.Native = elm.Native || {};
4− elm.Native.JavaScript = elm.Native.JavaScript || {};
5− if (elm.Native.JavaScript.values) return elm.Native.JavaScript.values;
3+ elm.Native = elm.Native || {};
4+ elm.Native.JavaScript = elm.Native.JavaScript || {};
5+ if (elm.Native.JavaScript.values) return elm.Native.JavaScript.values;
66
7− var List = Elm.Native.List.make(elm);
8− var Render = ElmRuntime.use(ElmRuntime.Render.Element);
7+ var List = Elm.Native.List.make(elm);
8+ var Render = ElmRuntime.use(ElmRuntime.Render.Element);
99
10− function fromJS(v) {
11− var type = typeof v;
12− if (type === 'number' ) return v;
13− if (type === 'boolean') return v;
14− if (type === 'string' ) return v;
15− if (v instanceof Array) {
16− var arr = [];
17− var len = v.length;
18− for (var i = 0; i < len; ++i) {
19− var x = fromJS(v[i]);
20− if (x !== null) arr.push(x);
21− }
22− return List.fromArray(arr);
23− }
24− if (type === 'object') {
25− var rec = { _:{} };
26− for (var f in v) {
27− var x = fromJS(v[f]);
28− if (x !== null) rec[f] = x;
29− }
30− return rec;
31− }
32− return null;
33− }
10+ function fromJS(v) {
11+ var type = typeof v;
12+ if (type === 'number' ) return v;
13+ if (type === 'boolean') return v;
14+ if (type === 'string' ) return v;
15+ if (v instanceof Array) {
16+ var arr = [];
17+ var len = v.length;
18+ for (var i = 0; i < len; ++i) {
19+ var x = fromJS(v[i]);
20+ if (x !== null) arr.push(x);
21+ }
22+ return List.fromArray(arr);
23+ }
24+ if (type === 'object') {
25+ var rec = { _:{} };
26+ for (var f in v) {
27+ var x = fromJS(v[f]);
28+ if (x !== null) rec[f] = x;
29+ }
30+ return rec;
31+ }
32+ return null;
33+ }
3434
35− function toJS(v) {
36− var type = typeof v;
37− if (type === 'number' || type === 'boolean' || type === 'string') return v;
38− if (type === 'object' && '_' in v) {
39− var obj = {};
40− for (var k in v) {
41− var x = toJS(v[k]);
42− if (x !== null) obj[k] = x;
43− }
44− return obj;
45− }
46− if (type === 'object' && (v.ctor === '::' || v.ctor === '[]')) {
47− var array = List.toArray(v);
48− for (var i = array.length; i--; ) {
49− array[i] = toJS(array[i]);
50− }
51− return array;
52− }
53− return null;
54− }
35+ function toJS(v) {
36+ var type = typeof v;
37+ if (type === 'number' || type === 'boolean' || type === 'string') return v;
38+ if (type === 'object' && '_' in v) {
39+ var obj = {};
40+ for (var k in v) {
41+ var x = toJS(v[k]);
42+ if (x !== null) obj[k] = x;
43+ }
44+ return obj;
45+ }
46+ if (type === 'object' && (v.ctor === '::' || v.ctor === '[]')) {
47+ var array = List.toArray(v);
48+ for (var i = array.length; i--; ) {
49+ array[i] = toJS(array[i]);
50+ }
51+ return array;
52+ }
53+ return null;
54+ }
5555
56− function fromRecord(r) {
57− if (typeof r === 'object' && '_' in r) {
58− return toJS(r);
59− }
60− throw new Error("'fromRecord' must be called on a record.");
61− }
56+ function fromRecord(r) {
57+ if (typeof r === 'object' && '_' in r) {
58+ return toJS(r);
59+ }
60+ throw new Error("'fromRecord' must be called on a record.");
61+ }
6262
63− function id(n) { return n; }
64−
65− function toElement(w,h,domNode) {
66− return A3( newElement, w, h, {
67− ctor: 'Custom',
68− type: 'DomNode',
69− render: function(node) { return node; },
70− update: function(node,oldNode,newNode) {
71− if (node === newNode) return;
72− node.parentNode.replaceChild(newNode, node);
73− },
74− model: domNode
75− });
76− }
77−
78− function fromElement(element) {
79− return Render.render(element);
80− }
81−
82− return elm.Native.JavaScript.values = {
83− toInt : function(n) { return n|0; },
84− toFloat : function(n) { return +n; },
85− toBool : id,
86− toString : id,
87− toList : List.fromArray,
88− fromString : id,
89− fromList : List.toArray,
90− fromInt : id,
91− fromFloat : id,
92− fromBool : id,
93−
94− toElement : toElement,
95− fromElement : fromElement,
96− toRecord : fromJS,
97− fromRecord : fromRecord
98− };
63+ return elm.Native.JavaScript.values = {
64+ toRecord : fromJS,
65+ fromRecord : fromRecord
66+ };
9967
10068};
libraries/Native/Json.js+71−58
@@ -1,72 +1,85 @@
11Elm.Native.Json = {};
22Elm.Native.Json.make = function(elm) {
33
4− elm.Native = elm.Native || {};
5− elm.Native.Json = elm.Native.Json || {};
6− if (elm.Native.Json.values) return elm.Native.Json.values;
4+ elm.Native = elm.Native || {};
5+ elm.Native.Json = elm.Native.Json || {};
6+ if (elm.Native.Json.values) return elm.Native.Json.values;
77
8− var Maybe = Elm.Maybe.make(elm);
9− var Dict = Elm.Dict.make(elm);
10− var List = Elm.List.make(elm);
11− var JS = Elm.JavaScript.make(elm);
12− var Utils = Elm.Native.Utils.make(elm);
8+ var Maybe = Elm.Maybe.make(elm);
9+ var Dict = Elm.Dict.make(elm);
10+ var List = Elm.Native.List.make(elm);
11+ var Utils = Elm.Native.Utils.make(elm);
1312
14− function fromValue(v) {
15− switch (v.ctor) {
16− case 'Null' : return null;
17− case 'String' : return JS.fromString(v._0);
18− case 'Object' :
19− var obj = {};
20− var array = JS.fromList(Dict.toList(v._0));
21− for (var i = array.length; i--; ) {
22− obj[JS.fromString(array[i]._0)] = fromValue(array[i]._1);
23− }
24− return obj;
25− case 'Array' :
26− var array = JS.fromList(v._0);
27− for (var i = array.length; i--; ) {
28− array[i] = fromValue(array[i]);
29− }
30− return array;
31− default :
32− return v._0;
13+ function toJS(v) {
14+ switch (v.ctor) {
15+ case 'Null' : return null;
16+ case 'String' : return v._0;
17+ case 'Number' : return v._0;
18+ case 'Boolean': return v._0;
19+ case 'Object' :
20+ var obj = {};
21+ var array = List.toArray(Dict.toList(v._0));
22+ for (var i = array.length; i--; ) {
23+ var entry = array[i];
24+ obj[entry._0] = toJS(entry._1);
25+ }
26+ return obj;
27+ case 'Array' :
28+ var array = List.toArray(v._0);
29+ for (var i = array.length; i--; ) {
30+ array[i] = toJS(array[i]);
31+ }
32+ return array;
33+ }
3334 }
34− }
3535
36− function toPrettyJSString(sep, obj) {
37− return JSON.stringify(fromValue(obj), null, JS.fromString(sep));
38− }
36+ function toString(sep, value) {
37+ return JSON.stringify(toJS(value), null, sep);
38+ }
3939
40− function toValue(v) {
41− switch (typeof v) {
42− case 'string' : return { ctor:"String", _0: JS.toString(v) };
43− case 'number' : return { ctor:"Number", _0: JS.toFloat(v) };
44− case 'boolean': return { ctor:"Boolean" , _0: JS.toBool(v) };
45− case 'object' :
46− if (v === null) return { ctor:"Null" };
47− if (v instanceof Array) {
48− for (var i = v.length; i--; ) { v[i] = toValue(v[i]); }
49− return { ctor:"Array", _0: JS.toList(v) };
50− }
51− var array = [];
52− for (var k in v) array.push(Utils.Tuple2(JS.toString(k), toValue(v[k])));
53− return { ctor:"Object", _0: Dict.fromList(JS.toList(array)) };
40+ function fromJS(v) {
41+ switch (typeof v) {
42+ case 'string' : return { ctor:"String" , _0: v };
43+ case 'number' : return { ctor:"Number" , _0: v };
44+ case 'boolean': return { ctor:"Boolean", _0: v };
45+ case 'object' :
46+ if (v === null) return { ctor:"Null" };
47+ if (v instanceof Array) {
48+ var array = new Array(v.length);
49+ for (var i = v.length; i--; ) {
50+ array[i] = fromJS(v[i]);
51+ }
52+ return {
53+ ctor:"Array",
54+ _0: List.fromArray(array)
55+ };
56+ }
57+ var array = [];
58+ for (var key in v) {
59+ var value = fromJS(v[key]);
60+ array.push(Utils.Tuple2(key, value));
61+ }
62+ var list = List.fromArray(array);
63+ return {
64+ ctor:"Object",
65+ _0: Dict.fromList(list)
66+ };
67+ }
5468 }
55− }
5669
57− function fromJSString(str) {
58− try {
59− return Maybe.Just(toValue(JSON.parse(str)));
60− } catch (e) {
61− return Maybe.Nothing;
70+ function fromString(str) {
71+ try {
72+ return Maybe.Just(fromJS(JSON.parse(str)));
73+ } catch (e) {
74+ return Maybe.Nothing;
75+ }
6276 }
63− }
6477
65− return elm.Native.Json.values = {
66− toJSString : F2(toPrettyJSString),
67− fromJSString : fromJSString,
68− toJSObject : fromValue,
69− fromJSObject : toValue
70− };
78+ return elm.Native.Json.values = {
79+ toString : F2(toString),
80+ fromString : fromString,
81+ fromJS : fromJS,
82+ toJS : toJS,
83+ };
7184
7285};
libraries/Native/Regex.js+14−14
@@ -6,8 +6,8 @@ Elm.Native.Regex.make = function(elm) {
66 if ('values' in Elm.Native.Regex)
77 return elm.Native.Regex.values = Elm.Native.Regex.values;
88
9+ var List = Elm.Native.List.make(elm);
910 var Maybe = Elm.Maybe.make(elm);
10− var JS = Elm.JavaScript.make(elm);
1111
1212 function escape(str) {
1313 return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
@@ -20,14 +20,14 @@ Elm.Native.Regex.make = function(elm) {
2020 }
2121
2222 function contains(re, string) {
23− return JS.fromString(string).match(re) !== null;
23+ return string.match(re) !== null;
2424 }
2525
2626 function find(n, re, str) {
2727 n = n.ctor === "All" ? Infinity : n._0;
2828 var out = [];
2929 var number = 0;
30− var string = JS.fromString(str);
30+ var string = str;
3131 var result;
3232 while (number++ < n && (result = re.exec(string))) {
3333 var i = result.length - 1;
@@ -36,17 +36,17 @@ Elm.Native.Regex.make = function(elm) {
3636 var submatch = result[i];
3737 subs[--i] = submatch === undefined
3838 ? Maybe.Nothing
39− : Maybe.Just(JS.toString(submatch));
39+ : Maybe.Just(submatch);
4040 }
4141 out.push({
4242 _:{},
43− match: JS.toString(result[0]),
44− submatches: JS.toList(subs),
43+ match: result[0],
44+ submatches: List.fromArray(subs),
4545 index: result.index,
4646 number: number,
4747 });
4848 }
49− return JS.toList(out);
49+ return List.fromArray(out);
5050 }
5151
5252 function replace(n, re, replacer, string) {
@@ -60,24 +60,24 @@ Elm.Native.Regex.make = function(elm) {
6060 var submatch = arguments[i];
6161 submatches[--i] = submatch === undefined
6262 ? Maybe.Nothing
63− : Maybe.Just(JS.toString(submatch));
63+ : Maybe.Just(submatch);
6464 }
65− return JS.fromString(replacer({
65+ return replacer({
6666 _:{},
6767 match:match,
68− submatches:JS.toList(submatches),
68+ submatches:List.fromArray(submatches),
6969 index:arguments[i-1],
7070 number:count
71− }));
71+ });
7272 }
7373 return string.replace(re, jsReplacer);
7474 }
7575
7676 function split(n, re, str) {
7777 if (n === Infinity) {
78− return JS.toList(JS.fromString(string).split(re));
78+ return List.fromArray(string.split(re));
7979 }
80− var string = JS.fromString(str);
80+ var string = str;
8181 var result;
8282 var out = [];
8383 var start = re.lastIndex;
@@ -87,7 +87,7 @@ Elm.Native.Regex.make = function(elm) {
8787 start = re.lastIndex;
8888 }
8989 out.push(string.slice(start));
90− return JS.toList(out);
90+ return List.fromArray(out);
9191 }
9292
9393 return Elm.Native.Regex.values = {
libraries/Native/Signal/Http.js+6−7
@@ -5,7 +5,6 @@ Elm.Native.Http.make = function(elm) {
55 elm.Native.Http = elm.Native.Http || {};
66 if (elm.Native.Http.values) return elm.Native.Http.values;
77
8− var JS = Elm.JavaScript.make(elm);
98 var List = Elm.List.make(elm);
109 var Signal = Elm.Signal.make(elm);
1110
@@ -38,17 +37,17 @@ Elm.Native.Http.make = function(elm) {
3837 request.onreadystatechange = function(e) {
3938 if (request.readyState === 4) {
4039 response.value = (request.status >= 200 && request.status < 300 ?
41− { ctor:'Success', _0:JS.toString(request.responseText) } :
42− { ctor:'Failure', _0:request.status, _1:JS.toString(request.statusText) });
40+ { ctor:'Success', _0:request.responseText } :
41+ { ctor:'Failure', _0:request.status, _1:request.statusText });
4342 setTimeout(function() { updateQueue(queue,responses); }, 0);
4443 }
4544 };
46− request.open(JS.fromString(req.verb), JS.fromString(req.url), true);
45+ request.open(req.verb, req.url, true);
4746 function setHeader(pair) {
48− request.setRequestHeader( JS.fromString(pair._0), JS.fromString(pair._1) );
47+ request.setRequestHeader( pair._0, pair._1 );
4948 }
50− List.map(setHeader)(req.headers);
51− request.send(JS.fromString(req.body));
49+ A2( List.map, setHeader, req.headers );
50+ request.send(req.body);
5251 }
5352
5453 function send(requests) {
libraries/Native/Signal/Touch.js+3−3
@@ -6,7 +6,7 @@ Elm.Native.Touch.make = function(elm) {
66 if (elm.Native.Touch.values) return elm.Native.Touch.values;
77
88 var Signal = Elm.Signal.make(elm);
9− var JS = Elm.JavaScript.make(elm);
9+ var List = Elm.Native.List.make(elm);
1010 var Utils = Elm.Native.Utils.make(elm);
1111
1212 function Dict() {
@@ -136,7 +136,7 @@ Elm.Native.Touch.make = function(elm) {
136136 return sig;
137137 }
138138
139− var touches = dependency(JS.toList);
139+ var touches = dependency(List.fromArray);
140140
141141 var taps = function() {
142142 var sig = dependency(function(_) { return tap; });
@@ -149,4 +149,4 @@ Elm.Native.Touch.make = function(elm) {
149149
150150 return elm.Native.Touch.values = { touches: touches, taps: taps };
151151
152−};
152+};
libraries/Native/Signal/WebSocket.js+3−5
@@ -6,12 +6,11 @@ Elm.Native.WebSocket.make = function(elm) {
66 if (elm.Native.WebSocket.values) return elm.Native.WebSocket.values;
77
88 var Signal = Elm.Signal.make(elm);
9− var JS = Elm.JavaScript.make(elm);
109 var List = Elm.Native.List.make(elm);
1110
1211 function open(url, outgoing) {
1312 var incoming = Signal.constant(List.Nil);
14− var ws = new WebSocket(JS.fromString(url));
13+ var ws = new WebSocket(url);
1514
1615 var pending = [];
1716 var ready = false;
@@ -22,12 +21,11 @@ Elm.Native.WebSocket.make = function(elm) {
2221 ready = true;
2322 };
2423 ws.onmessage = function(event) {
25− elm.notify(incoming.id, JS.toString(event.data));
24+ elm.notify(incoming.id, event.data);
2625 };
2726
2827 function send(msg) {
29− var s = JS.fromString(msg);
30− ready ? ws.send(s) : pending.push(s);
28+ ready ? ws.send(msg) : pending.push(msg);
3129 }
3230
3331 function take1(x,y) { return x }
libraries/Native/String.js+9−9
@@ -8,7 +8,7 @@ Elm.Native.String.make = function(elm) {
88
99 var Char = Elm.Char.make(elm);
1010 var Maybe = Elm.Maybe.make(elm);
11− var JS = Elm.JavaScript.make(elm);
11+ var List = Elm.Native.List.make(elm);
1212 var Utils = Elm.Native.Utils.make(elm);
1313
1414 function isEmpty(str) {
@@ -26,7 +26,7 @@ Elm.Native.String.make = function(elm) {
2626 return a + b;
2727 }
2828 function concat(strs) {
29− return JS.fromList(strs).join('');
29+ return List.toArray(strs).join('');
3030 }
3131 function length(str) {
3232 return str.length;
@@ -59,10 +59,10 @@ Elm.Native.String.make = function(elm) {
5959 }
6060
6161 function split(sep, str) {
62− return JS.toList(str.split(sep));
62+ return List.fromArray(str.split(sep));
6363 }
6464 function join(sep, strs) {
65− return JS.fromList(strs).join(sep);
65+ return List.toArray(strs).join(sep);
6666 }
6767 function repeat(n, str) {
6868 var result = '';
@@ -111,10 +111,10 @@ Elm.Native.String.make = function(elm) {
111111 }
112112
113113 function words(str) {
114− return JS.toList(str.split(/\s+/g));
114+ return List.fromArray(str.split(/\s+/g));
115115 }
116116 function lines(str) {
117− return JS.toList(str.split(/\r\n|\r|\n/g));
117+ return List.fromArray(str.split(/\r\n|\r|\n/g));
118118 }
119119
120120 function toUpper(str) {
@@ -155,7 +155,7 @@ Elm.Native.String.make = function(elm) {
155155 is.push(i);
156156 i = i + subLen;
157157 }
158− return JS.toList(is);
158+ return List.fromArray(is);
159159 }
160160
161161 function toInt(s) {
@@ -193,10 +193,10 @@ Elm.Native.String.make = function(elm) {
193193 }
194194
195195 function toList(str) {
196− return JS.toList(str.split('').map(Utils.chr));
196+ return List.fromArray(str.split('').map(Utils.chr));
197197 }
198198 function fromList(chars) {
199− return JS.fromList(chars).join('');
199+ return List.toArray(chars).join('');
200200 }
201201
202202 return Elm.Native.String.values = {
libraries/Text.elm−1
@@ -35,7 +35,6 @@ import String
3535import Color (Color, black)
3636import Graphics.Element (Element, Three, Pos, ElementPrim, Properties)
3737import Maybe (Maybe, Nothing)
38−import JavaScript (JSString)
3938import Native.Show
4039import Native.Text
4140
libraries/elm_dependencies.json−1
@@ -19,7 +19,6 @@
1919 , "Graphics.Input"
2020 , "Graphics.Input.Field"
2121 , "Http"
22− , "JavaScript"
2322 , "JavaScript.Experimental"
2423 , "Json"
2524 , "Keyboard"