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 <!-- ----------------------------------------------------------------------- -->
244 <section title="Layout and Rendering">
248 <section title="Metadata">
250 Any immediate children of the root element which are in the
251 <t>meta</t> namespace are treated as metadata and are exempted from
252 the rest of the template application process. Currently only one
253 type of metadata element is defined:
256 <t><meta:doc></t>: structured documentation for the
262 <section title="Other Elements">
264 All remaining children of the root element are treated as elements
265 to be <i>applied</i> to the box, in the order in which they appear
266 in the file using the following procedure.
268 <remark text="While this process outlined below sounds very
269 complex, it actually works pretty intuitively. The
270 description below is given in great detail since
271 most applications will wind up being unintentionally
272 dependent on subtle features of this process.
273 However, most of the time you can just pretend that
274 the XML tags and the boxes are the same thing."/>
276 <heading title="Intuitive Description"/>
280 During a box initialization, script-private references to a
281 box's descendants with <t>id</t> attributes are placed on the
282 box. These references allow scripts on that box to easily refer
283 to descendant nodes created by the template in which the script
284 appears. For example, these two blocks of code have exactly the
289 <ui:box id="foo"/> <ui:box/>
290 $foo.color = "red"; var $foo = this[0];
295 <heading title="Precise Description"/>
297 To apply an XML tag <t><b>x</b></t> to a box <t><b>b</b></t>, perform the following
298 operations, in this order:
300 <list type="ordered">
302 Allocate a fresh scope <t><b>s</b></t> whose parent scope is
305 Process each child element or text segment of <t><b>x</b></t>
306 in the order they appear in the document:
310 Treat each text segment <t><b>t</b></t> as JavaScript code
311 and execute it with <t><b>s</b></t> as the root scope.
313 For each child element <t><b>x'</b></t> of <t><b>x</b></t>:
316 Create a new box <t><b>b'</b></t>.
318 If the name of tag <t><b>x'</b></t> is not
319 "<t>box</t>" in the <t>ui</t> namespace, prepend the
320 tag's namespace identifier uri (if any) to the name of
321 the tag, and use the result as a key to retrieve a
322 property from the root stream (defined later).
323 Interpret the resulting stream as a template and apply
324 that template to <t><b>b'</b></t>.
326 (recursively) apply <t><b>x'</b></t> to <t><b>b'</b></t>.
328 If <t><b>x'</b></t> has an <t>id</t> attribute, declare a variable
329 in <t><b>s</b></t> whose name is the value of the <t>id</t>
330 attribute, prefixed with the <t>$</t> character, and whose
331 value is <t><b>b'</b></t>
333 Copy any <t>$</t>-variables created during the application
334 of <t><b>x'</b></t> into scope <t><b>s</b></t>.
336 Append <t><b>b'</b></t> as the last child of <t><b>b</b></t>.
340 Apply any attributes on <t><b>x</b></t> to <t><b>b</b></t>, except for
341 <t>id</t>. Since XML specifies that the order of attributes
342 cannot be significant, Ibex processes attributes in
343 alphabetical order by attribute name. For example, if
344 <t><b>x</b></t> has the attribute <t>foo="bar"</t>, then the
345 equivalent of the statement <t>B.foo="bar";</t> will be
346 performed, with the following exceptions:
349 If the value portion of the attribute is the string
350 "<t>true</t>", put the boolean <t>true</t>. If the
351 value is "<t>false</t>", put the boolean <t>false</t>.
353 If the value is a valid ECMAscript number, put it as a
354 number (instead of a string).
356 If the value begins with a dollar sign (<t>$</t>),
357 retrieve the value of the corresponding variable in
358 <t><b>s</b></t> and use that value instead.
360 If the value begins with a dot (<t>.</t>), prepend the
361 attributes' namespace identifier uri (if any) and
362 interpret the remainder as a property to be retrieved from
363 the root stream (defined later).
367 <heading title="Initialization Invariants"/>
369 The last two steps are referred to as the <i>initialization</i> of the
370 node. There are two important aspects of this ordering to be aware of:
372 <list type="unordered">
374 A given box will be fully initialized before its parent is
375 given a reference to that box. This way, parents can be
376 certain that they will never wind up accessing a box when it
377 is in a partially-initialized state.
379 Attributes are applied <i>after</i> scripts are run so that
380 the attributes will trigger any <i>traps</i> (defined later)
381 placed by the script.
389 <!-- ----------------------------------------------------------------------- -->
390 <section title="Layout and Rendering">
392 <section title="Visual Components">
394 Each box occupies a rectangular region on the surface. The visual
395 appearance of a surface is created by rendering each box in its tree.
396 Unless the <t>clip</t> attribute is <t>false</t>, each box will
397 clip its childrens' visual representations to its own, so that the
398 children appear "confined to" the parent. Children are rendered after
399 their parents so they appear "on top of" their parents.
401 Each box has two major visual components, each with subcomponents:
405 <definition term="path">
407 A box's <t>path</t> consists of zero or more lines and curves.
408 The path may be filled with a color, gradient, or texture, and
409 may be stroked with a line of a given thickness and color. If
410 the path is not specified, it defaults to the perimiter of the
411 box. [<i>Note: Vector Graphics support (including the ability
412 to set the <t>path</t> property to anything other than the
413 default) is currently not implemented</i>].
418 an associated <t>strokecolor</t>, which is a color
420 an associated <t>strokewidth</t>, which is a number
421 specifying the width of the stroke. [<i>Note: Vector
422 Graphics support (including the <t>strokewidth</t>
423 property) is currently not implemented</i>]
425 a <t>fill</t>, which is either a color, gradient, or
430 <definition term="text">
432 Each box also has a single line of <t>text</t>, whose
433 appearance is determined by its:
436 associated <t>font</t>, which can be any font supported by
437 the <link url="http://www.freetype.org" text="FreeType2"/>
440 an associated <t>fontsize</t> in <i>pixels</i>
442 an associated <t>textcolor</t>
446 These eight components plus the size of a box fully specify its
447 appearance. Every single box you see in Ibex is drawn only on the
448 basis of these components and its size.
451 <section title="Size and Position">
453 The size and position of every box is determined by its
454 properties, its childrens' sizes, and its parent's size and
455 position. Box layout and rendering happens in four phases:
456 <i>packing</i>, <i>constraining</i>, <i>placing</i>, and
457 <i>rendering</i>. The Core is careful to only perform a phase on
458 a box if the box has changed in a way that invalidates the work
459 done the last time that phase was performed. The packing and
460 constraining phases are performed in a single traversal of the
461 tree (packing is preorder, constraining is postorder), and the
462 placing and rendering phases are performed in a second traversal
463 of the tree (first placing, then rendering, both preorder).
465 For brevity, the rest of this chapter deals only with width and
466 columns. Height and rows is treated identically and independently.
467 Also, it is important to note that the term <i>minimum width</i> is
468 not the same thing as the property <t>minwidth</t>, although they
471 <heading title="The Size of the Root Box"/>
473 When the user resizes a window, Ibex changes the root box's
474 <t>maxwidth</t> and <t>maxheight</t> to match the size chosen by
475 the user and then determines the root box's size using the same sizing
476 rules it uses for other boxes.
478 Ibex will always attempt to prevent the
479 user from making the surface smaller than the root box's
480 <t>minwidth</t> and <t>minheight</t>. If the <t>hshrink</t> or
481 <t>vshrink</t> flag is set, Ibex will try to prevent the user from
482 resizing the surface at all. However, not all platforms give Ibex
483 enough control to do this.
485 <image url="alignmentpoint.pdf" caption="The effect of alignment points on layout" width="3in"/>
486 <heading title="The alignment point"/>
488 When talking about positioning, we will often refer to the
489 <i>alignment point</i>.
491 If the <t>align</t> property is "<t>center</t>", then the
492 alignment point is the center of the box.
494 If the <t>align</t> property is "<t>topleft</t>",
495 "<t>bottomleft</t>", "<t>topright</t>", or
496 "<t>bottomright</t>", then the alignment point is
497 corresponding corner of the box.
499 If the <t>align</t> property is "<t>top</t>",
500 "<t>bottom</t>", "<t>right</t>", or "<t>left</t>", then
501 the alignment point is middle of the corresponding edge of the
504 When positioning a child box, the alignment point is determined by
505 the <i>parent's</i> <t>align</t> property. When rendering a
506 visual element (a texture, path, or text string) within a box, the
507 alignment point is determined by the <i>box's own</i> <t>align</t>
510 A simple way to think about this is that whenever there are two boxes
511 involved in the decision, you should use the parent's alignment point.
513 <section title="Packing">
515 A grid of <i>cells</i> is created within the parent. If the
516 parent's <t>cols</t> property is set to 0, the cell grid has an
517 infinite number of columns. Either <t>cols</t> or <t>rows</t>
518 must be zero, but not both.
520 If a child's <t>visible</t> property is <t>false</t>, it does
521 not occupy any cells (and is not rendered). Otherwise, each child
522 occupies a rectangular set of cells <t>child.colspan</t> cells
523 wide and <t>child.rowspan</t> cells high.
525 The Core iterates over the cells in the grid in the following
526 order: if <t>rows</t> is 0, the Core iterates across each column
527 before proceeding to the next row; otherwise rows come before
528 columns. At each cell, the Core attempts to place the <i>first
529 remaining unplaced child's</i> top-left corner in that cell
530 (with the child occupying some set of cells extending down and
531 to the right of that cell). If the parent has a fixed number of
532 columns and the child's <t>colspan</t> exceeds that limit, the
533 child is placed in column zero regardless, but only occupies the
534 available set of cells (it does not "hang off the end" of the
535 box). <image url="layout.pdf" width="1in"/>
540 <ui:box id="2" rowspan="2" />
541 <ui:box id="3" colspan="2" />
543 <ui:box id="5" colspan="2" />
552 <section title="Constraining">
554 Each box's minimum width is computed recursively as the
560 The width of the box's <t>text</t> (after applying the
561 box's <t>transform</t>) [<i>Note: Vector Graphics support
562 (including the <t>transform</t> property) is currently not
565 The width of the box's path (after applying the box's
566 <t>transform</t>) <i>if the box is <t>packed</t></i>.
568 The width of the bounding box enclosing the box's cells.
571 The minimum width of each cell is computed as the minimum
572 width of the box occupying it divided by the box's
575 If a box's <t>hshrink</t> property is set to
576 <t>true</t>, the box's maximum width is the same as its
577 minimum width; otherwise it is the box's
580 The maximum width of each cell is the <t>maxwidth</t> of
581 the box occupying it divided by the box's
585 <section title="Placing">
587 Each column's <i>actual width</i> is set to the maximum
588 <i>minimum width</i> of all the cells in that column.
589 <b>NOTE:</b> although a column or row can be sized smaller
590 than its "minimum width" or larger than its "maximum width", a
591 box will <i>never</i> be smaller than its <t>minwidth</t> or
592 larger than its <t>maxwidth</t>.
594 Each column's maximum width is the largest maximum width of
595 the cells in that column, but no smaller than the column's
598 A value <t>k</t> is chosen such that when each column's width
599 is set to <t>min(maximum width, max(minimum width, k))</t>,
600 the sum of all the column widths equals the parent's width.
601 If no such value exists, positive or negative infinity is used
602 (whichever is appropriate). Each column is then set to the
603 width dictated by <t>k</t>.
605 Next, the rows and columns are positioned within the parent
606 box. The rows and columns are transformed according to the
607 parent's <t>transform</t> property [<i>Note: Vector Graphics
608 support (including the <t>transform</t> property) is currently
609 not implemented</i>]., and the bounding box of the resulting
610 cells are placed such that the cells' alignment point
611 coincides with the parent's alignment point (both alignment
612 points are determined by the parent's <t>align</t> property).
614 <image url="grid.pdf" caption="Positioning grid cells"/>
616 <b>Packed boxes:</b> Each packed box's actual position
617 and size is then set to the aggregation of the actual sizes of
618 the cells it spans. If this size exceeds the box's maximum
619 width, the box is sized to its maximum width and centered
620 horizontally within the space occupied by its cells.
622 <b>Non-packed boxes</b>: each non-packed box is transformed
623 according to the parent's <t>transform</t> property and then
624 positioned so that its alignment point is <t>(child.x,
625 child.y)</t> pixels from the parent's alignment point (both
626 alignment points are determined by the parent's <t>align</t>
632 <section title="Rendering">
634 Boxes are rendered in a depth-first, pre-order traversal. Note that
635 this may cause a non-packed box to overlap its siblings.
637 <list type="ordered">
639 If the box's <t>transform</t> property is non-null, the
640 coordinate space is transformed accordingly for the rest of
641 this phase and for the rendering of all children. [<i>Note:
642 Vector Graphics support (including the <t>transform</t>
643 property) is currently not implemented</i>].
645 If the box is packed and has a non-<t>null</t> path, the
646 path is translated such that the alignment point of the path's
647 bounding box coincides with the box's alignment point (both
648 alignment points are determined by the box's <t>align</t>
651 If a box has a path, that path is filled with the color,
652 gradient, or image specified by the <t>fill</t> property and
653 stroked with the color and width specified by the
654 <t>strokecolor</t> and <t>strokewidth</t> properties.
656 If the box has a non-null <t>text</t> attribute,
657 the text is rendered in <t>font</t> with size
658 <t>fontsize</t> and color <t>textcolor</t>. The text is
659 then translated such that the alignment point of the text'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 The box's children are rendered (pre-order traversal).
672 <!-- _______________________________________________________________________ -->
673 <section title="Box Properties">
675 Each box is a full-fledged ECMAscript object, and can store
676 key-value pairs as properties. Some of these keys have special
677 meaning, which will be explained later. Each box's numeric
678 properties hold its <i>child boxes</i>.
680 <section title="Rendering Properties">
682 Every box has several special properties which control how it is
683 drawn. In general, if you put an
684 invalid value to a special property, no action will be taken -- the
687 <property name="strokecolor" type="string" default="clear">
689 If the value is a 5-character hex string (<t>#RGB</t>),
690 7-character hex string (<t>#RRGGBB</t>), 9-character hex
691 string (<t>#AARRGGBB</t>), the box's stroke color will be set
694 If the value is one of the <link
695 url="http://www.color.org/ICC-1A_1999-04.PDF"
696 text="ICC"/> colors (the same set of color names
697 supported by SVG), the stroke color be set to that color.
699 If the value is <t>null</t>, the stroke color will be set
700 to clear (<t>#00000000</t>).
703 <property name="strokewidth" type="int" default="1">
704 The width (in pixels) to stroke the path with.
707 <property name="fill">
708 This property can be set to any of the values specified for
710 Alternatively, if the value written is an object, its stream
711 will be read and interpreted as a PNG, GIF, or JPEG image,
712 which will become the texture for this box, and the box's
713 <t>minwidth</t> and <t>minheight</t> properties will be
714 automatically set to the dimensions of the image.
717 <property name="path" type="string" default='""'>
718 The box's path. The grammar and feature set supported are
719 identical to that specified in <link
720 url="http://www.w3.org/TR/SVG11/paths.html" text="SVG 1.1,
724 <property name="text" type="string" default='""'>
725 The box's text; writing <t>null</t> to this property sets it
729 <property name="textcolor" type="number" default="black">
730 The color in which to render the font; accepts the same values as <t>strokecolor</t>.
733 <property name="font" type="stream" default=".ibex.ui.font.sansserif">
734 When an object is written to this property, its stream is read
735 using the <link url="http://www.freetype.org" text="FreeType 2 library"/>,
736 and the resulting font is used to render the
740 <property name="fontsize" type="number" default="10">
741 The size (in points) to render the text.
746 <section title="Layout Properties">
748 <property name="shrink" type="boolean" default="false">
749 If set to <t>true</t>, this box will shrink
750 (horizontally/vertically/both) to the smallest size allowed by
751 its children and the bounding box of its path.
754 <property name="x y" type="integer" default="varies">
755 If the box is a root box, this is the (x/y)-coordinate of the
756 surface; otherwise it is the distance between the parent's
757 alignment point and this box's alignment point.
760 <property name="minwidth minheight" type="integer" default="0">
761 The desired minimum width and height.
764 <property name="maxwidth maxheight" type="integer" default="ibex.ui.maxdim">
765 The desired maximum width and height.
768 <property name="width height" type="integer">
769 When read, this is the current (width/height) of this box.
770 Writing to this property is equivalent to writing to
771 <i>both</i> the minimum and maximum (width/height).
774 <property name="cols rows" type="integer" default="0">
775 The number of (columns/rows) in which to lay out the children of this
776 box. If set to zero, the number of (columns/rows) is unconstrained.
777 Either <t>rows</t> or <t>cols</t> must be zero. If
778 <t>0</t> is written to <t>cols</t> when <t>rows</t> is
779 <t>0</t>, the write is ignored. If a nonzero value is
780 written to <t>cols</t> when <t>rows</t> is nonzero,
781 <t>rows</t> is set to <t>0</t>, and vice versa.
784 <property name="colspan rowspan" type="integer" default="1">
785 The number of (columns/rows) that this box spans within its parent.
788 <property name="align" type="string" default="center">
789 Determines the box's alignment point for positioning its text,
790 texture, path, and children.
793 <property name="visible" type="boolean" default="true">
794 If set to <t>false</t>, this box will be rendered as if its
795 width and height were zero. If this is a root box, the
796 associated surface will be hidden.
798 When reading from this property, the value <t>false</t> will
799 be returned if this box <i>or any of its ancestors</i> is not
800 visible. Thus it is possible to write <t>true</t> to a box's
801 <t>visible</t> property and then read back <t>false</t>.
804 <property name="packed" type="boolean" default="true">
805 The layout strategy for this box. If set to <t>true</t>, the
806 box occupies no cells and is laid out independently of its
812 <section title="Child Control Properties">
814 <property name="redirect" type="box" default="thisbox">
815 Writing to this property sets the box's redirect target. This
816 property cannot be read from, and can only be written to if
817 the value being written is a <i>descendant</i> of the current
820 If a box has a non-null redirect target, reads and writes to
821 any of the other properties in this section will be forwarded
822 to the redirect target.
824 The <t>redirect</t> attribute is very useful for hiding the
825 internal structure of a widget, and for allowing widgets to act as
826 "smart" containers for other widgets. For example, a menu widget might
827 have an invisible child as its redirect target; this way, when boxes
828 representing items on the menu are added as children of the menu
829 widget, they do not appear until the menu is pulled down.
832 <property name="numeric properties" type="int" default="">
833 The <i>n</i>th child of box <t>b</t> can be accessed by reading from
834 <t>b[n]</t>. The <i>n</i>th child can be removed by writing
835 <t>null</t> to <t>b[n]</t> (the child will become parentless). A
836 new child can be inserted <i>before</i> the <i>n</i>th child by
837 writing it to <t>b[n]</t>; if the value written is already a child of
838 <t>b</t>, it will be removed from <t>b</t> first. It is important
839 to note that this behavior is different from ECMAscript arrays --
840 writing a non-<t>null</t> value to <t>b[n]</t> does not eliminate
841 the <i>n</i>th child; it merely shifts it over one position.
842 <b>Note:</b> Unlike most JavaScript objects, enumerating a Box's
843 properties with the JavaScript <t>for..in</t> construct will
844 enumerate <i>only</i> the box's children and not any other properties.
847 <property name="clip" type="boolean" default="true">
848 If <t>true</t>, the visual representation of this box's
849 children will be clipped to the boundaries of this box.
850 <b>Note:</b> setting this property to <t>false</t> imposes a
851 substantial performance penalty.
854 <property name="numchildren" type="integer" default="0">
855 The number of children this box has.
859 <property name="surface" type="" default="null">
861 If this box has a parent, this property returns
862 <t><i>parent</i>.surface</t>; otherwise it returns null.
863 This property is a simple building block that the widget
864 library uses to implement more complex functionality such as
865 focus control and popups.
870 <section title="Other Box Properties">
872 <property name="cursor" type="string" default="null">
873 The shape that the cursor should take when inside this
874 box. Valid values are: "<t>default</t>" , "<t>wait</t>",
875 "<t>crosshair</t>", "<t>text</t>", "<t>hand</t>", and
876 "<t>move</t>", as well as resizing cursors"<t>east</t>",
877 "<t>west</t>", "<t>north</t>", "<t>south</t>",
878 "<t>northwest</t>", "<t>northeast</t>",
879 "<t>southwest</t>", and "<t>southeast</t>". Note that on
880 some platforms, resize cursors for opposite directions (such
881 as <t>northwest</t> and <t>southeast</t> are the
883 If a box's cursor is <t>null</t>, its parent's cursor will
884 be used. If the root box's cursor is null, the
885 "<t>default</t>" cursor will be used.
888 <property name="static" type="object" default="N/A">
889 Reading from this property will return the parent scope used
890 to execute the <t><static/></t> block of the template
891 in which the currently-executing code resides.
894 <property name="thisbox" type="box" default=" ">
895 Returns a reference to the box itself.
896 If <t>null</t> is written to this property, and this box is
897 the root box of a surface, the box will be detached and the
898 surface destroyed. If this box has a parent, it will be
899 detached from its parent.
902 <property name="indexof()" type="function" default=" ">
903 This property is actually a function; invoking
904 <t>parent.indexof(child)</t> will return the numerical index
905 of <t>child</t> in <t>parent</t> if <t>child</t> is a
906 child of <t>parent</t> (or <t>parent</t>'s redirect
907 target), and <t>-1</t> otherwise. Writing to this property
911 <property name="distanceto()" type="function" default=" ">
912 This property is actually a function; invoking
913 <t>box.distanceto(otherbox)</t> will return an object with two
914 properties, <t>x</t> and <t>y</t>, containing the horizontal
915 and vertical distance between the two boxes (negative if
916 <t>otherbox</t> is to the left of / above <t>box</t>). This
917 can be used to determine the relative placement of two boxes
918 on different branches of the box tree.
923 <section title="Root Box Properties">
925 The following special properties are only meaningful on the root box
928 <property name="Focused">
929 The value <t>true</t> is put to this property on the root box
930 when the surface gains the input focus, and <t>false</t> when
931 the surface loses the input focus. Reading from this value will
932 return <t>true</t> if the surface is focused and <t>false</t>
933 if it is not. Putting <t>true</t> to this property will
934 <i>not</i> cause the surface to "steal" the input focus from other
938 <property name="Maximized">
939 The value <t>true</t> is put to this property on the root box
940 when the surface is maximized, and <t>false</t> when the surface
941 is un-maximized. Reading from this value will return <t>true</t>
942 if the surface is maximized and <t>false</t> if it is
943 not. Putting <t>true</t> to this property will maximize the
944 window, and putting <t>false</t> to this property will
945 unmaximize the window.
946 Note that not all platforms support maximization.
949 <property name="Minimized">
950 The value <t>true</t> is put to this property on the root box
951 when the surface is minimized, and <t>false</t> when the surface
952 is unminimized. Reading from this value will return <t>true</t>
953 if the surface is minimized and <t>false</t> if it is
954 not. Putting <t>true</t> to this property will minimize the
955 window, and putting <t>false</t> will unminimize it.
958 <property name="Close">
959 When the user attempts to close a surface, the value
960 <t>true</t> will be put to this property. Scripts may trap
961 this property to prevent the window from closing. Putting the
963 <t>true</t> to this property on a root box has the same
964 effect as putting <t>null</t> to the <t>thisbox</t>
968 <property name="icon">
969 The surface's icon. This is usually displayed on the titlebar of a
970 window. The value should be an object whose stream is a PNG image. Note
971 that not all platforms support this property.
974 <property name="titlebar">
975 The surface's titlebar text. Note that not all platforms support
976 this property. Only ASCII characters 0x20-0x7F are permitted.
983 <!-- _______________________________________________________________________ -->
984 <section title="Streams">
986 <heading title="Every object has a stream..."/>
988 Every object has a <i>stream</i> associated with it. A stream is a
989 sequence of bytes that can be read or written to.
991 By default an object has an empty stream (zero bytes). However, some objects
992 (returned from special methods on the <t>ibex</t> object) have
993 streams yielding data read from an url, file, or a component of a zip
994 archive. In a future release, the stream associated with a box will
995 be an .ibex template which, when applied, will fully reconstitute the
998 <heading title="...but streams are not objects"/>
1000 Despite the ubiquity of streams, you cannot actually reference a
1001 stream, since it is not an object. Instead, you simply reference the
1002 object it belongs to. If you are familiar with Java, this is similar
1003 to how every Java object has a monitor associated with it, but you
1004 cannot directly manipulate the monitor (you can't pass around a
1005 reference to just the monitor).
1007 In the rest of the section we will sometimes refer to "getting
1008 properties from a stream" or "passing a stream to a function"; this is
1009 just shorthand for saying to perform those actions on the object the
1012 <section title="Creating Streams from URLs">
1014 You can create a stream from a URL by calling
1017 var r = ibex.stream.url("http://...");
1020 This will return an object whose stream draws data from the specified
1021 URL. Streams are loaded lazily whenever possible.
1025 <section title="Getting Substreams">
1027 Most stream objects let you access
1028 substreams using the usual JavaScript operators <t>[]</t> and
1029 <t>.</t>, as well as the <t>for..in</t> syntax.
1032 // r1 and r2 are equivalent but not equal (!=)
1033 var r1 = ibex.stream.url("http://www.ibex.org/foo/bar.html");
1034 var r2 = ibex.stream.url("http://www.ibex.org/foo")["bar.html"];
1039 <section title="The Root Stream">
1041 The empty-string property on the <t>ibex</t> object is called the
1042 <i>root stream</i>. You can access this object as <t>ibex..</t> or
1043 <t>ibex[""]</t>. Additionally, any expression which starts with a
1044 dot is treated as property to be retrieved from the root stream. The
1045 following three expressions are equivalent:
1055 <section title="Static Blocks">
1059 You can access variables within the static block of a template by
1060 appending a double period (<t>..</t>) and the variable name to the
1061 stream used to load that template:
1064 <!-- org/ibex/themes/linux/scrollbar.ibex -->
1068 ibex.log.print(org.ibex.themes.linux.scrollbar..foo); // prints "12"
1073 <section title="Formatting Streams">
1075 If you attempt to send a stream as part of an XML-RPC call, the
1076 stream will be read in its entirity, Base64-encoded, and transmitted
1077 as a <t><base64/></t> element.
1079 Ibex supports two special URL protocols. The first is <t>data:</t>,
1080 which inteprets the rest of the URL as a Base64 encoded sequence of
1081 bytes to use as a source. The other is <t>utf8:</t> which
1082 interpretets the rest of the string as a Unicode character sequence to
1083 be UTF-8 encoded as a string of bytes to use as a source.
1086 var r5 = ibex.stream.url("data:WFWE876WEh99sd76f");
1087 var r6 = ibex.stream.url("utf8:this is a test");
1090 You can read a UTF-8 encoded string from a stream like this:
1093 var myString = ibex.stream.fromUTF(ibex.stream.url("utf8:testing..."));
1095 You can also parse XML from a stream using SAX like this:
1098 ibex.stream.xml.sax(
1099 ibex.stream.url("http://foo.com/foo.xml"),
1100 { beginElement : function(tagname, attributeKeyValuePairs) { ... },
1101 endElement : function(tagname) { ... },
1102 content : function(contentString) { ... }
1103 whitespace : function(whitespaceString) { ... }
1111 <!-- _______________________________________________________________________ -->
1112 <section title="The Ibex object">
1114 The <t>ibex</t> object is present in the top-level scope of every
1115 script. It has the following properties:
1117 <heading title="General"/>
1119 <property name="ibex.box">
1120 reading from this property returns a new box
1122 <property name="ibex.clone(o)">
1123 creates a clone of object
1125 <property name="ibex.bless(s)">
1126 returns a blessed clone of stream
1129 <heading title="ECMA Library Objects"/>
1131 <property name="ibex.date">
1132 reading from this property returns a new date
1134 <property name="ibex.math">
1135 this object contains the ECMA math functions
1137 <property name="ibex.regexp(s)">
1138 return a regexp object corresponding to string <i>s</i>
1140 <property name="ibex.string">
1141 this object contains the ECMA string manipulation functions
1144 <heading title="Logging"/>
1146 <property name="ibex.log.debug(m1, ... mn)">
1147 log the debug messages <i>m1</i> through <i>mn</i>.
1151 <property name="ibex.log.info(m1, ... mn)">
1152 log the info messages <i>m1</i> through <i>mn</i>.
1155 <property name="ibex.log.warn(m1, ... mn)">
1156 log the warning messages <i>m1</i> through <i>mn</i>.
1159 <property name="ibex.log.error(m1, ... mn)">
1160 log the error messages <i>m1</i> through <i>mn</i>.
1163 <heading title="User Interface"/>
1165 <property name="ibex.ui.browser(u)">
1166 opens a new browser window with URL <i>u</i>
1169 <property name="ibex.ui.key.control">
1170 true if the control key is depressed
1173 <property name="ibex.ui.key.shift">
1174 true if the shift key is depressed
1177 <property name="ibex.ui.key.alt">
1178 true if the alt key is depressed
1181 <property name="ibex.ui.key.name.alt">
1182 the name of the "alt" key (usually either "alt", "meta", or
1186 <property name="ibex.ui.clipboard">
1187 the contents of the clipboard; can be read and written to
1190 <property name="ibex.ui.maxdim">
1191 the maximum dimension of any UI element; usually
1192 2<sup>31</sup>, but may be smaller
1195 <property name="ibex.ui.screen.width">
1196 the width of the screen, in pixels
1199 <property name="ibex.ui.screen.height">
1200 the height of the screen, in pixels
1203 <property name="ibex.ui.mouse.button">
1204 either 0, 1, 2, or 3, indicating the mouse button currently
1208 <property name="ibex.ui.frame">
1209 when a box is written to this property, it becomes the root
1213 <property name="ibex.ui.window">
1214 when a box is written to this property, it becomes the root
1218 <property name="ibex.ui.font.serif">
1219 an object whose stream is a a builtin serif font
1222 <property name="ibex.ui.font.sansserif">
1223 an object whose stream is a builtin sans-serif font
1226 <property name="ibex.ui.font.monospace">
1227 an object whose stream is a a builtin fixed-width font
1230 <heading title="Networking"/>
1232 <property name="ibex.net.rpc.xml(u)">
1233 return an XML-RPC call object with endpoint URL <i>u</i>
1236 <property name="ibex.net.rpc.soap(u,">
1237 return a SOAP call object with endpoint URL <i>u</i>,
1238 SoapAction <i>a</i>, and XML Namespace <i>n</i>
1241 <heading title="Threads"/>
1243 <property name="ibex.thread">
1244 when a function is written to this property, a new thread is
1248 <property name="ibex.thread.yield()">
1249 yield the current thread
1252 <property name="ibex.thread.sleep(n)">
1253 sleep for <i>n</i> milliseconds
1256 <heading title="Streams"/>
1258 <property name="ibex.stream.url(u)">
1259 returns a new object whose stream is drawn from URL <i>u</i>
1262 <property name="ibex.stream.unzip(s)">
1263 unpacks a zip archive from <i>s</i>'s stream
1266 <property name="ibex.stream.uncab(s)">
1267 unpacks a cab archive from <i>s</i>'s stream
1270 <property name="ibex.stream.cache(s,k)">
1271 valign=top>wraps a disk-backed read cache keyed on <i>k</i>
1272 around <i>s</i>'s stream
1275 <property name="ibex.stream.watch(s,f)">
1276 returns an object whose stream is drawn from <i>s</i>'s
1277 stream, but invokes <i>f(n,d)</i> as it is read from.
1280 <property name="ibex.stream.parse.xml(s, h)">
1281 Use SAX to parse the XML document on stream <i>s</i> with
1285 <property name="ibex.stream.parse.html(s, h)">
1286 Same as <t>parse.xml()</t>, but tries to fix broken HTML.
1289 <property name="ibex.stream.parse.utf8(s)">
1290 treat <i>s</i>'s stream as a string encoded as a UTF-8 byte stream and return the string
1293 <property name="ibex.stream.homedir">
1294 <t>ibex.stream.tempdir</t>
1297 <heading title="Cryptography"/>
1299 <property name="ibex.crypto.rsa(k,s)">
1300 <i>not implemented yet:</i> return a
1301 stream which rsa-decrypts stream <i>s</i> with key <i>k</i>
1304 <property name="ibex.crypto.rc4(k,s)">
1305 <i>not implemented yet:</i> return a
1306 stream which rc4-decrypts stream <i>s</i> with key <i>k</i>
1309 <property name="ibex.crypto.md5(s)">
1310 <i>not implemented yet:</i> immediately
1311 MD5-hash stream <i>s</i>
1314 <property name="ibex.crypto.sha1(s)">
1315 <i>not implemented yet:</i> immediately
1316 SHA1-hash stream <i>s</i>
1320 <!-- _______________________________________________________________________ -->
1321 <section title="Traps">
1323 You can add a trap to a property by applying the <t>++=</t> operator
1324 to a function with one argument. The trap will be invoked whenever
1325 that property is written to.
1329 foo ++= function(z) {
1330 ibex.log.info("foo is " + z);
1335 If another script were to set the property "<t>foo</t>"
1336 on the box above to the value <t>5</t>, the function above would be
1337 invoked with the argument <t>5</t>. The function would then log
1338 the string "<t>foo is 5</t>".
1340 Within a trap, the expression <t>trapee</t> can be used to
1341 get a reference to the box on which the trap was placed.
1343 The expression <t>trapname</t> returns the name of the
1344 trap executing the current function. This is useful when a function
1345 is applied to multiple traps. For example:
1349 func ++= function(z) {
1350 ibex.log.info("called trap " + trapname);
1357 <section title="Removing Traps">
1359 You can remove a trap by using the <t>--=</t> operator with the same
1360 function you added as a trap:
1364 var myfunc = function(z) { /* ... */ }
1375 <heading title="Multiple Traps on the Same Property"/>
1377 When the trapped property is <i>written</i> to, each of the trap
1378 functions placed on it will be invoked in the opposite order that
1379 they were placed on the box -- the most recently placed trap will
1380 execute first. This last-to-first execution of traps is called
1381 <i>cascading</i>. After the last trap is invoked, the value is
1382 stored on the box (remember, boxes are objects, so they can hold
1383 properties just like all other ECMAscript objects).
1385 <section title="Manual Cascades">
1387 There are two additional tricks you can use when placing traps. The
1388 first is a <i>manual cascade</i>. If you want to cascade to lower
1389 traps in the middle of a function, or you want to cascade with a
1390 different value than the value passed to you (in effect "lying" to
1391 lower traps), you can use <t>cascade</t>. For example:
1394 <ui:box color="black">
1395 color ++= function(c) {
1396 ibex.log.info("refusing to change colors!");
1402 This effectively creates a box whose color cannot be changed, and
1403 which complains loudly if you try to do so.
1405 Do <i>not</i> try to do something like this:
1408 <ui:box color="black">
1409 color ++= function(z) {
1410 color = "black"; // INFINITE LOOP! BAD!!!
1414 To prevent automatic cascading, return <t>true</t> from your function:
1417 <ui:box color="black">
1418 color ++= function(z) {
1419 return true; // the box's color will not change
1426 <section title="Read Traps">
1428 The other trick is a <i>read-trap</i>. Read traps are just like normal
1429 traps, except that you use a function that takes zero arguments instead of one. Read traps
1430 also do not automatically cascade.
1434 doublewidth <t>++=</t> function() { return 2 * width; }
1438 If another script attempts to read from the <t>doublewidth</t>
1439 property on this box, the value it gets will be twice the actual width
1440 of the box. Note that
1441 the actual <t>doublewidth</t> property on the box never gets written
1442 to, since the trap does not cascade.
1444 You can manually cascade on read traps as well:
1448 text <t>++=</t> function() { return "my text is " + cascade; }
1452 Read traps are only rarely needed -- most of the time a write trap
1457 <heading title="Prohibited Traps"/>
1459 To prevent confusing and hard-to-debug behaviors, scripts may not
1460 place traps on any of the properties described in the sections
1461 <link text="Box Layout Properties" section="Layout Properties"/>, <link
1462 section="Child-Control Properties"/>, or <link section="Other Box
1463 Properties"/> except for <t>childadded</t>,
1464 <t>childremoved</t> and <t>surface</t>. FIXME: remove?
1466 <heading title="Exceptions and Traps"/>
1468 If an uncaught exception is thrown from a trap, Ibex will log the
1469 exception, but will <i>not</i> propagate it to the code which
1470 triggered the trap. If the trap was a read trap, the value
1471 <t>null</t> will be returned.
1472 FIXME: is this right?
1474 <heading title="Architectural Significance of Traps"/>
1476 Traps are the backbone of Ibex. Since almost all UI programming is
1477 event/demand driven, traps eliminate the need for separate
1478 member/getter/setter declarations, often cutting the amount of typing
1479 you have to do to a third of what it would normally be.
1481 <section title="Cloning">
1483 <i>Cloning</i> is a companion technique for traps; together they can
1484 be used to simulate any sort of environment you might need. When you
1485 call <t>ibex.clone(o)</t>, Ibex returns a new object (called the
1486 <i>clone</i>) which compares with equality (<t>==</t>) to the
1487 original object. Furthermore, both objects are "equal" as keys in
1492 var theclone = ibex.clone(o);
1494 ibex.log.info(hash[theclone]); // prints "5"
1497 Any writes to properties on the clone will actually write to
1498 properties on the original object, and reads from properties on the
1499 clone will read properties on the original object. In fact, the only
1500 thing that can be used to distinguish the original from the clone is
1501 traps -- a trap placed on the clone is <i>not</i> placed on the
1502 original object as well.
1507 <!-- _______________________________________________________________________ -->
1508 <section title="Threads">
1510 <section title="Contexts">
1512 From the perspective of an application writer, Ibex is strictly
1513 single-threaded. Ibex is always in exactly one of the following three
1516 <list type="unordered">
1518 <b>Rendering Context</b> -- (redrawing the screen)
1520 <b>Event Context</b> (executing javascript traps triggered by an event)
1522 <b>Thread Context</b> (executing a background thread spawned with <t>ibex.thread</t>)
1526 There are two important restrictions on what can be done in particular contexts:
1528 <list type="unordered">
1530 The <t>box.mouse</t> property and its subproperties
1531 (<t>x</t>, <t>y</t>, and <t>inside</t>) can only be read
1532 from within the Event Context, or in a thread context
1533 <i>after</i> a the <t>box.mouse</t> property on this box or
1534 an ancestor box has been written to.
1536 Blocking operations (anything that accesses the network or
1537 disk) can only be performed in the Thread Context.
1543 <section title="Background Threads">
1545 Ibex offers easy access to threads. Spawning a background thread is as
1546 simple as writing a function to the <t>ibex.thread</t> property:
1549 ibex.thread = function() {
1550 ibex.log.info("this is happening in a background thread!");
1554 The argument set passed to the function is currently undefined and is
1555 reserved for use in future versions of Ibex. Scripts should not
1556 depend on the number or content of these arguments.
1558 Ibex is <i>cooperatively multitasked</i>, so threads must not process
1559 for too long. This was a deliberate choice; cooperatively
1560 multitasked environments do not require complex locking primitives
1561 like mutexes and semaphores which are difficult for novices to
1562 understand. The disadvantage of cooperative multitasking is that one
1563 thread can hog the CPU. This is unlikely to happen in Ibex for two reasons:
1564 first, all blocking I/O operations <i>automatically</i> yield the CPU,
1565 so the overall user interface never becomes unresponsive because it is
1566 waiting for a disk or network transfer. Second, since Ibex is strictly
1567 a user interface platform, Ibex scripts are unlikely to perform highly
1568 compute-intensive operations that keep the CPU busy for more than a
1574 <section title="Events">
1576 Every execution of the Event Context begins with an event, which
1577 consists of a key/value pair, and a mouse position, which consists of
1578 an x and y coordinate. The possible keys are <t>_Press[1-3]</t>,
1579 <t>_Release[1-3]</t>, <t>_Click[1-3]</t>, <t>_DoubleClick[1-3]</t>,
1580 <t>_Move</t>, <t>_KeyPressed</t>, and <t>_KeyReleased</t>.
1582 Here are two example events:
1584 An event is triggered by writing the key to the value on a box. This
1585 triggers any trap handlers which may be present. Once these handlers
1586 have executed, Ibex figures out which child of the current box contains
1587 the mouse (taking into account that some boxes may cover up others)
1588 and writes the key and value to that box. If none of the box's
1589 children contain the mouse position, Ibex removes the leading
1590 underscore from the key name and writes the value to
1591 <i>that</i> property. Once all the traps on that property have
1592 executed, the value is written to the box's parent.
1594 Intuitively, Ibex delivers the underscored event to every box from the
1595 root to the target, and then delivers the non-underscored event to
1596 that same set of boxes in reverse order. So the event travels down
1597 the tree to the target, and then back up to the root. The following
1598 example prints out "first second third fourth" in that order.
1602 _Press1 ++= function(b) { ibex.log.info("first"); }
1603 Press1 ++= function(b) { ibex.log.info("fourth"); }
1605 _Press1 ++= function(b) { ibex.log.info("second"); }
1606 Press1 ++= function(b) { ibex.log.info("third"); }
1611 In general, you should use the <i>non-underscore</i> names to respond
1612 to user input and use the underscored names when you want to override
1613 child boxes' behavior or route events to particular boxes (for
1614 example, when implementing a focus protocol). This is why the
1615 underscored elements are delivered to parents before children (so
1616 parents can override their childrens' behavior), but non-underscored
1617 events are delivered to children before parents (since, visually, a
1618 mouse click is usually "intended" for the leaf box underneath the
1623 <heading title="Stopping the Process"/>
1625 At any point in this sequence, a trap handler can choose not to
1626 cascade (by returning <t>true</t> from the trap handler function).
1627 This will immediately cease the propagation of the event. This is how
1628 you would indicate that an event has been "handled".
1630 <heading title="Non-Propagating Events"/>
1632 Ibex uses the following events to notify a box about changes that
1633 only matter to that particular box. These events do not propagate
1634 either up or down the tree.
1636 <property name="Enter Leave">
1637 The value <t>true</t> is written to this property when the mouse (enters/leaves) the box.
1640 <property name="SizeChange">
1641 The value <t>true</t> is put to this property after the size
1642 of this box changes.
1645 <property name="ChildChange">
1646 When a child is added or removed, that child is written to
1647 this property. The write is always performed <i>after</i> the
1648 addition or removal, so these two cases can be distinguished
1649 by checking <t>indexof(child)</t>.
1651 Note that if the parent's redirect target is set to another
1652 box, this trap will only be invoked when children are
1653 manipulated by reading and writing to the parent. Reads and
1654 writes directly to the redirect target will <i>not</i> trigger
1657 Note also that this traps is still triggered if a box's
1658 <t>redirect</t> target is <i>null</i>. This is useful for
1659 boxes that need to accept children and then relocate them
1663 <section title="Listing of Events">
1665 <property name="Press1 Press2 Press3">
1666 Indicates that the use has pressed a mouse button. On
1667 platforms with three mouse buttons, the <i>middle</i> button
1668 is button 3 -- this ensures that applications written to only
1669 use two buttons (1 and 2) will work intuitively on three button
1673 <property name="Release1 Release2 Release3">
1674 Indicates that the use has released a mouse button.
1677 <property name="Click1 Click2 Click3">
1678 Indicates that the user has pressed and released the
1679 mouse button without moving the mouse much (exactly how
1680 much is platform-dependent).
1683 <property name="DoubleClick1 DoubleClick2 DoubleClick3">
1684 Indicates that the user has clicked the
1685 mouse button twice within a short period of time (exactly how long is platform-dependent).
1688 <property name="Move">
1689 Indicates that the mouse has moved while within this box, or that
1690 the mouse while outside this box <i>if a button was pressed while within this box and has not yet been released</i>
1693 <property name="KeyPressed KeyReleased">
1695 A string is written to this property when a key is pressed or
1696 released If the key was any other key, a multi-character
1697 string describing the key will be put. For simplicity, we use
1698 the VK_ constants in the <link
1699 url="http://java.sun.com/products/jdk/1.1/docs/api/java.awt.event.KeyEvent.html#VK_0"
1700 text=" Java 1.1 API java.awt.event.KeyEvent class"/>. When a
1701 key is pressed or released, the string put will be the portion
1702 of its VK_ constant after the underscore, all in lower case.
1705 If the shift key was depressed immediately before the
1706 event took place, then the string will be capitalized. Special
1707 keynames are also capitalized; shift+home is reported as
1708 "<t>HOME</t>". Symbols are capitalized as they appear on the
1709 keyboard; for example, on an American QWERTY keyboard, shift+2
1710 is reported as "<t>@</t>".
1712 If the alt, meta, or command key was depressed immediately
1713 before this key was pressed, then the string will be prefixed
1714 with the string "<t>A-</t>". If the control key was depressed
1715 while this key was pressed, then the string will be prefixed
1716 with the string "<t>C-</t>". If both alt and control are
1717 depressed, the string is prefixed with "<t>C-A-</t>".
1719 Ibex does not distinguish between a key press resulting from
1720 the user physically pushing down a key, and a 'key press'
1721 resulting from the keyboard's typematic repeat. In the rare
1722 case that an application needs to distinguish between these
1723 two events, it should watch for KeyReleased messages and
1724 maintain an internal key-state vector.
1732 <!-- _______________________________________________________________________ -->
1733 <section title="Networking">
1735 <section title="XML-RPC">
1737 XML-RPC objects can be created by calling <t>ibex.net.rpc.xml(<i>XML-RPC
1738 URL</i>)</t>, and then invoking methods on that object. For example,
1741 Press1 += function(v) {
1742 ibex.thread = function() {
1743 color = ibex.net.rpc.xml("http://xmlrpc.ibex.org/RPC2/").
1744 color.getTodaysColor("Friday");
1749 When the user clicks the first mouse button on this box, it will
1750 contact the server <t>xmlrpc.ibex.org</t>, route to the
1751 <t>/RPC2/</t> handler and invoke the <t>getTodaysColor()</t>
1752 method on the <t>color</t> object with a single string argument
1753 "<t>Friday</t>". The return value will be used to change the color
1754 of the box the user clicked on.
1756 Note that in this example we spawned a background thread to handle the
1757 request -- the <t>Press1</t> event is delivered in the foreground
1758 thread, and XML-RPC methods may only be invoked in background
1759 threads. This is to prevent the UI from "locking up" if the server
1760 takes a long time to reply.
1762 If the XML-RPC method faults, an object will be thrown with two
1763 properties: <t>faultCode</t> and <t>faultString</t>, as defined in
1764 the <link url="http://www.xmlrpc.org/spec" text="XML-RPC specification"/>. If
1765 Ibex encounters a network, transport, or session-layer error, it will
1766 throw a <t>String</t> object describing the error in a
1767 human-readable format. Scripts should not rely on the contents of
1768 this string having any special structure or significance.
1770 If an object with an associated non-empty stream is passed as an
1771 argument to an XML-RPC method, it will be sent as a <base64/>
1772 element. If a <base64/> element is found in the XML-RPC reply, it
1773 will be returned as an object with a stream drawn from that byte sequence.
1775 Each object returned by <t>ibex.net.rpc.xml()</t> represents a
1776 single HTTP connection. The connection will be held open until
1777 the object is garbage collected or the server closes the
1778 connection. If a second call is issued on the object before the
1779 first one returns (usually from a seperate thread), the two calls
1781 url="http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.2.2"
1782 text="pipelined"/>. This can dramatically improve performance.
1784 Ibex supports HTTP Basic and Digest authentication. To use
1785 authentication, pass <t>ibex.net.rpc.xml()</t> a URL in the form
1788 http[s]://user:password@hostname/
1791 Ibex will use Digest authentication if the server supports it;
1792 otherwise it will use Basic authentication. Please be aware that
1793 many XML-RPC server implementations contain a <link
1794 url="http://www.ibex.org/faq.html#auth" text="broken
1795 implementation of Basic authentication"/>.
1799 <section title="SOAP">
1801 SOAP methods are invoked the same way as XML-RPC methods, but with three differences:
1803 <list type="ordered">
1805 <t>ibex.net.rpc.soap()</t> is used instead of
1806 <t>ibex.net.rpc.xml()</t>
1808 Instead of specifying just the URL of the service itself, you
1809 must specify the URL, the SOAPAction argument, and the
1812 The actual method invocation takes only one argument, which
1813 must be an object. This is necessary since SOAP arguments are
1814 specified by name, rather than ordering.
1818 SOAP faults are handled the same way as XML-RPC faults except that the
1819 capitalization of the <t>faultstring</t> and <t>faultcode</t>
1820 members is all lower-case, to match the SOAP spec. Here is a
1824 Press1 ++= function(v) {
1825 ibex.thread = function() {
1826 color = ibex.net.rpc.soap("http://soap.ibex.org/SOAP",
1828 "http://ibex.org/namespace"
1829 ).color.getTodaysColor( {
1836 As you can see, SOAP is much more verbose, yet does not offer
1837 substantially improved functionality. We recommend that XML-RPC be
1838 used whenever possible, and that SOAP be reserved for legacy
1841 The current Ibex SOAP stack does not support 'document style' or
1842 multi-ref (<t>href</t>) data structures.
1846 <section title="Security">
1848 Applications downloaded from the network (as opposed to those loaded
1849 from the filesystem) may only make certain kinds of connections to
1850 certain hosts. See Appendix A for a detailed description of the
1856 <!-- _______________________________________________________________________ -->
1857 <section title="Error Handling">
1859 If the Ibex Core encounters an error while servicing a function call
1860 originating in JavaScript, the core will throw a string consisting of
1861 an error code followed by a colon, a space, and a descriptive message.
1865 "ibex.net.dns.unknownhostexception: unable to resolve host foo.com"
1868 The code should be used to determine how the program should respond to
1869 an error. The codes are organized in a hierarchy, so the
1870 string.startsWith() method can be used to determine if an error lies
1871 within a particular subhierarchy. The descriptive message portion of
1872 the string may be shown to the user.
1874 <property name="ibex.assertion.failed">
1877 <property name="ibex.io">
1878 General I/O exceptions
1880 <property name="ibex.io.encoding">
1881 Error translating between character encodings.
1883 <property name="ibex.io.zip">
1884 Attempted to access a corrupt zip archive.
1886 <property name="ibex.io.eof">
1887 End of file encountered unexpectedly
1889 <property name="ibex.net.security.prohibitedHost">
1890 A piece of untrusted Ibex code attempted to contact a
1891 restricted host. See <link appendix="Security Architecture and Considerations"/> for details.
1893 <property name="ibex.net.dns.temporaryFailure">
1894 An attempt to resolve a hostname failed but it is not known
1895 for certain that the hostname is invalid.
1897 <property name="ibex.net.dns.unknownHost">
1898 An attempt to resolve a hostname failed because the hostname
1901 <property name="ibex.net.socket.closed">
1902 A socket was closed unexpectedly.
1904 <property name="ibex.net.socket.connectionFailed">
1905 A connection could not be made to the remote host.
1907 <property name="ibex.net.url.malformed">
1908 Tried to parse a malformed URL.
1910 <property name="ibex.net.ssl">
1911 General SSL protocol errors.
1913 <property name="ibex.net.ssl.untrustedCertificate">
1914 The server's certificate was not signed by a CA trusted by Ibex.
1916 <property name="ibex.net.http.">
1917 Thrown when an HTTP error code is returned during an
1918 operation. The three characters <t><i>xyz</i></t> will be
1919 the three-digit HTTP status code.
1921 <property name="ibex.net.xmlrpc.null">
1922 The caller attempted to transmit the <t>null</t> value via XML-RPC.
1924 <property name="ibex.net.xmlrpc.circular">
1925 The caller attempted to transmit a circular data structure via XML-RPC.
1927 <property name="ibex.net.xmlrpc.specialObject">
1928 The caller attempted to transmit a "special" object via
1929 XML-RPC (for example, a Box or the Ibex object).
1931 <property name="ibex.null.put">
1932 A JavaScript attempted to put to a property on the <t>null</t> value
1934 <property name="ibex.null.get">
1935 A JavaScript attempted to get from a property on the <t>null</t> value
1937 <property name="ibex.null.call">
1938 A JavaScript attempted to call the <t>null</t> value
1941 If an exception is thrown inside a trap, the exception will propagate
1942 to the script that triggered the trap.
1944 If an uncaught exception is thrown while applying a template, or the
1945 requested template could not be found, an error will be logged and the
1946 box to which the template was being applied will be made invisible
1947 (<t>visible = false</t>). This ensures that half-applied widgets are
1948 never shown to the user.
1952 <!-- _______________________________________________________________________ -->
1953 <section title="Advanced Topics">
1955 <section title="Re-routing events">
1957 At any point in the Event Context, you can write to the <t>mouse</t>
1958 property on any box. The value written should be an object with two
1959 properties, <t>x</t> and <t>y</t>. For example:
1962 _Press1 ++= function(p) {
1963 mouse = { x: 32, y: 77 };
1967 The coordinates specified are relative to the box whose <t>mouse</t>
1968 property is being written to. There is no need to supply the
1969 <t>inside</t> property; it is computed automatically. Writing to
1970 the <t>mouse</t> property causes Ibex to recompute the eventual
1971 target box, and also alter the values returned by <t>mouse.x</t>,
1972 <t>mouse.y</t>, and <t>mouse.inside</t> for any <i>descendants</i>
1973 of the current box. Writing to the <t>mouse</t> property also
1974 automatically prevents the event from returning to the box's parents
1975 -- it is equivalent to not cascading on the non-underscored event.
1976 This ensures that child boxes cannot trick their parent boxes into
1977 thinking that the mouse has moved.
1979 If you want the event to "skip over" the boxes between the trapee
1980 and the target, or if you want to re-route an event to a box which
1981 is not a descendant of the current box, simply write the value to
1982 the proper key on the target box.
1986 _KeyPressed = function(k) { ibex.log.info("first"); }
1987 KeyPressed = function(k) { ibex.log.info("sixth"); }
1988 $recipient.target = $target;
1989 <ui:box id="recipient">
1990 _KeyPressed = function(k) {
1991 ibex.log.info("second");
1992 thisbox.target.KeyPressed = k;
1993 // inhibit cascade; keep event from going to $excluded
1996 KeyPressed = function(k) { ibex.log.info("fifth"); }
1997 <ui:box id="excluded">
1998 _KeyPressed = function(k) {
1999 ibex.log.info("this never happens");
2003 <ui:box id="target">
2004 _KeyPressed = function(k) { ibex.log.info("third"); }
2005 KeyPressed = function(k) { ibex.log.info("fourth"); }
2012 <section title="Synthesizing Your Own Events">
2014 You can create "fake events" by simply writing to the <t>mouse</t>
2015 property and then writing a value to one of the underscored properties
2016 on a box. This will have exactly the same effect as if the use had
2017 actually pressed a key, clicked a button, or moved the mouse -- they
2018 are indistinguishable.
2022 <section title="Ibex self-emulation">
2024 When the core first starts up, it clones the <t>ibex</t> object,
2025 creates a stream for the initial .ibex, and then places a trap on the
2026 cloned <t>ibex</t> object so that its empty-string property returns
2027 the .ibex stream. The cloned Ibex object is then passed as the third
2028 (optional) argument to <t>ibex.apply()</t>, making it the default
2029 <t>ibex</t> object for the scripts that are executed as part of the
2030 template instantiation.
2033 var new_ibex = ibex.clone(ibex);
2034 var stream = ibex.bless(ibex.stream.url("http://..."));
2035 new_ibex[""] ++= function() { return stream; }
2036 ibex.apply(ibex.box, new_ibex..main, new_ibex);
2039 Note that we called <t>ibex.bless()</t> on the stream before tacking
2040 it on to the new Ibex object. The bless function returns a clone of
2041 the object passed to it, with a few traps which are explained below.
2042 Additionally, any sub-streams retrieved by accessing properties of the
2043 blessed stream will also automatically be blessed (blessed streams are
2046 Blessing a stream serves three purposes:
2048 <list type="unordered">
2050 Blessed clones always return the appropriate static block when
2051 their empty property is accessed; this ensures that references
2052 to the static blocks of other templates work properly.
2054 Blessed substreams can return their parent stream by accessing
2055 a hidden property which is reserved for internal use by Ibex.
2056 This ensures that Ibex can automatically add filename
2057 extensions where needed, according to the following rules:
2060 If the stream is a template to be applied, the string
2061 "<t>.ibex</t>" is appended.
2063 If the stream is an image, the string "<t>.png</t>" is
2064 appended. If no stream is found, "<t>.jpeg</t>" and
2065 "<t>.gif</t>" are tried, in that order.
2067 If the stream is an font, the string "<t>.ttf</t>" is
2071 Every call to <t>ibex.bless()</t> returns a different object
2072 (which happens to be a clone of the object passed to it) with
2073 a completely separate set of static blocks.
2077 Ibex can self-emulate by using <t>ibex.clone()</t> on the Ibex object;
2078 this technique is very similar to the use of ClassLoaders in
2079 Java. This is useful for a number of applications, including
2080 debuggers, IDEs, sandboxing untrusted code, remote-control, and
2081 others. For example:
2084 var newLoadFunction = function(url) { /* ... */ };
2085 var new_ibex = ibex.clone(ibex);
2086 new_ibex.load ++= function() { return newLoadFunction; }
2087 ibex.apply(ibex.box, .main, new_ibex);
2092 <!-- _______________________________________________________________________ -->
2093 <appendix title="Security Architecture and Considerations">
2095 Due to the expense and hassle imposed by the commercial PKI code
2096 signing architecture, and the fact that it <link
2097 url="http://www.counterpane.com/pki-risks-ft.txt" text="doesn't
2098 really provide any security anyways"/>, Ibex user interfaces are
2099 distributed as unsigned, untrusted code. As such, they are handled
2100 very carefully by the Ibex Core, and assumed to be potentially
2103 Ibex's security architecture is divided into defenses against four
2104 major classes of attacks:
2106 <heading title="Malicious UI attempts to acquire or alter data on the client"/>
2108 Ibex user interfaces are run in an extremely restrictive sandbox. The
2109 environment does not provide primitives for accessing any data outside
2110 the Ibex core except via XML-RPC and SOAP calls. There are no
2111 facilities to allow Ibex user interfaces to access the client's
2112 operating system or to interact with other applications on the same
2113 host (unless they provide a public XML-RPC or SOAP interface).
2114 An Ibex script may only access a file on the user's hard disk if the
2115 user explicitly chooses that file from an "open file" or "save file"
2116 dialog. There is one exception to this rule: if all templates
2117 currently loaded in the Ibex core originated from the local
2118 filesystem, those templates can load additional .ibexs from the local
2121 The Ibex Core is written in Java, so it is not possible for
2122 scripts to perform buffer overflow attacks against the core
2125 Ibex applications may only read from the clipboard when the user
2126 middle-clicks (X11 paste), presses control-V (Windows paste), or
2127 presses alt-V (Macintosh paste; the command key is mapped to Ibex
2128 "alt"). This ensures that Ibex applications are only granted access to
2129 data that other applications have placed on the clipboard when the user
2130 specifically indicates that that information should be made available
2131 to the Ibex application.
2133 <heading title="Malicious UI attempts to use client to circumvent firewalls"/>
2135 Ibex user interfaces may only make XML-RPC or SOAP calls and load .ibex
2136 archives via HTTP; they cannot execute arbitrary HTTP GET's or open
2137 regular TCP sockets.
2139 Ibex will not allow a script to connect to a non-public IP address
2140 (10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16, as specified in <link
2141 url="http://www.cis.ohio-state.edu/cgi-bin/rfc/rfc1918.html" text="RFC
2142 1918"/>). There is one exception -- if all templates currently loaded
2143 in the core originated from the same IP address, those scripts may
2144 make calls to that IP address regardless of whether or not it is
2145 firewalled. If Ibex does not have access to a DNS resolver (because it
2146 is using a proxy which performs DNS lookups), Ibex will provide the
2147 proxy with the appropriate <link
2148 url="http://www.ibex.org/x-requestorigin.html"
2149 text="X-RequestOrigin"/> header that the proxy needs in order
2150 to maintain security.
2152 The only remaining possible attack is against a XML-RPC or SOAP
2153 service running on a firewalled host with a public address. Assigning
2154 such machines public IP addresses is a poor network security policy,
2155 and doing so squanders scarce public IPv4 addresses. As such, the onus
2156 is on the administrators of such machines to explicitly block access
2157 to clients reporting a <t>User-Agent:</t> header beginning with the
2158 four characters "<t>IBEX</t>".
2160 <heading title="Malicious UI attempts to trick user into divulging secret information"/>
2162 All top-level windows created by Ibex are <i>scarred</i> -- a stripe
2163 and a lock is drawn across the corner of the window. There is no way
2164 for a user interface to remove this scar. Ibex user interfaces may not
2165 create windows smaller than the size of the scar.
2167 <heading title="Malicious network attempts to snoop or man-in-the-middle transactions"/>
2169 Ibex user interfaces may transmit network data using HTTPS (SSL 3.0)
2170 for encryption. Ibex will attempt 128-bit encryption, but will
2171 negotiate down to 40-bit if the server does not support strong
2172 crypto. Ibex's SSL implementation is currently provided by <link
2173 url="http://www.ibex.org/tinyssl" text="TinySSL"/> and <link
2174 url="http://www.bouncycastle.org" text="The Legion of the Bouncy
2177 All HTTPS connections must be authenticated by the server using a
2178 certificate whose name matches the domain name of the HTTPS URL. The
2179 certificate must be signed by a trusted root CA. Ibex trusts the same
2180 93 root CAs whose certificates are included as "trusted" in Microsoft
2181 Internet Explorer 5.5 SP2. This provides a minimal level of protection
2182 against man-in-the-middle attacks; you should not trust this
2183 connection with any data you would not normally trust an SSL-enabled
2188 <!-- _______________________________________________________________________ -->
2189 <appendix title="ECMAscript compliance">
2191 Ibex's scripts are written in a modified subset of ECMA-262, revision 3
2192 (aka JavaScript 1.5). The interpreter strays from the spec in a few
2195 <section title="Omissions">
2197 The following ECMA features are not supported:
2199 <list type="unordered">
2201 The <t>undefined</t> value, <t>===</t>, and <t>!==</t>
2203 The <t>new</t> keyword (and ECMAScript object inheritance)
2206 <t>getter</t> and <t>setter</t>
2208 The ECMA <t>this</t> keyword.
2210 The <t>String</t>, <t>Number</t>, and <t>Boolean</t>
2211 classes. Note that <t>string</t>, <t>number</t>, and
2212 <t>boolean</t> values are supported, however.
2214 You may not <t>throw</t> the <t>null</t> value.
2218 Additionally, you must declare all root-scope variables (with
2219 <t>var</t>) before using them; failure to do so will result in an
2220 exception. Box properties are pre-defined in the scope that scripts
2225 <section title="Extensions">
2227 <list type="unordered">
2229 The token <t>..</t> is equivalent to <t>[""]</t>.
2235 Extended <t>catch</t> syntax. The following code:
2237 } catch(e propname "foo.bar.baz") {
2244 if (e.propname != null and e.propname >= "foo.bar.baz" and
2245 "foo.bar.baz/" > e.propname) {
2250 Multiple extended-catch blocks can appear at the end of a single try
2251 block. However, at most one non-extended catch block may appear, and
2252 if it does appear, it must be the last one.
2254 Since Ibex ECMAscripts are wrapped in XML, the lexical token
2255 "<t>lt</t>" is be interpreted as <t><</t>, the lexical
2256 token "<t>gt</t>" is be interpreted as <t>></t>, and the
2257 token "<t>and</t>" is interpreted as <t>&&</t>.
2258 Thus these tokens cannot be used as variable names.
2260 The identifier <t>static</t> is a reserved word in
2261 ECMAScript, but not in Ibex.
2263 Ibex defines an additional reserved word, "<t>assert</t>",
2264 which will evaluate the expression which follows it, throwing
2265 a <t>ibex.assertion.failed</t> exception if the expression
2266 evaluates to <t>false</t>.
2268 To ensure that Ibex files appear the same in all text editors, tab
2269 characters are not allowed in Ibex files.
2273 Some useful tutorials include:
2275 <list type="unordered">
2278 url="http://developer.netscape.com/docs/manuals/communicator/jsref/index.htm"
2279 text=" JavaScript 1.2 Reference"/>. Although this document is
2280 out of date, it is arguably the best guide available for free
2281 on the Internet. The changes from JavaScript 1.2 (aka ECMA-262
2282 r1) to 1.5 were minimal, and many of them were <link
2283 url="ecmascriptcompliance" text="omitted"/> from Ibex.
2286 url="http://search.barnesandnoble.com/booksearch/isbnInquiry.asp?isbn=0596000480"
2287 text=" JavaScript: The Definitive Guide"/>, by David Flanagan
2288 and Paula Ferguson. The latest edition of this book covers
2289 JavaScript 1.5 (ECMA-262 r3).
2292 url="http://www.ecma.ch/ecma1/STAND/ECMA-262.HTM"
2293 text="ECMA-262"/> specification. This is an extremely
2300 <!-- _______________________________________________________________________ -->
2301 <appendix title="Logging and Command Line Invocation">
2304 Usage: ibex [-lawp] [ url | file | directory ]
2305 -l [level] set logging level to { debug, info (default), warn, error, silent }
2306 -l rpc log all XML-RPC and SOAP conversations
2307 -l user@host email log to user@host
2308 -l host:port emit log to TCP socket
2309 -l [file] write log to a file on disk
2311 -w <window-id> reserved for libibex
2312 -p dump profiling information [not yet supported]
2315 If Ibex encounters a serious problem before it starts logging
2316 information, or if it is unable to open the log file, it will abort
2317 immediately with a critical abort, which will be displayed on the
2318 console for POSIX-native cores and in a dialog box for JVM-based and
2321 Note that Microsoft Windows does not provide any mechanism for
2322 redirecting standard input/output of an application which is not
2323 compiled as a "console application". Therefore, Ibex is compiled
2324 as a "console application", and will open a console window when
2325 invoked. To inhibit this console window, provide a logging
2326 destination (file, port, etc).
2328 The <t><i>source-location</i></t> parameter can be either the path
2329 to an <t>.ibex</t> archive, the http url of an <t>.ibex</t>
2330 archive, or the path to a directory comprising an unpacked
2331 <t>.ibex</t> archive.
2333 The <t><i>initial-template</i></t> parameter is the stream name of
2334 a template to be used as the initial template. If ommitted, it
2335 defaults to <t>main</t>.
2337 The <t>-v</t> option causes Ibex to enable verbose logging; this will
2338 cause it to log <i>lots</i> of information to the log file. This
2339 option will also substantially decrease Ibex's performance.
2343 <!-- _______________________________________________________________________ -->
2345 <appendix title="Grammars">
2347 <i>Grammar support is experimental in this release
2348 and may not work properly. It may change in incompatible ways or
2349 disappear completely from future releases</i>
2351 Grammars are defined with a statement in the following form:
2356 A grammar is really just another function; once defined you can't tell
2357 it apart from an ordinary function. A grammar takes one argument,
2358 which can be a string or stream. The argument is parsed and the
2359 result of executing the code block 'c' is returned.
2361 The property 'a' is read; if the value is a grammar, a new production
2362 rule (ie a new alternative, as with '<t>|</t>') is added to that grammar
2363 (this is a destructive update). This allows you to add productions to
2364 pre-existing grammars (for example, adding a new type of expression to
2365 a programming language by extending the 'expr' grammar). If the old
2366 value is not a grammar, the value is discarded and a new grammar
2369 The value 'b' is a pattern, which may consist of seven simple
2372 <list type="unordered">
2375 grouping parens <t>()</t>
2377 combinators: <t> | + * ?</t>
2379 references to other grammars
2382 The value 'c' and the braces surrounding it are an *optional* code
2383 block, in which the following identifiers are bound:
2385 <list type="unordered">
2387 The identifier 'whole' is bound to the string matched by the
2388 entire expression. If the code block is omitted it behaves
2389 as if it were "<t>{ return whole; }</t>".
2391 For every reference to another grammar which was matched in the
2392 pattern, the *name used to reference that other grammar* will
2393 be bound to the value returned by its code block. Here's an
2394 example of this important distinction:
2397 var foo ::= 'a' | 'b';
2399 var baz ::= 'c' | bar { /* foo is not defined here, but bar is */ };
2402 On the last line, the identifier 'bar' serves two purposes: it
2403 pulls in the definition of the pattern *and* acts as a binder
2404 within the scope of the braces.
2406 If a reference is matched multiple times (either because it
2407 appears multiple times in the pattern or because the * or +
2408 operator was applied to it) then its name will be bound to an
2409 array containing the matches.
2413 Here is the metacircular definition of the grammar facility:
2416 grammar ::= identifier '::=' pattern (';' | '{' code '}' ';'?)
2417 identifier ::= ('a'..'z' | 'A'..'Z' | '_' | '$') (identifier | '0'..'9')*
2418 char ::= '\0x0000'..'\0xffff'
2419 literal ::= '\'' char+ '\''
2420 | '\'' char '\'' '..' '\'' char '\''
2421 pattern ::= identifier
2428 | pattern '|' pattern
2433 Copyright (C) 2004 Adam Megacz, verbatim redistribution permitted.
2434 Ibex is a trademark of Adam Megacz