{-# LANGUAGE EmptyDataDecls, FlexibleContexts, FlexibleInstances, GADTs, GeneralizedNewtypeDeriving, MultiParamTypeClasses,
OverlappingInstances, PackageImports, RankNTypes, ScopedTypeVariables, TypeSynonymInstances, UndecidableInstances, TypeFamilies #-}
{-# OPTIONS -F -pgmFhsx2hs -Wwarn -fno-warn-orphans -fno-warn-name-shadowing -fno-warn-unused-matches #-}
module Scaffolding.HSP.Widget where
import Control.Applicative ((<$>))
import Control.Monad ({-liftM-})
import Control.Monad.RWS (RWS, runRWS, mapRWS)
import Control.Monad.State (MonadState (get, put))
import Control.Monad.Writer (tell)
import "mtl" Control.Monad.Identity (Identity(runIdentity))
import Data.Maybe (fromMaybe)
--import Data.Maybe (fromMaybe)
import Data.Text (Text)
import qualified Data.Text.Lazy as TL
import HSP.Monad
import HSP.XMLGenerator hiding (onClick)
import HSP.HTML4 (renderAsHTML)
import qualified HSP.XML as HSP
import HJScript (HJScript'(..), JShow, HasConstructor, Array(Array), Args, Exp(..), HJScript, IsClass, JBool, JInt, JObject(..), JString, JType, Var, Object(..), Rec(..), ( # ), (#!), (.=.), (.-.), (.+.), (?), (.==.), first, second, call, callProc, callMethod, callVoidMethod, evalHJScript, false, function, functionDecl, inVar, jShow, new, push, string, this, derefVar, procedureDecl, val, postinc, int, varWith, propertyVar, forIn, arrLength, delete, procedure, deref, true, false, foreach, for, outputBlock, jshow, runHJScript, doIfNoElse)
-- import HJScript.DOM ({-alert, document, window-})
import HJScript.XMLGenerator (fromStringLit)
import HJScript.DOM hiding (Object, Form)
--import HJScript.Lang (doIf)
import HJScript.Objects.JQuery (JQuery, append, jSetText, jVal, selectExpr, runExp)
-- import qualified XMLGenerator as HSX
import Happstack.Server (ServerPartT)
import HSP.ServerPartT ()
import Scaffolding.HJScriptExtra
import Scaffolding.MonadStack.Headers (MonadHeaders, tellHeaders)
import Text.JSON (JSON, Result(Ok, Error), decode {-, encode-})
import Text.Digestive (Form, transform, transformEither, mapView)
import Text.Digestive.Forms (FormInput, inputString)
class (XMLGenerator x,
XMLGen x,
SetAttr x (XMLType x),
AppendChild x (XMLType x),
EmbedAsChild x TL.Text,
EmbedAsChild x Text,
EmbedAsChild x Char,
EmbedAsAttr x (Attr TL.Text TL.Text),
EmbedAsAttr x (Attr TL.Text Int),
EmbedAsAttr x (Attr TL.Text Bool),
EmbedAsChild x HSP.XML,
MonadHeaders IO x,
StringType x ~ TL.Text
) => WidgetGenerator x
-- this is pretty wacky
flattenForm :: (Functor m, Monad m, MonadHeaders IO x) => Form m i e ([HJScript ()], [XMLGenT x (XMLType x)]) a -> Form m i e [XMLGenT x (XMLType x)] a
flattenForm =
mapView $ \(js, h:hs) ->
(tellHeaders [onReadyXML' js] >> h) : hs
{-
We currently do not use any output/input queues. Events are sent one at a time and processed immediately. However, this can cause events to get lost. For example, if a widget sends events as part of initialization, the listener may not be connected yet and those events will be lost. We could instead have a queue that holds the events until someone listens. Then we run the problem of a space leak if no one ever listens.
Really Quick Summary:
A widget is a bundle of HTML and javascript code. The html is rendered
in-place. The javascript code is added to the $(document).onready()
-- | helper function which turns javascript into a