{-# 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 String, EmbedAsChild x Text, EmbedAsChild x Char, EmbedAsAttr x (Attr String String), EmbedAsAttr x (Attr String Int), EmbedAsAttr x (Attr String Bool), EmbedAsChild x HSP.XML, MonadHeaders IO x, StringType x ~ String, Widgets x) => 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