Difference between revisions of "Yhc/Javascript/Programmers guide/EchoCPS2 demo source"
< Yhc | Javascript | Programmers guide
Jump to navigation
Jump to search
(More comments) |
Tomjaguarpaw (talk | contribs) (Deleting page that hasn't been edited for over 10 years) |
||
Line 1: | Line 1: | ||
− | <haskell> |
||
− | -- 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 |
||
− | </haskell> |