From 17de026a5d37ccc30a955b2e14e3352baeacb294 Mon Sep 17 00:00:00 2001 From: adam Date: Thu, 25 Mar 2004 12:22:05 +0000 Subject: [PATCH] strictly formatting fixes to the reference; no new content darcs-hash:20040325122205-5007d-d1015f5cf6a6937b049b97e9e2314252e397729d.gz --- doc/reference.xml | 1326 ++++++++++++++++++++++++++--------------------------- 1 file changed, 645 insertions(+), 681 deletions(-) diff --git a/doc/reference.xml b/doc/reference.xml index e0365aa..15b8da4 100644 --- a/doc/reference.xml +++ b/doc/reference.xml @@ -27,27 +27,22 @@ you are not familiar with ECMAscript, some reference materials are provided in - The shoehorn sequence (how the Ibex Core gets onto the - client's computer, and how it knows where to download the initial .ibex - from) is not described in this document, since it will be different - for every platform that Ibex is ported to. + The wildebeest sequence (how the Ibex Core gets onto the + client's computer, and how it knows where to download the initial + .ibex from) is not described in this document, since it + will be different for every platform that Ibex is ported to. 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 . - - - -
- -
- +
+ Ibex itself; the native code (or Java bytecode) that runs on - the client. This term does not include the shoehorn + 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" @@ -56,87 +51,85 @@ we'll refer to this as the ".ibex" to be clear that we're talking about the actual zip archive, rather than its visual appearance when rendered on the screen. - + We will use the term "the server" to refer to any other computer which the client makes XML-RPC or SOAP calls to. Note that it is possible for the client and server to be the same machine. - - + + this is a very small piece of code that is downloaded the first time a client uses Ibex. It downloads the Ibex core, verifies its signature, and launches it with the appropriate parameters indicating where to find the initial UI. The - Shoehorn works differently on every platform, and is outside + Wildebeest works differently on every platform, and is outside the scope of this document. - + 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 + "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 + expression "return (3 + foo.bar)" gets the value of bar property on object foo and then adds 3 to it before returning the result. - + We will use the terms JavaScript and ECMAScript interchangeably in this document. The Ibex interpreter is not completely ECMA-compliant, however (see for details). +
+
-
+
-
- - Each top-level window in an Ibex UI is called a - 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 - decorations. + Each top-level window in an Ibex UI is called a + 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 + decorations. - Whenever we refer to the size or position of a surface, we are - referring to the size or position of the UI-accessible portion of the - surface; this does not include any platform-specific decorations. This - means that if you set the position of a frame to (0,0), the - platform-specific titlebar will actually be off the screen on most - platforms (it will be above and to the left of the top-left corner of - the screen). + Whenever we refer to the size or position of a surface, we are + referring to the size or position of the UI-accessible portion of the + surface; this does not include any platform-specific decorations. This + means that if you set the position of a frame to (0,0), the + platform-specific titlebar will actually be off the screen on most + platforms (it will be above and to the left of the top-left corner of + the screen). - 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. + 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. -
+
-
+
- A box is the fundamental unit from which all Ibex user - interfaces are built. Boxes can contain other boxes (known as - 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. + A box is the fundamental unit from which all Ibex user + interfaces are built. Boxes can contain other boxes (known as + 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 JavaScript object (the - "Object Representation"), and as an XML tag (the "XML - Representation"). + There are three ways to think of a box: as a rendered visualization on + the screen (the "Visual Representation"), as a JavaScript object (the + "Object Representation"), and as an XML tag (the "XML + Representation"). - FIXME: diagram here + FIXME: diagram here - All three representations are equally valid, and being able to figure - out what an action in one representation would mean in terms of the other - two representations is crucial to a solid understanding of Ibex. + All three representations are equally valid, and being able to figure + out what an action in one representation would mean in terms of the other + two representations is crucial to a solid understanding of Ibex. -
-
Each box is a full-fledged ECMAscript object, and can store key-value @@ -144,13 +137,13 @@ will be explained later. Each box's numeric properties hold its child boxes. -
+
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 + 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 (they obscure @@ -170,7 +163,7 @@ The path has an associated strokecolor, which is a color - + The path has an associated strokewidth, which is a number specifying the width of the stroke. @@ -195,7 +188,7 @@ appearance. Every single box you see in Ibex is drawn only on the basis of these components and its size. -
+
@@ -205,7 +198,7 @@ instantiation, 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 template, when + 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. @@ -215,40 +208,39 @@ instantiated, the XML is effectively "thrown away", and JavaScript code is free to alter the boxes. -
- -
- - Each template is an XML document whose root element - is <ibex>. Any text content of the root element is - ignored, and may safely be used for comments. The root element may - have any of the following elements as children, each of which may - appear no more than once, and which must appear in this order: - - Here is a sample Ibex file: - -
-    
-        This is a sample Ibex file. Text up here is ignored.
-        Copyright (C) 2004 Mustapha Mond.
-        
-            // code here will be executed only once
-        
-        
-    
-    
+
+ + +
+ + Each template is an XML document whose root element + is <ibex>. Any text content of the root element is + ignored, and may safely be used for comments. The root element may + have any of the following elements as children, each of which may + appear no more than once, and which must appear in this order: + + Here is a sample Ibex file: + +
+  
+      This is a sample Ibex file. Text up here is ignored.
+      Copyright (C) 2004 Mustapha Mond.
+      
+          // code here will be executed only once
+      
+      
+  
+  
-
- -
+ The following description of the box application is extremely detailed and precise; it is intended for UI designers who need to know the @@ -260,69 +252,70 @@ However, most of the time you can just pretend that the XML tags and the boxes are the same thing. - 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 in the + Process each child element or text segment of X in the order they appear in the document: For each text - segment t: + segment t: - Treat t a JavaScript script, and execute it - with s as the root scope. + Treat t a JavaScript script, 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 + If the name of tag x is not "box" (in the default XML 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. + a template and apply 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). @@ -345,36 +338,35 @@ -
+ -
+
- A user begins by specifying the URL of an Ibex application run. - Usually this is done by visiting a web page which uses the - shoehorn to install the core if it is not already on the user's - machine, but you can also supply the URL on the command line. + A user begins by specifying the URL of an Ibex application run. + Usually this is done by visiting a web page which uses the + wildebeest to install the core if it is not already on the user's + machine, but you can also supply the URL on the command line. - The Ibex Core downloads the .ibex for the application, loads it, applies - the main.ibex template and renders it onto the screen, running - any associated ECMAscript code. + The Ibex Core downloads the .ibex for the application, loads it, applies + the main.ibex template and renders it onto the screen, running + any associated ECMAscript code. - 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. + 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. - DIAGRAM: graphic here showing the circular feedback cycle. + DIAGRAM: graphic here showing the circular feedback cycle. - The Ibex core quits when the last remaining surface has been destroyed. + The Ibex core quits when the last remaining surface has been destroyed. -
+
-
@@ -393,20 +385,20 @@ 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 + 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 + 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 + 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. @@ -419,16 +411,16 @@ - If the align property is "center", then the + 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 + 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 + If the align property is "top", + "bottom", "right", or "left", then the alignment point is middle of the corresponding edge of the box. @@ -437,9 +429,9 @@ FIXME: diagram When positioning a child box, the alignment point is determined by the - parent's align property. When positioning a visual + parent's align property. When positioning a visual element (a texture, path, or text string) within a box, the alignment - point is determined by the box's own align property. + 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. @@ -449,36 +441,36 @@
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 + 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 + 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. + 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 + 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). - +
-        
-            
-            
-            
-            
-            
-        
+    
+        
+        
+        
+        
+        
+    
     
Notes on the layout example: @@ -503,29 +495,29 @@ maximum of: - Its minwidth + Its minwidth - The width of the box's text (after applying the - box's transform). + The width of the box's text (after applying the + box's transform). The width of the box's path (after applying the box's - transform) if the box is packed. + 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. + colspan. - If a box's hshrink property is set to - true, the box's maximum width is the same as its + 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. + maxwidth. - The maximum width of each cell is the maxwidth of + The maximum width of each cell is the maxwidth of the box occupying it divided by the box's - colspan. + colspan. @@ -539,8 +531,8 @@ 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. + box will never be smaller than its minwidth or + larger than its maxwidth. Each column's maximum width is the largest maximum width of the cells in that column, but no smaller than the column's @@ -556,10 +548,10 @@ Next, the rows and columns are positioned within the parent box. The rows and columns are transformed according to the - parent's transform property, and the bounding box of + parent's transform property, 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 + alignment points are determined by the parent's align property). FIXME: diagram Packed boxes: Each packed box's actual position @@ -567,11 +559,12 @@ 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 + 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). @@ -585,27 +578,27 @@ - If the box's transform property is non-null, the + 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. - If the box is packed and has a non-null path, the + 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 + 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 + gradient, or image specified by the fill property and stroked with the color and width specified by the - strokecolor and strokewidth properties. + 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 + 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 + alignment points are determined by the box's align property). The box's children are rendered (pre-prder traversal). @@ -627,47 +620,48 @@ 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 + 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). + 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. + 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 + 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 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 box's text; writing null to this property sets it + to "". 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. + box's text. @@ -675,7 +669,7 @@ - The color in which to render the font; accepts the same values as strokecolor. + The color in which to render the font; accepts the same values as strokecolor.
@@ -683,7 +677,7 @@
- If set to true, this box will shrink + 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. @@ -697,7 +691,7 @@ The distance between this box's (left/top) edge and the root box's (left/top) edge. A put to this property has the same - effect as a put to the (x/y) property, + effect as a put to the (x/y) property, except that it is relative to the root box rather than to this box's parent. FIXME is this fakeable? How is distance measured? @@ -720,11 +714,11 @@ 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. + 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. @@ -741,10 +735,10 @@ 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 + 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. + true to a box's visible property and then + read back false. @@ -756,7 +750,7 @@
During a box initialization, script-private references to a box's - descendants with id attributes are placed on the box. These + descendants with id attributes are placed on the box. These references allow scripts on that box to easily refer to descendant nodes created by the template in which the script appears. For example, these two blocks of code have exactly the same effect: @@ -773,7 +767,7 @@ out. If a box has a non-null redirect target, reads and writes to these properties 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 @@ -781,24 +775,24 @@ widget, they do not appear until the menu is pulled down. - 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 + 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 + 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 + 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 + 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. @@ -814,7 +808,7 @@ 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. @@ -826,18 +820,18 @@ 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. @@ -857,13 +851,13 @@ 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. @@ -871,17 +865,17 @@ 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. These properties are meant to be trapped on FIXME defined later?. Placing a trap on - childadded/childremoved lets a box receive + childadded/childremoved lets a box receive notification when a child is added/removed. In either situation, the child will be passed as an argument to the trap function after the addition or removal has been @@ -894,7 +888,7 @@ the traps. Note also that these traps are still triggered if a box's - redirect target is null. This is useful for + redirect target is null. This is useful for boxes that need to accept children and then relocate them elsewhere. @@ -907,15 +901,15 @@ to that particular box. - The value true is written to this property when the mouse enters the box. + The value true is written to this property when the mouse enters the box. - The value true is written to this property when the mouse leaves the box. + The value true is written to this property when the mouse leaves the box. - The value true is put to this property after the size + The value true is put to this property after the size of this box changes. @@ -927,42 +921,42 @@ 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 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 + 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 + 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. + 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 + true will be put to this property. Scripts may trap this property FIXME defined later? 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 + true to this property on a root box has the same + effect as putting null to the thisbox property. @@ -990,7 +984,7 @@ 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 @@ -1019,7 +1013,7 @@ You can create a stream from a URL by calling
-        var r = ibex.stream.url("http://...");
+    var r = ibex.stream.url("http://...");
     
This will return an object whose stream draws data from the specified @@ -1030,29 +1024,29 @@
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 (!=)
-      var r1 = ibex.stream.url("http://www.ibex.org/foo/bar.html");
-      var r2 = ibex.stream.url("http://www.ibex.org/foo")["bar.html"];
+    // r1 and r2 are equivalent but not equal (!=)
+    var r1 = ibex.stream.url("http://www.ibex.org/foo/bar.html");
+    var r2 = ibex.stream.url("http://www.ibex.org/foo")["bar.html"];
     
- 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:
-      ibex..foo
-      ibex[""].foo
-      .foo
+    ibex..foo
+    ibex[""].foo
+    .foo
     
@@ -1060,15 +1054,15 @@
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:
-      
-              foo = 12;
-      ...
-      // elsewhere
-      ibex.log.print(org.ibex.themes.monopoly.scrollbar..foo);   // prints "12"
+    
+            foo = 12;
+    ...
+    // elsewhere
+    ibex.log.print(org.ibex.themes.monopoly.scrollbar..foo);   // prints "12"
     
@@ -1077,33 +1071,34 @@ 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.
-      var r5 = ibex.stream.url("data:WFWE876WEh99sd76f");
-      var r6 = ibex.stream.url("utf8:this is a test");
+    var r5 = ibex.stream.url("data:WFWE876WEh99sd76f");
+    var r6 = ibex.stream.url("utf8:this is a test");
     
You can read a UTF-8 encoded string from a stream like this:
-      var myString = ibex.stream.fromUTF(ibex.stream.url("utf8:this is a test"));
+    var myString = ibex.stream.fromUTF(ibex.stream.url("utf8:this is a test"));
     
You can also parse XML from a stream using SAX like this:
-      ibex.stream.xml.sax(ibex.stream.url("http://foo.com/foo.xml"),
-                         { beginElement : function(tagname, attributeKeyValuePairs) { ... },
-                           endElement   : function(tagname) { ... },
-                           content      : function(contentString) { ... }
-                           whitespace   : function(whitespaceString) { ... }
-                         });
+    ibex.stream.xml.sax(
+        ibex.stream.url("http://foo.com/foo.xml"),
+            { beginElement : function(tagname, attributeKeyValuePairs) { ... },
+              endElement   : function(tagname) { ... },
+              content      : function(contentString) { ... }
+              whitespace   : function(whitespaceString) { ... }
+            });
     
@@ -1113,10 +1108,10 @@
- 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: -
+ reading from this property returns a new box @@ -1128,9 +1123,7 @@ returns a blessed clone of stream -
- -
+ reading from this property returns a new date @@ -1145,9 +1138,7 @@ this object contains the ECMA string manipulation functions -
- -
+ log the debug message m, optionally dumping object @@ -1169,11 +1160,7 @@ o -
- -
- -
+ opens a new browser window with URL u @@ -1240,7 +1227,7 @@ an object whose stream is a a builtin fixed-width font -
+ not yet implemented @@ -1255,9 +1242,7 @@ SoapAction a, and XML Namespace n -
- -
+ when a function is written to this property, a new thread is @@ -1272,9 +1257,7 @@ sleep for n milliseconds -
- -
+ returns a new object whose stream is drawn from URL u @@ -1304,7 +1287,7 @@ - Same as parse.xml(), but tries to fix broken HTML. + Same as parse.xml(), but tries to fix broken HTML. @@ -1312,12 +1295,10 @@ - ibex.stream.tempdir + ibex.stream.tempdir -
- -
+ not implemented yet: return a @@ -1339,69 +1320,63 @@ 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.
-        
-            foo ++= function(z) {
-               ibex.log.info("foo is " + z);
-            }
-        
+    
+        foo ++= function(z) {
+           ibex.log.info("foo is " + z);
+        }
+    
     
- 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:
-        
-            func ++= function(z) {
-                ibex.log.info("called trap " + trapname);
-            }
-            foo ++= func;
-            bar ++= func;
-        
+    
+        func ++= function(z) {
+            ibex.log.info("called trap " + trapname);
+        }
+        foo ++= func;
+        bar ++= func;
+    
     
-
-
- 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:
-        
-            var myfunc = function(z) { /* ... */ }
-            // add the trap
-            func ++= myfunc;
-            // ...
-            // remove the trap
-            func --= myfunc;
-        
+    
+        var myfunc = function(z) { /* ... */ }
+        // add the trap
+        func ++= myfunc;
+        // ...
+        // remove the trap
+        func --= myfunc;
+    
     
-
+ When the property is written to, each of the trap functions placed on it will be invoked in the opposite order that they were placed on @@ -1411,23 +1386,21 @@ 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 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:
-        
-            color ++= function(c) {
-                ibex.log.info("refusing to change colors!");
-                cascade = "black";
-            }
-        
+    
+        color ++= function(c) {
+            ibex.log.info("refusing to change colors!");
+            cascade = "black";
+        }
+    
     
This effectively creates a box whose color cannot be changed, and @@ -1436,20 +1409,20 @@ Do not try to do something like this:
-        
-            color ++= function(z) {
-                color = "black";      // INFINITE LOOP! BAD!!!
-            }
-        
+    
+        color ++= function(z) {
+            color = "black";      // INFINITE LOOP! BAD!!!
+        }
+    
     
- To prevent automatic cascading, return true from your function: + To prevent automatic cascading, return true from your function:
-        
-            color ++= function(z) {
-                return true;          // the box's color will not change
-            }
-        
+    
+        color ++= function(z) {
+            return true;          // the box's color will not change
+        }
+    
     
@@ -1461,23 +1434,23 @@ 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; }
+    
     
Read traps are only rarely needed -- most of the time a write trap @@ -1485,48 +1458,44 @@
-
+ To prevent confusing and hard-to-debug behaviors, scripts may not 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 triggered the trap. If the trap was a read trap, the value - null will be returned. + null will be returned. FIXME: is this right? -
-
+ Traps are the backbone of Ibex. Since almost all UI programming is event/demand driven, traps eliminate the need for separate member/getter/setter declarations, often cutting the amount of typing you have to do to a third of what it would normally be. -
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:
-       var hash = {};
-       var theclone = ibex.clone(o);
-       hash[o] = 5;
-       ibex.log.info(hash[theclone]);    // prints "5"
+    var hash = {};
+    var theclone = ibex.clone(o);
+    hash[o] = 5;
+    ibex.log.info(hash[theclone]);    // prints "5"
     
Any writes to properties on the clone will actually write to @@ -1538,79 +1507,9 @@
-
- - 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 - 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 - template instantiation. - -
-       var new_ibex = ibex.clone(ibex);
-       var stream = ibex.bless(ibex.stream.url("http://..."));
-       new_ibex[""] ++= function() { return stream; }
-       ibex.apply(ibex.box, new_ibex..main, new_ibex);
-    
- - 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). - - Blessing a stream serves three purposes: - - - - Blessed clones always return the appropriate static block when - their empty property is accessed; this ensures that references - to the static blocks of other templates work properly. - - Blessed substreams can return their parent stream by accessing - a hidden property which is reserved for internal use by Ibex. - This ensures that Ibex can automatically add filename - extensions where needed, according to the following rules: - - - If the stream is a template to be applied, the string - ".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 font, the string ".ttf" is - appended. - - - 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; - 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 - others. For example: - -
-       var newLoadFunction = function(url) { /* ... */ };
-       var new_ibex = ibex.clone(ibex);
-       new_ibex.load ++= function() { return newLoadFunction; }
-       ibex.apply(ibex.box, .main, new_ibex);
-    
- -
-
-
+
@@ -1624,7 +1523,7 @@ 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) @@ -1632,10 +1531,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 @@ -1648,12 +1547,12 @@
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() {
-            ibex.log.info("this is happening in a background thread!");
-        }
+    ibex.thread = function() {
+        ibex.log.info("this is happening in a background thread!");
+    }
     
The argument set passed to the function is currently undefined and is @@ -1674,14 +1573,15 @@ few milliseconds.
+
-
+
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. + 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: @@ -1702,14 +1602,14 @@ 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"); }
-              
-          
+    
+        _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 @@ -1724,91 +1624,22 @@
-
+ At any point in this sequence, a trap handler can choose not to - cascade (by returning true from the trap handler function). + 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". -
- -
- - 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 to keep the 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. - -
- -
- - Ibex will trigger the Enter and Leave properties as + Ibex will trigger the Enter and Leave properties as it walks down the tree, based on the position of the mouse (or the - faked position if the mouse property has been written to). - However, Enter and Leave are not events since they + faked position if the mouse property has been written to). + However, Enter and Leave are not events since they do not implicitly cascade up or down the tree. -
- -
+
Indicates that the use has pressed a mouse button. On @@ -1850,15 +1681,15 @@ 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 + "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 + 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 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 + 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 + 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 @@ -1869,42 +1700,43 @@
-
+
- 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) {
-            ibex.thread = function() {
-                color = ibex.net.rpc.xml("http://xmlrpc.ibex.org/RPC2/").color.getTodaysColor("Friday");
-            }
+    Press1 += function(v) {
+        ibex.thread = function() {
+            color = ibex.net.rpc.xml("http://xmlrpc.ibex.org/RPC2/").
+                       color.getTodaysColor("Friday");
         }
+    }
     
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. @@ -1913,7 +1745,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 @@ -1923,8 +1755,8 @@ 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 - http[s]://user:password@hostname/. Ibex will use Digest + authentication, pass ibex.net.rpc.xml() a URL in the form + http[s]://user:password@hostname/. Ibex will use Digest authentication if the server supports it; otherwise it will use Basic authentication. Please be aware that many XML-RPC server implementations contain a - 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 @@ -1952,21 +1784,21 @@ 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:
-        Press1 ++= function(v) {
-            ibex.thread = function() {
-                color = ibex.net.rpc.soap("http://soap.ibex.org/SOAP",   // endpoint
-                                         "GETTODAYSCOLOR",             // SOAPAction header
-                                         "http://ibex.org/namespace"    // namespace for SOAP-ENV
-                                    ).color.getTodaysColor( {
-                                        whichday : Friday
-                                    } );
-            }
+    Press1 ++= function(v) {
+        ibex.thread = function() {
+            color = ibex.net.rpc.soap("http://soap.ibex.org/SOAP",
+                                     "GETTODAYSCOLOR",            
+                                     "http://ibex.org/namespace"  
+                                ).color.getTodaysColor( {
+                                    whichday : Friday
+                                } );
         }
+    }
     
As you can see, SOAP is much more verbose, yet does not offer @@ -1975,7 +1807,7 @@ applications. The current Ibex SOAP stack does not support 'document style' or - multi-ref (href) data structures. + multi-ref (href) data structures.
@@ -1998,7 +1830,7 @@ For example:
-       "ibex.net.dns.unknownhostexception: unable to resolve host foo.com"
+    "ibex.net.dns.unknownhostexception: unable to resolve host foo.com"
     
The code should be used to determine how the program should respond to @@ -2024,7 +1856,7 @@ A piece of untrusted Ibex code attempted to contact a - restricted host. See for details. + restricted host. See for details. An attempt to resolve a hostname failed but it is not known @@ -2051,11 +1883,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. @@ -2065,13 +1897,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 @@ -2080,12 +1912,152 @@ 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, + creates a stream for the initial .ibex, and then places a trap on the + 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 + template instantiation. + +
+    var new_ibex = ibex.clone(ibex);
+    var stream = ibex.bless(ibex.stream.url("http://..."));
+    new_ibex[""] ++= function() { return stream; }
+    ibex.apply(ibex.box, new_ibex..main, new_ibex);
+    
+ + 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). + + Blessing a stream serves three purposes: + + + + Blessed clones always return the appropriate static block when + their empty property is accessed; this ensures that references + to the static blocks of other templates work properly. + + Blessed substreams can return their parent stream by accessing + a hidden property which is reserved for internal use by Ibex. + This ensures that Ibex can automatically add filename + extensions where needed, according to the following rules: + + + If the stream is a template to be applied, the string + ".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 font, the string ".ttf" is + appended. + + + 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; + 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 + others. For example: + +
+    var newLoadFunction = function(url) { /* ... */ };
+    var new_ibex = ibex.clone(ibex);
+    new_ibex.load ++= function() { return newLoadFunction; }
+    ibex.apply(ibex.box, .main, new_ibex);
+    
+
+
+ + Due to the expense and hassle imposed by the commercial PKI code @@ -2099,7 +2071,7 @@ Ibex's security architecture is divided into defenses against four major classes of attacks: -
+ Ibex user interfaces are run in an extremely restrictive sandbox. The environment does not provide primitives for accessing any data outside @@ -2126,9 +2098,7 @@ specifically indicates that that information should be made available to the Ibex application. -
- -
+ Ibex user interfaces may only make XML-RPC or SOAP calls and load .ibex archives via HTTP; they cannot execute arbitrary HTTP GET's or open @@ -2152,21 +2122,17 @@ 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 - three characters "Ibex". + to clients reporting a User-Agent: header beginning with the + three characters "Ibex". -
- -
+ 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. -
- -
+ Ibex user interfaces may transmit network data using HTTPS (SSL 3.0) for encryption. Ibex will attempt 128-bit encryption, but will @@ -2185,9 +2151,7 @@ connection with any data you would not normally trust an SSL-enabled web browser with. -
- -
+ @@ -2202,52 +2166,51 @@ - 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.
- -
- 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") {
-               // ...
-            }
+        } catch(e propname "foo.bar.baz") {
+           // ...
+        }
         
Is equivalent to:
         } catch(e) {
-           if (e.propname != null && e.propname >= "foo.bar.baz" && e.propname < "foo.bar.baz/") {
+           if (e.propname != null and e.propname >= "foo.bar.baz" and
+               "foo.bar.baz/" > e.propname) {
                // ...
            }
         }
@@ -2257,18 +2220,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.
@@ -2300,6 +2263,7 @@
 
     
     
+ @@ -2307,8 +2271,8 @@ Very early in the loading process, Ibex begins logging messages about what it is doing. Where this output is logged to differs by platform; currently it goes to standard output when running inside a JVM, and to - $TMPDIR\ibex-log.txt on Win32 (where $TMPDIR is the - value returned by GetTempPath()). The logs contain a lot of + $TMPDIR\ibex-log.txt on Win32 (where $TMPDIR is the + value returned by GetTempPath()). The logs contain a lot of valuable debugging information and performance hints; if you are having trouble developing an Ibex application, be sure to check the logs. @@ -2322,36 +2286,36 @@ You can invoke Ibex directly from the command line during development. When using a JVM, the invocation format is: -
-      java -jar path-to-ibex-jar [-sv] source-location [initial-template]
+    
    
+  java -jar path-to-ibex-jar [-sv] source-location [initial-template]
     
- Where path-to-ibex-jar is the path to ibex.jar, + Where path-to-ibex-jar is the path to ibex.jar, which can be downloaded . On Win32, the invocation format is:
-      ibex.exe [-v] source-location [initial-template]
+    ibex.exe [-v] source-location [initial-template]
     
- The file ibex.exe is placed in Windows' ActiveX cache + The file ibex.exe is placed in Windows' ActiveX cache directory the first time Ibex is used on the machine. The ActiveX cache location depends on what version of Windows you are using; - on newer versions of Windows it is C:\WINDOWS\DOWNLOADED - PROGRAM FILES\. You can also extract ibex.exe from - ibex.cab, which is available C:\WINDOWS\DOWNLOADED + PROGRAM FILES\. You can also extract ibex.exe from + ibex.cab, which is available . - The source-location parameter can be either the path + 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. - 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 + 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. @@ -2368,7 +2332,7 @@ Grammars are defined with a statement in the following form:
-       a ::= b { c }
+    a ::= b { c }
     
A grammar is really just another function; once defined you can't tell it apart from an ordinary function. A grammar takes one argument, @@ -2376,7 +2340,7 @@ result of executing the code block 'c' is returned. The property 'a' is read; if the value is a grammar, a new production - rule (ie a new alternative, as with '|') is added to that grammar + rule (ie a new alternative, as with '|') is added to that grammar (this is a destructive update). This allows you to add productions to pre-existing grammars (for example, adding a new type of expression to a programming language by extending the 'expr' grammar). If the old @@ -2389,9 +2353,9 @@ string literals - grouping parens () + grouping parens () - combinators: | + * ? + combinators: | + * ? references to other grammars @@ -2403,7 +2367,7 @@ The identifier 'whole' is bound to the string matched by the entire expression. If the code block is omitted it behaves - as if it were "{ return whole; }". + as if it were "{ return whole; }". For every reference to another grammar which was matched in the pattern, the *name used to reference that other grammar* will -- 1.7.10.4