X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=doc%2Freference%2Freference.xml;h=37148d6e4e650186d9c48fc08de526544594220f;hb=HEAD;hp=485010981c75b52dd9cd01793f5ea4192431b053;hpb=332129d6e1b9d55064d5edd9554bcf0fd0054a6f;p=org.ibex.core.git diff --git a/doc/reference/reference.xml b/doc/reference/reference.xml index 4850109..37148d6 100644 --- a/doc/reference/reference.xml +++ b/doc/reference/reference.xml @@ -1,44 +1,130 @@ - +
- - If you are reading the html version of this document and are - thinking of printing it out, you might be interested in the nicely - typeset produced - with LaTeX. - + + ** If you are reading the html version of this document and are ** + ** thinking of printing it out, you might be interested in the nicely ** + ** typeset produced ** + ** with LaTeX. ** + + Ibex is a software platform based on the philosophy that the most + useful systems consist of both **statically typed** and + **dynamically typed** languages, working in concert. + + + + - Statically typed languages (such as Java) are well suited for + high-performance, reliable, reusable code. Unfortunately + programs written in statically typed languages often take + longer to develop, and their commitment to a specific type + system makes interoperating with other languages cumbersome. + + - Dynamically typed languages (such as JavaScript) typically + perform poorly (due to runtime checks and inadequate static + information for optimization), tend to admit more errors (due + to less static checking), and export APIs which are not + precisely defined (due to the huge number of possible + type/method combinations). However, writing programs in + dynamically typed languages is a much more rapid process, and + the implicit coercions in such languages make interoperability + between similar languages very easy. + + + + The architectural incarnation of this philosophy is the Ibex Object + Model, a universal interface to dynamically typed languages. The + IOM serves as a common interface between statically typed languages + and dynamically typed languages both locally and over the network. - This document is a reference. It is not a - specification or a - tutorial. +
+ + The Ibex Object Model consists of three primitive types: + + + - __number__ -- a floating point number + - __string__ -- a unicode string + - __boolean__ -- either [[true]] or [[false]] + + + From these primitives, more complex structures can be built from + two aggregate types: + + + - __array__ -- a collection of objects indexed by a non-negative integer + - __hash__ -- a collection of objects indexed by objects (often strings) + + + Any of the following actions can be performed on an object: - This document does not guide the user gently through examples (as a - tutorial would), and it doesn't provide enough detail and formality - for a third party to construct a compatible re-implementation of the - Ibex Core (as a specification would). + + - __get(key)__ -- attempts to retrieve the object indexed by + [[key]]. Returns an object. - Rather, the goal of this document is to completely describe every - aspect of the environment that the Ibex Core provides to client - applications, from the bottom up. If you want to be an Ibex expert, - this is the right document to read. It is assumed that you are already - familiar with XML and with either JavaScript or ECMAscript. + - __put(key, val)__ -- attempts to add object [[val]] with key + [[key]] to an object. Does not return a value. - If you need to use or rely on some behavior you notice in the Ibex - Core, but which is not clearly defined here, please post to . + - __call(args)__ -- attempts to call the object as if it were a + function. The [[args]] value is a list of arguments. May or + may not return a value. + + + The keys of some objects may be enumerated by attempting to "call" + the object; the return value will be an array of the object's keys. + + Finally, an object may be **coerced** to any of the three + primitive types, although this coercion may fail. Objects may + also be coerced to the **bytestream** type, which represents an + unbounded stream of octets. Dynamically typed code may not + explicitly manipulate bytestreams, although it can pass objects + to statically typed code which in turn coerces those objects to + bytestreams. + Any of the above operations may **throw** an exception, which is + itself an object. + + Any entity in the statically typed world which supports these + operations may expose itself to the dynamically typed world. + Furthermore, it can expect that any values passed to it will support + all of the operations shown above. +
+ +
+ - relation to XML + - cover templates here with David's isomorphism? +
+ +
+ + The remainder of this document describes the three major + systems founded on the Ibex Object Model: + + + - The Ibex User Interface + - The Ibex Persistent Storage Service + - The Ibex Mail Server + - IbexDoc + + + Currently, all four of these systems use Java as the statically + typed language and IbexScript (a derivitave of JavaScript) as + the dynamically typed language. However, since they interact + strictly via the Ibex Object Model, either component can be + rewritten in a different language. + +
+
Ibex itself; the native code (or Java bytecode) that runs on - the client. This term does not include the Wildebeest - or the UI + the client. This term does not include the **Wildebeest** + or the **UI** A set of files (mostly XML, JavaScript, and PNG images) - bundled up in a zip archive, ending with the ".ibex" + bundled up in a zip archive, ending with the "[[.ibex]]" extension. Together, these files specify the appearance and behavior of the application's user interface. @@ -59,16 +145,16 @@ In ECMAscript, when you change the value of a property on an - object, you are putting to that property, or - writing to it. For example, the ECMAscript expression - "foo.bar = 5" puts the value 5 to the bar + object, you are **putting** to that property, or + **writing** to it. For example, the ECMAscript expression + "[[foo.bar = 5]]" **puts** the value 5 to the bar property on object foo. In ECMAscript, when you access the value of a property on an - object, you are getting that property, or - reading from it. For example, the ECMAscript - expression "return (3 + foo.bar)" gets the + object, you are **getting** that property, or + **reading** from it. For example, the ECMAscript + expression "[[return (3 + foo.bar)]]" **gets** the value of bar property on object foo and then adds 3 to it before returning the result. @@ -80,32 +166,34 @@
+
+
A user typically begins an Ibex session by clicking on a link to - an Ibex application. This link serves the {\tt launch.html} file - to the user's browser, which in turn downloads the appropriate - {\it Wildebeest} -- currently either an ActiveX Control + an Ibex application. This link serves the [[launch.html]] file + to the user's browser (1), which in turn downloads the appropriate + **Wildebeest** (2)-- currently either an ActiveX Control (Win32/MSIE), XPInstaller (Mozilla), or Signed Applet (all others). The Wildebeest downloads the appropriate core for the user's - machine and verifies its digital signature. It then launches the - core, which downloads the UI (an .ibex archive), loads it, - applies the main.t template (found in the archive), and - renders it onto the screen, running any associated JavaScript - code. + machine and verifies its digital signature (3). It then launches + the core, which downloads the UI (4), (an [[.ibex]] archive), + loads it, applies the [[main.t]] template (found in the archive), + and renders it onto the screen, running any associated JavaScript + code (5). The user interacts with the application by clicking and moving the - mouse, and by pressing keys on the keyboard. These actions trigger - fragments of JavaScript code which are designated to handle events. - This JavaScript code can then relay important information back to the - server using XML-RPC or SOAP, or it can modify the structure and - properties of the user interface to change its appearance, thereby - giving feedback to the user. + mouse, and by pressing keys on the keyboard (5). These actions + trigger fragments of JavaScript code which are designated to + handle events. This JavaScript code can then relay important + information back to the server using XML-RPC or SOAP (5), or it + can modify the structure and properties of the user interface to + change its appearance, thereby giving feedback to the user. The Ibex core quits when the last remaining surface has been destroyed. @@ -117,9 +205,9 @@ Each top-level window in an Ibex UI is called a - surface. There are two kinds of surfaces: frames, + **surface**. There are two kinds of surfaces: **frames**, which usually have a platform-specific titlebar and border, and - windows, which never have any additional platform-specific + **windows**, which never have any additional platform-specific decorations. Whenever we refer to the size or position @@ -132,25 +220,25 @@ Surfaces are not actual JavaScript objects; you cannot obtain a reference to a surface. However, each surface is uniquely identified - by its root box, described in the next section. + by its **root box**, described in the next section.
- A box is the fundamental unit from which all Ibex user + A **box** is the fundamental unit from which all Ibex user interfaces are built. Boxes can contain other boxes (referred to as - its children). Each surface has a single box associated with - it called the root box; the root box and its children (and - its children's children, and so on) form the surface's box - tree. + its **children**). Each surface has a single box associated with + it called the **root box**; the root box and its children (and + its children's children, and so on) form the surface's **box + tree**. There are three ways to think of a box: - As a rendered visualization on the screen (the "Visual Representation") + As a rendered visualization on the screen (the "**Visual Representation**") - As a JavaScript object (the "Object Representation") + As a JavaScript object (the "**Object Representation**") As as an XML tag (the "XML Template Representation"). @@ -164,19 +252,18 @@ of Ibex.
-
A template (discussed in the next section) is an XML file which acts as a blueprint for constructing a tree of boxes. We call this - construction process applying, since unlike - instantiation in object-oriented programming systems, you - always apply a template to a pre-existing box, and you can apply - multiple templates to the same box. + construction process **applying**, since unlike **instantiation** in + object-oriented programming systems, you always apply a template to + a pre-existing box, and you can apply multiple templates to the same + box. Each XML tag corresponds to a single box, or to another template - which will be applied to that box. For example, a scrollbar + which will be applied to that box. For example, a [[scrollbar]] template, when applied, will construct a tree of boxes which has the visual appearance and behavior of a scrollbar. @@ -188,11 +275,11 @@ applying a template is complete, Ibex completely forgets the fact that it has applied a particular template to a particular box. One consequence of this approach is that if you think of templates as - classes, then Ibex has no equivalent for Java's instanceof + classes, then Ibex has no equivalent for Java's [[instanceof]] operator. Each template is an XML document whose root element is - <ibex>. Here is a sample template file: + [[<ibex>]]. Here is a sample template file:
   
@@ -219,19 +306,19 @@
   
The following two namespaces are predefined and need not be declared - using xmlns: + using [[xmlns]]: - http://xmlns.ibex.org/meta + [[http://xmlns.ibex.org/meta]] - This will be referred to as the "meta namespace" in the + This will be referred to as the "[[meta]] namespace" in the remainder of this document. - http://xmlns.ibex.org/ui + [[http://xmlns.ibex.org/ui]] - This will be referred to as the "ui namespace" in the + This will be referred to as the "[[ui]] namespace" in the remainder of this document. @@ -240,7 +327,7 @@
- If the root <ibex> element contains any non-whitespace + If the root [[<ibex>]] element contains any non-whitespace text content, this text is interpreted as JavaScript code and is executed the first time the template is referenced. This code is executed in a fresh scope containing two predefined properties: @@ -250,23 +337,22 @@ - A reference to this template's static object, which is - initially null. The static object can be accessed (read + A reference to this template's **static object**, which is + initially [[null]]. The static object can be accessed (read and written) from both static scripts as well as instance scripts in a particular template. FIXME - -
+
Any immediate children of the root element which are in the - meta namespace are treated as metadata and are exempted from + [[meta]] namespace are treated as metadata and are exempted from the rest of the template application process. Currently only one type of metadata element is defined: - <meta:doc>: structured documentation for the + [[<meta:doc>]]: structured documentation for the template. @@ -275,7 +361,7 @@
All remaining children of the root element are treated as elements - to be applied to the box, in the order in which they appear + to be **applied** to the box, in the order in which they appear in the file using the following procedure. - To apply an XML tag x to a box b, perform the following + To apply an XML tag [[__x__]] to a box [[__b__]], perform the following operations, in this order: - Allocate a fresh scope s whose parent scope is - b. + Allocate a fresh scope [[__s__]] whose parent scope is + [[__b__]]. - Process each child element or text segment of x + Process each child element or text segment of [[__x__]] in the order they appear in the document: - Treat each text segment t as JavaScript code - and execute it with s as the root scope. + Treat each text segment [[__t__]] as JavaScript code + and execute it with [[__s__]] as the root scope. - For each child element x' of x: + For each child element [[__x'__]] of [[__x__]]: - Create a new box b'. + Create a new box [[__b'__]]. - If the name of tag x' is not - "box" in the ui namespace, prepend the + If the name of tag [[__x'__]] is not + "[[box]]" in the [[ui]] namespace, prepend the tag's namespace identifier uri (if any) to the name of the tag, and use the result as a key to retrieve a property from the root stream (defined later). Interpret the resulting stream as a template and apply - that template to b'. + that template to [[__b'__]]. - (recursively) apply x' to b'. + (recursively) apply [[__x'__]] to [[__b'__]]. - If x' has an id attribute, declare a variable - in s whose name is the value of the id - attribute, prefixed with the $ character, and whose - value is b' + If [[__x'__]] has an [[id]] attribute, declare a variable + in [[__s__]] whose name is the value of the [[id]] + attribute, prefixed with the [[$]] character, and whose + value is [[__b'__]] - Copy any $-variables created during the application - of x' into scope s. + Copy any [[$]]-variables created during the application + of [[__x'__]] into scope [[__s__]]. - Append b' as the last child of b. + Append [[__b'__]] as the last child of [[__b__]]. - Apply any attributes on x to b, except for - id. Since XML specifies that the order of attributes + Apply any attributes on [[__x__]] to [[__b__]], except for + [[id]]. Since XML specifies that the order of attributes cannot be significant, Ibex processes attributes in alphabetical order by attribute name. For example, if - x has the attribute foo="bar", then the - equivalent of the statement B.foo="bar"; will be + [[__x__]] has the attribute [[foo="bar"]], then the + equivalent of the statement [[B.foo="bar";]] will be performed, with the following exceptions: If the value portion of the attribute is the string - "true", put the boolean true. If the - value is "false", put the boolean false. + "[[true]]", put the boolean [[true]]. If the + value is "[[false]]", put the boolean [[false]]. If the value is a valid ECMAscript number, put it as a number (instead of a string). - If the value begins with a dollar sign ($), + If the value begins with a dollar sign ([[$]]), retrieve the value of the corresponding variable in - s and use that value instead. + [[__s__]] and use that value instead. - If the value begins with a dot (.), prepend the + If the value begins with a dot ([[.]]), prepend the attributes' namespace identifier uri (if any) and interpret the remainder as a property to be retrieved from the root stream (defined later). @@ -379,7 +465,7 @@ - The last two steps are referred to as the initialization of the + The last two steps are referred to as the **initialization** of the node. There are two important aspects of this ordering to be aware of: @@ -389,8 +475,8 @@ certain that they will never wind up accessing a box when it is in a partially-initialized state. - Attributes are applied after scripts are run so that - the attributes will trigger any traps (defined later) + Attributes are applied **after** scripts are run so that + the attributes will trigger any **traps** (defined later) placed by the script. @@ -400,74 +486,323 @@
-
+
-
- - Each box occupies a rectangular region on the surface. The visual - appearance of a surface is created by rendering each box in its tree. - Unless the clip attribute is false, each box will - clip its childrens' visual representations to its own, so that the - children appear "confined to" the parent. Children are rendered after - their parents so they appear "on top of" their parents. - - Each box has two major visual components, each with subcomponents: + FIXME: needs way, way, way more diagrams of nonrectangular boxes. + + Each box occupies a region on the surface. The visual + appearance of a surface is created by rendering each box in its + tree. Unless the [[clip]] attribute is [[false]], each box will + clip its childrens' visual representations to its own, so that + the children appear "confined to" the parent. Children are + rendered after their parents so they appear "on top of" their + parents. - FIXME: diagram + + + Until now we've tactily assumed that boxes are rectangular. In + fact, unlike its predecessor (XWT), Ibex boxes can be **any + shape at all**. We refer to the outline of a box as its path, + which may be composed of lines and curves (arcs and splines). + If the path is not set (or set to [[null]]), the box's path is + **implicitly** a rectangle. + + A key step in understanding how Ibex works, and understanding + how operations on rectangular boxes generalize to arbitrary + boxes is to realize that "the path **is** the box". Just as a + rectangular box clips its children to the inside of the + rectangle, a circular box will clip its children to the inside + of the circle. + + In fact, Ibex's integration of vector graphics with + constraint-based user interface layout runs quite deep -- boxes + which "contain" text are actually boxes whose outline path + **is** the actual letters of the text. This means that you can + assign children to a text-shaped box, and the children's + appearance will be cliped to the **inside** of the text letters. + + The only time rectangular and non-rectangular boxes act + differently is when box packing takes place; when packing boxes, + Ibex only looks at the **bounding box** of a path (the smallest + rectangle that completely encloses the box's path). In the case + of rectangular boxes (which have not been rotated or sheared), + this bounding box happens to be exactly the same as the box's + path. So Ibex is actually treating these boxes the same, but + the chosen treatment favors rectangular boxes. + +
+ + The appearance of a box consists of three visual elements: its + path, stroke, and fill. - - - A box's path consists of zero or more lines and curves. - The path may be filled with a color, gradient, or texture, and - may be stroked with a line of a given thickness and color. If - the path is not specified, it defaults to the perimiter of the - box. [Note: Vector Graphics support (including the ability - to set the path property to anything other than the - default) is currently not implemented]. - - A path also has: - - - an associated strokecolor, which is a color - - an associated strokewidth, which is a number - specifying the width of the stroke. [Note: Vector - Graphics support (including the strokewidth - property) is currently not implemented] - - a fill, which is either a color, gradient, or - texture - - - - - - Each box also has a single line of text, whose - appearance is determined by its: - - - associated font, which can be any font supported by - the - library. - - an associated fontsize in pixels - - an associated textcolor - - - - These eight components plus the size of a box fully specify its - appearance. Every single box you see in Ibex is drawn only on the - basis of these components and its size. -
+ + A box's [[path]] consists of zero or more contours, each of + which consists of one or more lines, bezier curves (cubic or + quadradic), or generalized elliptic arcs. The grammar and + feature set supported are identical to that specified in . + + One of the most common sources of frustration when working with + text representations of vector paths, or programs that manipulate + them, is making a mistake when setting a transform which causes + the entire path to be off the screen. Since no part of the path + is visible, you have no idea which direction it went! To minimize + the chance of this happening, and generally make dealing with + vectors a more enjoyable experience, Ibex always **recenters** a + path. When you set a box's path (either by writing to its + [[path]] or [[text]] properties), Ibex translates the entire path + so that it is lined up with the X and Y axes, as close to the + origin as possible, in the positive-X, positive-Y quadrant. Ibex + will note this translation by setting the box's [[transform]] to + the transformation used to do this. If you do not desire this + behavior, just set the [[transform]] back to the identity + transform. + + + + The color with which to stroke the path. Ibex paths may + only be stroked with a single color, solid line (not + dashed), of "hairline width" (meaning that the line is never more than one + antialiased pixel wide no matter what magnification it is + viewed at). + + This property can be set to a 5-character hex string + ([[#RGB]]), 7-character hex string ([[#RRGGBB]]), + 9-character hex string ([[#AARRGGBB]]), specifying the box's + hexadecimal color. Any other string is compared against the + colors (the same set of color names supported + by SVG). If this property is set to [[null]], the stroke + color will be set to clear ([[#00000000]]). + + Other vector formats (notably SVG and PDF) support "thick" + lines, dashed lines, lines stroked with a gradient or + texture, and an assortment of special caps and joins for + these thick lines (hairline lines do not need joins or + caps). Fortunately, all of these constructs can be + converted into **filled** paths rather easily, making it + possible for Ibex to support the same functionality with a + much simpler API (and more efficient rendering engine). + + + + The graphic element with which to fill the path. This + property can be set to any of the values specified for + [[stroke]], as well as to a texture (an image) or a + gradient. Paths which self-intersect are filled according + to the SVG guidelines. + + When an image (texture) is written to this property, the + box's [[minwidth]] and [[minheight]] properties will be + automatically set to the dimensions of the image (they can + be changed later if desired). + +
+ +
+ + Ibex treats text exactly the same way it treats other paths. + Writing to the [[text]] property actually sets the box's path to + the outline of the rendered form of the text, and text is + subject to the same rotation, shearing, and scaling + transformations as all other boxes. You can even **read back** + the curves from which the text is composed by reading from the + [[path]] property (the string returned will be in SVG Path + syntax), modify it, and write it to the [[path]] property of + another box. + + + The box's text; writing [[null]] to this property sets it to + [[""]]. In order to help eliminate common chores when working + with text, Ibex will automatically take the following actions + when you write to the [[text]] property: + + + + The text is converted to curves using the Freetype library, + and the resulting curve becomes the box's path. + + If the box's [[strokecolor]] is [[null]], it is set to black + ([[#FF000000]]). When first created, a box has an invisible + stroke; automatically setting the stroke to a visible color + helps eliminate confusing errors. You can change the stroke + color back to clear after writing to the [[text]] property. + + The box's [[aspect]] property is automatically set to the + correct aspect ratio for the chosen string in the chosen + font. This ensures that resizing will not warp the text. + + + + Fonts are rendered using the [[stroke]] assigned to the box, + using the font assigned to the [[font]] property. When an + object is written to this property, it is coerced to a stream which is interpreted using + the , and the resulting font is used to render the box's + [[text]]. + + To choose the size of a font, just set the box's [[height]] + property to the desired height **in pixels**. Conversion + functions from points to pixels are available. + +
+ +
+ The [[transform]] property allows the user to specify an + arbitrary affine transformation to be applied to the box's path, + text, and children. The syntax and features supported are + identical to those described in , and include rotation, shearing, scaling, and + translation. + + + FIXME + + + One tricky part about transformations is their interaction with + box packing and dimension properties. A box's size properties + (such as [[minwidth]] or [[height]]) are **always** measured in + the box's own coordinate space (ie after applying the box's + [[transform]]). This means that the sum of the [[width]]s of a + box's children may not be equal to the parent box's [[width]], + even if the children appear (on screen) to completely fill its + width. + + One other consequence of combining transformations with + constraint-based layout is that when a box is rotated, its width + and height are no longer completely independent (remember, the + box's width is measured in the rotated coordinate space). If a + box is turned at a 45 degree angle and then forced into a space + 10 pixels wide, enlarging the box's width will force a reduction + in its height (in order to cram it in the 10 pixel space). In + situations like this, Ibex will first look to the box's + [[aspect]], if explicitly set, and obey that. If the box's + [[aspect]] is unspecified, Ibex will use the ratio between the + box's [[minwidth]] and [[minheight]] to guide the tradeoff. If + either of these properties is [[0]], Ibex will simply attempt to + make the ratio as close to [[1:1]] as possible. + + When we talk about a box's **bounding box**, we are referring to + the smallest rectangle in the **parent's** coordinate space + which completely encloses the child box's path. This is the + only time we will deal with the size of a child using a + coordinate space other than its own. +
-
+
+ + We will cover the layout algorithm in detail in the next section, + but we introduce the properties at play here and give an intuition + about their purpose. + + + The layout strategy for this box. If set to [[true]], the + box occupies no cells and is laid out independently of its + siblings. + + + + This property controls the strategy Ibex uses for changing the + box's width and height in response to layout constraints. + + If [[zoom]] is set to [[false]] (the default), then the box's + [[path]] will be altered by multiplying all the vertices by a + scaling factor in order to make the path's bounding box meet + the required constraints. The box's [[transform]] will not be + affected, and the scaling of the box's children will not be + affected. + + If [[zoom]] is set to [[true]], the box's [[path]] will not be + altered in response to layout constraints; rather, its + [[transform]] will be altered in order to "zoom in" or "zoom + out" and bring all of the path's vertices within the desired + region. Since the box's [[transform]] also applies to its + descendants, they too will be magnified or reduced. + + + + If set to [[true]], this box will shrink + (horizontally/vertically/both) to the smallest size allowed by + its children and the bounding box of its path. + + + + If the box is a root box, writing to these properties moves + the surface; reading from them returns the position of the + surface. + + On non-root boxes, writing to these properties is a shorthand + for adding a [["translate(x, y)"]] to the box's [[transform]]. + Reading from these properties will return FIXME. + + + + The desired minimum width and height. See the [[zoom]] + property for a description of how the box is altered to meet + these constraints. + + + + The desired maximum width and height. See the [[zoom]] + property for a description of how the box is altered to meet + these constraints. + + + + When read, this is the current (width/height) of this box. + Writing to this property is equivalent to writing to + **both** the minimum and maximum (width/height). + + + + The number of (columns/rows) in which to lay out the children of this + box. If set to zero, the number of (columns/rows) is unconstrained. + Either [[rows]] or [[cols]] must be zero. If + [[0]] is written to [[cols]] when [[rows]] is + [[0]], the write is ignored. If a nonzero value is + written to [[cols]] when [[rows]] is nonzero, + [[rows]] is set to [[0]], and vice versa. + + + + The number of (columns/rows) that this box spans within its parent. + + + + The width-to-height ratio constraint for this box; can be set + either as a floating point number ([[0.5]]) or a ratio + ([["1:2"]]). Setting this to [[0.0]] disables the ratio + constraint. + + Note packed boxes always **shrink** in order to satisfy aspect + constraints, while unpacked boxes always **grow** in order to + satisfy them -- even if this means growing larger than the box's + parent. + + + + If set to [[false]], this box will be rendered as if its + width and height were zero. If this is a root box, the + associated surface will be hidden. + + When reading from this property, the value [[false]] will + be returned if this box **or any of its ancestors** is not + visible. Thus it is possible to write [[true]] to a box's + [[visible]] property and then read back [[false]]. + +
+ +
+ +
The size and position of every box is determined by its properties, its childrens' sizes, and its parent's size and position. Box layout and rendering happens in four phases: - packing, constraining, placing, and - rendering. The Core is careful to only perform a phase on + **packing**, **constraining**, **placing**, and + **rendering**. The Core is careful to only perform a phase on a box if the box has changed in a way that invalidates the work done the last time that phase was performed. The packing and constraining phases are performed in a single traversal of the @@ -477,75 +812,58 @@ For brevity, the rest of this chapter deals only with width and columns. Height and rows is treated identically and independently. - Also, it is important to note that the term minimum width is - not the same thing as the property minwidth, although they + Also, it is important to note that the term **minimum width** is + not the same thing as the property [[minwidth]], although they are closely related. - - - When the user resizes a window, Ibex changes the root box's - maxwidth and maxheight to match the size chosen by - the user and then determines the root box's size using the same sizing - rules it uses for other boxes. - - Ibex will always attempt to prevent the - user from making the surface smaller than the root box's - minwidth and minheight. If the hshrink or - vshrink flag is set, Ibex will try to prevent the user from - resizing the surface at all. However, not all platforms give Ibex - enough control to do this. - - - - - When talking about positioning, we will often refer to the - alignment point. - - If the align property is "center", then the - alignment point is the center of the box. - - If the align property is "topleft", - "bottomleft", "topright", or - "bottomright", then the alignment point is - corresponding corner of the box. - - If the align property is "top", - "bottom", "right", or "left", then - the alignment point is middle of the corresponding edge of the - box. - - When positioning a child box, the alignment point is determined by - the parent's align property. When rendering a - visual element (a texture, path, or text string) within a box, the - alignment point is determined by the box's own align - property. - - A simple way to think about this is that whenever there are two boxes - involved in the decision, you should use the parent's alignment point. -
- A grid of cells is created within the parent. If the - parent's cols property is set to 0, the cell grid has an - infinite number of columns. Either cols or rows + A grid of **cells** is created within the parent. If the + parent's [[cols]] property is set to 0, the cell grid has an + infinite number of columns. Either [[cols]] or [[rows]] must be zero, but not both. - If a child's visible property is false, it does - not occupy any cells (and is not rendered). Otherwise, each child - occupies a rectangular set of cells child.colspan cells - wide and child.rowspan cells high. + + + A box's target region is the portion of its parent which the + layout algorithm has determined that the box should occupy. A + box's target region is determined mainly by the value of its + [[pinned]] property: + + + If a box's [[pinned]] property is [[null]], it is said to be + "unpinned" or "not pinned". In this case, the box's target + region will be the set of cells in its parent which it + occupies. + + If a box's [[pinned]] region is set to some other box, then + this box's target region will be the projection of that + other box's actual dimensions and position, projected onto + this box's parent. The net effect is that the pinned box + will "track" the size and position of the box it is pinned + to. A box may not be pinned to one of its descendants, nor + may boxes be pinned in a cycle (A is pinned to B, B is + pinned to C, and C is pinned to A). + + + If a child's [[visible]] property is [[false]], it does not + occupy any cells (and is not rendered). If a box's [[pinned]] + property (described below) is non-[[null]], it does not occupy + any cells and is exempt from the packing process. Otherwise, + each child occupies a rectangular set of cells [[child.colspan]] + cells wide and [[child.rowspan]] cells high. The Core iterates over the cells in the grid in the following - order: if rows is 0, the Core iterates across each column + order: if [[rows]] is 0, the Core iterates across each column before proceeding to the next row; otherwise rows come before - columns. At each cell, the Core attempts to place the first - remaining unplaced child's top-left corner in that cell - (with the child occupying some set of cells extending down and - to the right of that cell). If the parent has a fixed number of - columns and the child's colspan exceeds that limit, the - child is placed in column zero regardless, but only occupies the - available set of cells (it does not "hang off the end" of the - box). + columns. At each cell, the Core attempts to place the **first + remaining unplaced, packed child's** top-left corner in that + cell (with the child occupying some set of cells extending down + and to the right of that cell). If the parent has a fixed + number of columns and the child's [[colspan]] exceeds that + limit, the child is placed in column zero regardless, but only + occupies the available set of cells (it does not "hang off the + end" of the box).
       
@@ -555,286 +873,169 @@
           
           
       
-
-
-
       
+ Each box's minimum width is computed recursively as the + maximum of: - Each box's minimum width is computed recursively as the - maximum of: - - - Its minwidth + + Its [[minwidth]] - The width of the box's text (after applying the - box's transform) [Note: Vector Graphics support - (including the transform property) is currently not - implemented]. + The width of its [[path]] - The width of the box's path (after applying the box's - transform) if the box is packed. - - The width of the bounding box enclosing the box's cells. - - - The minimum width of each cell is computed as the minimum - width of the box occupying it divided by the box's - colspan. - - If a box's hshrink property is set to - true, the box's maximum width is the same as its - minimum width; otherwise it is the box's - maxwidth. - - The maximum width of each cell is the maxwidth of - the box occupying it divided by the box's - colspan. + The sum of the widths of the bounding boxes enclosing its + children, when those children are sized to **their own** + minimum widths. + + The box's minimum **height** multiplied by its [[aspect]], + if its aspect is not [[0]] (unspecified). + + + If a box's [[hshrink]] property is set to + [[true]], the box's maximum width is the same as its + minimum width; otherwise it is the box's + [[maxwidth]].
- - Each column's actual width is set to the maximum - minimum width of all the cells in that column. - NOTE: although a column or row can be sized smaller - than its "minimum width" or larger than its "maximum width", a - box will never be smaller than its minwidth or - larger than its maxwidth. + + + + Once the box's size and the size and position of its target + region have been computed, the box is placed relative to its + **target origin**, which is determined by by the [[origin]] + property: + + + Determines which corner of the box's target region should be + treated as the origin for layout purposes. + + If the [[origin]] property is "[[center]]", then the + target origin is at the center of the target region. - Each column's maximum width is the largest maximum width of - the cells in that column, but no smaller than the column's - minimum width. - - A value k is chosen such that when each column's width - is set to min(maximum width, max(minimum width, k)), - the sum of all the column widths equals the parent's width. - If no such value exists, positive or negative infinity is used - (whichever is appropriate). Each column is then set to the - width dictated by k. + If the [[origin]] property is "[[topleft]]", + "[[bottomleft]]", "[[topright]]", or "[[bottomright]]", then + the target origin is at the corresponding corner of the + target region. - Next, the rows and columns are positioned within the parent - box. The rows and columns are transformed according to the - parent's transform property [Note: Vector Graphics - support (including the transform property) is currently - not implemented]., and the bounding box of the resulting - cells are placed such that the cells' alignment point - coincides with the parent's alignment point (both alignment - points are determined by the parent's align property). - - + If the [[origin]] property is "[[top]]", "[[bottom]]", + "[[right]]", or "[[left]]", then the target origin is middle + of the corresponding edge of the target region. + - Packed boxes: Each packed box's actual position - and size is then set to the aggregation of the actual sizes of - the cells it spans. If this size exceeds the box's maximum - width, the box is sized to its maximum width and centered - horizontally within the space occupied by its cells. - - Non-packed boxes: each non-packed box is transformed - according to the parent's transform property and then - positioned so that its alignment point is (child.x, - child.y) pixels from the parent's alignment point (both - alignment points are determined by the parent's align - property). - -
-
- -
+ + Determines the offset from the box's origin at which it will + be placed. + - Boxes are rendered in a depth-first, pre-order traversal. Note that - this may cause a non-packed box to overlap its siblings. - - - - If the box's transform property is non-null, the - coordinate space is transformed accordingly for the rest of - this phase and for the rendering of all children. [Note: - Vector Graphics support (including the transform - property) is currently not implemented]. - - If the box is packed and has a non-null path, the - path is translated such that the alignment point of the path's - bounding box coincides with the box's alignment point (both - alignment points are determined by the box's align - property). - - If a box has a path, that path is filled with the color, - gradient, or image specified by the fill property and - stroked with the color and width specified by the - strokecolor and strokewidth properties. - - If the box has a non-null text attribute, - the text is rendered in font with size - fontsize and color textcolor. The text is - then translated such that the alignment point of the text's - bounding box coincides with the box's alignment point (both - alignment points are determined by the box's align - property). - - The box's children are rendered (pre-order traversal). + If the box's [[hshrink]] property is not set, it is expanded to + its maximum width, but no larger than its parent's width. - - -
+ Finally, if the child has a nonzero [[aspect]], one of its + dimensions (either width or height) will **grow** in order to + ensure that [[width == height * aspect]]. This may cause the + child to exceed the paren't size. + + + First, the coordinate space in which the child is positioned is + translated so that the origin coincides with the + corner/edge/center of the box's parent corresponding to the + child's [[align]] property. The child's [[transform]] attribute + is applied to the coordinate space, and the child is positioned + in this transformed space with its aligment point at the origin. + + The following diagram may be helpful: + + FIXME: diagram + + + + Thoughout this section, when we refer to the [[minwidth]], + [[maxwidth]], or minimum width of a child box, we are referring + to the corresponding dimension of the child's **bounding box** + -- the smallest rectangle **in the parent's coordinate space** + that completely encloses the child's path. + + Ibex formulates a set of constraints for placing a box's + **packed** children as follows: + + + A box's width can be no greater than the sum of the + columns it occupies + + The sum of a set of colums cannot be smaller than the + minimum width of a box that spans them. + + The sum of the widths of the parents' columns will be at + least as large as the parent's width is (but possibly + larger). + + + Subject to these two unbreakable constraints, Ibex searches for + a solution which will optimize the following three goals, + prioritized from most important to least important: + + + (__Most Important__) The sum of all columns will be a close + to the parent's with as possible (ie as small as possible) + + Ibex will attempt to make a set of columns no wider than + the [[maxwidth]] of a box spanning them. + + Ibex will attempt to make all + columns the same width. (**least important**) + + + Each packed box is then placed within the set of cells that it + spans. Usually the box will exactly fill this rectangle; if it + does not (due to [[maxwidth]], minimum width, or aspect + constraints), the box's will be placed so that its alignment + point coincides with the alignment point of that rectangle of + cells. + + + + When the user resizes a window, Ibex changes the root box's + [[maxwidth]] and [[maxheight]] to match the size chosen by + the user and then determines the root box's size using the same sizing + rules it uses for other boxes. + + Ibex will always attempt to prevent the + user from making the surface smaller than the root box's + [[minwidth]] and [[minheight]]. If the [[hshrink]] or + [[vshrink]] flag is set, Ibex will try to prevent the user from + resizing the surface at all. However, not all platforms give Ibex + enough control to do this. +
+
+
Each box is a full-fledged ECMAscript object, and can store key-value pairs as properties. Some of these keys have special meaning, which will be explained later. Each box's numeric - properties hold its child boxes. - -
- - Every box has several special properties which control how it is - drawn. In general, if you put an - invalid value to a special property, no action will be taken -- the - put will be ignored. - - - - If the value is a 5-character hex string (#RGB), - 7-character hex string (#RRGGBB), 9-character hex - string (#AARRGGBB), the box's stroke color will be set - to that color. - - If the value is one of the colors (the same set of color names - supported by SVG), the stroke color be set to that color. - - If the value is null, the stroke color will be set - to clear (#00000000). - - - - The width (in pixels) to stroke the path with. - - - - This property can be set to any of the values specified for - strokecolor. - Alternatively, if the value written is an object, its stream - will be read and interpreted as a PNG, GIF, or JPEG image, - which will become the texture for this box, and the box's - minwidth and minheight properties will be - automatically set to the dimensions of the image. - - - - The box's path. The grammar and feature set supported are - identical to that specified in . - - - - The box's text; writing null to this property sets it - to "". - - - - The color in which to render the font; accepts the same values as strokecolor. - - - - When an object is written to this property, its stream is read - using the , - and the resulting font is used to render the - box's text. - - - - The size (in points) to render the text. - - -
- -
- - - If set to true, this box will shrink - (horizontally/vertically/both) to the smallest size allowed by - its children and the bounding box of its path. - - - - If the box is a root box, this is the (x/y)-coordinate of the - surface; otherwise it is the distance between the parent's - alignment point and this box's alignment point. - - - - The desired minimum width and height. - - - - The desired maximum width and height. - - - - When read, this is the current (width/height) of this box. - Writing to this property is equivalent to writing to - both the minimum and maximum (width/height). - - - - The number of (columns/rows) in which to lay out the children of this - box. If set to zero, the number of (columns/rows) is unconstrained. - Either rows or cols must be zero. If - 0 is written to cols when rows is - 0, the write is ignored. If a nonzero value is - written to cols when rows is nonzero, - rows is set to 0, and vice versa. - - - - The number of (columns/rows) that this box spans within its parent. - - - - Determines the box's alignment point for positioning its text, - texture, path, and children. - - - - If set to false, this box will be rendered as if its - width and height were zero. If this is a root box, the - associated surface will be hidden. - - When reading from this property, the value false will - be returned if this box or any of its ancestors is not - visible. Thus it is possible to write true to a box's - visible property and then read back false. - - - - The layout strategy for this box. If set to true, the - box occupies no cells and is laid out independently of its - siblings. - - -
+ properties hold its **child boxes**.
Writing to this property sets the box's redirect target. This property cannot be read from, and can only be written to if - the value being written is a descendant of the current + the value being written is a **descendant** of the current value. If a box has a non-null redirect target, reads and writes to any of the other properties in this section will be forwarded to the redirect target. - The redirect attribute is very useful for hiding the + The [[redirect]] attribute is very useful for hiding the internal structure of a widget, and for allowing widgets to act as "smart" containers for other widgets. For example, a menu widget might have an invisible child as its redirect target; this way, when boxes @@ -843,24 +1044,24 @@ - The nth child of box b can be accessed by reading from - b[n]. The nth child can be removed by writing - null to b[n] (the child will become parentless). A - new child can be inserted before the nth child by - writing it to b[n]; if the value written is already a child of - b, it will be removed from b first. It is important + The **n**th child of box [[b]] can be accessed by reading from + [[b[n]]]. The **n**th child can be removed by writing + [[null]] to [[b[n]]] (the child will become parentless). A + new child can be inserted **before** the **n**th child by + writing it to [[b[n]]]; if the value written is already a child of + [[b]], it will be removed from [[b]] first. It is important to note that this behavior is different from ECMAscript arrays -- - writing a non-null value to b[n] does not eliminate - the nth child; it merely shifts it over one position. - Note: Unlike most JavaScript objects, enumerating a Box's - properties with the JavaScript for..in construct will - enumerate only the box's children and not any other properties. + writing a non-[[null]] value to [[b[n]]] does not eliminate + the **n**th child; it merely shifts it over one position. + __Note:__ Unlike most JavaScript objects, enumerating a Box's + properties with the JavaScript [[for..in]] construct will + enumerate **only** the box's children and not any other properties. - If true, the visual representation of this box's + If [[true]], the visual representation of this box's children will be clipped to the boundaries of this box. - Note: setting this property to false imposes a + __Note:__ setting this property to [[false]] imposes a substantial performance penalty. @@ -870,9 +1071,8 @@ - FIXME If this box has a parent, this property returns - parent.surface; otherwise it returns null. + [[**parent**.surface]]; otherwise it returns null. This property is a simple building block that the widget library uses to implement more complex functionality such as focus control and popups. @@ -884,29 +1084,29 @@ The shape that the cursor should take when inside this - box. Valid values are: "default" , "wait", - "crosshair", "text", "hand", and - "move", as well as resizing cursors"east", - "west", "north", "south", - "northwest", "northeast", - "southwest", and "southeast". Note that on + box. Valid values are: "[[default]]" , "[[wait]]", + "[[crosshair]]", "[[text]]", "[[hand]]", and + "[[move]]", as well as resizing cursors"[[east]]", + "[[west]]", "[[north]]", "[[south]]", + "[[northwest]]", "[[northeast]]", + "[[southwest]]", and "[[southeast]]". Note that on some platforms, resize cursors for opposite directions (such - as northwest and southeast are the + as [[northwest]] and [[southeast]] are the same). - If a box's cursor is null, its parent's cursor will + If a box's cursor is [[null]], its parent's cursor will be used. If the root box's cursor is null, the - "default" cursor will be used. + "[[default]]" cursor will be used. Reading from this property will return the parent scope used - to execute the block of the template + to execute the [[]] block of the template in which the currently-executing code resides. Returns a reference to the box itself. - If null is written to this property, and this box is + If [[null]] is written to this property, and this box is the root box of a surface, the box will be detached and the surface destroyed. If this box has a parent, it will be detached from its parent. @@ -914,95 +1114,309 @@ This property is actually a function; invoking - parent.indexof(child) will return the numerical index - of child in parent if child is a - child of parent (or parent's redirect - target), and -1 otherwise. Writing to this property + [[parent.indexof(child)]] will return the numerical index + of [[child]] in [[parent]] if [[child]] is a + child of [[parent]] (or [[parent]]'s redirect + target), and [[-1]] otherwise. Writing to this property has no effect. This property is actually a function; invoking - box.distanceto(otherbox) will return an object with two - properties, x and y, containing the horizontal + [[box.distanceto(otherbox)]] will return an object with two + properties, [[x]] and [[y]], containing the horizontal and vertical distance between the two boxes (negative if - otherbox is to the left of / above box). This + [[otherbox]] is to the left of / above [[box]]). This can be used to determine the relative placement of two boxes on different branches of the box tree.
-
- - The following special properties are only meaningful on the root box - of a surface. - - - The value true is put to this property on the root box - when the surface gains the input focus, and false when - the surface loses the input focus. Reading from this value will - return true if the surface is focused and false - if it is not. Putting true to this property will - not cause the surface to "steal" the input focus from other - windows. - - - - The value true is put to this property on the root box - when the surface is maximized, and false when the surface - is un-maximized. Reading from this value will return true - if the surface is maximized and false if it is - not. Putting true to this property will maximize the - window, and putting false to this property will - unmaximize the window. - Note that not all platforms support maximization. - - - - The value true is put to this property on the root box - when the surface is minimized, and false when the surface - is unminimized. Reading from this value will return true - if the surface is minimized and false if it is - not. Putting true to this property will minimize the - window, and putting false will unminimize it. - - - - When the user attempts to close a surface, the value - true will be put to this property. Scripts may trap - this property to prevent the window from closing. Putting the - value - true to this property on a root box has the same - effect as putting null to the thisbox - property. - - - - The surface's icon. This is usually displayed on the titlebar of a - window. The value should be an object whose stream is a PNG image. Note - that not all platforms support this property. - - - - The surface's titlebar text. Note that not all platforms support - this property. Only ASCII characters 0x20-0x7F are permitted. - +
+ + The following special properties are only meaningful on the root box + of a surface. + + + The value [[true]] is put to this property on the root box + when the surface gains the input focus, and [[false]] when + the surface loses the input focus. Reading from this value will + return [[true]] if the surface is focused and [[false]] + if it is not. Putting [[true]] to this property will + **not** cause the surface to "steal" the input focus from other + windows. + + + + The value [[true]] is put to this property on the root box + when the surface is maximized/minimized, and [[false]] when + the surface is un-maximized/minimized. Reading from this value + will return [[true]] if the surface is maximized/minimized and + [[false]] if it is not. Putting [[true]] to this property will + maximize/minimize the window, and putting [[false]] to this + property will unmaximize/unminimize the window. + + Note that not all platforms support maximization. + + + + When the user attempts to close a surface, the value + [[true]] will be put to this property. Scripts may trap + this property to prevent the window from closing. Putting the + value + [[true]] to this property on a root box has the same + effect as putting [[null]] to the [[thisbox]] + property. + + + + The surface's titlebar text and icon. If a string is written + to this property, the surface's titlebar text is set to that + string; if a stream yielding an image is written, the + surface's icon is set to that image. Note that not all + platforms support this property. Only ASCII characters + 0x20-0x7F are permitted. + + +
+ +
+ + +
+ + Every execution of the Event Context begins with an event, which + consists of a key/value pair, and a mouse position, which consists of + an x and y coordinate. The possible keys are [[_Press[1-3]]], + [[_Release[1-3]]], [[_Click[1-3]]], [[_DoubleClick[1-3]]], + [[_Move]], [[_KeyPressed]], and [[_KeyReleased]]. + + Here are two example events: + + An event is triggered by writing the key to the value on a box. This + triggers any trap handlers which may be present. Once these handlers + have executed, Ibex figures out which child of the current box contains + the mouse (taking into account that some boxes may cover up others) + and writes the key and value to that box. If none of the box's + children contain the mouse position, Ibex removes the leading + underscore from the key name and writes the value to + **that** property. Once all the traps on that property have + executed, the value is written to the box's parent. + + Intuitively, Ibex delivers the underscored event to every box from the + root to the target, and then delivers the non-underscored event to + that same set of boxes in reverse order. So the event travels down + the tree to the target, and then back up to the root. The following + example prints out "first second third fourth" in that order. + +
+    
+        _Press1 ++= function(b) { ibex.log.info("first"); }
+         Press1 ++= function(b) { ibex.log.info("fourth"); }
+        
+          _Press1 ++= function(b) { ibex.log.info("second"); }
+           Press1 ++= function(b) { ibex.log.info("third"); }
+        
+    
+    
+ + In general, you should use the **non-underscore** names to respond + to user input and use the underscored names when you want to override + child boxes' behavior or route events to particular boxes (for + example, when implementing a focus protocol). This is why the + underscored elements are delivered to parents before children (so + parents can override their childrens' behavior), but non-underscored + events are delivered to children before parents (since, visually, a + mouse click is usually "intended" for the leaf box underneath the + cursor). + + + + At any point in this sequence, a trap handler can choose not to + cascade (by returning [[true]] from the trap handler function). + This will immediately cease the propagation of the event. This is how + you would indicate that an event has been "handled". + + + + Ibex uses the following events to notify a box about changes that + only matter to that particular box. These events do not propagate + either up or down the tree. + + + The value [[true]] is written to this property when the mouse (enters/leaves) the box. + + + + The value [[true]] is put to this property after the size + of this box changes. + + + + When a child is added or removed, that child is written to + this property. The write is always performed **after** the + addition or removal, so these two cases can be distinguished + by checking [[indexof(child)]]. + + Note that if the parent's redirect target is set to another + box, this trap will only be invoked when children are + manipulated by reading and writing to the parent. Reads and + writes directly to the redirect target will **not** trigger + this trap. + + Note also that this traps is still triggered if a box's + [[redirect]] target is **null**. This is useful for + boxes that need to accept children and then relocate them + elsewhere. + + +
+ + + Indicates that the use has pressed a mouse button. On + platforms with three mouse buttons, the **middle** button + is button 3 -- this ensures that applications written to only + use two buttons (1 and 2) will work intuitively on three button + platforms. + + + + Indicates that the use has released a mouse button. + + + + Indicates that the user has pressed and released the + mouse button without moving the mouse much (exactly how + much is platform-dependent). + + + + Indicates that the user has clicked the + mouse button twice within a short period of time (exactly how long is platform-dependent). + + + + Indicates that the mouse has moved while within this box, or that + the mouse while outside this box **if a button was pressed while within this box and has not yet been released** + + + + + A string is written to this property when a key is pressed or + released If the key was any other key, a multi-character + string describing the key will be put. For simplicity, we use + the VK_ constants in the . When a + key is pressed or released, the string put will be the portion + of its VK_ constant after the underscore, all in lower case. + + + If the shift key was depressed immediately before the + event took place, then the string will be capitalized. Special + keynames are also capitalized; shift+home is reported as + "[[HOME]]". Symbols are capitalized as they appear on the + keyboard; for example, on an American QWERTY keyboard, shift+2 + is reported as "[[@]]". + + If the alt, meta, or command key was depressed immediately + before this key was pressed, then the string will be prefixed + with the string "[[A-]]". If the control key was depressed + while this key was pressed, then the string will be prefixed + with the string "[[C-]]". If both alt and control are + depressed, the string is prefixed with "[[C-A-]]". + + Ibex does not distinguish between a key press resulting from + the user physically pushing down a key, and a 'key press' + resulting from the keyboard's typematic repeat. In the rare + case that an application needs to distinguish between these + two events, it should watch for KeyReleased messages and + maintain an internal key-state vector. + + +
+
+ + At any point in the Event Context, you can write to the [[mouse]] + property on any box. The value written should be an object with two + properties, [[x]] and [[y]]. For example: + +
+    _Press1 ++= function(p) {
+        mouse = { x: 32, y: 77 };
+    }
+    
+ + The coordinates specified are relative to the box whose [[mouse]] + property is being written to. There is no need to supply the + [[inside]] property; it is computed automatically. Writing to + the [[mouse]] property causes Ibex to recompute the eventual + target box, and also alter the values returned by [[mouse.x]], + [[mouse.y]], and [[mouse.inside]] for any **descendants** + of the current box. Writing to the [[mouse]] property also + automatically prevents the event from returning to the box's parents + -- it is equivalent to not cascading on the non-underscored event. + This ensures that child boxes cannot trick their parent boxes into + thinking that the mouse has moved. + + If you want the event to "skip over" the boxes between the trapee + and the target, or if you want to re-route an event to a box which + is not a descendant of the current box, simply write the value to + the proper key on the target box. + +
+    
+        _KeyPressed = function(k) { ibex.log.info("first"); }
+         KeyPressed = function(k) { ibex.log.info("sixth"); }
+        $recipient.target = $target;
+        
+            _KeyPressed = function(k) {
+                ibex.log.info("second");
+                thisbox.target.KeyPressed = k;
+                // inhibit cascade; keep event from going to $excluded
+                return true;
+            }
+             KeyPressed = function(k) { ibex.log.info("fifth"); }
+            
+                _KeyPressed = function(k) {
+                   ibex.log.info("this never happens");
+                }
+            
+        
+         
+            _KeyPressed = function(k) { ibex.log.info("third"); }
+             KeyPressed = function(k) { ibex.log.info("fourth"); }
+        
+    
+    
+ +
+ +
+ + You can create "fake events" by simply writing to the [[mouse]] + property and then writing a value to one of the underscored properties + on a box. This will have exactly the same effect as if the use had + actually pressed a key, clicked a button, or moved the mouse -- they + are indistinguishable.
+
-
+
+
- Every object has a stream associated with it. A stream is a + Every object has a **stream** associated with it. A stream is a sequence of bytes that can be read or written to. By default an object has an empty stream (zero bytes). However, some objects - (returned from special methods on the ibex object) have + (returned from special methods on the [[ibex]] object) have streams yielding data read from an url, file, or a component of a zip archive. In a future release, the stream associated with a box will be an .ibex template which, when applied, will fully reconstitute the @@ -1038,8 +1452,8 @@
Most stream objects let you access - substreams using the usual JavaScript operators [] and - ., as well as the for..in syntax. + substreams using the usual JavaScript operators [[[]]] and + [[.]], as well as the [[for..in]] syntax.
     // r1 and r2 are equivalent but not equal (!=)
@@ -1051,9 +1465,9 @@
 
   
- The empty-string property on the ibex object is called the - root stream. You can access this object as ibex.. or - ibex[""]. Additionally, any expression which starts with a + The empty-string property on the [[ibex]] object is called the + **root stream**. You can access this object as [[ibex..]] or + [[ibex[""]]]. Additionally, any expression which starts with a dot is treated as property to be retrieved from the root stream. The following three expressions are equivalent: @@ -1070,7 +1484,7 @@ FIXME You can access variables within the static block of a template by - appending a double period (..) and the variable name to the + appending a double period ([[..]]) and the variable name to the stream used to load that template:
@@ -1087,11 +1501,11 @@
 
     If you attempt to send a stream as part of an XML-RPC call, the
     stream will be read in its entirity, Base64-encoded, and transmitted
-    as a  element.
+    as a [[]] element.
     
-    Ibex supports two special URL protocols.  The first is data:,
+    Ibex supports two special URL protocols.  The first is [[data:]],
     which inteprets the rest of the URL as a Base64 encoded sequence of
-    bytes to use as a source.  The other is utf8: which
+    bytes to use as a source.  The other is [[utf8:]] which
     interpretets the rest of the string as a Unicode character sequence to
     be UTF-8 encoded as a string of bytes to use as a source.
     
@@ -1124,7 +1538,7 @@
 
 
- The ibex object is present in the top-level scope of every + The [[ibex]] object is present in the top-level scope of every script. It has the following properties: @@ -1148,7 +1562,7 @@ this object contains the ECMA math functions - return a regexp object corresponding to string s + return a regexp object corresponding to string **s** this object contains the ECMA string manipulation functions @@ -1157,26 +1571,26 @@ - log the debug messages m1 through mn. - o + log the debug messages **m1** through **mn**. + **o** - log the info messages m1 through mn. + log the info messages **m1** through **mn**. - log the warning messages m1 through mn. + log the warning messages **m1** through **mn**. - log the error messages m1 through mn. + log the error messages **m1** through **mn**. - opens a new browser window with URL u + opens a new browser window with URL **u** @@ -1243,12 +1657,12 @@ - return an XML-RPC call object with endpoint URL u + return an XML-RPC call object with endpoint URL **u** - return a SOAP call object with endpoint URL u, - SoapAction a, and XML Namespace n + return a SOAP call object with endpoint URL **u**, + SoapAction **a**, and XML Namespace **n** @@ -1263,77 +1677,77 @@ - sleep for n milliseconds + sleep for **n** milliseconds - returns a new object whose stream is drawn from URL u + returns a new object whose stream is drawn from URL **u** - unpacks a zip archive from s's stream + unpacks a zip archive from **s**'s stream - unpacks a cab archive from s's stream + unpacks a cab archive from **s**'s stream - valign=top>wraps a disk-backed read cache keyed on k - around s's stream + valign=top>wraps a disk-backed read cache keyed on **k** + around **s**'s stream - returns an object whose stream is drawn from s's - stream, but invokes f(n,d) as it is read from. + returns an object whose stream is drawn from **s**'s + stream, but invokes **f(n,d)** as it is read from. - Use SAX to parse the XML document on stream s with - handler h + Use SAX to parse the XML document on stream **s** with + handler **h** - Same as parse.xml(), but tries to fix broken HTML. + Same as [[parse.xml()]], but tries to fix broken HTML. - treat s's stream as a string encoded as a UTF-8 byte stream and return the string + treat **s**'s stream as a string encoded as a UTF-8 byte stream and return the string - ibex.stream.tempdir + [[ibex.stream.tempdir]] - not implemented yet: return a - stream which rsa-decrypts stream s with key k + **not implemented yet:** return a + stream which rsa-decrypts stream **s** with key **k** - not implemented yet: return a - stream which rc4-decrypts stream s with key k + **not implemented yet:** return a + stream which rc4-decrypts stream **s** with key **k** - not implemented yet: immediately - MD5-hash stream s + **not implemented yet:** immediately + MD5-hash stream **s** - not implemented yet: immediately - SHA1-hash stream s + **not implemented yet:** immediately + SHA1-hash stream **s**
- You can add a trap to a property by applying the ++= operator + You can add a trap to a property by applying the [[++=]] operator to a function with one argument. The trap will be invoked whenever that property is written to. @@ -1345,15 +1759,15 @@
- If another script were to set the property "foo" - on the box above to the value 5, the function above would be - invoked with the argument 5. The function would then log - the string "foo is 5". + If another script were to set the property "[[foo]]" + on the box above to the value [[5]], the function above would be + invoked with the argument [[5]]. The function would then log + the string "[[foo is 5]]". - Within a trap, the expression trapee can be used to + Within a trap, the expression [[trapee]] can be used to get a reference to the box on which the trap was placed. - The expression trapname returns the name of the + The expression [[trapname]] returns the name of the trap executing the current function. This is useful when a function is applied to multiple traps. For example: @@ -1369,7 +1783,7 @@
- You can remove a trap by using the --= operator with the same + You can remove a trap by using the [[--=]] operator with the same function you added as a trap:
@@ -1387,21 +1801,21 @@
 
   
 
-    When the trapped property is written to, each of the trap
+    When the trapped property is **written** to, each of the trap
     functions placed on it will be invoked in the opposite order that
     they were placed on the box -- the most recently placed trap will
     execute first. This last-to-first execution of traps is called
-    cascading. After the last trap is invoked, the value is
+    **cascading**. After the last trap is invoked, the value is
     stored on the box (remember, boxes are objects, so they can hold
     properties just like all other ECMAscript objects).
     
   
There are two additional tricks you can use when placing traps. The - first is a manual cascade. If you want to cascade to lower + first is a **manual cascade**. If you want to cascade to lower traps in the middle of a function, or you want to cascade with a different value than the value passed to you (in effect "lying" to - lower traps), you can use cascade. For example: + lower traps), you can use [[cascade]]. For example:
     
@@ -1415,7 +1829,7 @@
     This effectively creates a box whose color cannot be changed, and
     which complains loudly if you try to do so.
     
-    Do not try to do something like this:
+    Do **not** try to do something like this:
     
     
     
@@ -1424,7 +1838,7 @@
         }
     
     
- To prevent automatic cascading, return true from your function: + To prevent automatic cascading, return [[true]] from your function:
     
@@ -1438,27 +1852,27 @@
 
   
- The other trick is a read-trap. Read traps are just like normal + The other trick is a **read-trap**. Read traps are just like normal traps, except that you use a function that takes zero arguments instead of one. Read traps also do not automatically cascade.
     
-        doublewidth ++= function() { return 2 * width; }
+        doublewidth [[++=]] function() { return 2 * width; }
     
     
- If another script attempts to read from the doublewidth + If another script attempts to read from the [[doublewidth]] property on this box, the value it gets will be twice the actual width of the box. Note that - the actual doublewidth property on the box never gets written + the actual [[doublewidth]] property on the box never gets written to, since the trap does not cascade. You can manually cascade on read traps as well:
     
-        text ++= function() { return "my text is " + cascade; }
+        text [[++=]] function() { return "my text is " + cascade; }
     
     
@@ -1473,15 +1887,15 @@ place traps on any of the properties described in the sections , , or except for childadded, - childremoved and surface. FIXME: remove? + Properties"/> except for [[childadded]], + [[childremoved]] and [[surface]]. FIXME: remove? If an uncaught exception is thrown from a trap, Ibex will log the - exception, but will not propagate it to the code which + exception, but will **not** propagate it to the code which triggered the trap. If the trap was a read trap, the value - null will be returned. + [[null]] will be returned. FIXME: is this right? @@ -1493,10 +1907,10 @@
- Cloning is a companion technique for traps; together they can + **Cloning** is a companion technique for traps; together they can be used to simulate any sort of environment you might need. When you - call ibex.clone(o), Ibex returns a new object (called the - clone) which compares with equality (==) to the + call [[ibex.clone(o)]], Ibex returns a new object (called the + **clone**) which compares with equality ([[==]]) to the original object. Furthermore, both objects are "equal" as keys in hashtables, so: @@ -1511,28 +1925,25 @@ properties on the original object, and reads from properties on the clone will read properties on the original object. In fact, the only thing that can be used to distinguish the original from the clone is - traps -- a trap placed on the clone is not placed on the + traps -- a trap placed on the clone is **not** placed on the original object as well.
- -
-
From the perspective of an application writer, Ibex is strictly single-threaded. Ibex is always in exactly one of the following three - contexts: + **contexts**: - Rendering Context -- (redrawing the screen) + __Rendering Context__ -- (redrawing the screen) - Event Context (executing javascript traps triggered by an event) + __Event Context__ (executing javascript traps triggered by an event) - Thread Context (executing a background thread spawned with ibex.thread) + __Thread Context__ (executing a background thread spawned with [[ibex.thread]]) @@ -1540,10 +1951,10 @@ - The box.mouse property and its subproperties - (x, y, and inside) can only be read + The [[box.mouse]] property and its subproperties + ([[x]], [[y]], and [[inside]]) can only be read from within the Event Context, or in a thread context - after a the box.mouse property on this box or + **after** a the [[box.mouse]] property on this box or an ancestor box has been written to. Blocking operations (anything that accesses the network or @@ -1556,7 +1967,7 @@
Ibex offers easy access to threads. Spawning a background thread is as - simple as writing a function to the ibex.thread property: + simple as writing a function to the [[ibex.thread]] property:
     ibex.thread = function() {
@@ -1568,13 +1979,13 @@
     reserved for use in future versions of Ibex. Scripts should not
     depend on the number or content of these arguments.
     
-    Ibex is cooperatively multitasked, so threads must not process
+    Ibex is **cooperatively multitasked**, so threads must not process
     for too long.  This was a deliberate choice; cooperatively
     multitasked environments do not require complex locking primitives
     like mutexes and semaphores which are difficult for novices to
     understand.  The disadvantage of cooperative multitasking is that one
     thread can hog the CPU.  This is unlikely to happen in Ibex for two reasons:
-    first, all blocking I/O operations automatically yield the CPU,
+    first, all blocking I/O operations **automatically** yield the CPU,
     so the overall user interface never becomes unresponsive because it is
     waiting for a disk or network transfer.  Second, since Ibex is strictly
     a user interface platform, Ibex scripts are unlikely to perform highly
@@ -1583,172 +1994,13 @@
     
     
- -
- - Every execution of the Event Context begins with an event, which - consists of a key/value pair, and a mouse position, which consists of - an x and y coordinate. The possible keys are _Press[1-3], - _Release[1-3], _Click[1-3], _DoubleClick[1-3], - _Move, _KeyPressed, and _KeyReleased. - - Here are two example events: - - An event is triggered by writing the key to the value on a box. This - triggers any trap handlers which may be present. Once these handlers - have executed, Ibex figures out which child of the current box contains - the mouse (taking into account that some boxes may cover up others) - and writes the key and value to that box. If none of the box's - children contain the mouse position, Ibex removes the leading - underscore from the key name and writes the value to - that property. Once all the traps on that property have - executed, the value is written to the box's parent. - - Intuitively, Ibex delivers the underscored event to every box from the - root to the target, and then delivers the non-underscored event to - that same set of boxes in reverse order. So the event travels down - the tree to the target, and then back up to the root. The following - example prints out "first second third fourth" in that order. - -
-    
-        _Press1 ++= function(b) { ibex.log.info("first"); }
-         Press1 ++= function(b) { ibex.log.info("fourth"); }
-        
-          _Press1 ++= function(b) { ibex.log.info("second"); }
-           Press1 ++= function(b) { ibex.log.info("third"); }
-        
-    
-    
- - In general, you should use the non-underscore names to respond - to user input and use the underscored names when you want to override - child boxes' behavior or route events to particular boxes (for - example, when implementing a focus protocol). This is why the - underscored elements are delivered to parents before children (so - parents can override their childrens' behavior), but non-underscored - events are delivered to children before parents (since, visually, a - mouse click is usually "intended" for the leaf box underneath the - cursor). - -
- - - - At any point in this sequence, a trap handler can choose not to - cascade (by returning true from the trap handler function). - This will immediately cease the propagation of the event. This is how - you would indicate that an event has been "handled". - - - - Ibex uses the following events to notify a box about changes that - only matter to that particular box. These events do not propagate - either up or down the tree. - - - The value true is written to this property when the mouse (enters/leaves) the box. - - - - The value true is put to this property after the size - of this box changes. - - - - When a child is added or removed, that child is written to - this property. The write is always performed after the - addition or removal, so these two cases can be distinguished - by checking indexof(child). - - Note that if the parent's redirect target is set to another - box, this trap will only be invoked when children are - manipulated by reading and writing to the parent. Reads and - writes directly to the redirect target will not trigger - this trap. - - Note also that this traps is still triggered if a box's - redirect target is null. This is useful for - boxes that need to accept children and then relocate them - elsewhere. - - -
- - - Indicates that the use has pressed a mouse button. On - platforms with three mouse buttons, the middle button - is button 3 -- this ensures that applications written to only - use two buttons (1 and 2) will work intuitively on three button - platforms. - - - - Indicates that the use has released a mouse button. - - - - Indicates that the user has pressed and released the - mouse button without moving the mouse much (exactly how - much is platform-dependent). - - - - Indicates that the user has clicked the - mouse button twice within a short period of time (exactly how long is platform-dependent). - - - - Indicates that the mouse has moved while within this box, or that - the mouse while outside this box if a button was pressed while within this box and has not yet been released - - - - - A string is written to this property when a key is pressed or - released If the key was any other key, a multi-character - string describing the key will be put. For simplicity, we use - the VK_ constants in the . When a - key is pressed or released, the string put will be the portion - of its VK_ constant after the underscore, all in lower case. - - - If the shift key was depressed immediately before the - event took place, then the string will be capitalized. Special - keynames are also capitalized; shift+home is reported as - "HOME". Symbols are capitalized as they appear on the - keyboard; for example, on an American QWERTY keyboard, shift+2 - is reported as "@". - - If the alt, meta, or command key was depressed immediately - before this key was pressed, then the string will be prefixed - with the string "A-". If the control key was depressed - while this key was pressed, then the string will be prefixed - with the string "C-". If both alt and control are - depressed, the string is prefixed with "C-A-". - - Ibex does not distinguish between a key press resulting from - the user physically pushing down a key, and a 'key press' - resulting from the keyboard's typematic repeat. In the rare - case that an application needs to distinguish between these - two events, it should watch for KeyReleased messages and - maintain an internal key-state vector. - - - -
- -
-
- XML-RPC objects can be created by calling ibex.net.rpc.xml(XML-RPC - URL), and then invoking methods on that object. For example, + XML-RPC objects can be created by calling [[ibex.net.rpc.xml(**XML-RPC + URL**)]], and then invoking methods on that object. For example,
     Press1 += function(v) {
@@ -1760,23 +2012,23 @@
     
When the user clicks the first mouse button on this box, it will - contact the server xmlrpc.ibex.org, route to the - /RPC2/ handler and invoke the getTodaysColor() - method on the color object with a single string argument - "Friday". The return value will be used to change the color + contact the server [[xmlrpc.ibex.org]], route to the + [[/RPC2/]] handler and invoke the [[getTodaysColor()]] + method on the [[color]] object with a single string argument + "[[Friday]]". The return value will be used to change the color of the box the user clicked on. Note that in this example we spawned a background thread to handle the - request -- the Press1 event is delivered in the foreground + request -- the [[Press1]] event is delivered in the foreground thread, and XML-RPC methods may only be invoked in background threads. This is to prevent the UI from "locking up" if the server takes a long time to reply. If the XML-RPC method faults, an object will be thrown with two - properties: faultCode and faultString, as defined in + properties: [[faultCode]] and [[faultString]], as defined in the . If Ibex encounters a network, transport, or session-layer error, it will - throw a String object describing the error in a + throw a [[String]] object describing the error in a human-readable format. Scripts should not rely on the contents of this string having any special structure or significance. @@ -1785,7 +2037,7 @@ element. If a element is found in the XML-RPC reply, it will be returned as an object with a stream drawn from that byte sequence. - Each object returned by ibex.net.rpc.xml() represents a + Each object returned by [[ibex.net.rpc.xml()]] represents a single HTTP connection. The connection will be held open until the object is garbage collected or the server closes the connection. If a second call is issued on the object before the @@ -1795,7 +2047,7 @@ text="pipelined"/>. This can dramatically improve performance. Ibex supports HTTP Basic and Digest authentication. To use - authentication, pass ibex.net.rpc.xml() a URL in the form + authentication, pass [[ibex.net.rpc.xml()]] a URL in the form
        http[s]://user:password@hostname/
@@ -1815,8 +2067,8 @@
     
     
 
-        ibex.net.rpc.soap() is used instead of
-        ibex.net.rpc.xml()
+        [[ibex.net.rpc.soap()]] is used instead of
+        [[ibex.net.rpc.xml()]]
         
         Instead of specifying just the URL of the service itself, you
         must specify the URL, the SOAPAction argument, and the
@@ -1829,7 +2081,7 @@
     
     
     SOAP faults are handled the same way as XML-RPC faults except that the
-    capitalization of the faultstring and faultcode
+    capitalization of the [[faultstring]] and [[faultcode]]
     members is all lower-case, to match the SOAP spec. Here is a
     SOAP example:
     
@@ -1852,7 +2104,7 @@
     applications.
     
     The current Ibex SOAP stack does not support 'document style' or
-    multi-ref (href) data structures.
+    multi-ref ([[href]]) data structures.
     
     
@@ -1928,11 +2180,11 @@ Thrown when an HTTP error code is returned during an - operation. The three characters xyz will be + operation. The three characters [[**xyz**]] will be the three-digit HTTP status code. - The caller attempted to transmit the null value via XML-RPC. + The caller attempted to transmit the [[null]] value via XML-RPC. The caller attempted to transmit a circular data structure via XML-RPC. @@ -1942,13 +2194,13 @@ XML-RPC (for example, a Box or the Ibex object). - A JavaScript attempted to put to a property on the null value + A JavaScript attempted to put to a property on the [[null]] value - A JavaScript attempted to get from a property on the null value + A JavaScript attempted to get from a property on the [[null]] value - A JavaScript attempted to call the null value + A JavaScript attempted to call the [[null]] value If an exception is thrown inside a trap, the exception will propagate @@ -1957,89 +2209,20 @@ If an uncaught exception is thrown while applying a template, or the requested template could not be found, an error will be logged and the box to which the template was being applied will be made invisible - (visible = false). This ensures that half-applied widgets are + ([[visible = false]]). This ensures that half-applied widgets are never shown to the user.
- -
- -
- - At any point in the Event Context, you can write to the mouse - property on any box. The value written should be an object with two - properties, x and y. For example: - -
-    _Press1 ++= function(p) {
-        mouse = { x: 32, y: 77 };
-    }
-    
- - The coordinates specified are relative to the box whose mouse - property is being written to. There is no need to supply the - inside property; it is computed automatically. Writing to - the mouse property causes Ibex to recompute the eventual - target box, and also alter the values returned by mouse.x, - mouse.y, and mouse.inside for any descendants - of the current box. Writing to the mouse property also - automatically prevents the event from returning to the box's parents - -- it is equivalent to not cascading on the non-underscored event. - This ensures that child boxes cannot trick their parent boxes into - thinking that the mouse has moved. - - If you want the event to "skip over" the boxes between the trapee - and the target, or if you want to re-route an event to a box which - is not a descendant of the current box, simply write the value to - the proper key on the target box. - -
-    
-        _KeyPressed = function(k) { ibex.log.info("first"); }
-         KeyPressed = function(k) { ibex.log.info("sixth"); }
-        $recipient.target = $target;
-        
-            _KeyPressed = function(k) {
-                ibex.log.info("second");
-                thisbox.target.KeyPressed = k;
-                // inhibit cascade; keep event from going to $excluded
-                return true;
-            }
-             KeyPressed = function(k) { ibex.log.info("fifth"); }
-            
-                _KeyPressed = function(k) {
-                   ibex.log.info("this never happens");
-                }
-            
-        
-         
-            _KeyPressed = function(k) { ibex.log.info("third"); }
-             KeyPressed = function(k) { ibex.log.info("fourth"); }
-        
-    
-    
- -
- -
- - You can create "fake events" by simply writing to the mouse - property and then writing a value to one of the underscored properties - on a box. This will have exactly the same effect as if the use had - actually pressed a key, clicked a button, or moved the mouse -- they - are indistinguishable. - -
- When the core first starts up, it clones the ibex object, + When the core first starts up, it clones the [[ibex]] object, creates a stream for the initial .ibex, and then places a trap on the - cloned ibex object so that its empty-string property returns + cloned [[ibex]] object so that its empty-string property returns the .ibex stream. The cloned Ibex object is then passed as the third - (optional) argument to ibex.apply(), making it the default - ibex object for the scripts that are executed as part of the + (optional) argument to [[ibex.apply()]], making it the default + [[ibex]] object for the scripts that are executed as part of the template instantiation.
@@ -2049,12 +2232,12 @@
     ibex.apply(ibex.box, new_ibex..main, new_ibex);
     
- Note that we called ibex.bless() on the stream before tacking + Note that we called [[ibex.bless()]] on the stream before tacking it on to the new Ibex object. The bless function returns a clone of the object passed to it, with a few traps which are explained below. Additionally, any sub-streams retrieved by accessing properties of the blessed stream will also automatically be blessed (blessed streams are - monadic). + **monadic**). Blessing a stream serves three purposes: @@ -2071,23 +2254,23 @@ If the stream is a template to be applied, the string - ".ibex" is appended. + "[[.ibex]]" is appended. - If the stream is an image, the string ".png" is - appended. If no stream is found, ".jpeg" and - ".gif" are tried, in that order. + If the stream is an image, the string "[[.png]]" is + appended. If no stream is found, "[[.jpeg]]" and + "[[.gif]]" are tried, in that order. - If the stream is an font, the string ".ttf" is + If the stream is an font, the string "[[.ttf]]" is appended. - Every call to ibex.bless() returns a different object + Every call to [[ibex.bless()]] returns a different object (which happens to be a clone of the object passed to it) with a completely separate set of static blocks. - Ibex can self-emulate by using ibex.clone() on the Ibex object; + Ibex can self-emulate by using [[ibex.clone()]] on the Ibex object; this technique is very similar to the use of ClassLoaders in Java. This is useful for a number of applications, including debuggers, IDEs, sandboxing untrusted code, remote-control, and @@ -2099,7 +2282,7 @@ new_ibex.load ++= function() { return newLoadFunction; } ibex.apply(ibex.box, .main, new_ibex);
-
+
@@ -2167,12 +2350,12 @@ such machines public IP addresses is a poor network security policy, and doing so squanders scarce public IPv4 addresses. As such, the onus is on the administrators of such machines to explicitly block access - to clients reporting a User-Agent: header beginning with the - four characters "IBEX". + to clients reporting a [[User-Agent:]] header beginning with the + four characters "[[IBEX]]". - All top-level windows created by Ibex are scarred -- a stripe + All top-level windows created by Ibex are **scarred** -- a stripe and a lock is drawn across the corner of the window. There is no way for a user interface to remove this scar. Ibex user interfaces may not create windows smaller than the size of the scar. @@ -2211,25 +2394,25 @@ - The undefined value, ===, and !== + The [[undefined]] value, [[===]], and [[!==]] - The new keyword (and ECMAScript object inheritance) - eval + The [[new]] keyword (and ECMAScript object inheritance) + [[eval]] - getter and setter + [[getter]] and [[setter]] - The ECMA this keyword. + The ECMA [[this]] keyword. - The String, Number, and Boolean - classes. Note that string, number, and - boolean values are supported, however. + The [[String]], [[Number]], and [[Boolean]] + classes. Note that [[string]], [[number]], and + [[boolean]] values are supported, however. - You may not throw the null value. + You may not [[throw]] the [[null]] value. Additionally, you must declare all root-scope variables (with - var) before using them; failure to do so will result in an + [[var]]) before using them; failure to do so will result in an exception. Box properties are pre-defined in the scope that scripts are executed in. @@ -2239,13 +2422,13 @@ - The token .. is equivalent to [""]. + The token [[..]] is equivalent to [[[""]]]. Trapping Cloning - Extended catch syntax. The following code: + Extended [[catch]] syntax. The following code:
         } catch(e propname "foo.bar.baz") {
            // ...
@@ -2265,18 +2448,18 @@
         if it does appear, it must be the last one.
     
         Since Ibex ECMAscripts are wrapped in XML, the lexical token
-        "lt" is be interpreted as <, the lexical
-        token "gt" is be interpreted as >, and the
-        token "and" is interpreted as &&.
+        "[[lt]]" is be interpreted as [[<]], the lexical
+        token "[[gt]]" is be interpreted as [[>]], and the
+        token "[[and]]" is interpreted as [[&&]].
         Thus these tokens cannot be used as variable names.
     
-        The identifier static is a reserved word in
+        The identifier [[static]] is a reserved word in
         ECMAScript, but not in Ibex.
     
-        Ibex defines an additional reserved word, "assert",
+        Ibex defines an additional reserved word, "[[assert]]",
         which will evaluate the expression which follows it, throwing
-        a ibex.assertion.failed exception if the expression
-        evaluates to false.
+        a [[ibex.assertion.failed]] exception if the expression
+        evaluates to [[false]].
     
         To ensure that Ibex files appear the same in all text editors, tab
         characters are not allowed in Ibex files.
@@ -2321,7 +2504,7 @@
         -l host:port    emit log to TCP socket
         -l [file]       write log to a file on disk
         -a              check assertions
-        -w   reserved for libibex
+        -w [window-id]  reserved for libibex
         -p              dump profiling information [not yet supported]
     
@@ -2338,17 +2521,17 @@ invoked. To inhibit this console window, provide a logging destination (file, port, etc). - The source-location parameter can be either the path - to an .ibex archive, the http url of an .ibex + The [[**source-location**]] parameter can be either the path + to an [[.ibex]] archive, the http url of an [[.ibex]] archive, or the path to a directory comprising an unpacked - .ibex archive. + [[.ibex]] archive. - The initial-template parameter is the stream name of + The [[**initial-template**]] parameter is the stream name of a template to be used as the initial template. If ommitted, it - defaults to main. + defaults to [[main]]. - The -v option causes Ibex to enable verbose logging; this will - cause it to log lots of information to the log file. This + The [[-v]] option causes Ibex to enable verbose logging; this will + cause it to log **lots** of information to the log file. This option will also substantially decrease Ibex's performance. @@ -2357,9 +2540,9 @@ - +** Copyright (C) 2004 Adam Megacz, verbatim redistribution permitted. Ibex is a trademark of Adam Megacz - - +** + \ No newline at end of file