Personal tools

Yhc/Javascript/Programmers guide/EchoCPS2 demo source

From HaskellWiki

< Yhc | Javascript | Programmers guide(Difference between revisions)
Jump to: navigation, search
(Initial import)
 
(More comments)
 
Line 2: Line 2:
 
-- A program similar to the Echo program, written
 
-- A program similar to the Echo program, written
 
-- without monads as the first step to Fudgets adoption.
 
-- without monads as the first step to Fudgets adoption.
-- The program also demonstrates use of the DOM Level1 framework
+
-- The program also demonstrates use of the DOM Level2 framework
 
-- also implemented in CPS style.
 
-- also implemented in CPS style.
   
 
module EchoCPS2 where
 
module EchoCPS2 where
   
  +
-- This module contains useful functions to access properties of underlying
  +
-- Javascript objects in the type-agnostic manner: proceed with caution!
 
import UnsafeJS
 
import UnsafeJS
   
  +
-- This module contains functions to wrap expressions in CPS style
 
import CPS
 
import CPS
  +
  +
-- This module contains Roman-Decimal conversion funcitons
 
import Roman
 
import Roman
  +
  +
-- The modules under DOM are autogenerated from IDL
  +
-- The modules under CDOM are utilities to simplify the use of DOM facilities
 
import DOM.Level2.Dom
 
import DOM.Level2.Dom
 
import DOM.Level2.Html2
 
import DOM.Level2.Html2
Line 21: Line 29:
 
import DOM.Level2.HTMLInputElement
 
import DOM.Level2.HTMLInputElement
 
import DOM.Level2.KeyEvent
 
import DOM.Level2.KeyEvent
  +
  +
-- This module contains functions to obtain timestamps
 
import Debug.Profiling
 
import Debug.Profiling
   
  +
-- Line-mode output: create a <div> element, place a text in it,
  +
-- append to the parent element (document body). The mbb argument
  +
-- specifies whether the text will be inserted before a specific
  +
-- element (Just) or just appended to the end of the document (Nothing).
  +
-- The s argument is the string to output, and the c argument is
  +
-- the continuation.
   
 
putLine s mbb c = getHTMLDocument $ \doc ->
 
putLine s mbb c = getHTMLDocument $ \doc ->
Line 43: Line 59:
 
set'id "input-echo" inp $ \_ ->
 
set'id "input-echo" inp $ \_ ->
 
setEventHandler "keypress" (inkey inp) inp $ \_ ->
 
setEventHandler "keypress" (inkey inp) inp $ \_ ->
  +
  +
-- The setEventHandler function still uses the "on-" element attributes,
  +
-- but given better event type information is contained in the DOM Level2
  +
-- definitions, the handler type signature may be set.
  +
  +
-- The setEventHandler itself has type:
  +
-- setEventHandler :: (CElement zz, CEvent a) => String -> (a -> Bool) -> zz -> CPS c zz
  +
 
focus inp $ id
 
focus inp $ id
   
Line 51: Line 75:
 
dec = (catchJS ((toRoman . read) v) (\_ -> ""))
 
dec = (catchJS ((toRoman . read) v) (\_ -> ""))
 
in (rom, dec)
 
in (rom, dec)
  +
  +
-- The "onkeypress" handler: it does all the job. Note the o argument:
  +
-- it holds reference to the element a handler is attached to. This forms
  +
-- a closure (which may not be very much desired for some browsers), but
  +
-- makes it extremely easy to distinguish between elements that cause
  +
-- the handler to fire. The e argument is expected to be of the TKeyEvent
  +
-- type (defined in DOM IDL).
   
 
inkey :: THTMLInputElement -> TKeyEvent -> Bool
 
inkey :: THTMLInputElement -> TKeyEvent -> Bool
  +
  +
-- Now it is possible to refer to event object methods and attributes
  +
-- in type safe manner instead of unsafe getting attributes by name.
  +
-- The KeyEvent interface defines the cDOM_VK_ENTER constant for the
  +
-- "Enter" key.
 
 
 
inkey o e = get'keyCode e $ \kci ->
 
inkey o e = get'keyCode e $ \kci ->

Latest revision as of 13:38, 25 August 2007

-- A program similar to the Echo program, written
-- without monads as the first step to Fudgets adoption.
-- The program also demonstrates use of the DOM Level2 framework
-- also implemented in CPS style.
 
module  EchoCPS2 where
 
-- This module contains useful functions to access properties of underlying
-- Javascript objects in the type-agnostic manner: proceed with caution!
import UnsafeJS
 
-- This module contains functions to wrap expressions in CPS style
import CPS
 
-- This module contains Roman-Decimal conversion funcitons
import Roman
 
-- The modules under DOM are autogenerated from IDL
-- The modules under CDOM are utilities to simplify the use of DOM facilities
import DOM.Level2.Dom
import DOM.Level2.Html2
import CDOM.Level2.DomUtils
import CDOM.Level2.Events
import DOM.Level2.Events
import DOM.Level2.Document
import DOM.Level2.HTMLElement
import DOM.Level2.HTMLDivElement
import DOM.Level2.HTMLInputElement
import DOM.Level2.KeyEvent
 
-- This module contains functions to obtain timestamps
import Debug.Profiling
 
-- Line-mode output: create a <div> element, place a text in it, 
-- append to the parent element (document body). The mbb argument
-- specifies whether the text will be inserted before a specific
-- element (Just) or just appended to the end of the document (Nothing).
-- The s argument is the string to output, and the c argument is
-- the continuation.
 
putLine s mbb c = getHTMLDocument $ \doc ->
                  documentBody doc $ \body ->
                  mkDiv doc $ \dv ->
                  mkText doc s $ \tx ->
                  addChild tx dv $ \ch ->
                  let iac = case mbb of
                              Nothing -> addChild dv
                              Just b -> insertChild b dv
                  in  iac body $ \ct -> 
                  c ct
 
 
main = getHTMLDocument $ \doc ->
       documentBody doc $ \body ->
       putLine ("*** Echo Benchmark ***") nodeNothing $ \_ ->
       mkInput doc $ \inp ->
       addChild inp body $ \_ ->
       set'id "input-echo" inp $ \_ ->
       setEventHandler "keypress" (inkey inp) inp $ \_ ->
 
-- The setEventHandler function still uses the "on-" element attributes,
-- but given better event type information is contained in the DOM Level2
-- definitions, the handler type signature may be set.
 
-- The setEventHandler itself has type:
-- setEventHandler :: (CElement zz, CEvent a) => String -> (a -> Bool) -> zz -> CPS c zz
 
       focus inp $ id
 
romdec :: String -> (String, String)
 
romdec v =
  let rom = (catchJS ((show . fromRoman) v) (\_ -> ""))
      dec = (catchJS ((toRoman . read) v) (\_ -> ""))
  in (rom, dec)
 
-- The "onkeypress" handler: it does all the job. Note the o argument:
-- it holds reference to the element a handler is attached to. This forms
-- a closure (which may not be very much desired for some browsers), but
-- makes it extremely easy to distinguish between elements that cause 
-- the handler to fire. The e argument is expected to be of the TKeyEvent
-- type (defined in DOM IDL).
 
inkey :: THTMLInputElement -> TKeyEvent -> Bool
 
-- Now it is possible to refer to event object methods and attributes
-- in type safe manner instead of unsafe getting attributes by name.
-- The KeyEvent interface defines the cDOM_VK_ENTER constant for the
-- "Enter" key.
 
inkey o e = get'keyCode e $ \kci ->
            if kci == cDOM_VK_ENTER
              then
                get'value o $ \v ->
                if length v > 0
                  then
                    getTimeStamp $ \t1 -> 
                    toCPE (romdec v) $ \(rom, dec) ->
                    rom `seq` dec `seq` getTimeStamp $ \t2 ->
                    putLine (v ++ " " ++ rom ++ " " ++ dec ++ " " ++ show (t2 - t1) ++ " ms") 
                            (Just o) $ \_ ->
                    set'value "" o $ \_ ->
                    True
                  else  
                    True
              else True