Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Haskell
Wiki community
Recent changes
Random page
HaskellWiki
Search
Search
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Haskell in web browser/Basics
(section)
Page
Discussion
English
Read
Edit
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
View history
General
What links here
Related changes
Special pages
Page information
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
===DOM=== Formalized description of DOM interfaces is provided by [http://www.w3.org the Web Consortium] in the form of [http://www.omg.org/gettingstarted/omg_idl.htm OMG IDL] definitions. An example of such definitions can be found [http://www.w3.org/TR/DOM-Level-2-HTML/idl-definitions.html here]. It was necessary to convert these definitions to Haskell function declarations to make them available to Haskell programs for Web browser. The special utility, <code>domconv</code> is part of the Javascript backend toolset. The utility is based on [http://hackage.haskell.org/package/hdirect/ HaskellDirect], although most of non-IDL related functionality was stripped, and Haskell source generator was completely rewritten. In this section, we discuss the logic of IDL to Haskell conversion. ====DOM interfaces vs. Haskell type classes==== Web Consortium's DOM definitions are presented as a hierarchy of interfaces. For example, the [http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247 Node] interface is a parent to the majority of other interfaces, such as [http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#i-Document Document] (direct ancestor), or [http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-58190037 HTMLElement] (not a direct ancestor, but ''HTMLElement'' should inherit all properties and methods of ''Node''). This is achieved by defining Haskell type classes whose hierarchy repeats the hierarchy of DOM interfaces. Thus, we have the [http://www.golubovsky.org:5984/_utils/yhcws/DOM-Level2-Dom.html#t%3ACNode CNode] and [http://www.golubovsky.org:5984/_utils/yhcws/DOM-Level2-Dom.html#t%3ACDocument CDocument] classes. For each DOM interface, also a phantom data type is defined: [http://www.golubovsky.org:5984/_utils/yhcws/DOM-Level2-Dom.html#t%3ATNode TNode], and [http://www.golubovsky.org:5984/_utils/yhcws/DOM-Level2-Dom.html#t%3ATDocument TDocument] correspondingly. Phantom types are assigned to concrete values (references to DOM objects) while type classes are used to constrain types of parameters of functions working with those DOM objects. The ''CDocument'' class is defined as: <haskell> class CNode a => CDocument a data TNode data TDocument instance CNode TNode instance CDocument TDocument instance CNode TDocument </haskell> to reflect inheritance of ''Document'' from ''Node''. Accordingly, continuing our example, for ''HTMLElement'', we have: <haskell> class CNode a => CElement a class CElement a => CHTMLElement a data THTMLElement instance CElement THTMLElement instance CHTMLElement THTMLElement instance CNode THTMLElement </haskell> and so on. This means that a value of ''THTMLElement'' may be passed as argument to a function expecting an instance of ''CNode'', but not the opposite. Similarly, a value of ''TDocument'' can by no means be passed to a function expecting a ''THTMLElement''. This increases type safety of a program which, if written in Javascript, would have lacked such safety completely (or eventually would end up throwing an exception from runtime type check). Below is an example of such type constrained function: <haskell> hasChildNodes :: CNode this => this -> CPS c Bool </haskell> which corresponds to the [http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-810594187 hasChildNodes] function defined within the ''Node'' interface. Any DOM object which is a ''Node'' can be passed to this function (by reference) as the <code>this</code> argument. ====Attributes vs. getters and setters==== Within interfaces, DOM specification defines attributes and methods. Attributes are either read-only (such as [http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-F68D095 nodeName] of the ''Node'' interface) or read-write (such as [http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-F68D080 nodeValue] of the same interface). In Haskell bindings, getter (for read-only attributes), and both getter and setter (for read-write attributes) functions are defined in straightforward manner: <haskell> get'nodeName :: CNode this => this -> CPS c String set'nodeValue :: CNode zz => String -> zz -> CPS c zz get'nodeValue :: CNode this => this -> CPS c String </haskell> Getters always take the object containing an attribute as the first argument, <code>this</code>, and it is always constrained to the type class corresponding to the DOM interface. Setters always take the value to be set as the first argument, and the object containing the attribute as the second argument. Setters always return reference to the same object where an attribute was set. The latter property allows to concatenate multiple setters in Continuation-passing style, such as: <haskell> ........$ \he -> (set'id "myid") (set'lang "en") (set'title "Hello") </haskell> This whole construction will pass the same object (<code>he</code>) to the continuation, but continuation will deal with updated object. The setters in the example above are defined in the [http://www.golubovsky.org:5984/_utils/yhcws/DOM-Level2-HTMLElement.html DOM.Level2.HTMLElement] module. ====Methods vs. functions==== Interface methods are translated to Haskell functions whose type signatures have proper type coetraints. Thus, the [http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-getElBId getElementById] function defined in the ''Document'' interface as <code> Element getElementById(in DOMString elementId); </code> translates to Haskell function: <haskell> getElementById :: (CDocument this, CElement zz) => this -> String -> CPS c zz </haskell> as follows from its type, ''getElementById'' does not return a value of concrete type, but rather a type-constrained value. Values of types corresponding to DOM interfaces, translate to type-constrained rather than concrete values. This sometimes makes it necessary to supply explicit type signatures unless a function receiving the returned constrained value has a type signature that brings a constrained type down to a concrete type. ====Maker functions==== The IDL conversion utility <code>domconv</code> auto-creates convenient functions that serve as constructors of DOM objects corresponding to HTML tags. An example of such maker function is: <haskell> mkDiv :: CHTMLDocument a => a -> CPS c THTMLDivElement </haskell> which creates a DOM node tagged with <DIV>. Such maker functions are defined for most of HTML elements. Maker functions always return values of concrete type.
Summary:
Please note that all contributions to HaskellWiki are considered to be released under simple permissive license (see
HaskellWiki:Copyrights
for details). If you don't want your writing to be edited mercilessly and redistributed at will, then don't submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!
Cancel
Editing help
(opens in new window)
Toggle limited content width