module Dingo.Internal.JavaScript ( renderCommandsToJs ) where import Blaze.ByteString.Builder (toLazyByteString) import Data.Aeson (Value) import Data.Aeson.Encode (fromValue) import Data.ByteString (ByteString) import qualified Data.ByteString.Lazy as LBS import Data.Monoid (mconcat) import Data.Text (Text) import qualified Data.Text as TS import Data.Text.Lazy.Encoding (encodeUtf8, decodeUtf8) import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy.Builder as TLB import Dingo.Internal.Base (Command(..)) import Dingo.Selector (fromSelector) import Text.Blaze (Html, toHtml) import Text.Blaze.Renderer.Text (renderHtml) import Text.Julius (JavascriptUrl, ToJavascript(..), renderJavascriptUrl, julius) -- Convert a JSON value to Javascript. instance ToJavascript Value where toJavascript json = toJavascript $ decodeUtf8 $ toLazyByteString $ fromValue json jsHtml :: Html -> TL.Text jsHtml html = TLB.toLazyText $ mconcat [ TLB.fromText "'" , TLB.fromLazyText $ renderHtml html -- FIXME: Proper quoting , TLB.fromText "'" ] -- Render julius for embedding into julius. unJulius :: JavascriptUrl Text -> TL.Text unJulius = renderJavascriptUrl (\_ _ -> TS.empty) -- Render a command to Javascript. renderCommandToJs :: Command -> JavascriptUrl Text renderCommandToJs (CallbackBySelector ev selector callbackId) = [julius| $("#{TLB.toLazyText $ fromSelector selector}").#{ev}(function () { Dingo.callback(#{callbackId}); }); |] renderCommandToJs (SetWidgetValue widgetId value) = [julius| Dingo.setWidgetValue(#{widgetId}, #{value}); |] renderCommandToJs (SetTitle title) = [julius| document.title = #{jsHtml $ toHtml title}; |] renderCommandToJs (AppendToWidgetChildren widgetId html) = [julius| $("#i#{widgetId}").append(#{jsHtml html}); |] renderCommandToJs (ReplaceWidgetChildren widgetId html) = [julius| $("#i#{widgetId}").html(#{jsHtml html}); |] renderCommandToJs (HeadMerge html) = [julius| $("head").append(#{jsHtml html}); |] renderCommandToJs (AddEncoderDecoderFunctions widgetId e d) = [julius| Dingo.addEncoder(#{widgetId}, #{unJulius e}); Dingo.addDecoder(#{widgetId}, #{unJulius d}); |] renderCommandToJs (TriggerEvent widgetId e) = [julius| $("#i#{widgetId}").trigger('#{e}'); |] renderCommandToJs (RawJavascript js) = js -- Render a list of commands to JavaScript renderCommandsToJs :: [Command] -> ByteString renderCommandsToJs cs = mconcat $ LBS.toChunks $ encodeUtf8 $ unJulius $ mconcat $ map renderCommandToJs cs