2{-# LANGUAGE FlexibleInstances #-}
3{-# LANGUAGE TypeSynonymInstances #-}
4{-# LANGUAGE ScopedTypeVariables #-}
5{-# LANGUAGE Rank2Types #-}
7{-# LANGUAGE ForeignFunctionInterface #-}
8{-# LANGUAGE JavaScriptFFI #-}
10{-# OPTIONS_GHC -fno-warn-orphans #-}
11-----------------------------------------------------------------------------
13-- Module : Language.Javascript.JSaddle.Object
14-- Copyright : (c) Hamish Mackenzie
17-- Maintainer : Hamish Mackenzie <Hamish.K.Mackenzie@googlemail.com>
19-- | Interface to JavaScript object
21-----------------------------------------------------------------------------
23module Language.Javascript.JSaddle.Object (
49 -- * Setting the value of a property
53 -- * Calling JavaSctipt
60 -- * Calling Haskell From JavaScript
66 -- ** Object Constructors
68 -- | There is no good way to support calling haskell code as a JavaScript
69 -- constructor for the same reason that the return type of
70 -- 'JSCallAsFunction' is 'JSUndefined'.
72 -- Instead of writing a constructor in Haskell write a function
73 -- that takes a continuation. Create the JavaScript object
74 -- and pass it to the continuation.
82 -- * Enumerating Properties
88 , objCallAsConstructor
92import Control.Applicative
93import Prelude hiding ((!!))
94import Language.Javascript.JSaddle.Types
95 (JSPropertyNameArray, JSString, Object(..), MutableJSArray,
97import Foreign.C.Types (CSize(..), CULong(..), CUInt(..), CULLong(..))
99import GHCJS.Types (nullRef, jsval)
100import GHCJS.Foreign.Callback
101 (releaseCallback, syncCallback2, OnBlocked(..), Callback)
102import GHCJS.Marshal.Pure (pFromJSVal)
103import JavaScript.Array (JSArray)
104import qualified JavaScript.Array as Array (toListIO, fromListIO)
105import JavaScript.Array.Internal (SomeJSArray(..))
106import qualified JavaScript.Object as Object (create)
107import Control.Monad (liftM)
108import Data.Coerce (coerce)
110import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSObjectRef
111 (jsobjectmake, jspropertynamearraygetnameatindex,
112 jspropertynamearraygetcount, jsobjectcopypropertynames,
113 jsobjectcallasconstructor, jsobjectmakearray,
114 jsobjectcallasfunction,
115 JSObjectCallAsFunctionCallback, mkJSObjectCallAsFunctionCallback,
116 jsobjectmakefunctionwithcallback)
117import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSValueRef
118 (jsvaluemakeundefined)
119import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSContextRef
120 (jscontextgetglobalobject)
121import Foreign (peekArray, nullPtr, withArrayLen)
122import Foreign.Ptr (freeHaskellFunPtr)
123import Language.Javascript.JSaddle.Native
124 (makeNewJSString, makeNewJSVal, wrapJSString, withJSVals,
125 withObject, withJSString, withToJSVal)
126import System.IO.Unsafe (unsafePerformIO)
127import Foreign.ForeignPtr (newForeignPtr_)
129import Language.Javascript.JSaddle.Exception (rethrow)
130import Language.Javascript.JSaddle.Value
131 (JSUndefined, valToObject)
132import Language.Javascript.JSaddle.Classes
133 (ToJSVal(..), ToJSString(..), MakeObject(..))
134import Language.Javascript.JSaddle.Arguments (MakeArgs(..))
135import Language.Javascript.JSaddle.Monad
137import Control.Monad.Trans.Reader (runReaderT, ask)
138import Control.Monad.IO.Class (MonadIO(..))
139import qualified Control.Exception as E (catch)
140import Control.Exception (SomeException)
141import Foreign.Storable (Storable(..))
142import Language.Javascript.JSaddle.Properties
143import Control.Lens (IndexPreservingGetter, to)
144import Language.Javascript.JSaddle.String (nullJSString)
145import Data.Text (Text)
148-- >>> import Language.Javascript.JSaddle.Test (testJSaddle)
149-- >>> import Language.Javascript.JSaddle.Evaluate (eval)
150-- >>> import Language.Javascript.JSaddle.Value (val, valToText, JSNull(..))
151-- >>> import Control.Lens.Operators ((^.))
152-- >>> import qualified Data.Text as T (unpack)
154-- | Object can be made by evaluating a fnction in 'JSM' as long
155-- as it returns something we can make into a Object.
156instance MakeObject v => MakeObject (JSM v) where
157 makeObject v = v >>= makeObject
158 {-# INLINE makeObject #-}
160-- | Lookup a property based on its name.
162-- >>> testJSaddle $ eval "'Hello World'.length"
164-- >>> testJSaddle $ val "Hello World" ! "length"
166(!) :: (MakeObject this, ToJSString name)
167 => this -- ^ Object to look on
168 -> name -- ^ Name of the property to find
169 -> JSM JSVal -- ^ Property reference
171 rthis <- makeObject this
172 rethrow $ objGetPropertyByName rthis rname
174 rname = toJSString name
177-- | Lookup a property based on its index.
179-- >>> testJSaddle $ eval "'Hello World'[6]"
181-- >>> testJSaddle $ val "Hello World" !! 6
183(!!) :: (MakeObject this)
184 => this -- ^ Object to look on
185 -> Index -- ^ Index of the property to lookup
186 -> JSM JSVal -- ^ Property reference
188 rthis <- makeObject this
189 rethrow $ objGetPropertyAtIndex rthis index
192-- | Makes a getter for a particular property name.
194-- > js name = to (!name)
196-- >>> testJSaddle $ eval "'Hello World'.length"
198-- >>> testJSaddle $ val "Hello World" ^. js "length"
200js :: (MakeObject s, ToJSString name)
201 => name -- ^ Name of the property to find
202 -> IndexPreservingGetter s (JSM JSVal)
206-- | Makes a setter for a particular property name.
208-- > jss name = to (<#name)
210-- >>> testJSaddle $ eval "'Hello World'.length"
212-- >>> testJSaddle $ val "Hello World" ^. js "length"
214jss :: (ToJSString name, ToJSVal val)
215 => name -- ^ Name of the property to find
217 -> forall o . MakeObject o => IndexPreservingGetter o (JSM ())
218jss name val = to (\o -> o <# name $ val)
221-- | Handy way to call a function
223-- > jsf name = to (\o -> o # name $ args)
225-- >>> testJSaddle $ val "Hello World" ^. jsf "indexOf" ["World"]
227jsf :: (ToJSString name, MakeArgs args) => name -> args -> JSF
228jsf name args = to (\o -> o # name $ args)
231-- | Java script function applications have this type
232type JSF = forall o . MakeObject o => IndexPreservingGetter o (JSM JSVal)
234-- | Handy way to call a function that expects no arguments
236-- > js0 name = jsf name ()
238-- >>> testJSaddle $ val "Hello World" ^. js0 "toLowerCase"
240js0 :: (ToJSString name) => name -> JSF
241js0 name = jsf name ()
244-- | Handy way to call a function that expects one argument
246-- > js1 name a0 = jsf name [a0]
248-- >>> testJSaddle $ val "Hello World" ^. js1 "indexOf" "World"
250js1 :: (ToJSString name, ToJSVal a0) => name -> a0 -> JSF
251js1 name a0 = jsf name [a0]
254-- | Handy way to call a function that expects two arguments
255js2 :: (ToJSString name, ToJSVal a0, ToJSVal a1) => name -> a0 -> a1 -> JSF
256js2 name a0 a1 = jsf name (a0, a1)
259-- | Handy way to call a function that expects three arguments
260js3 :: (ToJSString name, ToJSVal a0, ToJSVal a1, ToJSVal a2)
261 => name -> a0 -> a1 -> a2 -> JSF
262js3 name a0 a1 a2 = jsf name (a0, a1, a2)
265-- | Handy way to call a function that expects four arguments
266js4 :: (ToJSString name, ToJSVal a0, ToJSVal a1, ToJSVal a2,
268 => name -> a0 -> a1 -> a2 -> a3 -> JSF
269js4 name a0 a1 a2 a3 = jsf name (a0, a1, a2, a3)
272-- | Handy way to call a function that expects five arguments
273js5 :: (ToJSString name, ToJSVal a0, ToJSVal a1, ToJSVal a2,
274 ToJSVal a3, ToJSVal a4)
275 => name -> a0 -> a1 -> a2 -> a3 -> a4 -> JSF
276js5 name a0 a1 a2 a3 a4 = jsf name (a0, a1, a2, a3, a4)
280-- | Handy way to get and hold onto a reference top level javascript
282-- >>> testJSaddle $ eval "w = console; w.log('Hello World')"
283-- ** Message: console message: @1: Hello World
286-- >>> testJSaddle $ do w <- jsg "console"; w ^. js1 "log" "Hello World"
287-- ** Message: console message: ... @0: Hello World
290jsg :: ToJSString a => a -> JSM JSVal
291jsg name = global ! name
294-- | Handy way to call a function
296-- > jsgf name = jsg name . to (# args)
298-- >>> testJSaddle $ eval "globalFunc = function (x) {return x.length;}"
299-- function (x) {return x.length;}
300-- >>> testJSaddle $ jsgf "globalFunc" ["World"]
302jsgf :: (ToJSString name, MakeArgs args) => name -> args -> JSM JSVal
303jsgf name = global # name
306-- | Handy way to call a function that expects no arguments
308-- > jsg0 name = jsgf name ()
310-- >>> testJSaddle $ jsg0 "globalFunc"
311-- TypeError:...undefined...is not an objec...
312jsg0 :: (ToJSString name) => name -> JSM JSVal
313jsg0 name = jsgf name ()
316-- | Handy way to call a function that expects one argument
318-- > jsg1 name a0 = jsgf name [a0]
320-- >>> testJSaddle $ jsg1 "globalFunc" "World"
322jsg1 :: (ToJSString name, ToJSVal a0) => name -> a0 -> JSM JSVal
323jsg1 name a0 = jsgf name [a0]
326-- | Handy way to call a function that expects two arguments
327jsg2 :: (ToJSString name, ToJSVal a0, ToJSVal a1) => name -> a0 -> a1 -> JSM JSVal
328jsg2 name a0 a1 = jsgf name (a0, a1)
331-- | Handy way to call a function that expects three arguments
332jsg3 :: (ToJSString name, ToJSVal a0, ToJSVal a1, ToJSVal a2)
333 => name -> a0 -> a1 -> a2 -> JSM JSVal
334jsg3 name a0 a1 a2 = jsgf name (a0, a1, a2)
337-- | Handy way to call a function that expects four arguments
338jsg4 :: (ToJSString name, ToJSVal a0, ToJSVal a1, ToJSVal a2,
340 => name -> a0 -> a1 -> a2 -> a3 -> JSM JSVal
341jsg4 name a0 a1 a2 a3 = jsgf name (a0, a1, a2, a3)
344-- | Handy way to call a function that expects five arguments
345jsg5 :: (ToJSString name, ToJSVal a0, ToJSVal a1, ToJSVal a2,
346 ToJSVal a3, ToJSVal a4)
347 => name -> a0 -> a1 -> a2 -> a3 -> a4 -> JSM JSVal
348jsg5 name a0 a1 a2 a3 a4 = jsgf name (a0, a1, a2, a3, a4)
351-- | Call a JavaScript function
353-- >>> testJSaddle $ eval "'Hello World'.indexOf('World')"
355-- >>> testJSaddle $ val "Hello World" # "indexOf" $ ["World"]
358(#) :: (MakeObject this, ToJSString name, MakeArgs args)
359 => this -> name -> args -> JSM JSVal
360(#) this name args = do
361 rthis <- makeObject this
362 f <- rethrow $ objGetPropertyByName rthis name
364 rethrow $ objCallAsFunction f' rthis args
367-- | Call a JavaScript function
369-- >>> testJSaddle $ eval "something = {}; something[6]=function (x) {return x.length;}; something[6]('World')"
371-- >>> testJSaddle $ jsg "something" ## 6 $ ["World"]
374(##) :: (MakeObject this, MakeArgs args)
375 => this -> Index -> args -> JSM JSVal
376(##) this index args = do
377 rthis <- makeObject this
378 f <- rethrow $ objGetPropertyAtIndex rthis index
380 rethrow $ objCallAsFunction f' rthis args
383-- | Set a JavaScript property
385-- >>> testJSaddle $ eval "var j = {}; j.x = 1; j.x"
387-- >>> testJSaddle $ do {j <- obj; (j <# "x") 1; j!"x"}
390(<#) :: (MakeObject this, ToJSString name, ToJSVal val)
391 => this -- ^ Object to set the property on
392 -> name -- ^ Name of the property to set
393 -> val -- ^ Value to set it to
395(<#) this name val = do
396 rthis <- makeObject this
397 rethrow $ objSetPropertyByName rthis name val 0
400-- | Set a JavaScript property
402-- >>> testJSaddle $ eval "var j = {}; j[6] = 1; j[6]"
404-- >>> testJSaddle $ do {j <- obj; (j <## 6) 1; j!!6}
407(<##) :: (MakeObject this, ToJSVal val)
408 => this -- ^ Object to set the property on
409 -> Index -- ^ Index of the property to set
410 -> val -- ^ Value to set it to
412(<##) this index val = do
413 rthis <- makeObject this
414 rethrow $ objSetPropertyAtIndex rthis index val
417-- | Use this to create a new JavaScript object
419-- If you pass more than 7 arguments to a constructor for a built in
420-- JavaScript type (like Date) then this function will fail.
422-- >>> testJSaddle $ new (jsg "Date") (2013, 1, 1)
423-- Fri Feb 01 2013 00:00:00 GMT+... (...)
424new :: (MakeObject constructor, MakeArgs args)
428new constructor args = do
429 f <- makeObject constructor
430 rethrow $ objCallAsConstructor f args
433-- | Call function with a given @this@. In most cases you should use '#'.
435-- >>> testJSaddle $ eval "(function(){return this;}).apply('Hello', [])"
437-- >>> testJSaddle $ do { test <- eval "(function(){return this;})"; call test (val "Hello") () }
439call :: (MakeObject f, MakeObject this, MakeArgs args)
440 => f -> this -> args -> JSM JSVal
442 rfunction <- makeObject f
443 rthis <- makeObject this
444 rethrow $ objCallAsFunction rfunction rthis args
447-- | Make an empty object using the default constuctor
449-- >>> testJSaddle $ eval "var a = {}; a.x = 'Hello'; a.x"
451-- >>> testJSaddle $ do { a <- obj; (a <# "x") "Hello"; a ^. js "x" }
455obj = liftIO Object.create
459 Object <$> (liftIO (jsobjectmake gctxt nullPtr nullPtr) >>= makeNewJSVal)
463-- | Type used for Haskell functions called from JavaScript.
464type JSCallAsFunction = JSVal -- ^ Function object
466 -> [JSVal] -- ^ Function arguments
467 -> JSM JSUndefined -- ^ Only 'JSUndefined' can be returned because
468 -- the function may need to be executed in a
469 -- different thread. If you need to get a
470 -- value out pass in a continuation function
471 -- as an argument and invoke it from haskell.
473-- | Short hand @::JSCallAsFunction@ so a haskell function can be passed to
474-- a to a JavaScipt one.
476-- >>> testJSaddle $ eval "(function(f) {f('Hello');})(function (a) {console.log(a)})"
477-- ** Message: console message: @1: Hello
480-- >>> testJSaddle $ call (eval "(function(f) {f('Hello');})") global [fun $ \ _ _ args -> valToText (head args) >>= (liftIO . putStrLn . T.unpack) ]
483fun :: JSCallAsFunction -> JSCallAsFunction
488type HaskellCallback = Callback (JSVal -> JSVal -> IO ())
490type HaskellCallback = JSObjectCallAsFunctionCallback
493data Function = Function {functionCallback :: HaskellCallback, functionObject :: Object}
495-- ^ Make a JavaScript function object that wraps a Haskell function.
496function :: ToJSString name
497 => name -- ^ Name of the function
498 -> JSCallAsFunction -- ^ Haskell function to call
499 -> JSM Function -- ^ Returns a JavaScript function object that will
500 -- call the Haskell one when it is called
502function name f = liftIO $ do
503 callback <- syncCallback2 ContinueAsync $ \this args -> do
504 rargs <- Array.toListIO (coerce args)
505 runReaderT (f this this rargs) () -- TODO pass function object through
506 Function callback <$> makeFunctionWithCallback (toJSString name) callback
507foreign import javascript unsafe "$r = function () { $2(this, arguments); }"
508 makeFunctionWithCallback :: JSString -> Callback (JSVal -> JSVal -> IO ()) -> IO Object
512 callback <- liftIO $ mkJSObjectCallAsFunctionCallback (wrap gctxt)
513 withJSString (toJSString name) $ \name' ->
514 Function callback . Object <$>
515 (liftIO (jsobjectmakefunctionwithcallback gctxt name' callback) >>= makeNewJSVal)
517 wrap gctxt _ctx fobj' this' argc argv exception = do
518 args' <- peekArray (fromIntegral argc) argv
519 (`runReaderT` gctxt) $ do
520 fobj <- makeNewJSVal fobj'
521 this <- makeNewJSVal this'
522 args <- mapM makeNewJSVal args'
524 liftIO $ jsvaluemakeundefined gctxt
525 `E.catch` \(e :: SomeException) ->
526 (`runReaderT` gctxt) $ do
527 withToJSVal (show e) $ liftIO . poke exception
528 liftIO $ jsvaluemakeundefined gctxt
531freeFunction :: MonadIO m => Function -> m ()
532freeFunction (Function callback _) = liftIO $
534 releaseCallback callback
536 freeHaskellFunPtr callback
539instance ToJSVal Function where
540 toJSVal (Function _ f) = toJSVal f
541 {-# INLINE toJSVal #-}
543-- | A callback to Haskell can be used as a JavaScript value. This will create
544-- an anonymous JavaScript function object. Use 'function' to create one with
546instance ToJSVal JSCallAsFunction where
547 toJSVal f = functionObject <$> function nullJSString f >>= toJSVal
548 {-# INLINE toJSVal #-}
550instance MakeArgs JSCallAsFunction where
552 rarg <- functionObject <$> function nullJSString f >>= toJSVal
554 {-# INLINE makeArgs #-}
556makeArray :: MakeArgs args => args -> MutableJSArray -> JSM Object
558makeArray args exceptions = do
559 rargs <- makeArgs args
560 liftIO $ Object . jsval <$> Array.fromListIO rargs
562makeArray args exceptions = do
564 rargs <- makeArgs args
566 withJSVals rargs $ \rargs' ->
567 liftIO $ withArrayLen rargs' $ \ len ptr ->
568 jsobjectmakearray gctxt (fromIntegral len) ptr exceptions
569 Object <$> makeNewJSVal result
571{-# INLINE makeArray #-}
573-- | Make an JavaScript array from a list of values
575-- >>> testJSaddle $ eval "['Hello', 'World'][1]"
577-- >>> testJSaddle $ array ["Hello", "World"] !! 1
579-- >>> testJSaddle $ eval "['Hello', null, undefined, true, 1]"
581-- >>> testJSaddle $ array ("Hello", JSNull, (), True, 1.0::Double)
583array :: MakeArgs args => args -> JSM Object
584array = rethrow . makeArray
586-- Make an array out of various lists
587instance ToJSVal [JSVal] where
588 toJSVal = toJSVal . array
589 {-# INLINE toJSVal #-}
591instance ToJSVal [JSM JSVal] where
592 toJSVal = toJSVal . array
593 {-# INLINE toJSVal #-}
595instance ToJSVal [Double] where
596 toJSVal = toJSVal . array
597 {-# INLINE toJSVal #-}
599instance ToJSVal [Float] where
600 toJSVal = toJSVal . array
601 {-# INLINE toJSVal #-}
603instance ToJSVal [Int] where
604 toJSVal = toJSVal . array
605 {-# INLINE toJSVal #-}
607instance ToJSVal [JSString] where
608 toJSVal = toJSVal . array
609 {-# INLINE toJSVal #-}
611instance ToJSVal [String] where
612 toJSVal = toJSVal . array
613 {-# INLINE toJSVal #-}
615instance ToJSVal [Text] where
616 toJSVal = toJSVal . array
617 {-# INLINE toJSVal #-}
619instance ToJSVal [Bool] where
620 toJSVal = toJSVal . array
621 {-# INLINE toJSVal #-}
623-- | JavaScript's global object
626global = liftIO js_window
628foreign import javascript unsafe "$r = window"
629 js_window :: IO Object
633 result <- liftIO $ jscontextgetglobalobject gctxt
634 Object <$> makeNewJSVal result
638-- | Get an array containing the property names present on a given object
639#if !defined(ghcjs_HOST_OS)
640copyPropertyNames :: MakeObject this => this -> JSM JSPropertyNameArray
641copyPropertyNames this = do
643 this' <- makeObject this
644 withObject this' $ \rthis ->
645 liftIO $ jsobjectcopypropertynames gctxt rthis
646{-# INLINE copyPropertyNames #-}
648-- | Get the number of names in a property name array
649propertyNamesCount :: MonadIO m => JSPropertyNameArray -> m CSize
650propertyNamesCount names = liftIO $ jspropertynamearraygetcount names
651{-# INLINE propertyNamesCount #-}
653-- | Get a name out of a property name array
654propertyNamesAt :: MonadIO m => JSPropertyNameArray -> CSize -> m JSString
655propertyNamesAt names index = liftIO $ jspropertynamearraygetnameatindex names index >>= makeNewJSString
656{-# INLINE propertyNamesAt #-}
658-- | Convert property array to a list
659propertyNamesList :: MonadIO m => JSPropertyNameArray -> m [JSString]
660propertyNamesList names = do
661 count <- propertyNamesCount names
662 mapM (propertyNamesAt names) $ enumFromTo 0 (count - 1)
663{-# INLINE propertyNamesList #-}
666-- | Get a list containing the property names present on a given object
667propertyNames :: MakeObject this => this -> JSM [JSString]
669propertyNames this = makeObject this >>= liftIO . js_propertyNames >>= liftIO . (fmap (map pFromJSVal)) . Array.toListIO
670{-# INLINE propertyNames #-}
671foreign import javascript unsafe "$r = []; h$forIn($1, function(n){$r.push(n);})"
672 js_propertyNames :: Object -> IO JSArray
674propertyNames this = copyPropertyNames this >>= propertyNamesList
675{-# INLINE propertyNames #-}
678-- | Get a list containing references to all the properties present on a given object
679properties :: MakeObject this => this -> JSM [JSVal]
680properties this = propertyNames this >>= mapM (this !)
682-- | Call a JavaScript object as function. Consider using '#'.
683objCallAsFunction :: MakeArgs args
690objCallAsFunction f this args exceptions = do
691 rargs <- makeArgs args >>= liftIO . Array.fromListIO
692 liftIO $ js_apply f this rargs exceptions
693{-# INLINE objCallAsFunction #-}
694foreign import javascript unsafe "try { $r = $1.apply($2, $3) } catch(e) { $4[0] = e }"
695 js_apply :: Object -> Object -> MutableJSArray -> MutableJSArray -> IO JSVal
697objCallAsFunction f this args exceptions = do
699 rargs <- makeArgs args
701 withObject f $ \rfunction ->
702 withObject this $ \rthis ->
703 withJSVals rargs $ \rargs' ->
704 liftIO $ withArrayLen rargs' $ \ largs pargs ->
705 jsobjectcallasfunction gctxt rfunction rthis (fromIntegral largs) pargs exceptions
707{-# INLINE objCallAsFunction #-}
710-- | Call a JavaScript object as a constructor. Consider using 'new'.
712-- If you pass more than 7 arguments to a constructor for a built in
713-- JavaScript type (like Date) then this function will fail.
714objCallAsConstructor :: MakeArgs args
720objCallAsConstructor f args exceptions = do
721 rargs <- makeArgs args >>= liftIO . Array.fromListIO
722 liftIO $ js_new f rargs exceptions
723foreign import javascript unsafe "\
726 case 0 : $r = new $1(); break;\
727 case 1 : $r = new $1($2[0]); break;\
728 case 2 : $r = new $1($2[0],$2[1]); break;\
729 case 3 : $r = new $1($2[0],$2[1],$2[2]); break;\
730 case 4 : $r = new $1($2[0],$2[1],$2[2],$2[3]); break;\
731 case 5 : $r = new $1($2[0],$2[1],$2[2],$2[3],$2[4]); break;\
732 case 6 : $r = new $1($2[0],$2[1],$2[2],$2[3],$2[4],$2[5]); break;\
733 case 7 : $r = new $1($2[0],$2[1],$2[2],$2[3],$2[4],$2[5],$2[6]); break;\
736 var temp = function() {\
737 ret = $1.apply(this, $2);\
739 temp.prototype = $1.prototype;\
741 if(ret instanceof Object)\
750 js_new :: Object -> MutableJSArray -> MutableJSArray -> IO JSVal
752objCallAsConstructor f args exceptions = do
754 rargs <- makeArgs args
756 withObject f $ \rfunction ->
757 withJSVals rargs $ \rargs' ->
758 liftIO $ withArrayLen rargs' $ \ largs pargs ->
759 jsobjectcallasconstructor gctxt rfunction (fromIntegral largs) pargs exceptions
765nullObject = Object nullRef
767nullObject = Object . unsafePerformIO $ newForeignPtr_ nullPtr
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list