@@ -61,7 +61,7 @@ module Language.Javascript.JSaddle.Value (
61 , maybeNullOrUndefined'
61 , maybeNullOrUndefined'
63 , valMakeNumber
63 , valMakeNumber
64− , valString
64+ , valMakeString
66 -- * Convert to and from JSValue
66 -- * Convert to and from JSValue
67 , deRefVal
67 , deRefVal
@@ -90,8 +90,6 @@ import Language.Javascript.JSaddle.Native
90import Language.Javascript.JSaddle.WebSockets (Command(..), Result(..), sendCommand)
90import Language.Javascript.JSaddle.WebSockets (Command(..), Result(..), sendCommand)
92import Language.Javascript.JSaddle.Monad (JSM)
92import Language.Javascript.JSaddle.Monad (JSM)
93−import Control.Monad.Trans.Reader (ask)
94−import Control.Monad.IO.Class (MonadIO(..))
95import Data.Text (Text)
93import Data.Text (Text)
96import qualified Data.Text as T (pack, unpack)
94import qualified Data.Text as T (pack, unpack)
97import Language.Javascript.JSaddle.Classes
95import Language.Javascript.JSaddle.Classes
@@ -105,7 +103,7 @@ import Data.Int (Int32, Int64)
105-- >>> import Language.Javascript.JSaddle.Test (testJSaddle)
103-- >>> import Language.Javascript.JSaddle.Test (testJSaddle)
106-- >>> import Language.Javascript.JSaddle.Monad (catch)
104-- >>> import Language.Javascript.JSaddle.Monad (catch)
107-- >>> import Language.Javascript.JSaddle.Exception (JSException(..))
105-- >>> import Language.Javascript.JSaddle.Exception (JSException(..))
108−-- >>> import Language.Javascript.JSaddle.Object (obj)
106+-- >>> import Language.Javascript.JSaddle.Object (obj, jsg)
109-- >>> import qualified Data.Text as T (pack)
107-- >>> import qualified Data.Text as T (pack)
111data JSNull = JSNull -- ^ Type that represents a value that can only be null.
109data JSNull = JSNull -- ^ Type that represents a value that can only be null.
@@ -204,21 +202,21 @@ valToNumber value =
204-- | Given a JavaScript value get its string value (as a JavaScript string).
202-- | Given a JavaScript value get its string value (as a JavaScript string).
205-- May throw JSException.
203-- May throw JSException.
207−-- >>> testJSaddle $ valToStr JSNull >>= strToText
205+-- >>> testJSaddle $ strToText <$> valToStr JSNull
209−-- >>> testJSaddle $ valToStr () >>= strToText
207+-- >>> testJSaddle $ strToText <$> valToStr ()
210-- undefined
208-- undefined
211−-- >>> testJSaddle $ valToStr True >>= strToText
209+-- >>> testJSaddle $ strToText <$> valToStr True
213−-- >>> testJSaddle $ valToStr False >>= strToText
211+-- >>> testJSaddle $ strToText <$> valToStr False
215−-- >>> testJSaddle $ valToStr (1.0 :: Double) >>= strToText
213+-- >>> testJSaddle $ strToText <$> valToStr (1.0 :: Double)
217−-- >>> testJSaddle $ valToStr (0.0 :: Double) >>= strToText
215+-- >>> testJSaddle $ strToText <$> valToStr (0.0 :: Double)
219−-- >>> testJSaddle $ valToStr "" >>= strToText
217+-- >>> testJSaddle $ strToText <$> valToStr ""
220-- <BLANKLINE>
218-- <BLANKLINE>
221−-- >>> testJSaddle $ valToStr "1" >>= strToText
219+-- >>> testJSaddle $ strToText <$> valToStr "1"
223valToStr :: ToJSVal value => value -> JSM JSString
221valToStr :: ToJSVal value => value -> JSM JSString
224#ifdef ghcjs_HOST_OS
222#ifdef ghcjs_HOST_OS
@@ -251,33 +249,33 @@ valToStr value =
251-- >>> testJSaddle $ show <$> valToText "1"
249-- >>> testJSaddle $ show <$> valToText "1"
253valToText :: ToJSVal value => value -> JSM Text
251valToText :: ToJSVal value => value -> JSM Text
254−valToText jsvar = valToStr jsvar >>= strToText
252+valToText jsvar = strToText <$> valToStr jsvar
256-- | Given a JavaScript value get a JSON string value.
254-- | Given a JavaScript value get a JSON string value.
257-- May throw JSException.
255-- May throw JSException.
259−-- >>> testJSaddle $ valToJSON 0 JSNull >>= strToText
257+-- >>> testJSaddle $ strToText <$> valToJSON JSNull
261−-- >>> testJSaddle $ valToJSON 0 () >>= strToText
259+-- >>> testJSaddle $ strToText <$> valToJSON ()
262-- <BLANKLINE>
260-- <BLANKLINE>
263−-- >>> testJSaddle $ valToJSON 0 True >>= strToText
261+-- >>> testJSaddle $ strToText <$> valToJSON True
265−-- >>> testJSaddle $ valToJSON 0 False >>= strToText
263+-- >>> testJSaddle $ strToText <$> valToJSON False
267−-- >>> testJSaddle $ valToJSON 0 (1.0 :: Double) >>= strToText
265+-- >>> testJSaddle $ strToText <$> valToJSON (1.0 :: Double)
269−-- >>> testJSaddle $ valToJSON 0 (0.0 :: Double) >>= strToText
267+-- >>> testJSaddle $ strToText <$> valToJSON (0.0 :: Double)
271−-- >>> testJSaddle $ valToJSON 0 "" >>= strToText
269+-- >>> testJSaddle $ strToText <$> valToJSON ""
273−-- >>> testJSaddle $ valToJSON 0 "1" >>= strToText
271+-- >>> testJSaddle $ strToText <$> valToJSON "1"
275−-- >>> testJSaddle $ obj >>= valToJSON 0 >>= strToText
273+-- >>> testJSaddle $ strToText <$> (obj >>= valToJSON)
277valToJSON :: ToJSVal value => value -> JSM JSString
275valToJSON :: ToJSVal value => value -> JSM JSString
278#ifdef ghcjs_HOST_OS
276#ifdef ghcjs_HOST_OS
279valToJSON value = jsrefToJSON <$> toJSVal value
277valToJSON value = jsrefToJSON <$> toJSVal value
280−foreign import javascript unsafe "$r = JSON.stringify($1);" jsrefToJSON :: JSVal -> JSString
278+foreign import javascript unsafe "$r = $1 === undefined ? "" : JSON.stringify($1);" jsrefToJSON :: JSVal -> JSString
282valToJSON value =
280valToJSON value =
283 withToJSVal value $ \rval -> do
281 withToJSVal value $ \rval -> do
@@ -289,9 +287,9 @@ valToJSON value =
289-- May throw JSException.
287-- May throw JSException.
291-- >>> testJSaddle $ (valToObject JSNull >>= valToText) `catch` \ (JSException e) -> valToText e
289-- >>> testJSaddle $ (valToObject JSNull >>= valToText) `catch` \ (JSException e) -> valToText e
292−-- TypeError:...null...is not an object
290+-- null
293-- >>> testJSaddle $ (valToObject () >>= valToText) `catch` \ (JSException e) -> valToText e
291-- >>> testJSaddle $ (valToObject () >>= valToText) `catch` \ (JSException e) -> valToText e
294−-- TypeError:...undefined...is not an object
292+-- undefined
295-- >>> testJSaddle $ valToObject True
293-- >>> testJSaddle $ valToObject True
297-- >>> testJSaddle $ valToObject False
295-- >>> testJSaddle $ valToObject False
@@ -356,9 +354,13 @@ valIsNull :: ToJSVal value => value -> JSM Bool
356#ifdef ghcjs_HOST_OS
354#ifdef ghcjs_HOST_OS
357valIsNull value = isNull <$> toJSVal value
355valIsNull value = isNull <$> toJSVal value
359−valIsNull value = toJSVal value >>= \case
358+ toJSVal value >>= \case
360− JSVal 0 -> return True
359+ JSVal 0 -> return True
361+ withJSVal v $ \rval -> do
362+ IsNullResult result <- sendCommand $ IsNull rval
361− _ -> return False
363+ return result
364----------- undefined ---------------
366----------- undefined ---------------
@@ -389,7 +391,11 @@ valIsUndefined :: ToJSVal value => value -> JSM Bool
389valIsUndefined value = isUndefined <$> toJSVal value
391valIsUndefined value = isUndefined <$> toJSVal value
391valIsUndefined value = toJSVal value >>= \case
393valIsUndefined value = toJSVal value >>= \case
392− JSVal ref -> return $ ref == 1
394+ JSVal 1 -> return True
396+ withJSVal v $ \rval -> do
397+ IsUndefinedResult result <- sendCommand $ IsUndefined rval
395-- | Convert a JSVal to a Maybe JSVal (converting null and undefined to Nothing)
401-- | Convert a JSVal to a Maybe JSVal (converting null and undefined to Nothing)
@@ -475,15 +481,18 @@ valMakeText :: Text -> JSM JSVal
475#ifdef ghcjs_HOST_OS
481#ifdef ghcjs_HOST_OS
476valMakeText = return . pToJSVal . textToJSString
482valMakeText = return . pToJSVal . textToJSString
478−valMakeText text = valString <$> textToStr text
484+valMakeText text = valMakeString (textToStr text)
481-- | Make a JavaScript string from `JSString`
487-- | Make a JavaScript string from `JSString`
482−valString :: JSString -> JSVal
488+valMakeString :: JSString -> JSM JSVal
483#ifdef ghcjs_HOST_OS
489#ifdef ghcjs_HOST_OS
484−valString = pToJSVal
490+valMakeString = return . pToJSVal
486−valString (JSString ref) = JSVal ref
492+valMakeString s =
493+ withJSString s $ \s' -> do
494+ StringToValueResult result <- sendCommand $ StringToValue s'
489-- | Makes a JavaScript string
498-- | Makes a JavaScript string
@@ -500,11 +509,11 @@ instance ToJSVal String where
501-- | Makes a JavaScript string
510-- | Makes a JavaScript string
502instance ToJSVal JSString where
511instance ToJSVal JSString where
503− toJSVal = return . valString
512+ toJSVal = valMakeString
505-- | If we already have a JSString we are fine
514-- | If we already have a JSString we are fine
506instance ToJSString JSString where
515instance ToJSString JSString where
507− toJSString = return
516+ toJSString = id
509instance ToJSString Text where
518instance ToJSString Text where
510 toJSString = textToStr
519 toJSString = textToStr
@@ -531,6 +540,8 @@ instance ToJSString String where
531-- >>> testJSaddle $ showJSValue <$> deRefVal "1"
540-- >>> testJSaddle $ showJSValue <$> deRefVal "1"
533-- >>> testJSaddle $ showJSValue <$> (valToObject True >>= deRefVal)
542-- >>> testJSaddle $ showJSValue <$> (valToObject True >>= deRefVal)
544+-- >>> testJSaddle $ showJSValue <$> (obj >>= deRefVal)
535deRefVal :: ToJSVal value => value -> JSM JSValue
546deRefVal :: ToJSVal value => value -> JSM JSValue
536#ifdef ghcjs_HOST_OS
547#ifdef ghcjs_HOST_OS
@@ -602,6 +613,15 @@ foreign import javascript unsafe
602 "$1===$2" jsvalueisstrictequal :: JSVal -> JSVal -> Bool
613 "$1===$2" jsvalueisstrictequal :: JSVal -> JSVal -> Bool
616+-- | Determine if two values are equal (JavaScripts ===)
617+-- >>> testJSaddle $ strictEqual True False
619+-- >>> testJSaddle $ strictEqual True True
621+-- >>> testJSaddle $ strictEqual "Hello" ()
623+-- >>> testJSaddle $ strictEqual "Hello" "Hello"
605strictEqual :: (ToJSVal a, ToJSVal b) => a -> b -> JSM Bool
625strictEqual :: (ToJSVal a, ToJSVal b) => a -> b -> JSM Bool
606strictEqual a b = do
626strictEqual a b = do
607 aval <- toJSVal a
627 aval <- toJSVal a
@@ -626,6 +646,9 @@ foreign import javascript unsafe "\
626 js_isInstanceOf :: JSVal -> Object -> MutableJSArray -> Bool
646 js_isInstanceOf :: JSVal -> Object -> MutableJSArray -> Bool
649+-- | Determine if two values are equal (JavaScripts ===)
650+-- >>> testJSaddle $ instanceOf obj (Object <$> jsg "Object")
629instanceOf :: (ToJSVal value, MakeObject constructor) => value -> constructor -> JSM Bool
652instanceOf :: (ToJSVal value, MakeObject constructor) => value -> constructor -> JSM Bool
630instanceOf value constructor = do
653instanceOf value constructor = do
631 v <- toJSVal value
654 v <- toJSVal value