@@ -1,3 +1,4 @@
1+{-# LANGUAGE TemplateHaskell #-}
1{-# LANGUAGE AllowAmbiguousTypes #-}
2{-# LANGUAGE AllowAmbiguousTypes #-}
2{-# LANGUAGE ConstraintKinds #-}
3{-# LANGUAGE ConstraintKinds #-}
3{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE FlexibleContexts #-}
@@ -32,12 +33,40 @@ import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSStringRef
32import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSValueRef
33import Graphics.UI.Gtk.WebKit.JavaScriptCore.JSValueRef
33import Graphics.UI.Gtk.WebKit.WebView
34import Graphics.UI.Gtk.WebKit.WebView
36+import Foreign.JavaScript.TH
35import Reflex.Dom.Internal.Foreign
37import Reflex.Dom.Internal.Foreign
37data JSWebSocket = JSWebSocket { wsValue :: JSValueRef
39data JSWebSocket = JSWebSocket { wsValue :: JSValueRef
38 , wsContext :: JSContextRef
40 , wsContext :: JSContextRef
43+importJS Unsafe "this[0]['send'](this[1])" "_sendWSTextData" [t| forall x m. MonadJS x m => JSRef x -> String -> m () |]
45+sendWSTextData :: JSWebSocket -> String -> IO ()
46+sendWSTextData (JSWebSocket ws c) str = runWithJSContext (_sendWSTextData (JSRef_JavaScriptCore ws) str) c
48+class IsWebSocketMessage a where
49+ webSocketSend :: JSWebSocket -> a -> IO ()
51+-- Use binary websocket communication for ByteString
52+instance IsWebSocketMessage ByteString where
53+ webSocketSend (JSWebSocket ws c) bs = do
54+ elems <- forM (BS.unpack bs) $ \x -> jsvaluemakenumber c $ fromIntegral x
55+ let numElems = length elems
56+ bs' <- bracket (mallocArray numElems) free $ \elemsArr -> do
57+ pokeArray elemsArr elems
58+ a <- jsobjectmakearray c (fromIntegral numElems) elemsArr nullPtr
59+ newUint8Array <- jsstringcreatewithutf8cstring "new Uint8Array(this)"
60+ jsevaluatescript c newUint8Array a nullPtr 1 nullPtr
61+ send <- jsstringcreatewithutf8cstring ""
62+ sendArgs <- toJSObject c [ws, bs']
63+ _ <- jsevaluatescript c send sendArgs nullPtr 1 nullPtr
66+-- Use plaintext websocket communication for Text
67+instance IsWebSocketMessage Text where
68+ webSocketSend jws t = sendWSTextData jws (T.unpack t)
41newWebSocket :: WebView -> Text -> (ByteString -> IO ()) -> IO () -> IO () -> IO JSWebSocket
70newWebSocket :: WebView -> Text -> (ByteString -> IO ()) -> IO () -> IO () -> IO JSWebSocket
42newWebSocket wv url onMessage onOpen onClose = withWebViewContext wv $ \c -> do
71newWebSocket wv url onMessage onOpen onClose = withWebViewContext wv $ \c -> do
43 url' <- jsvaluemakestring c =<< jsstringcreatewithutf8cstring (T.unpack url)
72 url' <- jsvaluemakestring c =<< jsstringcreatewithutf8cstring (T.unpack url)
@@ -66,18 +95,3 @@ newWebSocket wv url onMessage onOpen onClose = withWebViewContext wv $ \c -> do
66 addCbs <- jsstringcreatewithutf8cstring "this[0]['onmessage'] = this[1]; this[0]['onopen'] = this[2]; this[0]['onclose'] = this[3];"
95 addCbs <- jsstringcreatewithutf8cstring "this[0]['onmessage'] = this[1]; this[0]['onopen'] = this[2]; this[0]['onclose'] = this[3];"
67 _ <- jsevaluatescript c addCbs o nullPtr 1 nullPtr
96 _ <- jsevaluatescript c addCbs o nullPtr 1 nullPtr
68 return $ JSWebSocket ws c
97 return $ JSWebSocket ws c
70−webSocketSend :: JSWebSocket -> ByteString -> IO ()
71−webSocketSend (JSWebSocket ws c) bs = do
72− elems <- forM (BS.unpack bs) $ \x -> jsvaluemakenumber c $ fromIntegral x
73− let numElems = length elems
74− bs' <- bracket (mallocArray numElems) free $ \elemsArr -> do
75− pokeArray elemsArr elems
76− a <- jsobjectmakearray c (fromIntegral numElems) elemsArr nullPtr
77− newUint8Array <- jsstringcreatewithutf8cstring "new Uint8Array(this)"
78− jsevaluatescript c newUint8Array a nullPtr 1 nullPtr
79− send <- jsstringcreatewithutf8cstring "this[0]['send'](String['fromCharCode']['apply'](null, this[1]))"
80− sendArgs <- toJSObject c [ws, bs']
81− _ <- jsevaluatescript c send sendArgs nullPtr 1 nullPtr