1 <ibex-doc title="The Ibex Reference" subtitle="Nitrogen Release" author="Adam Megacz" email="adam@ibex.org">
3 <!-- ----------------------------------------------------------------------- -->
4 <section title="Introduction">
7 If you are reading the html version of this document and are
8 thinking of printing it out, you might be interested in the nicely
9 typeset <link url="reference.pdf" text="pdf version"/> produced
13 This document is a <b>reference</b>. It is not a
14 <b>specification</b> or a
17 This document does not guide the user gently through examples (as a
18 tutorial would), and it doesn't provide enough detail and formality
19 for a third party to construct a compatible re-implementation of the
20 Ibex Core (as a specification would).
22 Rather, the goal of this document is to completely describe every
23 aspect of the environment that the Ibex Core provides to client
24 applications, from the bottom up. If you want to be an Ibex expert,
25 this is the right document to read. It is assumed that you are already
26 familiar with XML and with either JavaScript or ECMAscript.
28 If you need to use or rely on some behavior you notice in the Ibex
29 Core, but which is not clearly defined here, please post to <link
30 url="http://lists.ibex.org/listinfo/users" text="the users mailing list"/>.
32 <section title="Key Concepts">
34 <definition term="The Core">
35 Ibex itself; the native code (or Java bytecode) that runs on
36 the client. This term does not include the <i>Wildebeest</i>
37 or the <i>UI</i></definition>
39 <definition term="The UI / The Application">
40 A set of files (mostly XML, JavaScript, and PNG images)
41 bundled up in a zip archive, ending with the "<t>.ibex</t>"
42 extension. Together, these files specify the appearance and
43 behavior of the application's user interface.
46 <definition term="The Server">
47 We will use the term "the server" to refer to any other
48 computer which the client makes XML-RPC or SOAP calls
49 to. Note that it is possible for the client and server to be
50 the same machine.</definition>
52 <definition term="Wildebeest">
53 This is a very small piece of code that is downloaded the
54 first time a client uses Ibex. It downloads the Ibex core,
55 verifies its signature, and launches it with the appropriate
56 parameters indicating where to find the initial UI.
57 Wildebeest works differently on every platform, and is outside
58 the scope of this document.</definition>
60 <definition term="put/write">
61 In ECMAscript, when you change the value of a property on an
62 object, you are <i>putting</i> to that property, or
63 <i>writing</i> to it. For example, the ECMAscript expression
64 "<t>foo.bar = 5</t>" <i>puts</i> the value 5 to the bar
65 property on object foo.</definition>
67 <definition term="get/read">
68 In ECMAscript, when you access the value of a property on an
69 object, you are <i>getting</i> that property, or
70 <i>reading</i> from it. For example, the ECMAscript
71 expression "<t>return (3 + foo.bar)</t>" <i>gets</i> the
72 value of bar property on object foo and then adds 3 to it
73 before returning the result.</definition>
75 <definition term="JavaScript">
76 We will use the terms JavaScript and ECMAScript
77 interchangeably in this document. The Ibex interpreter is not
78 completely ECMA-compliant, however (see <link
79 appendix="ECMAscript compliance"/> for details).
84 <section title="Life Cycle of an Ibex Application">
86 <image url="lifecycle.pdf" caption="The Lifecycle of an Ibex Application"/>
88 A user typically begins an Ibex session by clicking on a link to
89 an Ibex application. This link serves the {\tt launch.html} file
90 to the user's browser, which in turn downloads the appropriate
91 {\it Wildebeest} -- currently either an ActiveX Control
92 (Win32/MSIE), XPInstaller (Mozilla), or Signed Applet (all
95 The Wildebeest downloads the appropriate core for the user's
96 machine and verifies its digital signature. It then launches the
97 core, which downloads the UI (an <t>.ibex</t> archive), loads it,
98 applies the <t>main.t</t> template (found in the archive), and
99 renders it onto the screen, running any associated JavaScript
102 The user interacts with the application by clicking and moving the
103 mouse, and by pressing keys on the keyboard. These actions trigger
104 fragments of JavaScript code which are designated to handle events.
105 This JavaScript code can then relay important information back to the
106 server using XML-RPC or SOAP, or it can modify the structure and
107 properties of the user interface to change its appearance, thereby
108 giving feedback to the user.
110 The Ibex core quits when the last remaining surface has been destroyed.
115 <section title="Surfaces">
117 <image url="offscreen.pdf" width="2in"
118 caption="An Ibex surface positioned at (83,0)"/>
119 Each top-level window in an Ibex UI is called a
120 <i>surface</i>. There are two kinds of surfaces: <i>frames</i>,
121 which usually have a platform-specific titlebar and border, and
122 <i>windows</i>, which never have any additional platform-specific
125 Whenever we refer to the size or position
126 of a surface, we are referring to the size or position of the
127 UI-accessible portion of the surface; this does not include any
128 platform-specific decorations. This means that if you set the
129 position of a frame to (0,0), the platform-specific titlebar will
130 actually be off the screen on most platforms (it will be above and
131 to the left of the top-left corner of the screen).
133 Surfaces are not actual JavaScript objects; you cannot obtain a
134 reference to a surface. However, each surface is uniquely identified
135 by its <i>root box</i>, described in the next section.
139 <section title="Boxes">
141 A <i>box</i> is the fundamental unit from which all Ibex user
142 interfaces are built. Boxes can contain other boxes (referred to as
143 its <i>children</i>). Each surface has a single box associated with
144 it called the <i>root box</i>; the root box and its children (and
145 its children's children, and so on) form the surface's <i>box
148 There are three ways to think of a box:
151 As a rendered visualization on the screen (the "<i>Visual Representation</i>")
153 As a JavaScript object (the "<i>Object Representation</i>")
155 As as an XML tag (the "XML Template Representation").
159 <image url="threeviews.pdf" caption="The three representations of an Ibex box"/>
161 All three representations are equally valid, and being able to
162 figure out what an action in one representation would mean in terms
163 of the other two representations is crucial to a solid understanding
169 <section title="The XML Template Representation">
171 A template (discussed in the next section) is an XML file which acts
172 as a blueprint for constructing a tree of boxes. We call this
173 construction process <i>applying</i>, since unlike
174 <i>instantiation</i> in object-oriented programming systems, you
175 always apply a template to a pre-existing box, and you can apply
176 multiple templates to the same box.
178 Each XML tag corresponds to a single box, or to another template
179 which will be applied to that box. For example, a <t>scrollbar</t>
180 template, when applied, will construct a tree of boxes which has the
181 visual appearance and behavior of a scrollbar.
183 Although it is useful to think of the XML tags as being boxes, keep
184 in mind that the XML representation is only a blueprint for
185 constructing a tree of JavaScript objects. Once the template has
186 been instantiated, the XML is effectively "thrown away", and
187 JavaScript code is free to alter the boxes. Once the process of
188 applying a template is complete, Ibex completely forgets the fact
189 that it has applied a particular template to a particular box. One
190 consequence of this approach is that if you think of templates as
191 classes, then Ibex has no equivalent for Java's <t>instanceof</t>
194 Each template is an XML document whose root element is
195 <t><ibex></t>. Here is a sample template file:
198 <ibex xmlns:lib="ibex.lib">
201 This is a cool widget.
204 // this code is executed only once
205 static = { instances : [] };
207 // this element applies the ibex.lib.focusable template
211 static.instances.push(thisbox);
212 <ui:box id="container"/>
221 The following two namespaces are predefined and need not be declared
224 <definition term="meta">
225 <t>http://xmlns.ibex.org/meta</t>
227 This will be referred to as the "<t>meta</t> namespace" in the
228 remainder of this document.
231 <definition term="ui">
232 <t>http://xmlns.ibex.org/ui</t>
234 This will be referred to as the "<t>ui</t> namespace" in the
235 remainder of this document.
238 Additionally, the default namespace for the document will be set to
239 the template's package FIXME.
241 <section title="Static Code">
243 If the root <t><ibex></t> element contains any non-whitespace
244 text content, this text is interpreted as JavaScript code and is
245 executed the first time the template is referenced. This code is
246 executed in a fresh scope containing two predefined properties:
248 <definition term="ibex">
249 The Ibex Object (described in <ref section="The Ibex Object"/>)
252 <definition term="static">
253 A reference to this template's <i>static object</i>, which is
254 initially <t>null</t>. The static object can be accessed (read
255 and written) from both static scripts as well as instance
256 scripts in a particular template. FIXME
261 <section title="Metadata">
263 Any immediate children of the root element which are in the
264 <t>meta</t> namespace are treated as metadata and are exempted from
265 the rest of the template application process. Currently only one
266 type of metadata element is defined:
269 <t><meta:doc></t>: structured documentation for the
275 <section title="Other Elements">
277 All remaining children of the root element are treated as elements
278 to be <i>applied</i> to the box, in the order in which they appear
279 in the file using the following procedure.
281 <remark text="While this process outlined below sounds very
282 complex, it actually works pretty intuitively. The
283 description below is given in great detail since
284 most applications will wind up being unintentionally
285 dependent on subtle features of this process.
286 However, most of the time you can just pretend that
287 the XML tags and the boxes are the same thing."/>
289 <heading title="Intuitive Description"/>
293 During a box initialization, script-private references to a
294 box's descendants with <t>id</t> attributes are placed on the
295 box. These references allow scripts on that box to easily refer
296 to descendant nodes created by the template in which the script
297 appears. For example, these two blocks of code have exactly the
302 <ui:box id="foo"/> <ui:box/>
303 $foo.color = "red"; var $foo = this[0];
308 <heading title="Precise Description"/>
310 To apply an XML tag <t><b>x</b></t> to a box <t><b>b</b></t>, perform the following
311 operations, in this order:
313 <list type="ordered">
315 Allocate a fresh scope <t><b>s</b></t> whose parent scope is
318 Process each child element or text segment of <t><b>x</b></t>
319 in the order they appear in the document:
323 Treat each text segment <t><b>t</b></t> as JavaScript code
324 and execute it with <t><b>s</b></t> as the root scope.
326 For each child element <t><b>x'</b></t> of <t><b>x</b></t>:
329 Create a new box <t><b>b'</b></t>.
331 If the name of tag <t><b>x'</b></t> is not
332 "<t>box</t>" in the <t>ui</t> namespace, prepend the
333 tag's namespace identifier uri (if any) to the name of
334 the tag, and use the result as a key to retrieve a
335 property from the root stream (defined later).
336 Interpret the resulting stream as a template and apply
337 that template to <t><b>b'</b></t>.
339 (recursively) apply <t><b>x'</b></t> to <t><b>b'</b></t>.
341 If <t><b>x'</b></t> has an <t>id</t> attribute, declare a variable
342 in <t><b>s</b></t> whose name is the value of the <t>id</t>
343 attribute, prefixed with the <t>$</t> character, and whose
344 value is <t><b>b'</b></t>
346 Copy any <t>$</t>-variables created during the application
347 of <t><b>x'</b></t> into scope <t><b>s</b></t>.
349 Append <t><b>b'</b></t> as the last child of <t><b>b</b></t>.
353 Apply any attributes on <t><b>x</b></t> to <t><b>b</b></t>, except for
354 <t>id</t>. Since XML specifies that the order of attributes
355 cannot be significant, Ibex processes attributes in
356 alphabetical order by attribute name. For example, if
357 <t><b>x</b></t> has the attribute <t>foo="bar"</t>, then the
358 equivalent of the statement <t>B.foo="bar";</t> will be
359 performed, with the following exceptions:
362 If the value portion of the attribute is the string
363 "<t>true</t>", put the boolean <t>true</t>. If the
364 value is "<t>false</t>", put the boolean <t>false</t>.
366 If the value is a valid ECMAscript number, put it as a
367 number (instead of a string).
369 If the value begins with a dollar sign (<t>$</t>),
370 retrieve the value of the corresponding variable in
371 <t><b>s</b></t> and use that value instead.
373 If the value begins with a dot (<t>.</t>), prepend the
374 attributes' namespace identifier uri (if any) and
375 interpret the remainder as a property to be retrieved from
376 the root stream (defined later).
380 <heading title="Initialization Invariants"/>
382 The last two steps are referred to as the <i>initialization</i> of the
383 node. There are two important aspects of this ordering to be aware of:
385 <list type="unordered">
387 A given box will be fully initialized before its parent is
388 given a reference to that box. This way, parents can be
389 certain that they will never wind up accessing a box when it
390 is in a partially-initialized state.
392 Attributes are applied <i>after</i> scripts are run so that
393 the attributes will trigger any <i>traps</i> (defined later)
394 placed by the script.
402 <!-- ----------------------------------------------------------------------- -->
403 <section title="Layout and Rendering">
405 <section title="Visual Components">
407 Each box occupies a rectangular region on the surface. The visual
408 appearance of a surface is created by rendering each box in its tree.
409 Unless the <t>clip</t> attribute is <t>false</t>, each box will
410 clip its childrens' visual representations to its own, so that the
411 children appear "confined to" the parent. Children are rendered after
412 their parents so they appear "on top of" their parents.
414 Each box has two major visual components, each with subcomponents:
418 <definition term="path">
420 A box's <t>path</t> consists of zero or more lines and curves.
421 The path may be filled with a color, gradient, or texture, and
422 may be stroked with a line of a given thickness and color. If
423 the path is not specified, it defaults to the perimiter of the
424 box. [<i>Note: Vector Graphics support (including the ability
425 to set the <t>path</t> property to anything other than the
426 default) is currently not implemented</i>].
431 an associated <t>strokecolor</t>, which is a color
433 an associated <t>strokewidth</t>, which is a number
434 specifying the width of the stroke. [<i>Note: Vector
435 Graphics support (including the <t>strokewidth</t>
436 property) is currently not implemented</i>]
438 a <t>fill</t>, which is either a color, gradient, or
443 <definition term="text">
445 Each box also has a single line of <t>text</t>, whose
446 appearance is determined by its:
449 associated <t>font</t>, which can be any font supported by
450 the <link url="http://www.freetype.org" text="FreeType2"/>
453 an associated <t>fontsize</t> in <i>pixels</i>
455 an associated <t>textcolor</t>
459 These eight components plus the size of a box fully specify its
460 appearance. Every single box you see in Ibex is drawn only on the
461 basis of these components and its size.
464 <section title="Size and Position">
466 The size and position of every box is determined by its
467 properties, its childrens' sizes, and its parent's size and
468 position. Box layout and rendering happens in four phases:
469 <i>packing</i>, <i>constraining</i>, <i>placing</i>, and
470 <i>rendering</i>. The Core is careful to only perform a phase on
471 a box if the box has changed in a way that invalidates the work
472 done the last time that phase was performed. The packing and
473 constraining phases are performed in a single traversal of the
474 tree (packing is preorder, constraining is postorder), and the
475 placing and rendering phases are performed in a second traversal
476 of the tree (first placing, then rendering, both preorder).
478 For brevity, the rest of this chapter deals only with width and
479 columns. Height and rows is treated identically and independently.
480 Also, it is important to note that the term <i>minimum width</i> is
481 not the same thing as the property <t>minwidth</t>, although they
484 <heading title="The Size of the Root Box"/>
486 When the user resizes a window, Ibex changes the root box's
487 <t>maxwidth</t> and <t>maxheight</t> to match the size chosen by
488 the user and then determines the root box's size using the same sizing
489 rules it uses for other boxes.
491 Ibex will always attempt to prevent the
492 user from making the surface smaller than the root box's
493 <t>minwidth</t> and <t>minheight</t>. If the <t>hshrink</t> or
494 <t>vshrink</t> flag is set, Ibex will try to prevent the user from
495 resizing the surface at all. However, not all platforms give Ibex
496 enough control to do this.
498 <image url="alignmentpoint.pdf" caption="The effect of alignment points on layout" width="3in"/>
499 <heading title="The alignment point"/>
501 When talking about positioning, we will often refer to the
502 <i>alignment point</i>.
504 If the <t>align</t> property is "<t>center</t>", then the
505 alignment point is the center of the box.
507 If the <t>align</t> property is "<t>topleft</t>",
508 "<t>bottomleft</t>", "<t>topright</t>", or
509 "<t>bottomright</t>", then the alignment point is
510 corresponding corner of the box.
512 If the <t>align</t> property is "<t>top</t>",
513 "<t>bottom</t>", "<t>right</t>", or "<t>left</t>", then
514 the alignment point is middle of the corresponding edge of the
517 When positioning a child box, the alignment point is determined by
518 the <i>parent's</i> <t>align</t> property. When rendering a
519 visual element (a texture, path, or text string) within a box, the
520 alignment point is determined by the <i>box's own</i> <t>align</t>
523 A simple way to think about this is that whenever there are two boxes
524 involved in the decision, you should use the parent's alignment point.
526 <section title="Packing">
528 A grid of <i>cells</i> is created within the parent. If the
529 parent's <t>cols</t> property is set to 0, the cell grid has an
530 infinite number of columns. Either <t>cols</t> or <t>rows</t>
531 must be zero, but not both.
533 If a child's <t>visible</t> property is <t>false</t>, it does
534 not occupy any cells (and is not rendered). Otherwise, each child
535 occupies a rectangular set of cells <t>child.colspan</t> cells
536 wide and <t>child.rowspan</t> cells high.
538 The Core iterates over the cells in the grid in the following
539 order: if <t>rows</t> is 0, the Core iterates across each column
540 before proceeding to the next row; otherwise rows come before
541 columns. At each cell, the Core attempts to place the <i>first
542 remaining unplaced child's</i> top-left corner in that cell
543 (with the child occupying some set of cells extending down and
544 to the right of that cell). If the parent has a fixed number of
545 columns and the child's <t>colspan</t> exceeds that limit, the
546 child is placed in column zero regardless, but only occupies the
547 available set of cells (it does not "hang off the end" of the
548 box). <image url="layout.pdf" width="1in"/>
553 <ui:box id="2" rowspan="2" />
554 <ui:box id="3" colspan="2" />
556 <ui:box id="5" colspan="2" />
565 <section title="Constraining">
567 Each box's minimum width is computed recursively as the
573 The width of the box's <t>text</t> (after applying the
574 box's <t>transform</t>) [<i>Note: Vector Graphics support
575 (including the <t>transform</t> property) is currently not
578 The width of the box's path (after applying the box's
579 <t>transform</t>) <i>if the box is <t>packed</t></i>.
581 The width of the bounding box enclosing the box's cells.
584 The minimum width of each cell is computed as the minimum
585 width of the box occupying it divided by the box's
588 If a box's <t>hshrink</t> property is set to
589 <t>true</t>, the box's maximum width is the same as its
590 minimum width; otherwise it is the box's
593 The maximum width of each cell is the <t>maxwidth</t> of
594 the box occupying it divided by the box's
598 <section title="Placing">
600 Each column's <i>actual width</i> is set to the maximum
601 <i>minimum width</i> of all the cells in that column.
602 <b>NOTE:</b> although a column or row can be sized smaller
603 than its "minimum width" or larger than its "maximum width", a
604 box will <i>never</i> be smaller than its <t>minwidth</t> or
605 larger than its <t>maxwidth</t>.
607 Each column's maximum width is the largest maximum width of
608 the cells in that column, but no smaller than the column's
611 A value <t>k</t> is chosen such that when each column's width
612 is set to <t>min(maximum width, max(minimum width, k))</t>,
613 the sum of all the column widths equals the parent's width.
614 If no such value exists, positive or negative infinity is used
615 (whichever is appropriate). Each column is then set to the
616 width dictated by <t>k</t>.
618 Next, the rows and columns are positioned within the parent
619 box. The rows and columns are transformed according to the
620 parent's <t>transform</t> property [<i>Note: Vector Graphics
621 support (including the <t>transform</t> property) is currently
622 not implemented</i>]., and the bounding box of the resulting
623 cells are placed such that the cells' alignment point
624 coincides with the parent's alignment point (both alignment
625 points are determined by the parent's <t>align</t> property).
627 <image url="grid.pdf" caption="Positioning grid cells"/>
629 <b>Packed boxes:</b> Each packed box's actual position
630 and size is then set to the aggregation of the actual sizes of
631 the cells it spans. If this size exceeds the box's maximum
632 width, the box is sized to its maximum width and centered
633 horizontally within the space occupied by its cells.
635 <b>Non-packed boxes</b>: each non-packed box is transformed
636 according to the parent's <t>transform</t> property and then
637 positioned so that its alignment point is <t>(child.x,
638 child.y)</t> pixels from the parent's alignment point (both
639 alignment points are determined by the parent's <t>align</t>
645 <section title="Rendering">
647 Boxes are rendered in a depth-first, pre-order traversal. Note that
648 this may cause a non-packed box to overlap its siblings.
650 <list type="ordered">
652 If the box's <t>transform</t> property is non-null, the
653 coordinate space is transformed accordingly for the rest of
654 this phase and for the rendering of all children. [<i>Note:
655 Vector Graphics support (including the <t>transform</t>
656 property) is currently not implemented</i>].
658 If the box is packed and has a non-<t>null</t> path, the
659 path is translated such that the alignment point of the path's
660 bounding box coincides with the box's alignment point (both
661 alignment points are determined by the box's <t>align</t>
664 If a box has a path, that path is filled with the color,
665 gradient, or image specified by the <t>fill</t> property and
666 stroked with the color and width specified by the
667 <t>strokecolor</t> and <t>strokewidth</t> properties.
669 If the box has a non-null <t>text</t> attribute,
670 the text is rendered in <t>font</t> with size
671 <t>fontsize</t> and color <t>textcolor</t>. The text is
672 then translated such that the alignment point of the text's
673 bounding box coincides with the box's alignment point (both
674 alignment points are determined by the box's <t>align</t>
677 The box's children are rendered (pre-order traversal).
685 <!-- ----------------------------------------------------------------------- -->
686 <section title="Box Properties">
688 Each box is a full-fledged ECMAscript object, and can store
689 key-value pairs as properties. Some of these keys have special
690 meaning, which will be explained later. Each box's numeric
691 properties hold its <i>child boxes</i>.
693 <section title="Rendering Properties">
695 Every box has several special properties which control how it is
696 drawn. In general, if you put an
697 invalid value to a special property, no action will be taken -- the
700 <property name="strokecolor" type="string" default="clear">
702 If the value is a 5-character hex string (<t>#RGB</t>),
703 7-character hex string (<t>#RRGGBB</t>), 9-character hex
704 string (<t>#AARRGGBB</t>), the box's stroke color will be set
707 If the value is one of the <link
708 url="http://www.color.org/ICC-1A_1999-04.PDF"
709 text="ICC"/> colors (the same set of color names
710 supported by SVG), the stroke color be set to that color.
712 If the value is <t>null</t>, the stroke color will be set
713 to clear (<t>#00000000</t>).
716 <property name="strokewidth" type="int" default="1">
717 The width (in pixels) to stroke the path with.
720 <property name="fill">
721 This property can be set to any of the values specified for
723 Alternatively, if the value written is an object, its stream
724 will be read and interpreted as a PNG, GIF, or JPEG image,
725 which will become the texture for this box, and the box's
726 <t>minwidth</t> and <t>minheight</t> properties will be
727 automatically set to the dimensions of the image.
730 <property name="path" type="string" default='""'>
731 The box's path. The grammar and feature set supported are
732 identical to that specified in <link
733 url="http://www.w3.org/TR/SVG11/paths.html" text="SVG 1.1,
737 <property name="text" type="string" default='""'>
738 The box's text; writing <t>null</t> to this property sets it
742 <property name="textcolor" type="number" default="black">
743 The color in which to render the font; accepts the same values as <t>strokecolor</t>.
746 <property name="font" type="stream" default=".ibex.ui.font.sansserif">
747 When an object is written to this property, its stream is read
748 using the <link url="http://www.freetype.org" text="FreeType 2 library"/>,
749 and the resulting font is used to render the
753 <property name="fontsize" type="number" default="10">
754 The size (in points) to render the text.
759 <section title="Layout Properties">
761 <property name="shrink" type="boolean" default="false">
762 If set to <t>true</t>, this box will shrink
763 (horizontally/vertically/both) to the smallest size allowed by
764 its children and the bounding box of its path.
767 <property name="x y" type="integer" default="varies">
768 If the box is a root box, this is the (x/y)-coordinate of the
769 surface; otherwise it is the distance between the parent's
770 alignment point and this box's alignment point.
773 <property name="minwidth minheight" type="integer" default="0">
774 The desired minimum width and height.
777 <property name="maxwidth maxheight" type="integer" default="ibex.ui.maxdim">
778 The desired maximum width and height.
781 <property name="width height" type="integer">
782 When read, this is the current (width/height) of this box.
783 Writing to this property is equivalent to writing to
784 <i>both</i> the minimum and maximum (width/height).
787 <property name="cols rows" type="integer" default="0">
788 The number of (columns/rows) in which to lay out the children of this
789 box. If set to zero, the number of (columns/rows) is unconstrained.
790 Either <t>rows</t> or <t>cols</t> must be zero. If
791 <t>0</t> is written to <t>cols</t> when <t>rows</t> is
792 <t>0</t>, the write is ignored. If a nonzero value is
793 written to <t>cols</t> when <t>rows</t> is nonzero,
794 <t>rows</t> is set to <t>0</t>, and vice versa.
797 <property name="colspan rowspan" type="integer" default="1">
798 The number of (columns/rows) that this box spans within its parent.
801 <property name="align" type="string" default="center">
802 Determines the box's alignment point for positioning its text,
803 texture, path, and children.
806 <property name="visible" type="boolean" default="true">
807 If set to <t>false</t>, this box will be rendered as if its
808 width and height were zero. If this is a root box, the
809 associated surface will be hidden.
811 When reading from this property, the value <t>false</t> will
812 be returned if this box <i>or any of its ancestors</i> is not
813 visible. Thus it is possible to write <t>true</t> to a box's
814 <t>visible</t> property and then read back <t>false</t>.
817 <property name="packed" type="boolean" default="true">
818 The layout strategy for this box. If set to <t>true</t>, the
819 box occupies no cells and is laid out independently of its
825 <section title="Child Control Properties">
827 <property name="redirect" type="box" default="thisbox">
828 Writing to this property sets the box's redirect target. This
829 property cannot be read from, and can only be written to if
830 the value being written is a <i>descendant</i> of the current
833 If a box has a non-null redirect target, reads and writes to
834 any of the other properties in this section will be forwarded
835 to the redirect target.
837 The <t>redirect</t> attribute is very useful for hiding the
838 internal structure of a widget, and for allowing widgets to act as
839 "smart" containers for other widgets. For example, a menu widget might
840 have an invisible child as its redirect target; this way, when boxes
841 representing items on the menu are added as children of the menu
842 widget, they do not appear until the menu is pulled down.
845 <property name="numeric properties" type="int" default="">
846 The <i>n</i>th child of box <t>b</t> can be accessed by reading from
847 <t>b[n]</t>. The <i>n</i>th child can be removed by writing
848 <t>null</t> to <t>b[n]</t> (the child will become parentless). A
849 new child can be inserted <i>before</i> the <i>n</i>th child by
850 writing it to <t>b[n]</t>; if the value written is already a child of
851 <t>b</t>, it will be removed from <t>b</t> first. It is important
852 to note that this behavior is different from ECMAscript arrays --
853 writing a non-<t>null</t> value to <t>b[n]</t> does not eliminate
854 the <i>n</i>th child; it merely shifts it over one position.
855 <b>Note:</b> Unlike most JavaScript objects, enumerating a Box's
856 properties with the JavaScript <t>for..in</t> construct will
857 enumerate <i>only</i> the box's children and not any other properties.
860 <property name="clip" type="boolean" default="true">
861 If <t>true</t>, the visual representation of this box's
862 children will be clipped to the boundaries of this box.
863 <b>Note:</b> setting this property to <t>false</t> imposes a
864 substantial performance penalty.
867 <property name="numchildren" type="integer" default="0">
868 The number of children this box has.
872 <property name="surface" type="" default="null">
874 If this box has a parent, this property returns
875 <t><i>parent</i>.surface</t>; otherwise it returns null.
876 This property is a simple building block that the widget
877 library uses to implement more complex functionality such as
878 focus control and popups.
883 <section title="Other Box Properties">
885 <property name="cursor" type="string" default="null">
886 The shape that the cursor should take when inside this
887 box. Valid values are: "<t>default</t>" , "<t>wait</t>",
888 "<t>crosshair</t>", "<t>text</t>", "<t>hand</t>", and
889 "<t>move</t>", as well as resizing cursors"<t>east</t>",
890 "<t>west</t>", "<t>north</t>", "<t>south</t>",
891 "<t>northwest</t>", "<t>northeast</t>",
892 "<t>southwest</t>", and "<t>southeast</t>". Note that on
893 some platforms, resize cursors for opposite directions (such
894 as <t>northwest</t> and <t>southeast</t> are the
896 If a box's cursor is <t>null</t>, its parent's cursor will
897 be used. If the root box's cursor is null, the
898 "<t>default</t>" cursor will be used.
901 <property name="static" type="object" default="N/A">
902 Reading from this property will return the parent scope used
903 to execute the <t><static/></t> block of the template
904 in which the currently-executing code resides.
907 <property name="thisbox" type="box" default=" ">
908 Returns a reference to the box itself.
909 If <t>null</t> is written to this property, and this box is
910 the root box of a surface, the box will be detached and the
911 surface destroyed. If this box has a parent, it will be
912 detached from its parent.
915 <property name="indexof()" type="function" default=" ">
916 This property is actually a function; invoking
917 <t>parent.indexof(child)</t> will return the numerical index
918 of <t>child</t> in <t>parent</t> if <t>child</t> is a
919 child of <t>parent</t> (or <t>parent</t>'s redirect
920 target), and <t>-1</t> otherwise. Writing to this property
924 <property name="distanceto()" type="function" default=" ">
925 This property is actually a function; invoking
926 <t>box.distanceto(otherbox)</t> will return an object with two
927 properties, <t>x</t> and <t>y</t>, containing the horizontal
928 and vertical distance between the two boxes (negative if
929 <t>otherbox</t> is to the left of / above <t>box</t>). This
930 can be used to determine the relative placement of two boxes
931 on different branches of the box tree.
936 <section title="Root Box Properties">
938 The following special properties are only meaningful on the root box
941 <property name="Focused">
942 The value <t>true</t> is put to this property on the root box
943 when the surface gains the input focus, and <t>false</t> when
944 the surface loses the input focus. Reading from this value will
945 return <t>true</t> if the surface is focused and <t>false</t>
946 if it is not. Putting <t>true</t> to this property will
947 <i>not</i> cause the surface to "steal" the input focus from other
951 <property name="Maximized">
952 The value <t>true</t> is put to this property on the root box
953 when the surface is maximized, and <t>false</t> when the surface
954 is un-maximized. Reading from this value will return <t>true</t>
955 if the surface is maximized and <t>false</t> if it is
956 not. Putting <t>true</t> to this property will maximize the
957 window, and putting <t>false</t> to this property will
958 unmaximize the window.
959 Note that not all platforms support maximization.
962 <property name="Minimized">
963 The value <t>true</t> is put to this property on the root box
964 when the surface is minimized, and <t>false</t> when the surface
965 is unminimized. Reading from this value will return <t>true</t>
966 if the surface is minimized and <t>false</t> if it is
967 not. Putting <t>true</t> to this property will minimize the
968 window, and putting <t>false</t> will unminimize it.
971 <property name="Close">
972 When the user attempts to close a surface, the value
973 <t>true</t> will be put to this property. Scripts may trap
974 this property to prevent the window from closing. Putting the
976 <t>true</t> to this property on a root box has the same
977 effect as putting <t>null</t> to the <t>thisbox</t>
981 <property name="icon">
982 The surface's icon. This is usually displayed on the titlebar of a
983 window. The value should be an object whose stream is a PNG image. Note
984 that not all platforms support this property.
987 <property name="titlebar">
988 The surface's titlebar text. Note that not all platforms support
989 this property. Only ASCII characters 0x20-0x7F are permitted.
996 <!-- ----------------------------------------------------------------------- -->
997 <section title="Streams">
999 <heading title="Every object has a stream..."/>
1001 Every object has a <i>stream</i> associated with it. A stream is a
1002 sequence of bytes that can be read or written to.
1004 By default an object has an empty stream (zero bytes). However, some objects
1005 (returned from special methods on the <t>ibex</t> object) have
1006 streams yielding data read from an url, file, or a component of a zip
1007 archive. In a future release, the stream associated with a box will
1008 be an .ibex template which, when applied, will fully reconstitute the
1011 <heading title="...but streams are not objects"/>
1013 Despite the ubiquity of streams, you cannot actually reference a
1014 stream, since it is not an object. Instead, you simply reference the
1015 object it belongs to. If you are familiar with Java, this is similar
1016 to how every Java object has a monitor associated with it, but you
1017 cannot directly manipulate the monitor (you can't pass around a
1018 reference to just the monitor).
1020 In the rest of the section we will sometimes refer to "getting
1021 properties from a stream" or "passing a stream to a function"; this is
1022 just shorthand for saying to perform those actions on the object the
1025 <section title="Creating Streams from URLs">
1027 You can create a stream from a URL by calling
1030 var r = ibex.stream.url("http://...");
1033 This will return an object whose stream draws data from the specified
1034 URL. Streams are loaded lazily whenever possible.
1038 <section title="Getting Substreams">
1040 Most stream objects let you access
1041 substreams using the usual JavaScript operators <t>[]</t> and
1042 <t>.</t>, as well as the <t>for..in</t> syntax.
1045 // r1 and r2 are equivalent but not equal (!=)
1046 var r1 = ibex.stream.url("http://www.ibex.org/foo/bar.html");
1047 var r2 = ibex.stream.url("http://www.ibex.org/foo")["bar.html"];
1052 <section title="The Root Stream">
1054 The empty-string property on the <t>ibex</t> object is called the
1055 <i>root stream</i>. You can access this object as <t>ibex..</t> or
1056 <t>ibex[""]</t>. Additionally, any expression which starts with a
1057 dot is treated as property to be retrieved from the root stream. The
1058 following three expressions are equivalent:
1068 <section title="Static Blocks">
1072 You can access variables within the static block of a template by
1073 appending a double period (<t>..</t>) and the variable name to the
1074 stream used to load that template:
1077 <!-- org/ibex/themes/linux/scrollbar.ibex -->
1081 ibex.log.print(org.ibex.themes.linux.scrollbar..foo); // prints "12"
1086 <section title="Formatting Streams">
1088 If you attempt to send a stream as part of an XML-RPC call, the
1089 stream will be read in its entirity, Base64-encoded, and transmitted
1090 as a <t><base64/></t> element.
1092 Ibex supports two special URL protocols. The first is <t>data:</t>,
1093 which inteprets the rest of the URL as a Base64 encoded sequence of
1094 bytes to use as a source. The other is <t>utf8:</t> which
1095 interpretets the rest of the string as a Unicode character sequence to
1096 be UTF-8 encoded as a string of bytes to use as a source.
1099 var r5 = ibex.stream.url("data:WFWE876WEh99sd76f");
1100 var r6 = ibex.stream.url("utf8:this is a test");
1103 You can read a UTF-8 encoded string from a stream like this:
1106 var myString = ibex.stream.fromUTF(ibex.stream.url("utf8:testing..."));
1108 You can also parse XML from a stream using SAX like this:
1111 ibex.stream.xml.sax(
1112 ibex.stream.url("http://foo.com/foo.xml"),
1113 { beginElement : function(tagname, attributeKeyValuePairs) { ... },
1114 endElement : function(tagname) { ... },
1115 content : function(contentString) { ... }
1116 whitespace : function(whitespaceString) { ... }
1124 <!-- ----------------------------------------------------------------------- -->
1125 <section title="The Ibex object">
1127 The <t>ibex</t> object is present in the top-level scope of every
1128 script. It has the following properties:
1130 <heading title="General"/>
1132 <property name="ibex.box">
1133 reading from this property returns a new box
1135 <property name="ibex.clone(o)">
1136 creates a clone of object
1138 <property name="ibex.bless(s)">
1139 returns a blessed clone of stream
1142 <heading title="ECMA Library Objects"/>
1144 <property name="ibex.date">
1145 reading from this property returns a new date
1147 <property name="ibex.math">
1148 this object contains the ECMA math functions
1150 <property name="ibex.regexp(s)">
1151 return a regexp object corresponding to string <i>s</i>
1153 <property name="ibex.string">
1154 this object contains the ECMA string manipulation functions
1157 <heading title="Logging"/>
1159 <property name="ibex.log.debug(m1, ... mn)">
1160 log the debug messages <i>m1</i> through <i>mn</i>.
1164 <property name="ibex.log.info(m1, ... mn)">
1165 log the info messages <i>m1</i> through <i>mn</i>.
1168 <property name="ibex.log.warn(m1, ... mn)">
1169 log the warning messages <i>m1</i> through <i>mn</i>.
1172 <property name="ibex.log.error(m1, ... mn)">
1173 log the error messages <i>m1</i> through <i>mn</i>.
1176 <heading title="User Interface"/>
1178 <property name="ibex.ui.browser(u)">
1179 opens a new browser window with URL <i>u</i>
1182 <property name="ibex.ui.key.control">
1183 true if the control key is depressed
1186 <property name="ibex.ui.key.shift">
1187 true if the shift key is depressed
1190 <property name="ibex.ui.key.alt">
1191 true if the alt key is depressed
1194 <property name="ibex.ui.key.name.alt">
1195 the name of the "alt" key (usually either "alt", "meta", or
1199 <property name="ibex.ui.clipboard">
1200 the contents of the clipboard; can be read and written to
1203 <property name="ibex.ui.maxdim">
1204 the maximum dimension of any UI element; usually
1205 2<sup>31</sup>, but may be smaller
1208 <property name="ibex.ui.screen.width">
1209 the width of the screen, in pixels
1212 <property name="ibex.ui.screen.height">
1213 the height of the screen, in pixels
1216 <property name="ibex.ui.mouse.button">
1217 either 0, 1, 2, or 3, indicating the mouse button currently
1221 <property name="ibex.ui.frame">
1222 when a box is written to this property, it becomes the root
1226 <property name="ibex.ui.window">
1227 when a box is written to this property, it becomes the root
1231 <property name="ibex.ui.font.serif">
1232 an object whose stream is a a builtin serif font
1235 <property name="ibex.ui.font.sansserif">
1236 an object whose stream is a builtin sans-serif font
1239 <property name="ibex.ui.font.monospace">
1240 an object whose stream is a a builtin fixed-width font
1243 <heading title="Networking"/>
1245 <property name="ibex.net.rpc.xml(u)">
1246 return an XML-RPC call object with endpoint URL <i>u</i>
1249 <property name="ibex.net.rpc.soap(u,">
1250 return a SOAP call object with endpoint URL <i>u</i>,
1251 SoapAction <i>a</i>, and XML Namespace <i>n</i>
1254 <heading title="Threads"/>
1256 <property name="ibex.thread">
1257 when a function is written to this property, a new thread is
1261 <property name="ibex.thread.yield()">
1262 yield the current thread
1265 <property name="ibex.thread.sleep(n)">
1266 sleep for <i>n</i> milliseconds
1269 <heading title="Streams"/>
1271 <property name="ibex.stream.url(u)">
1272 returns a new object whose stream is drawn from URL <i>u</i>
1275 <property name="ibex.stream.unzip(s)">
1276 unpacks a zip archive from <i>s</i>'s stream
1279 <property name="ibex.stream.uncab(s)">
1280 unpacks a cab archive from <i>s</i>'s stream
1283 <property name="ibex.stream.cache(s,k)">
1284 valign=top>wraps a disk-backed read cache keyed on <i>k</i>
1285 around <i>s</i>'s stream
1288 <property name="ibex.stream.watch(s,f)">
1289 returns an object whose stream is drawn from <i>s</i>'s
1290 stream, but invokes <i>f(n,d)</i> as it is read from.
1293 <property name="ibex.stream.parse.xml(s, h)">
1294 Use SAX to parse the XML document on stream <i>s</i> with
1298 <property name="ibex.stream.parse.html(s, h)">
1299 Same as <t>parse.xml()</t>, but tries to fix broken HTML.
1302 <property name="ibex.stream.parse.utf8(s)">
1303 treat <i>s</i>'s stream as a string encoded as a UTF-8 byte stream and return the string
1306 <property name="ibex.stream.homedir">
1307 <t>ibex.stream.tempdir</t>
1310 <heading title="Cryptography"/>
1312 <property name="ibex.crypto.rsa(k,s)">
1313 <i>not implemented yet:</i> return a
1314 stream which rsa-decrypts stream <i>s</i> with key <i>k</i>
1317 <property name="ibex.crypto.rc4(k,s)">
1318 <i>not implemented yet:</i> return a
1319 stream which rc4-decrypts stream <i>s</i> with key <i>k</i>
1322 <property name="ibex.crypto.md5(s)">
1323 <i>not implemented yet:</i> immediately
1324 MD5-hash stream <i>s</i>
1327 <property name="ibex.crypto.sha1(s)">
1328 <i>not implemented yet:</i> immediately
1329 SHA1-hash stream <i>s</i>
1333 <!-- ----------------------------------------------------------------------- -->
1334 <section title="Traps">
1336 You can add a trap to a property by applying the <t>++=</t> operator
1337 to a function with one argument. The trap will be invoked whenever
1338 that property is written to.
1342 foo ++= function(z) {
1343 ibex.log.info("foo is " + z);
1348 If another script were to set the property "<t>foo</t>"
1349 on the box above to the value <t>5</t>, the function above would be
1350 invoked with the argument <t>5</t>. The function would then log
1351 the string "<t>foo is 5</t>".
1353 Within a trap, the expression <t>trapee</t> can be used to
1354 get a reference to the box on which the trap was placed.
1356 The expression <t>trapname</t> returns the name of the
1357 trap executing the current function. This is useful when a function
1358 is applied to multiple traps. For example:
1362 func ++= function(z) {
1363 ibex.log.info("called trap " + trapname);
1370 <section title="Removing Traps">
1372 You can remove a trap by using the <t>--=</t> operator with the same
1373 function you added as a trap:
1377 var myfunc = function(z) { /* ... */ }
1388 <heading title="Multiple Traps on the Same Property"/>
1390 When the trapped property is <i>written</i> to, each of the trap
1391 functions placed on it will be invoked in the opposite order that
1392 they were placed on the box -- the most recently placed trap will
1393 execute first. This last-to-first execution of traps is called
1394 <i>cascading</i>. After the last trap is invoked, the value is
1395 stored on the box (remember, boxes are objects, so they can hold
1396 properties just like all other ECMAscript objects).
1398 <section title="Manual Cascades">
1400 There are two additional tricks you can use when placing traps. The
1401 first is a <i>manual cascade</i>. If you want to cascade to lower
1402 traps in the middle of a function, or you want to cascade with a
1403 different value than the value passed to you (in effect "lying" to
1404 lower traps), you can use <t>cascade</t>. For example:
1407 <ui:box color="black">
1408 color ++= function(c) {
1409 ibex.log.info("refusing to change colors!");
1415 This effectively creates a box whose color cannot be changed, and
1416 which complains loudly if you try to do so.
1418 Do <i>not</i> try to do something like this:
1421 <ui:box color="black">
1422 color ++= function(z) {
1423 color = "black"; // INFINITE LOOP! BAD!!!
1427 To prevent automatic cascading, return <t>true</t> from your function:
1430 <ui:box color="black">
1431 color ++= function(z) {
1432 return true; // the box's color will not change
1439 <section title="Read Traps">
1441 The other trick is a <i>read-trap</i>. Read traps are just like normal
1442 traps, except that you use a function that takes zero arguments instead of one. Read traps
1443 also do not automatically cascade.
1447 doublewidth <t>++=</t> function() { return 2 * width; }
1451 If another script attempts to read from the <t>doublewidth</t>
1452 property on this box, the value it gets will be twice the actual width
1453 of the box. Note that
1454 the actual <t>doublewidth</t> property on the box never gets written
1455 to, since the trap does not cascade.
1457 You can manually cascade on read traps as well:
1461 text <t>++=</t> function() { return "my text is " + cascade; }
1465 Read traps are only rarely needed -- most of the time a write trap
1470 <heading title="Prohibited Traps"/>
1472 To prevent confusing and hard-to-debug behaviors, scripts may not
1473 place traps on any of the properties described in the sections
1474 <link text="Box Layout Properties" section="Layout Properties"/>, <link
1475 section="Child-Control Properties"/>, or <link section="Other Box
1476 Properties"/> except for <t>childadded</t>,
1477 <t>childremoved</t> and <t>surface</t>. FIXME: remove?
1479 <heading title="Exceptions and Traps"/>
1481 If an uncaught exception is thrown from a trap, Ibex will log the
1482 exception, but will <i>not</i> propagate it to the code which
1483 triggered the trap. If the trap was a read trap, the value
1484 <t>null</t> will be returned.
1485 FIXME: is this right?
1487 <heading title="Architectural Significance of Traps"/>
1489 Traps are the backbone of Ibex. Since almost all UI programming is
1490 event/demand driven, traps eliminate the need for separate
1491 member/getter/setter declarations, often cutting the amount of typing
1492 you have to do to a third of what it would normally be.
1494 <section title="Cloning">
1496 <i>Cloning</i> is a companion technique for traps; together they can
1497 be used to simulate any sort of environment you might need. When you
1498 call <t>ibex.clone(o)</t>, Ibex returns a new object (called the
1499 <i>clone</i>) which compares with equality (<t>==</t>) to the
1500 original object. Furthermore, both objects are "equal" as keys in
1505 var theclone = ibex.clone(o);
1507 ibex.log.info(hash[theclone]); // prints "5"
1510 Any writes to properties on the clone will actually write to
1511 properties on the original object, and reads from properties on the
1512 clone will read properties on the original object. In fact, the only
1513 thing that can be used to distinguish the original from the clone is
1514 traps -- a trap placed on the clone is <i>not</i> placed on the
1515 original object as well.
1520 <!-- ----------------------------------------------------------------------- -->
1521 <section title="Threads">
1523 <section title="Contexts">
1525 From the perspective of an application writer, Ibex is strictly
1526 single-threaded. Ibex is always in exactly one of the following three
1529 <list type="unordered">
1531 <b>Rendering Context</b> -- (redrawing the screen)
1533 <b>Event Context</b> (executing javascript traps triggered by an event)
1535 <b>Thread Context</b> (executing a background thread spawned with <t>ibex.thread</t>)
1539 There are two important restrictions on what can be done in particular contexts:
1541 <list type="unordered">
1543 The <t>box.mouse</t> property and its subproperties
1544 (<t>x</t>, <t>y</t>, and <t>inside</t>) can only be read
1545 from within the Event Context, or in a thread context
1546 <i>after</i> a the <t>box.mouse</t> property on this box or
1547 an ancestor box has been written to.
1549 Blocking operations (anything that accesses the network or
1550 disk) can only be performed in the Thread Context.
1556 <section title="Background Threads">
1558 Ibex offers easy access to threads. Spawning a background thread is as
1559 simple as writing a function to the <t>ibex.thread</t> property:
1562 ibex.thread = function() {
1563 ibex.log.info("this is happening in a background thread!");
1567 The argument set passed to the function is currently undefined and is
1568 reserved for use in future versions of Ibex. Scripts should not
1569 depend on the number or content of these arguments.
1571 Ibex is <i>cooperatively multitasked</i>, so threads must not process
1572 for too long. This was a deliberate choice; cooperatively
1573 multitasked environments do not require complex locking primitives
1574 like mutexes and semaphores which are difficult for novices to
1575 understand. The disadvantage of cooperative multitasking is that one
1576 thread can hog the CPU. This is unlikely to happen in Ibex for two reasons:
1577 first, all blocking I/O operations <i>automatically</i> yield the CPU,
1578 so the overall user interface never becomes unresponsive because it is
1579 waiting for a disk or network transfer. Second, since Ibex is strictly
1580 a user interface platform, Ibex scripts are unlikely to perform highly
1581 compute-intensive operations that keep the CPU busy for more than a
1587 <section title="Events">
1589 Every execution of the Event Context begins with an event, which
1590 consists of a key/value pair, and a mouse position, which consists of
1591 an x and y coordinate. The possible keys are <t>_Press[1-3]</t>,
1592 <t>_Release[1-3]</t>, <t>_Click[1-3]</t>, <t>_DoubleClick[1-3]</t>,
1593 <t>_Move</t>, <t>_KeyPressed</t>, and <t>_KeyReleased</t>.
1595 Here are two example events:
1597 An event is triggered by writing the key to the value on a box. This
1598 triggers any trap handlers which may be present. Once these handlers
1599 have executed, Ibex figures out which child of the current box contains
1600 the mouse (taking into account that some boxes may cover up others)
1601 and writes the key and value to that box. If none of the box's
1602 children contain the mouse position, Ibex removes the leading
1603 underscore from the key name and writes the value to
1604 <i>that</i> property. Once all the traps on that property have
1605 executed, the value is written to the box's parent.
1607 Intuitively, Ibex delivers the underscored event to every box from the
1608 root to the target, and then delivers the non-underscored event to
1609 that same set of boxes in reverse order. So the event travels down
1610 the tree to the target, and then back up to the root. The following
1611 example prints out "first second third fourth" in that order.
1615 _Press1 ++= function(b) { ibex.log.info("first"); }
1616 Press1 ++= function(b) { ibex.log.info("fourth"); }
1618 _Press1 ++= function(b) { ibex.log.info("second"); }
1619 Press1 ++= function(b) { ibex.log.info("third"); }
1624 In general, you should use the <i>non-underscore</i> names to respond
1625 to user input and use the underscored names when you want to override
1626 child boxes' behavior or route events to particular boxes (for
1627 example, when implementing a focus protocol). This is why the
1628 underscored elements are delivered to parents before children (so
1629 parents can override their childrens' behavior), but non-underscored
1630 events are delivered to children before parents (since, visually, a
1631 mouse click is usually "intended" for the leaf box underneath the
1636 <heading title="Stopping the Process"/>
1638 At any point in this sequence, a trap handler can choose not to
1639 cascade (by returning <t>true</t> from the trap handler function).
1640 This will immediately cease the propagation of the event. This is how
1641 you would indicate that an event has been "handled".
1643 <heading title="Non-Propagating Events"/>
1645 Ibex uses the following events to notify a box about changes that
1646 only matter to that particular box. These events do not propagate
1647 either up or down the tree.
1649 <property name="Enter Leave">
1650 The value <t>true</t> is written to this property when the mouse (enters/leaves) the box.
1653 <property name="SizeChange">
1654 The value <t>true</t> is put to this property after the size
1655 of this box changes.
1658 <property name="ChildChange">
1659 When a child is added or removed, that child is written to
1660 this property. The write is always performed <i>after</i> the
1661 addition or removal, so these two cases can be distinguished
1662 by checking <t>indexof(child)</t>.
1664 Note that if the parent's redirect target is set to another
1665 box, this trap will only be invoked when children are
1666 manipulated by reading and writing to the parent. Reads and
1667 writes directly to the redirect target will <i>not</i> trigger
1670 Note also that this traps is still triggered if a box's
1671 <t>redirect</t> target is <i>null</i>. This is useful for
1672 boxes that need to accept children and then relocate them
1676 <section title="Listing of Events">
1678 <property name="Press1 Press2 Press3">
1679 Indicates that the use has pressed a mouse button. On
1680 platforms with three mouse buttons, the <i>middle</i> button
1681 is button 3 -- this ensures that applications written to only
1682 use two buttons (1 and 2) will work intuitively on three button
1686 <property name="Release1 Release2 Release3">
1687 Indicates that the use has released a mouse button.
1690 <property name="Click1 Click2 Click3">
1691 Indicates that the user has pressed and released the
1692 mouse button without moving the mouse much (exactly how
1693 much is platform-dependent).
1696 <property name="DoubleClick1 DoubleClick2 DoubleClick3">
1697 Indicates that the user has clicked the
1698 mouse button twice within a short period of time (exactly how long is platform-dependent).
1701 <property name="Move">
1702 Indicates that the mouse has moved while within this box, or that
1703 the mouse while outside this box <i>if a button was pressed while within this box and has not yet been released</i>
1706 <property name="KeyPressed KeyReleased">
1708 A string is written to this property when a key is pressed or
1709 released If the key was any other key, a multi-character
1710 string describing the key will be put. For simplicity, we use
1711 the VK_ constants in the <link
1712 url="http://java.sun.com/products/jdk/1.1/docs/api/java.awt.event.KeyEvent.html#VK_0"
1713 text=" Java 1.1 API java.awt.event.KeyEvent class"/>. When a
1714 key is pressed or released, the string put will be the portion
1715 of its VK_ constant after the underscore, all in lower case.
1718 If the shift key was depressed immediately before the
1719 event took place, then the string will be capitalized. Special
1720 keynames are also capitalized; shift+home is reported as
1721 "<t>HOME</t>". Symbols are capitalized as they appear on the
1722 keyboard; for example, on an American QWERTY keyboard, shift+2
1723 is reported as "<t>@</t>".
1725 If the alt, meta, or command key was depressed immediately
1726 before this key was pressed, then the string will be prefixed
1727 with the string "<t>A-</t>". If the control key was depressed
1728 while this key was pressed, then the string will be prefixed
1729 with the string "<t>C-</t>". If both alt and control are
1730 depressed, the string is prefixed with "<t>C-A-</t>".
1732 Ibex does not distinguish between a key press resulting from
1733 the user physically pushing down a key, and a 'key press'
1734 resulting from the keyboard's typematic repeat. In the rare
1735 case that an application needs to distinguish between these
1736 two events, it should watch for KeyReleased messages and
1737 maintain an internal key-state vector.
1745 <!-- ----------------------------------------------------------------------- -->
1746 <section title="Networking">
1748 <section title="XML-RPC">
1750 XML-RPC objects can be created by calling <t>ibex.net.rpc.xml(<i>XML-RPC
1751 URL</i>)</t>, and then invoking methods on that object. For example,
1754 Press1 += function(v) {
1755 ibex.thread = function() {
1756 color = ibex.net.rpc.xml("http://xmlrpc.ibex.org/RPC2/").
1757 color.getTodaysColor("Friday");
1762 When the user clicks the first mouse button on this box, it will
1763 contact the server <t>xmlrpc.ibex.org</t>, route to the
1764 <t>/RPC2/</t> handler and invoke the <t>getTodaysColor()</t>
1765 method on the <t>color</t> object with a single string argument
1766 "<t>Friday</t>". The return value will be used to change the color
1767 of the box the user clicked on.
1769 Note that in this example we spawned a background thread to handle the
1770 request -- the <t>Press1</t> event is delivered in the foreground
1771 thread, and XML-RPC methods may only be invoked in background
1772 threads. This is to prevent the UI from "locking up" if the server
1773 takes a long time to reply.
1775 If the XML-RPC method faults, an object will be thrown with two
1776 properties: <t>faultCode</t> and <t>faultString</t>, as defined in
1777 the <link url="http://www.xmlrpc.org/spec" text="XML-RPC specification"/>. If
1778 Ibex encounters a network, transport, or session-layer error, it will
1779 throw a <t>String</t> object describing the error in a
1780 human-readable format. Scripts should not rely on the contents of
1781 this string having any special structure or significance.
1783 If an object with an associated non-empty stream is passed as an
1784 argument to an XML-RPC method, it will be sent as a <base64/>
1785 element. If a <base64/> element is found in the XML-RPC reply, it
1786 will be returned as an object with a stream drawn from that byte sequence.
1788 Each object returned by <t>ibex.net.rpc.xml()</t> represents a
1789 single HTTP connection. The connection will be held open until
1790 the object is garbage collected or the server closes the
1791 connection. If a second call is issued on the object before the
1792 first one returns (usually from a seperate thread), the two calls
1794 url="http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.2.2"
1795 text="pipelined"/>. This can dramatically improve performance.
1797 Ibex supports HTTP Basic and Digest authentication. To use
1798 authentication, pass <t>ibex.net.rpc.xml()</t> a URL in the form
1801 http[s]://user:password@hostname/
1804 Ibex will use Digest authentication if the server supports it;
1805 otherwise it will use Basic authentication. Please be aware that
1806 many XML-RPC server implementations contain a <link
1807 url="http://www.ibex.org/faq.html#auth" text="broken
1808 implementation of Basic authentication"/>.
1812 <section title="SOAP">
1814 SOAP methods are invoked the same way as XML-RPC methods, but with three differences:
1816 <list type="ordered">
1818 <t>ibex.net.rpc.soap()</t> is used instead of
1819 <t>ibex.net.rpc.xml()</t>
1821 Instead of specifying just the URL of the service itself, you
1822 must specify the URL, the SOAPAction argument, and the
1825 The actual method invocation takes only one argument, which
1826 must be an object. This is necessary since SOAP arguments are
1827 specified by name, rather than ordering.
1831 SOAP faults are handled the same way as XML-RPC faults except that the
1832 capitalization of the <t>faultstring</t> and <t>faultcode</t>
1833 members is all lower-case, to match the SOAP spec. Here is a
1837 Press1 ++= function(v) {
1838 ibex.thread = function() {
1839 color = ibex.net.rpc.soap("http://soap.ibex.org/SOAP",
1841 "http://ibex.org/namespace"
1842 ).color.getTodaysColor( {
1849 As you can see, SOAP is much more verbose, yet does not offer
1850 substantially improved functionality. We recommend that XML-RPC be
1851 used whenever possible, and that SOAP be reserved for legacy
1854 The current Ibex SOAP stack does not support 'document style' or
1855 multi-ref (<t>href</t>) data structures.
1859 <section title="Security">
1861 Applications downloaded from the network (as opposed to those loaded
1862 from the filesystem) may only make certain kinds of connections to
1863 certain hosts. See Appendix A for a detailed description of the
1869 <!-- ----------------------------------------------------------------------- -->
1870 <section title="Error Handling">
1872 If the Ibex Core encounters an error while servicing a function call
1873 originating in JavaScript, the core will throw a string consisting of
1874 an error code followed by a colon, a space, and a descriptive message.
1878 "ibex.net.dns.unknownhostexception: unable to resolve host foo.com"
1881 The code should be used to determine how the program should respond to
1882 an error. The codes are organized in a hierarchy, so the
1883 string.startsWith() method can be used to determine if an error lies
1884 within a particular subhierarchy. The descriptive message portion of
1885 the string may be shown to the user.
1887 <property name="ibex.assertion.failed">
1890 <property name="ibex.io">
1891 General I/O exceptions
1893 <property name="ibex.io.encoding">
1894 Error translating between character encodings.
1896 <property name="ibex.io.zip">
1897 Attempted to access a corrupt zip archive.
1899 <property name="ibex.io.eof">
1900 End of file encountered unexpectedly
1902 <property name="ibex.net.security.prohibitedHost">
1903 A piece of untrusted Ibex code attempted to contact a
1904 restricted host. See <link appendix="Security Architecture and Considerations"/> for details.
1906 <property name="ibex.net.dns.temporaryFailure">
1907 An attempt to resolve a hostname failed but it is not known
1908 for certain that the hostname is invalid.
1910 <property name="ibex.net.dns.unknownHost">
1911 An attempt to resolve a hostname failed because the hostname
1914 <property name="ibex.net.socket.closed">
1915 A socket was closed unexpectedly.
1917 <property name="ibex.net.socket.connectionFailed">
1918 A connection could not be made to the remote host.
1920 <property name="ibex.net.url.malformed">
1921 Tried to parse a malformed URL.
1923 <property name="ibex.net.ssl">
1924 General SSL protocol errors.
1926 <property name="ibex.net.ssl.untrustedCertificate">
1927 The server's certificate was not signed by a CA trusted by Ibex.
1929 <property name="ibex.net.http.">
1930 Thrown when an HTTP error code is returned during an
1931 operation. The three characters <t><i>xyz</i></t> will be
1932 the three-digit HTTP status code.
1934 <property name="ibex.net.xmlrpc.null">
1935 The caller attempted to transmit the <t>null</t> value via XML-RPC.
1937 <property name="ibex.net.xmlrpc.circular">
1938 The caller attempted to transmit a circular data structure via XML-RPC.
1940 <property name="ibex.net.xmlrpc.specialObject">
1941 The caller attempted to transmit a "special" object via
1942 XML-RPC (for example, a Box or the Ibex object).
1944 <property name="ibex.null.put">
1945 A JavaScript attempted to put to a property on the <t>null</t> value
1947 <property name="ibex.null.get">
1948 A JavaScript attempted to get from a property on the <t>null</t> value
1950 <property name="ibex.null.call">
1951 A JavaScript attempted to call the <t>null</t> value
1954 If an exception is thrown inside a trap, the exception will propagate
1955 to the script that triggered the trap.
1957 If an uncaught exception is thrown while applying a template, or the
1958 requested template could not be found, an error will be logged and the
1959 box to which the template was being applied will be made invisible
1960 (<t>visible = false</t>). This ensures that half-applied widgets are
1961 never shown to the user.
1965 <!-- ----------------------------------------------------------------------- -->
1966 <section title="Advanced Topics">
1968 <section title="Re-routing events">
1970 At any point in the Event Context, you can write to the <t>mouse</t>
1971 property on any box. The value written should be an object with two
1972 properties, <t>x</t> and <t>y</t>. For example:
1975 _Press1 ++= function(p) {
1976 mouse = { x: 32, y: 77 };
1980 The coordinates specified are relative to the box whose <t>mouse</t>
1981 property is being written to. There is no need to supply the
1982 <t>inside</t> property; it is computed automatically. Writing to
1983 the <t>mouse</t> property causes Ibex to recompute the eventual
1984 target box, and also alter the values returned by <t>mouse.x</t>,
1985 <t>mouse.y</t>, and <t>mouse.inside</t> for any <i>descendants</i>
1986 of the current box. Writing to the <t>mouse</t> property also
1987 automatically prevents the event from returning to the box's parents
1988 -- it is equivalent to not cascading on the non-underscored event.
1989 This ensures that child boxes cannot trick their parent boxes into
1990 thinking that the mouse has moved.
1992 If you want the event to "skip over" the boxes between the trapee
1993 and the target, or if you want to re-route an event to a box which
1994 is not a descendant of the current box, simply write the value to
1995 the proper key on the target box.
1999 _KeyPressed = function(k) { ibex.log.info("first"); }
2000 KeyPressed = function(k) { ibex.log.info("sixth"); }
2001 $recipient.target = $target;
2002 <ui:box id="recipient">
2003 _KeyPressed = function(k) {
2004 ibex.log.info("second");
2005 thisbox.target.KeyPressed = k;
2006 // inhibit cascade; keep event from going to $excluded
2009 KeyPressed = function(k) { ibex.log.info("fifth"); }
2010 <ui:box id="excluded">
2011 _KeyPressed = function(k) {
2012 ibex.log.info("this never happens");
2016 <ui:box id="target">
2017 _KeyPressed = function(k) { ibex.log.info("third"); }
2018 KeyPressed = function(k) { ibex.log.info("fourth"); }
2025 <section title="Synthesizing Your Own Events">
2027 You can create "fake events" by simply writing to the <t>mouse</t>
2028 property and then writing a value to one of the underscored properties
2029 on a box. This will have exactly the same effect as if the use had
2030 actually pressed a key, clicked a button, or moved the mouse -- they
2031 are indistinguishable.
2035 <section title="Ibex self-emulation">
2037 When the core first starts up, it clones the <t>ibex</t> object,
2038 creates a stream for the initial .ibex, and then places a trap on the
2039 cloned <t>ibex</t> object so that its empty-string property returns
2040 the .ibex stream. The cloned Ibex object is then passed as the third
2041 (optional) argument to <t>ibex.apply()</t>, making it the default
2042 <t>ibex</t> object for the scripts that are executed as part of the
2043 template instantiation.
2046 var new_ibex = ibex.clone(ibex);
2047 var stream = ibex.bless(ibex.stream.url("http://..."));
2048 new_ibex[""] ++= function() { return stream; }
2049 ibex.apply(ibex.box, new_ibex..main, new_ibex);
2052 Note that we called <t>ibex.bless()</t> on the stream before tacking
2053 it on to the new Ibex object. The bless function returns a clone of
2054 the object passed to it, with a few traps which are explained below.
2055 Additionally, any sub-streams retrieved by accessing properties of the
2056 blessed stream will also automatically be blessed (blessed streams are
2059 Blessing a stream serves three purposes:
2061 <list type="unordered">
2063 Blessed clones always return the appropriate static block when
2064 their empty property is accessed; this ensures that references
2065 to the static blocks of other templates work properly.
2067 Blessed substreams can return their parent stream by accessing
2068 a hidden property which is reserved for internal use by Ibex.
2069 This ensures that Ibex can automatically add filename
2070 extensions where needed, according to the following rules:
2073 If the stream is a template to be applied, the string
2074 "<t>.ibex</t>" is appended.
2076 If the stream is an image, the string "<t>.png</t>" is
2077 appended. If no stream is found, "<t>.jpeg</t>" and
2078 "<t>.gif</t>" are tried, in that order.
2080 If the stream is an font, the string "<t>.ttf</t>" is
2084 Every call to <t>ibex.bless()</t> returns a different object
2085 (which happens to be a clone of the object passed to it) with
2086 a completely separate set of static blocks.
2090 Ibex can self-emulate by using <t>ibex.clone()</t> on the Ibex object;
2091 this technique is very similar to the use of ClassLoaders in
2092 Java. This is useful for a number of applications, including
2093 debuggers, IDEs, sandboxing untrusted code, remote-control, and
2094 others. For example:
2097 var newLoadFunction = function(url) { /* ... */ };
2098 var new_ibex = ibex.clone(ibex);
2099 new_ibex.load ++= function() { return newLoadFunction; }
2100 ibex.apply(ibex.box, .main, new_ibex);
2105 <!-- ----------------------------------------------------------------------- -->
2106 <appendix title="Security Architecture and Considerations">
2108 Due to the expense and hassle imposed by the commercial PKI code
2109 signing architecture, and the fact that it <link
2110 url="http://www.counterpane.com/pki-risks-ft.txt" text="doesn't
2111 really provide any security anyways"/>, Ibex user interfaces are
2112 distributed as unsigned, untrusted code. As such, they are handled
2113 very carefully by the Ibex Core, and assumed to be potentially
2116 Ibex's security architecture is divided into defenses against four
2117 major classes of attacks:
2119 <heading title="Malicious UI attempts to acquire or alter data on the client"/>
2121 Ibex user interfaces are run in an extremely restrictive sandbox. The
2122 environment does not provide primitives for accessing any data outside
2123 the Ibex core except via XML-RPC and SOAP calls. There are no
2124 facilities to allow Ibex user interfaces to access the client's
2125 operating system or to interact with other applications on the same
2126 host (unless they provide a public XML-RPC or SOAP interface).
2127 An Ibex script may only access a file on the user's hard disk if the
2128 user explicitly chooses that file from an "open file" or "save file"
2129 dialog. There is one exception to this rule: if all templates
2130 currently loaded in the Ibex core originated from the local
2131 filesystem, those templates can load additional .ibexs from the local
2134 The Ibex Core is written in Java, so it is not possible for
2135 scripts to perform buffer overflow attacks against the core
2138 Ibex applications may only read from the clipboard when the user
2139 middle-clicks (X11 paste), presses control-V (Windows paste), or
2140 presses alt-V (Macintosh paste; the command key is mapped to Ibex
2141 "alt"). This ensures that Ibex applications are only granted access to
2142 data that other applications have placed on the clipboard when the user
2143 specifically indicates that that information should be made available
2144 to the Ibex application.
2146 <heading title="Malicious UI attempts to use client to circumvent firewalls"/>
2148 Ibex user interfaces may only make XML-RPC or SOAP calls and load .ibex
2149 archives via HTTP; they cannot execute arbitrary HTTP GET's or open
2150 regular TCP sockets.
2152 Ibex will not allow a script to connect to a non-public IP address
2153 (10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16, as specified in <link
2154 url="http://www.cis.ohio-state.edu/cgi-bin/rfc/rfc1918.html" text="RFC
2155 1918"/>). There is one exception -- if all templates currently loaded
2156 in the core originated from the same IP address, those scripts may
2157 make calls to that IP address regardless of whether or not it is
2158 firewalled. If Ibex does not have access to a DNS resolver (because it
2159 is using a proxy which performs DNS lookups), Ibex will provide the
2160 proxy with the appropriate <link
2161 url="http://www.ibex.org/x-requestorigin.html"
2162 text="X-RequestOrigin"/> header that the proxy needs in order
2163 to maintain security.
2165 The only remaining possible attack is against a XML-RPC or SOAP
2166 service running on a firewalled host with a public address. Assigning
2167 such machines public IP addresses is a poor network security policy,
2168 and doing so squanders scarce public IPv4 addresses. As such, the onus
2169 is on the administrators of such machines to explicitly block access
2170 to clients reporting a <t>User-Agent:</t> header beginning with the
2171 four characters "<t>IBEX</t>".
2173 <heading title="Malicious UI attempts to trick user into divulging secret information"/>
2175 All top-level windows created by Ibex are <i>scarred</i> -- a stripe
2176 and a lock is drawn across the corner of the window. There is no way
2177 for a user interface to remove this scar. Ibex user interfaces may not
2178 create windows smaller than the size of the scar.
2180 <heading title="Malicious network attempts to snoop or man-in-the-middle transactions"/>
2182 Ibex user interfaces may transmit network data using HTTPS (SSL 3.0)
2183 for encryption. Ibex will attempt 128-bit encryption, but will
2184 negotiate down to 40-bit if the server does not support strong
2185 crypto. Ibex's SSL implementation is currently provided by <link
2186 url="http://www.ibex.org/tinyssl" text="TinySSL"/> and <link
2187 url="http://www.bouncycastle.org" text="The Legion of the Bouncy
2190 All HTTPS connections must be authenticated by the server using a
2191 certificate whose name matches the domain name of the HTTPS URL. The
2192 certificate must be signed by a trusted root CA. Ibex trusts the same
2193 93 root CAs whose certificates are included as "trusted" in Microsoft
2194 Internet Explorer 5.5 SP2. This provides a minimal level of protection
2195 against man-in-the-middle attacks; you should not trust this
2196 connection with any data you would not normally trust an SSL-enabled
2201 <!-- ----------------------------------------------------------------------- -->
2202 <appendix title="ECMAscript compliance">
2204 Ibex's scripts are written in a modified subset of ECMA-262, revision 3
2205 (aka JavaScript 1.5). The interpreter strays from the spec in a few
2208 <section title="Omissions">
2210 The following ECMA features are not supported:
2212 <list type="unordered">
2214 The <t>undefined</t> value, <t>===</t>, and <t>!==</t>
2216 The <t>new</t> keyword (and ECMAScript object inheritance)
2219 <t>getter</t> and <t>setter</t>
2221 The ECMA <t>this</t> keyword.
2223 The <t>String</t>, <t>Number</t>, and <t>Boolean</t>
2224 classes. Note that <t>string</t>, <t>number</t>, and
2225 <t>boolean</t> values are supported, however.
2227 You may not <t>throw</t> the <t>null</t> value.
2231 Additionally, you must declare all root-scope variables (with
2232 <t>var</t>) before using them; failure to do so will result in an
2233 exception. Box properties are pre-defined in the scope that scripts
2238 <section title="Extensions">
2240 <list type="unordered">
2242 The token <t>..</t> is equivalent to <t>[""]</t>.
2248 Extended <t>catch</t> syntax. The following code:
2250 } catch(e propname "foo.bar.baz") {
2257 if (e.propname != null and e.propname >= "foo.bar.baz" and
2258 "foo.bar.baz/" > e.propname) {
2263 Multiple extended-catch blocks can appear at the end of a single try
2264 block. However, at most one non-extended catch block may appear, and
2265 if it does appear, it must be the last one.
2267 Since Ibex ECMAscripts are wrapped in XML, the lexical token
2268 "<t>lt</t>" is be interpreted as <t><</t>, the lexical
2269 token "<t>gt</t>" is be interpreted as <t>></t>, and the
2270 token "<t>and</t>" is interpreted as <t>&&</t>.
2271 Thus these tokens cannot be used as variable names.
2273 The identifier <t>static</t> is a reserved word in
2274 ECMAScript, but not in Ibex.
2276 Ibex defines an additional reserved word, "<t>assert</t>",
2277 which will evaluate the expression which follows it, throwing
2278 a <t>ibex.assertion.failed</t> exception if the expression
2279 evaluates to <t>false</t>.
2281 To ensure that Ibex files appear the same in all text editors, tab
2282 characters are not allowed in Ibex files.
2286 Some useful tutorials include:
2288 <list type="unordered">
2291 url="http://developer.netscape.com/docs/manuals/communicator/jsref/index.htm"
2292 text=" JavaScript 1.2 Reference"/>. Although this document is
2293 out of date, it is arguably the best guide available for free
2294 on the Internet. The changes from JavaScript 1.2 (aka ECMA-262
2295 r1) to 1.5 were minimal, and many of them were <link
2296 url="ecmascriptcompliance" text="omitted"/> from Ibex.
2299 url="http://search.barnesandnoble.com/booksearch/isbnInquiry.asp?isbn=0596000480"
2300 text=" JavaScript: The Definitive Guide"/>, by David Flanagan
2301 and Paula Ferguson. The latest edition of this book covers
2302 JavaScript 1.5 (ECMA-262 r3).
2305 url="http://www.ecma.ch/ecma1/STAND/ECMA-262.HTM"
2306 text="ECMA-262"/> specification. This is an extremely
2313 <!-- ----------------------------------------------------------------------- -->
2314 <appendix title="Logging and Command Line Invocation">
2317 Usage: ibex [-lawp] [ url | file | directory ]
2318 -l [level] set logging level to { debug, info (default), warn, error, silent }
2319 -l rpc log all XML-RPC and SOAP conversations
2320 -l user@host email log to user@host
2321 -l host:port emit log to TCP socket
2322 -l [file] write log to a file on disk
2324 -w <window-id> reserved for libibex
2325 -p dump profiling information [not yet supported]
2328 If Ibex encounters a serious problem before it starts logging
2329 information, or if it is unable to open the log file, it will abort
2330 immediately with a critical abort, which will be displayed on the
2331 console for POSIX-native cores and in a dialog box for JVM-based and
2334 Note that Microsoft Windows does not provide any mechanism for
2335 redirecting standard input/output of an application which is not
2336 compiled as a "console application". Therefore, Ibex is compiled
2337 as a "console application", and will open a console window when
2338 invoked. To inhibit this console window, provide a logging
2339 destination (file, port, etc).
2341 The <t><i>source-location</i></t> parameter can be either the path
2342 to an <t>.ibex</t> archive, the http url of an <t>.ibex</t>
2343 archive, or the path to a directory comprising an unpacked
2344 <t>.ibex</t> archive.
2346 The <t><i>initial-template</i></t> parameter is the stream name of
2347 a template to be used as the initial template. If ommitted, it
2348 defaults to <t>main</t>.
2350 The <t>-v</t> option causes Ibex to enable verbose logging; this will
2351 cause it to log <i>lots</i> of information to the log file. This
2352 option will also substantially decrease Ibex's performance.
2356 <!-- ----------------------------------------------------------------------- -->
2358 <appendix title="Grammars">
2360 <i>Grammar support is experimental in this release
2361 and may not work properly. It may change in incompatible ways or
2362 disappear completely from future releases</i>
2364 Grammars are defined with a statement in the following form:
2369 A grammar is really just another function; once defined you can't tell
2370 it apart from an ordinary function. A grammar takes one argument,
2371 which can be a string or stream. The argument is parsed and the
2372 result of executing the code block 'c' is returned.
2374 The property 'a' is read; if the value is a grammar, a new production
2375 rule (ie a new alternative, as with '<t>|</t>') is added to that grammar
2376 (this is a destructive update). This allows you to add productions to
2377 pre-existing grammars (for example, adding a new type of expression to
2378 a programming language by extending the 'expr' grammar). If the old
2379 value is not a grammar, the value is discarded and a new grammar
2382 The value 'b' is a pattern, which may consist of seven simple
2385 <list type="unordered">
2388 grouping parens <t>()</t>
2390 combinators: <t> | + * ?</t>
2392 references to other grammars
2395 The value 'c' and the braces surrounding it are an *optional* code
2396 block, in which the following identifiers are bound:
2398 <list type="unordered">
2400 The identifier 'whole' is bound to the string matched by the
2401 entire expression. If the code block is omitted it behaves
2402 as if it were "<t>{ return whole; }</t>".
2404 For every reference to another grammar which was matched in the
2405 pattern, the *name used to reference that other grammar* will
2406 be bound to the value returned by its code block. Here's an
2407 example of this important distinction:
2410 var foo ::= 'a' | 'b';
2412 var baz ::= 'c' | bar { /* foo is not defined here, but bar is */ };
2415 On the last line, the identifier 'bar' serves two purposes: it
2416 pulls in the definition of the pattern *and* acts as a binder
2417 within the scope of the braces.
2419 If a reference is matched multiple times (either because it
2420 appears multiple times in the pattern or because the * or +
2421 operator was applied to it) then its name will be bound to an
2422 array containing the matches.
2426 Here is the metacircular definition of the grammar facility:
2429 grammar ::= identifier '::=' pattern (';' | '{' code '}' ';'?)
2430 identifier ::= ('a'..'z' | 'A'..'Z' | '_' | '$') (identifier | '0'..'9')*
2431 char ::= '\0x0000'..'\0xffff'
2432 literal ::= '\'' char+ '\''
2433 | '\'' char '\'' '..' '\'' char '\''
2434 pattern ::= identifier
2441 | pattern '|' pattern
2446 Copyright (C) 2004 Adam Megacz, verbatim redistribution permitted.
2447 Ibex is a trademark of Adam Megacz