javascript-extras 0.3.0.0 → 0.3.1.0
raw patch · 5 files changed
+130/−1 lines, 5 filesdep +ghcjs-primdep +javascript-extrasdep ~ghcjs-base-stubnew-component:exe:javascript-extras-test
Dependencies added: ghcjs-prim, javascript-extras
Dependency ranges changed: ghcjs-base-stub
Files
- javascript-extras.cabal +17/−1
- jsbits/extras.js +22/−0
- src/JavaScript/Extras/JSVar.hs +18/−0
- src/JavaScript/Extras/JSVar/Unsafe.hs +26/−0
- test/haskell/Main.hs +47/−0
javascript-extras.cabal view
@@ -1,5 +1,5 @@ name: javascript-extras-version: 0.3.0.0+version: 0.3.1.0 synopsis: Extra javascript functions when using GHCJS description: Extra javascript functions when using GHCJS homepage: https://github.com/louispan/javascript-extras#readme@@ -21,6 +21,7 @@ JavaScript.Extras.Number JavaScript.Extras.Property JavaScript.Extras.JSVar+ JavaScript.Extras.JSVar.Unsafe build-depends: base >= 4.7 && < 5 , deepseq >= 1.4 && < 2 , parallel >= 3.2 && < 4@@ -31,6 +32,21 @@ build-depends: ghcjs-base if !impl(ghcjs) build-depends: ghcjs-base-stub >= 0.1.0.1 && < 1++executable javascript-extras-test+ hs-source-dirs: test/haskell+ main-is: Main.hs+ ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N+ cpp-options: -DGHCJS_BROWSER+ build-depends: base >= 4.7 && < 5+ , javascript-extras >= 0.3.1+ default-language: Haskell2010+ default-extensions: ApplicativeDo+ if impl(ghcjs)+ build-depends: ghcjs-base+ , ghcjs-prim >= 0.1 && < 0.2+ if !impl(ghcjs)+ build-depends: ghcjs-base-stub >= 0.1.0.2 && < 1 source-repository head type: git
jsbits/extras.js view
@@ -1,3 +1,11 @@+// Node module dependencies+// Example package.json:+// {+// "dependencies": {+// "javascript-stringify": "^1.6.0"+// }+// }+ #include <ghcjs/rts.h> // zip list of string and JSVal to object, lists must have been completely forced first@@ -10,4 +18,18 @@ xs = CONS_TAIL(xs); } return obj;+}++var hge$javascriptStringify_ = null;+function hje$stringify(v) {+ if (!hge$javascriptStringify_) {+ hge$javascriptStringify_ = require('javascript-stringify');+ }+ return hge$javascriptStringify_(v, null, null, { references: true })+}++// Injection attack! Use with care+function hje$unstringify(str) {+ eval("var ret=" + str);+ return ret; }
src/JavaScript/Extras/JSVar.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE CPP #-}+ module JavaScript.Extras.JSVar where import Control.DeepSeq@@ -12,6 +14,9 @@ -- This is helpful when using OverloadedStrings newtype JSVar = JSVar J.JSVal +instance Show JSVar where+ show = JS.unpack . js_stringify+ instance J.IsJSVal JSVar instance J.PToJSVal JSVar where@@ -33,3 +38,16 @@ fromJS' :: JE.FromJS a => JSVar -> Maybe a fromJS' (JSVar v) = fromJS v++#ifdef __GHCJS__++foreign import javascript unsafe+ "$r = hje$stringify($1);"+ js_stringify :: JSVar -> J.JSString++#else++js_stringify :: JSVar -> J.JSString+js_stringify _ = JS.empty++#endif
+ src/JavaScript/Extras/JSVar/Unsafe.hs view
@@ -0,0 +1,26 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE CPP #-}++module JavaScript.Extras.JSVar.Unsafe where++import Data.JSString as JS+import qualified GHCJS.Types as J+import JavaScript.Extras.JSVar as JE++-- | Injection attack! Use with care+instance Read JE.JSVar where+ readsPrec _ str = [(js_eval (JS.pack str), [])]++#ifdef __GHCJS__++-- | Injection attack! Use with care+foreign import javascript unsafe+ "$r = hje$unstringify($1);"+ js_eval :: J.JSString -> JSVar++#else++js_eval :: J.JSString -> JSVar+js_eval _ = JSVar J.nullRef++#endif
+ test/haskell/Main.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE OverloadedStrings #-}++module Main (main) where++import qualified Data.JSString as JS+import qualified GHCJS.Foreign.Callback as J+import qualified GHCJS.Types as J+import qualified JavaScript.Extras as JE+import qualified JavaScript.Extras.JSVar.Unsafe as JE++#ifdef __GHCJS__++test :: JE.JSVar -> IO ()+test x = do+ let str = show x+ x' = read str :: JE.JSVar+ str' = show x'+ js_write $ "Test: " `mappend` (JS.pack str) `mappend` " == " `mappend` (JS.pack str')++main :: IO ()+main = do+ test js_int+ test js_obj+ cb <- J.syncCallback' (pure (JE.toJS js_int))+ test (JE.JSVar (J.jsval cb))+ J.releaseCallback cb+ test (JE.JSVar (J.jsval cb))++foreign import javascript unsafe+ "document.write('<p>' + $1 + '</p>')"+ js_write :: JS.JSString -> IO ()++foreign import javascript unsafe+ "5"+ js_int :: JE.JSVar++foreign import javascript unsafe+ "{ 'hello': 'world' }"+ js_obj :: JE.JSVar++#else++main :: IO ()+main = pure ()++#endif