@@ -77,13 +77,20 @@ module Language.Javascript.JSaddle.Object (
77import Prelude hiding ((!!))
77import Prelude hiding ((!!))
78import Language.Javascript.JSaddle.Types
78import Language.Javascript.JSaddle.Types
79 (JSPropertyNameArrayRef, JSStringRef, JSObjectRef, JSValueRefRef,
79 (JSPropertyNameArrayRef, JSStringRef, JSObjectRef, JSValueRefRef,
80− JSValueRef, JSContextRef, Index)
80+ JSValueRef, JSContextRef, Index, castRef)
81import Foreign.C.Types (CSize(..), CULong(..), CUInt(..), CULLong(..))
81import Foreign.C.Types (CSize(..), CULong(..), CUInt(..), CULLong(..))
82#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
82#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
83−import GHCJS.Types (nullRef, castRef, JSArray, JSFun)
83+import GHCJS.Types (nullRef)
84+import qualified JavaScript.Object.Internal as Object
85+import JavaScript.Object.Internal (Object(Object))
86+import GHCJS.Foreign.Callback (syncCallback2, OnBlocked(ThrowWouldBlock))
84−import GHCJS.Foreign (newObj, toArray, fromArray, syncCallback2, ForeignRetention(..))
87+--import GHCJS.Foreign (newObj, toArray, fromArray, syncCallback2, ForeignRetention(..))
85import Control.Monad (liftM)
88import Control.Monad (liftM)
86import Control.Applicative ((<$>))
89import Control.Applicative ((<$>))
90+import qualified JavaScript.Array as Array
91+import JavaScript.Array (JSArray)
92+import GHCJS.Prim (JSRef)
93+import Data.JSString (JSString)
88import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSObjectRef
95import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSObjectRef
89 (jsobjectmake, jspropertynamearraygetnameatindex,
96 (jsobjectmake, jspropertynamearraygetnameatindex,
@@ -119,6 +126,15 @@ import Control.Lens
119 (IndexPreservingGetter, to, (^.))
126 (IndexPreservingGetter, to, (^.))
120import Language.Javascript.JSaddle.String (textToStr)
127import Language.Javascript.JSaddle.String (textToStr)
129+objectToRef (Object r) = r
131+foreign import javascript unsafe
132+ "$r = $1" jsRefToJSSTring :: JSRef -> JSString
134+foreign import javascript unsafe
135+ "$r = $1" getJSArrayRef :: JSArray -> JSRef
122-- | If we already have a JSObjectRef we are fine
138-- | If we already have a JSObjectRef we are fine
123instance MakeObjectRef JSObjectRef where
139instance MakeObjectRef JSObjectRef where
124 makeObjectRef = return
140 makeObjectRef = return
@@ -245,7 +261,7 @@ infixr 2 #
245prop # args = do
261prop # args = do
246 rprop <- makePropRef prop
262 rprop <- makePropRef prop
247 (this, f) <- objGetProperty' rprop
263 (this, f) <- objGetProperty' rprop
248− rethrow $ objCallAsFunction f this args
264+ rethrow $ objCallAsFunction (castRef f) this args
250-- | Call a JavaScript function
266-- | Call a JavaScript function
@@ -296,7 +312,7 @@ call function this args = do
297obj :: JSM JSObjectRef
313obj :: JSM JSObjectRef
298#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
314#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
299−obj = liftIO $ newObj
315+obj = liftIO (castRef . objectToRef <$> Object.create)
302 gctxt <- ask
318 gctxt <- ask
@@ -328,60 +344,68 @@ foreign import ccall "wrapper"
328 mkJSObjectCallAsFunctionCallback :: JSObjectCallAsFunctionCallback' -> IO JSObjectCallAsFunctionCallback
344 mkJSObjectCallAsFunctionCallback :: JSObjectCallAsFunctionCallback' -> IO JSObjectCallAsFunctionCallback
347+fromArray :: JSArray -> IO [JSStringRef]
348+fromArray a = fmap jsRefToJSSTring <$> Array.toListIO a
349+toArray :: [JSValueRef] -> IO JSArray
350+toArray a = Array.fromListIO (fmap castRef a)
331-- ^ Make a JavaScript function object that wraps a Haskell function.
352-- ^ Make a JavaScript function object that wraps a Haskell function.
332function :: MakeStringRef name
353function :: MakeStringRef name
333 => name -- ^ Name of the function
354 => name -- ^ Name of the function
334 -> JSCallAsFunction -- ^ Haskell function to call
355 -> JSCallAsFunction -- ^ Haskell function to call
335 -> JSM JSObjectRef -- ^ Returns a JavaScript function object that will
356 -> JSM JSObjectRef -- ^ Returns a JavaScript function object that will
336 -- call the Haskell one when it is called
357 -- call the Haskell one when it is called
337−#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
358+-- #if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
338−function name f = liftIO $ do
359+-- function name f = liftIO $ do
339− callback <- syncCallback2 AlwaysRetain True $ \this args -> do
360+-- callback <- syncCallback2 ThrowWouldBlock True $ \this args -> do
340− rargs <- fromArray args
361+-- rargs <- fromArray args
341− runReaderT (f this this rargs) () -- TODO pass function object through
362+-- runReaderT (f this this rargs) () -- TODO pass function object through
342− makeFunctionWithCallback (makeStringRef name) callback
363+-- makeFunctionWithCallback (makeStringRef name) callback
343−foreign import javascript unsafe "$r = function () { $2(this, arguments); }"
364+-- foreign import javascript unsafe "$r = function () { $2(this, arguments); }"
344− makeFunctionWithCallback :: JSStringRef -> JSFun (JSValueRef -> JSValueRefRef -> IO ()) -> IO JSObjectRef
365+-- makeFunctionWithCallback :: JSStringRef -> JSFun (JSValueRef -> JSValueRefRef -> IO ()) -> IO JSObjectRef
345−#elif defined(USE_WEBKIT)
366+-- #elif defined(USE_WEBKIT)
346−function name f = do
367+-- function name f = do
347− gctxt <- ask
368+-- gctxt <- ask
348− callback <- liftIO $ mkJSObjectCallAsFunctionCallback wrap
369+-- callback <- liftIO $ mkJSObjectCallAsFunctionCallback wrap
349− liftIO $ jsobjectmakefunctionwithcallback gctxt (makeStringRef name) callback
370+-- liftIO $ jsobjectmakefunctionwithcallback gctxt (makeStringRef name) callback
351− wrap ctx fobj this argc argv exception = do
372+-- wrap ctx fobj this argc argv exception = do
352− args <- peekArray (fromIntegral argc) argv
373+-- args <- peekArray (fromIntegral argc) argv
353− (`runReaderT` ctx) $
374+-- (`runReaderT` ctx) $
354− f fobj this args >>= makeValueRef
375+-- f fobj this args >>= makeValueRef
355− `E.catch` \(e :: SomeException) -> do
376+-- `E.catch` \(e :: SomeException) -> do
356− str <- runReaderT (makeValueRef . T.pack $ show e) ctx
377+-- str <- runReaderT (makeValueRef . T.pack $ show e) ctx
357− poke exception str
378+-- poke exception str
358− jsvaluemakeundefined ctx
379+-- jsvaluemakeundefined ctx
360−function = undefined
381+-- function = undefined
363-- | A callback to Haskell can be used as a JavaScript value. This will create
386-- | A callback to Haskell can be used as a JavaScript value. This will create
364-- an anonymous JavaScript function object. Use 'function' to create one with
387-- an anonymous JavaScript function object. Use 'function' to create one with
365-- a name.
388-- a name.
366instance MakeValueRef JSCallAsFunction where
389instance MakeValueRef JSCallAsFunction where
367#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
390#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
368− makeValueRef = function (nullRef:: JSStringRef)
391+ makeValueRef a = castRef <$> function (jsRefToJSSTring nullRef :: JSStringRef) a
370− makeValueRef = function (nullPtr:: JSStringRef)
393+ makeValueRef a = castRef <$> function (jsRefToJSSTring nullPtr :: JSStringRef) a
373instance MakeArgRefs JSCallAsFunction where
396instance MakeArgRefs JSCallAsFunction where
374 makeArgRefs f = do
397 makeArgRefs f = do
375#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
398#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
376− rarg <- function (nullRef:: JSStringRef) f
399+ rarg <- function (jsRefToJSSTring nullRef :: JSStringRef) f
378− rarg <- function (nullPtr:: JSStringRef) f
401+ rarg <- function (jsRefToJSSTring nullPtr :: JSStringRef) f
380− return [rarg]
403+ return [castRef rarg]
382makeArray :: MakeArgRefs args => args -> JSValueRefRef -> JSM JSObjectRef
405makeArray :: MakeArgRefs args => args -> JSValueRefRef -> JSM JSObjectRef
383#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
406#if (defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)) || !defined(USE_WEBKIT)
407+--makeArray args exceptions = makeArgRefs args >>= liftIO . toArray
384−makeArray args exceptions = makeArgRefs args >>= liftM castRef . liftIO . toArray
408+makeArray args exceptions = makeArgRefs args >>= liftM (castRef . getJSArrayRef) . liftIO . toArray
386makeArray args exceptions = do
410makeArray args exceptions = do
387 gctxt <- ask
411 gctxt <- ask
@@ -441,7 +465,7 @@ propertyNames :: MakeObjectRef this => this -> JSM [JSStringRef]
441#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
465#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
442propertyNames this = makeObjectRef this >>= liftIO . js_propertyNames >>= liftIO . fromArray
466propertyNames this = makeObjectRef this >>= liftIO . js_propertyNames >>= liftIO . fromArray
443foreign import javascript unsafe "$r = []; h$forIn($1, function(n){$r.push(n);})"
467foreign import javascript unsafe "$r = []; h$forIn($1, function(n){$r.push(n);})"
444− js_propertyNames :: JSObjectRef -> IO (JSArray a)
468+ js_propertyNames :: JSObjectRef -> IO JSArray
445#elif defined(USE_WEBKIT)
469#elif defined(USE_WEBKIT)
446propertyNames this = copyPropertyNames this >>= propertyNamesList
470propertyNames this = copyPropertyNames this >>= propertyNamesList
@@ -461,7 +485,7 @@ objCallAsFunction :: MakeArgRefs args
461 -> JSM JSValueRef
485 -> JSM JSValueRef
462#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
486#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
463objCallAsFunction function this args exceptions = do
487objCallAsFunction function this args exceptions = do
464− rargs <- makeArgRefs args >>= liftIO . toArray
488+ rargs <- (makeArgRefs args >>= liftIO . toArray) >>= (liftIO . Array.thaw)
465 liftIO $ js_apply function this rargs exceptions
489 liftIO $ js_apply function this rargs exceptions
466foreign import javascript unsafe "try { $r = $1.apply($2, $3) } catch(e) { $4[0] = e }"
490foreign import javascript unsafe "try { $r = $1.apply($2, $3) } catch(e) { $4[0] = e }"
467 js_apply :: JSObjectRef -> JSObjectRef -> JSValueRefRef -> JSValueRefRef -> IO JSValueRef
491 js_apply :: JSObjectRef -> JSObjectRef -> JSValueRefRef -> JSValueRefRef -> IO JSValueRef
@@ -486,7 +510,7 @@ objCallAsConstructor :: MakeArgRefs args
486 -> JSM JSValueRef
510 -> JSM JSValueRef
487#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
511#if defined(ghcjs_HOST_OS) && defined(USE_JAVASCRIPTFFI)
488objCallAsConstructor function args exceptions = do
512objCallAsConstructor function args exceptions = do
489− rargs <- makeArgRefs args >>= liftIO . toArray
513+ rargs <- (makeArgRefs args >>= liftIO . toArray) >>= (liftIO . Array.thaw)
490 liftIO $ js_new function rargs exceptions
514 liftIO $ js_new function rargs exceptions
491foreign import javascript unsafe "\
515foreign import javascript unsafe "\