<ibex-doc title="The Ibex Reference" subtitle="Nitrogen Release" author="Adam Megacz" email="adam@ibex.org" logo="ibex-logo.pdf">

<!-- ----------------------------------------------------------------------- -->
<section title="Introduction">

    
    ** 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 <link url="reference.pdf" text="pdf version"/> 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.

  <list>

      - 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.

   </list>
    
   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.

   <section title="The Ibex Object Model">

      The Ibex Object Model consists of three primitive types:
    
      <list>
          - __number__  -- a floating point number
          - __string__  -- a unicode string
          - __boolean__ -- either [[true]] or [[false]]
      </list>
    
      From these primitives, more complex structures can be built from
      two aggregate types:
    
      <list>
          - __array__   -- a collection of objects indexed by a non-negative integer
          - __hash__    -- a collection of objects indexed by objects (often strings)
      </list>
    
      Any of the following actions can be performed on an object:
    
      <list>
          - __get(key)__ -- attempts to retrieve the object indexed by
            [[key]].  Returns an object.
    
          - __put(key, val)__ -- attempts to add object [[val]] with key
            [[key]] to an object.  Does not return a value.
    
          - __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.
      </list>
    
      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.
    </section>

    <section title="Namespaces">
        - relation to XML
        - cover templates here with David's isomorphism?
    </section>

    <section title="Platforms Founded on the Ibex Object Model">

       The remainder of this document describes the three major
       systems founded on the Ibex Object Model:

       <list>
           - The Ibex User Interface
           - The Ibex Persistent Storage Service
           - The Ibex Mail Server
           - IbexDoc
       </list>

       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.

    </section>
  
  <section title="Key Concepts">
  
    <definition term="The Core">
         Ibex itself; the native code (or Java bytecode) that runs on
         the client.  This term does not include the **Wildebeest**
         or the **UI**</definition>
  
    <definition term="The UI / The Application">
         A set of files (mostly XML, JavaScript, and PNG images)
         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.
         </definition>
  
    <definition term="The Server">
         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.</definition>
  
    <definition term="Wildebeest">
         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.
         Wildebeest works differently on every platform, and is outside
         the scope of this document.</definition>
  
    <definition term="put/write">
         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
         property on object foo.</definition>
  
    <definition term="get/read">
         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
         value of bar property on object foo and then adds 3 to it
         before returning the result.</definition>
  
    <definition term="JavaScript">
        We will use the terms JavaScript and ECMAScript
        interchangeably in this document.  The Ibex interpreter is not
        completely ECMA-compliant, however (see <link
        appendix="ECMAscript compliance"/> for details).
        </definition>

  </section>
</section>

<section title="The Ibex User Interface">
  <section title="Life Cycle of an Ibex Application">
  
    <image url="lifecycle.pdf" caption="The Lifecycle of an Ibex Application"/>

    A user typically begins an Ibex session by clicking on a link to
    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 (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 (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.

  </section>


  <section title="Surfaces">
  
    <image url="offscreen.pdf" width="2in"
           caption="An Ibex surface positioned at (83,0)"/>
    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).

    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.
      
  </section>
  
  <section title="Boxes">
  
    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**.
     
    There are three ways to think of a box:
    <list>
  
        As a rendered visualization on the screen (the "**Visual Representation**")
  
        As a JavaScript object (the "**Object Representation**")
  
        As as an XML tag (the "XML Template Representation").
  
    </list>

    <image url="threeviews.pdf" caption="The three representations of an Ibex box"/>
  
    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.
      
  </section>
  
<section title="The XML Template Representation">

  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.

  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, will construct a tree of boxes which has the
  visual appearance and behavior of a scrollbar.
    
  Although it is useful to think of the XML tags as being boxes, keep
  in mind that the XML representation is only a blueprint for
  constructing a tree of JavaScript objects.  Once the template has
  been instantiated, the XML is effectively "thrown away", and
  JavaScript code is free to alter the boxes.  Once the process of
  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]]
  operator.

  Each template is an XML document whose root element is
  [[&lt;ibex>]].  Here is a sample template file:

  <pre>
  <ibex xmlns:lib="ibex.lib">

      <meta:doc>
          This is a cool widget.
      </meta:doc>

      // this code is executed only once
      static = { instances : [] };

      // this element applies the ibex.lib.focusable template
      <lib:focusable/>

      <ui:box cols="5">
          static.instances.push(thisbox);
          <ui:box id="container"/>
          <ui:checkbox/>
          <ui:box>
              <lib:scrollbar/>
          </ui:box>
      </ui:box>
  </ibex>
  </pre>

  The following two namespaces are predefined and need not be declared
  using [[xmlns]]:

  <definition term="meta">
      [[http://xmlns.ibex.org/meta]]

      This will be referred to as the "[[meta]] namespace" in the
      remainder of this document.
      </definition>

  <definition term="ui">
      [[http://xmlns.ibex.org/ui]]

      This will be referred to as the "[[ui]] namespace" in the
      remainder of this document.
      </definition>

  Additionally, the default namespace for the document will be set to
  the template's package FIXME.

  <section title="Static Code">

    If the root [[&lt;ibex&gt;]] 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:
  
    <definition term="ibex">
      The Ibex Object (described in <ref section="The Ibex Object"/>)
      </definition>
  
    <definition term="static">
      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
      </definition>
  </section>
  
  <section title="Metadata">

    Any immediate children of the root element which are in the
    [[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:
  
    <list>
        [[&lt;meta:doc&gt;]]: structured documentation for the
        template.
    </list>

  </section>

  <section title="Other Elements">

    All remaining children of the root element are treated as elements
    to be **applied** to the box, in the order in which they appear
    in the file using the following procedure.
  
    <remark text="While this process outlined below sounds very
                  complex, it actually works pretty intuitively. The
                  description below is given in great detail since
                  most applications will wind up being unintentionally
                  dependent on subtle features of this process.
                  However, most of the time you can just pretend that
                  the XML tags and the boxes are the same thing."/>

      <heading title="Intuitive Description"/>

      ... FIXME

      During a box initialization, script-private references to a
      box's 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:
      
      <pre>
      <ui:box>                           <ui:box>
          <ui:box id="foo"/>                 <ui:box/>
          $foo.color = "red";             var $foo = this[0];
                                          $foo.color = "red";
      </ui:box>                          </ui:box>
      </pre>

      <heading title="Precise Description"/>
  
      To apply an XML tag [[__x__]] to a box [[__b__]], perform the following
      operations, in this order:
      
      <list type="ordered">
  
          Allocate a fresh scope [[__s__]] whose parent scope is
          [[__b__]].
          
          Process each child element or text segment of [[__x__]]
          in the order they appear in the document:
  
          <list>
  
              Treat each text segment [[__t__]] as JavaScript code
              and execute it with [[__s__]] as the root scope.
  
              For each child element [[__x'__]] of [[__x__]]:
  
              <list>
                  Create a new box [[__b'__]].
                  
                  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'__]].
                  
                  (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'__]]
                  
                  Copy any [[$]]-variables created during the application
                  of [[__x'__]] into scope [[__s__]].
                  
                  Append [[__b'__]] as the last child of [[__b__]].
              </list>
          </list>
          
          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
          performed, with the following exceptions:
  
          <list>
              If the value portion of the attribute is the string
              "[[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 ([[$]]),
              retrieve the value of the corresponding variable in
              [[__s__]] and use that value instead.
           
              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).
          </list>
      </list>

      <heading title="Initialization Invariants"/>  

      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:
               
      <list type="unordered">
  
          A given box will be fully initialized before its parent is
          given a reference to that box.  This way, parents can be
          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)
          placed by the script.
  
      </list>

  </section>
    
</section>

<!-- ----------------------------------------------------------------------- -->
<section title="Rendering">

      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.
      
      <heading title="Boxes Don't Have to Be Rectangular"/>

      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.

      <section title="Visual Elements">

      The appearance of a box consists of three visual elements: its
      path, stroke, and fill.
      
      <property name="path" type="string" default='""'>
          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 <link
          url="http://www.w3.org/TR/SVG11/paths.html" text="SVG 1.1,
          section 8"/>.

    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.
         </property>
    
    <property name="stroke" type="string" default="clear">
          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
          <link url="http://www.color.org/ICC-1A_1999-04.PDF"
          text="ICC"/> 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).
          </property>
    
      <property name="fill">
          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).
          </property>
      </section>   

      <section title="Text">

      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.

    <property name="text" type="string" default='""'>
      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:
      </property>

      <list>
          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.
      </list>
    
    <property name="font" type="stream" default=".ibex.ui.font.sansserif">
        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 <link url="http://www.freetype.org" text="FreeType 2
        library"/>, 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.
        </property>
     </section>

     <section title="Transformations">
      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 <link
      url="http://www.w3.org/TR/SVG11/coords.html" text="SVG 1.1,
      section 7"/>, and include rotation, shearing, scaling, and
      translation.

      <property name="transform">
          FIXME
      </property>

      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.
    </section>

  <section title="Layout Properties">

    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.
    
    <property name="packed" type="boolean" default="true">
        The layout strategy for this box.  If set to [[true]], the
        box occupies no cells and is laid out independently of its
        siblings.
        </property>
    
    <property name="zoom" type="boolean" default="false">
        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.
        </property>
    
    <property name="shrink" type="boolean" default="false">
        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.
        </property>
    
    <property name="x y" type="integer" default="varies">
        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.
        </property>
    
    <property name="minwidth minheight" type="integer" default="0">
        The desired minimum width and height.  See the [[zoom]]
        property for a description of how the box is altered to meet
        these constraints.
        </property>
    
    <property name="maxwidth maxheight" type="integer" default="ibex.ui.maxdim">
        The desired maximum width and height.  See the [[zoom]]
        property for a description of how the box is altered to meet
        these constraints.
        </property>
    
    <property name="width height" type="integer">
        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).
        </property>
    
    <property name="cols rows" type="integer" default="0">
        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.
        </property>
    
    <property name="colspan rowspan" type="integer" default="1">
        The number of (columns/rows) that this box spans within its parent.
        </property>
    
    <property name="aspect" type="float" default="0.0">
        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.
        </property>
    
    <property name="visible" type="boolean" default="true">
        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]].
        </property>
    </section>

</section>
  
<section title="Layout Algorithm">

      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
      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
      tree (packing is preorder, constraining is postorder), and the
      placing and rendering phases are performed in a second traversal
      of the tree (first placing, then rendering, both preorder).
      
      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
      are closely related.
      
    <section title="Packing">
  
      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.
          
      <heading title="Target Regions"/>

      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:

      <property name="pinned" type="box" default="null">
          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).
          </property>

      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
      before proceeding to the next row; otherwise rows come before
      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).  <image url="layout.pdf" width="1in"/>
      
      <pre>
      <ui:box cols="3">
          <ui:box id="1" />
          <ui:box id="2" rowspan="2" />
          <ui:box id="3" colspan="2" />
          <ui:box id="4" />
          <ui:box id="5" colspan="2" />
      </ui:box>
      </pre>
      
      </section>
  
    <section title="Constraining">
      Each box's minimum width is computed recursively as the
      maximum of:
  
      <list>
          Its [[minwidth]]
               
          The width of its [[path]]
               
          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).
      </list>

      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]].
    </section>  

    <section title="Placing">

      <heading title="Target Origin"/>

      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:

      <property name="origin" type="string" default="center">
          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.
          
          If the [[origin]] property is "[[topleft]]",
          "[[bottomleft]]", "[[topright]]", or "[[bottomright]]", then
          the target origin is at the corresponding corner of the
          target region.
          
          If the [[origin]] property is "[[top]]", "[[bottom]]",
          "[[right]]", or "[[left]]", then the target origin is middle
          of the corresponding edge of the target region.
          </property>

      <property name="x y" type="number" default="0">
          Determines the offset from the box's origin at which it will
          be placed.
          </property>

      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.

      <heading title="Non-Packed Boxes with a transform"/>

      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

      <heading title="Packed Boxes"/>

      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:

      <list>
            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).
      </list>

      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:

      <list>
            (__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**)
      </list>

      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.

      <heading title="The Size of the Root Box"/>
  
      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.
      
  </section>

</section>

<!-- ----------------------------------------------------------------------- -->
<section title="Box Properties">

  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**.

  <section title="Child Control Properties">
    
    <property name="redirect" type="box" default="thisbox">
        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
        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
        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
        representing items on the menu are added as children of the menu
        widget, they do not appear until the menu is pulled down.
        </property>
    
    <property name="numeric properties" type="int" default="">
        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 **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.
        </property>
    
    <property name="clip" type="boolean" default="true">
        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
        substantial performance penalty.
        </property>
    
    <property name="numchildren" type="integer" default="0">
        The number of children this box has.
        </property>
    
   
    <property name="surface" type="" default="null">
        If this box has a parent, this property returns
        [[**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.
        </property>
    
    </section>

  <section title="Other Box Properties">
    
    <property name="cursor" type="string" default="null">
        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
        some platforms, resize cursors for opposite directions (such
        as [[northwest]] and [[southeast]] are the
        same).
        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.
        </property>

    <property name="static" type="object" default="N/A">
        Reading from this property will return the parent scope used
        to execute the [[<static/>]] block of the template
        in which the currently-executing code resides.
        </property>
       
    <property name="thisbox" type="box" default=" ">
       Returns a reference to the box itself.
       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.
       </property>
    
    <property name="indexof()" type="function" default=" ">
        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
        has no effect.
        </property>

    <property name="distanceto()" type="function" default=" ">
        This property is actually a function; invoking
        [[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
        can be used to determine the relative placement of two boxes
        on different branches of the box tree.
        </property>

    </section>

  <section title="Root Box Properties">
    
    The following special properties are only meaningful on the root box
    of a surface.
    
    <property name="Focused">
        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.
        </property>
    
    <property name="Maximized Minimized">
        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.
        </property>
    
    <property name="Close">
        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.
        </property>
    
    <property name="titlebar">
        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.
        </property>
    
    </section>

  </section>


<section title="Events">

    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.
    
    <pre>
    <ui:box>
        _Press1 ++= function(b) { ibex.log.info("first"); }
         Press1 ++= function(b) { ibex.log.info("fourth"); }
        <ui:box>
          _Press1 ++= function(b) { ibex.log.info("second"); }
           Press1 ++= function(b) { ibex.log.info("third"); }
        </ui:box>
    </ui:box>
    </pre>

    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).
    
  <heading title="Stopping the Process"/>

    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".
    
  <heading title="Non-Propagating Events"/>

    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.

    <property name="Enter Leave">
        The value [[true]] is written to this property when the mouse (enters/leaves) the box.
        </property>
    
    <property name="SizeChange">
        The value [[true]] is put to this property after the size
        of this box changes.
        </property>

    <property name="ChildChange">
        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.
        </property>
    
  <section title="Listing of Events">
    
    <property name="Press1 Press2 Press3">
        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.
        </property>
    
    <property name="Release1 Release2 Release3">
        Indicates that the use has released a mouse button.
        </property>
    
    <property name="Click1 Click2 Click3">
        Indicates that the user has pressed and released the
        mouse button without moving the mouse much (exactly how
        much is platform-dependent).
        </property>
    
    <property name="DoubleClick1 DoubleClick2 DoubleClick3">
        Indicates that the user has clicked the 
        mouse button twice within a short period of time (exactly how long is platform-dependent).
        </property>
    
    <property name="Move">
        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**
        </property>
    
    <property name="KeyPressed KeyReleased">

        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 <link
        url="http://java.sun.com/products/jdk/1.1/docs/api/java.awt.event.KeyEvent.html#VK_0"
        text=" Java 1.1 API java.awt.event.KeyEvent class"/>.  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.

        <list>
        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.
        </list>
        </property>
    </section>
  <section title="Re-routing events">

    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:
    
    <pre>
    _Press1 ++= function(p) {
        mouse = { x: 32, y: 77 };
    }
    </pre>

    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.
    
    <pre>
    <ui:box>
        _KeyPressed = function(k) { ibex.log.info("first"); }
         KeyPressed = function(k) { ibex.log.info("sixth"); }
        $recipient.target = $target;
        <ui:box id="recipient">
            _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"); }
            <ui:box id="excluded">
                _KeyPressed = function(k) {
                   ibex.log.info("this never happens");
                }
            </ui:box>
        </ui:box>
        <ui:box id="target"> 
            _KeyPressed = function(k) { ibex.log.info("third"); }
             KeyPressed = function(k) { ibex.log.info("fourth"); }
        </ui:box>
    </ui:box>
    </pre>

    </section>

  <section title="Synthesizing Your Own Events">

    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.
    
    </section>
 </section>

</section>

<section title="Ibex Base Services">
<!-- ----------------------------------------------------------------------- -->
<section title="Streams">
    
    <heading title="Every object has a stream..."/>

    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
    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
    box's state.
    
    <heading title="...but streams are not objects"/>
    
    Despite the ubiquity of streams, you cannot actually reference a
    stream, since it is not an object.  Instead, you simply reference the
    object it belongs to.  If you are familiar with Java, this is similar
    to how every Java object has a monitor associated with it, but you
    cannot directly manipulate the monitor (you can't pass around a
    reference to just the monitor).
    
    In the rest of the section we will sometimes refer to "getting
    properties from a stream" or "passing a stream to a function"; this is
    just shorthand for saying to perform those actions on the object the
    stream belongs to.
    
  <section title="Creating Streams from URLs">
    
    You can create a stream from a URL by calling
    
    <pre>
    var r = ibex.stream.url("http://...");
    </pre>
    
    This will return an object whose stream draws data from the specified
    URL.  Streams are loaded lazily whenever possible.
    
    </section>

  <section title="Getting Substreams">

    Most stream objects let you access
    substreams using the usual JavaScript operators [[[]]] and
    [[.]], as well as the [[for..in]] syntax.
    
    <pre>
    // 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"];
    </pre>
    
    </section>

  <section title="The Root Stream">

    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:
    
    <pre>
    ibex..foo
    ibex[""].foo
    .foo
    </pre>

    </section>

  <section title="Static Blocks">

    FIXME

    You can access variables within the static block of a template by
    appending a double period ([[..]]) and the variable name to the
    stream used to load that template:
    
    <pre>
    <!-- org/ibex/themes/linux/scrollbar.ibex -->
            foo = 12;
    ...
    // elsewhere
    ibex.log.print(org.ibex.themes.linux.scrollbar..foo);  // prints "12"
    </pre>
    
    </section>

  <section title="Formatting Streams">

    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 [[<base64/>]] element.
    
    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
    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.
    
    <pre>
    var r5 = ibex.stream.url("data:WFWE876WEh99sd76f");
    var r6 = ibex.stream.url("utf8:this is a test");
    </pre>

    You can read a UTF-8 encoded string from a stream like this:
    
    <pre>
    var myString = ibex.stream.fromUTF(ibex.stream.url("utf8:testing..."));
    </pre>
    You can also parse XML from a stream using SAX like this:
    
    <pre>
    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) { ... }
        });
    </pre>
    
    </section>

  </section>

<!-- ----------------------------------------------------------------------- -->
<section title="The Ibex object">

    The [[ibex]] object is present in the top-level scope of every
    script.  It has the following properties:
    
  <heading title="General"/>

    <property name="ibex.box">
        reading from this property returns a new box
        </property>
    <property name="ibex.clone(o)">
        creates a clone of object
        </property>
    <property name="ibex.bless(s)">
        returns a blessed clone of stream
        </property>

  <heading title="ECMA Library Objects"/>

    <property name="ibex.date">
        reading from this property returns a new date
        </property>
    <property name="ibex.math">
        this object contains the ECMA math functions
        </property>
    <property name="ibex.regexp(s)">
        return a regexp object corresponding to string **s**
        </property>
    <property name="ibex.string">
        this object contains the ECMA string manipulation functions
        </property>

  <heading title="Logging"/>

    <property name="ibex.log.debug(m1, ... mn)">
        log the debug messages **m1** through **mn**.
        **o**
        </property>

    <property name="ibex.log.info(m1, ... mn)">
        log the info messages **m1** through **mn**.
        </property>

    <property name="ibex.log.warn(m1, ... mn)">
        log the warning messages **m1** through **mn**.
        </property>

    <property name="ibex.log.error(m1, ... mn)">
        log the error messages **m1** through **mn**.
        </property>

    <heading title="User Interface"/>

    <property name="ibex.ui.browser(u)">
        opens a new browser window with URL **u**
        </property>

    <property name="ibex.ui.key.control">
        true if the control key is depressed
        </property>

    <property name="ibex.ui.key.shift">
        true if the shift key is depressed
        </property>

    <property name="ibex.ui.key.alt">
        true if the alt key is depressed
        </property>

    <property name="ibex.ui.key.name.alt">
        the name of the "alt" key (usually either "alt", "meta", or
        "option")
        </property>

    <property name="ibex.ui.clipboard">
        the contents of the clipboard; can be read and written to
        </property>

    <property name="ibex.ui.maxdim">
        the maximum dimension of any UI element; usually
        2<sup>31</sup>, but may be smaller
        </property>

    <property name="ibex.ui.screen.width">
        the width of the screen, in pixels
        </property>

    <property name="ibex.ui.screen.height">
        the height of the screen, in pixels
        </property>

    <property name="ibex.ui.mouse.button">
        either 0, 1, 2, or 3, indicating the mouse button currently
        being pressed
        </property>

    <property name="ibex.ui.frame">
        when a box is written to this property, it becomes the root
        box of a new window
        </property>

    <property name="ibex.ui.window">
        when a box is written to this property, it becomes the root
        box of a new frame
        </property>

    <property name="ibex.ui.font.serif">
        an object whose stream is a a builtin serif font
        </property>

    <property name="ibex.ui.font.sansserif">
        an object whose stream is a builtin sans-serif font
        </property>

    <property name="ibex.ui.font.monospace">
        an object whose stream is a a builtin fixed-width font
        </property>

  <heading title="Networking"/>

    <property name="ibex.net.rpc.xml(u)">
        return an XML-RPC call object with endpoint URL **u**
        </property>

    <property name="ibex.net.rpc.soap(u,">
        return a SOAP call object with endpoint URL **u**,
        SoapAction **a**, and XML Namespace **n**
        </property>

  <heading title="Threads"/>

    <property name="ibex.thread">
        when a function is written to this property, a new thread is
        forked to call it
        </property>

    <property name="ibex.thread.yield()">
        yield the current thread
        </property>

    <property name="ibex.thread.sleep(n)">
        sleep for **n** milliseconds
        </property>

  <heading title="Streams"/>

    <property name="ibex.stream.url(u)">
         returns a new object whose stream is drawn from URL **u**
        </property>

    <property name="ibex.stream.unzip(s)">
        unpacks a zip archive from **s**'s stream
        </property>

    <property name="ibex.stream.uncab(s)">
        unpacks a cab archive from **s**'s stream
        </property>

    <property name="ibex.stream.cache(s,k)">
        valign=top>wraps a disk-backed read cache keyed on **k**
        around **s**'s stream
        </property>

    <property name="ibex.stream.watch(s,f)">
        returns an object whose stream is drawn from **s**'s
        stream, but invokes **f(n,d)** as it is read from.
        </property>

    <property name="ibex.stream.parse.xml(s, h)">
        Use SAX to parse the XML document on stream **s** with
        handler **h**
        </property>

    <property name="ibex.stream.parse.html(s, h)">
        Same as [[parse.xml()]], but tries to fix broken HTML.
        </property>

    <property name="ibex.stream.parse.utf8(s)">
        treat **s**'s stream as a string encoded as a UTF-8 byte stream and return the string
        </property>

    <property name="ibex.stream.homedir">
        [[ibex.stream.tempdir]]
        </property>

  <heading title="Cryptography"/>

    <property name="ibex.crypto.rsa(k,s)">
        **not implemented yet:** return a
        stream which rsa-decrypts stream **s** with key **k**
        </property>

    <property name="ibex.crypto.rc4(k,s)">
        **not implemented yet:** return a
        stream which rc4-decrypts stream **s** with key **k**
        </property>

    <property name="ibex.crypto.md5(s)">
        **not implemented yet:** immediately
        MD5-hash stream **s**
        </property>

    <property name="ibex.crypto.sha1(s)">
        **not implemented yet:** immediately
        SHA1-hash stream **s**
        </property>

</section>
<!-- ----------------------------------------------------------------------- -->
<section title="Traps">

    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.
    
    <pre>
    <ui:box>
        foo ++= function(z) {
           ibex.log.info("foo is " + z);
        }
    </ui:box>
    </pre>

    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
    get a reference to the box on which the trap was placed.
    
    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:
    
    <pre>
    <ui:box>
        func ++= function(z) {
            ibex.log.info("called trap " + trapname);
        }
        foo ++= func;
        bar ++= func;
    </ui:box>
    </pre>
    
  <section title="Removing Traps">

    You can remove a trap by using the [[--=]] operator with the same
    function you added as a trap:
    
    <pre>
    <ui:box>
        var myfunc = function(z) { /* ... */ }
        // add the trap
        func ++= myfunc;
        // ...
        // remove the trap
        func --= myfunc;
    </ui:box>
    </pre>
    
    </section>

  <heading title="Multiple Traps on the Same Property"/>

    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
    stored on the box (remember, boxes are objects, so they can hold
    properties just like all other ECMAscript objects).
    
  <section title="Manual Cascades">

    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:
    
    <pre>
    <ui:box color="black">
        color ++= function(c) {
            ibex.log.info("refusing to change colors!");
            cascade = "black";
        }
    </ui:box>
    </pre>

    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:
    
    <pre>
    <ui:box color="black">
        color ++= function(z) {
            color = "black";      // INFINITE LOOP! BAD!!!
        }
    </ui:box>
    </pre>
    To prevent automatic cascading, return [[true]] from your function:
    
    <pre>
    <ui:box color="black">
        color ++= function(z) {
            return true;          // the box's color will not change
        }
    </ui:box>
    </pre>

    </section>

  <section title="Read Traps">

    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.
    
    <pre>
    <ui:box>
        doublewidth [[++=]] function() { return 2 * width; }
    </ui:box>
    </pre>

    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
    to, since the trap does not cascade.
    
    You can manually cascade on read traps as well:
    
    <pre>
    <ui:box>
        text [[++=]] function() { return "my text is " + cascade; }
    </ui:box>
    </pre>

    Read traps are only rarely needed -- most of the time a write trap
    should be enough.
    
    </section>

  <heading title="Prohibited Traps"/>

    To prevent confusing and hard-to-debug behaviors, scripts may not
    place traps on any of the properties described in the sections
    <link text="Box Layout Properties" section="Layout Properties"/>, <link
    section="Child-Control Properties"/>, or <link section="Other Box
    Properties"/> except for [[childadded]],
    [[childremoved]] and [[surface]].  FIXME: remove?
    
  <heading title="Exceptions and Traps"/>

    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.
    FIXME: is this right?

  <heading title="Architectural Significance of Traps"/>

    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.

  <section title="Cloning">

    **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
    original object.  Furthermore, both objects are "equal" as keys in
    hashtables, so:
    
    <pre>
    var hash = {};
    var theclone = ibex.clone(o);
    hash[o] = 5;
    ibex.log.info(hash[theclone]);    // prints "5"
    </pre>

    Any writes to properties on the clone will actually write to
    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
    original object as well.
    
    </section>


  <section title="Contexts">

    From the perspective of an application writer, Ibex is strictly
    single-threaded.  Ibex is always in exactly one of the following three
    **contexts**:
    
    <list type="unordered">

        __Rendering Context__ -- (redrawing the screen)
        
        __Event Context__ (executing javascript traps triggered by an event)
        
        __Thread Context__ (executing a background thread spawned with [[ibex.thread]])

    </list>
    
    There are two important restrictions on what can be done in particular contexts:
    
    <list type="unordered">

        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
        an ancestor box has been written to.
        
        Blocking operations (anything that accesses the network or
        disk) can only be performed in the Thread Context.

    </list>

    </section>

  <section title="Background Threads">

    Ibex offers easy access to threads. Spawning a background thread is as
    simple as writing a function to the [[ibex.thread]] property:
    
    <pre>
    ibex.thread = function() {
        ibex.log.info("this is happening in a background thread!");
    }
    </pre>

    The argument set passed to the function is currently undefined and is
    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
    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,
    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
    compute-intensive operations that keep the CPU busy for more than a
    few milliseconds.
    
    </section>
</section>
<!-- ----------------------------------------------------------------------- -->
<section title="Networking">
    
  <section title="XML-RPC">
    
    XML-RPC objects can be created by calling [[ibex.net.rpc.xml(**XML-RPC
    URL**)]], and then invoking methods on that object. For example,
    
    <pre>
    Press1 += function(v) {
        ibex.thread = function() {
            color = ibex.net.rpc.xml("http://xmlrpc.ibex.org/RPC2/").
                       color.getTodaysColor("Friday");
        }
    }
    </pre>
    
    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
    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
    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
    the <link url="http://www.xmlrpc.org/spec" text="XML-RPC specification"/>. If
    Ibex encounters a network, transport, or session-layer error, it will
    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.
    
    If an object with an associated non-empty stream is passed as an
    argument to an XML-RPC method, it will be sent as a <base64/>
    element. If a <base64/> 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
    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
    first one returns (usually from a seperate thread), the two calls
    will be <link
    url="http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.2.2"
    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

    <pre>
       http[s]://user:password@hostname/
    </pre>

    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 <link
    url="http://www.ibex.org/faq.html#auth" text="broken
    implementation of Basic authentication"/>.
    
    </section>

  <section title="SOAP">
    
    SOAP methods are invoked the same way as XML-RPC methods, but with three differences:
    
    <list type="ordered">

        [[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
        namespace to use.
        
        The actual method invocation takes only one argument, which
        must be an object. This is necessary since SOAP arguments are
        specified by name, rather than ordering.

    </list>
    
    SOAP faults are handled the same way as XML-RPC faults except that the
    capitalization of the [[faultstring]] and [[faultcode]]
    members is all lower-case, to match the SOAP spec. Here is a
    SOAP example:
    
    <pre>
    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
                                } );
        }
    }
    </pre>

    As you can see, SOAP is much more verbose, yet does not offer
    substantially improved functionality. We recommend that XML-RPC be
    used whenever possible, and that SOAP be reserved for legacy
    applications.
    
    The current Ibex SOAP stack does not support 'document style' or
    multi-ref ([[href]]) data structures.
    
    </section>

  <section title="Security">

    Applications downloaded from the network (as opposed to those loaded
    from the filesystem) may only make certain kinds of connections to
    certain hosts.  See Appendix A for a detailed description of the
    security policy.
    
    </section>

  </section>
<!-- ----------------------------------------------------------------------- -->
<section title="Error Handling">

    If the Ibex Core encounters an error while servicing a function call
    originating in JavaScript, the core will throw a string consisting of
    an error code followed by a colon, a space, and a descriptive message.
    For example:
    
    <pre>
    "ibex.net.dns.unknownhostexception: unable to resolve host foo.com"
    </pre>

    The code should be used to determine how the program should respond to
    an error.  The codes are organized in a hierarchy, so the
    string.startsWith() method can be used to determine if an error lies
    within a particular subhierarchy.  The descriptive message portion of
    the string may be shown to the user.
    
    <property name="ibex.assertion.failed">
        an assertion failed
        </property>
    <property name="ibex.io">
        General I/O exceptions
        </property>
    <property name="ibex.io.encoding">
        Error translating between character encodings.
        </property>
    <property name="ibex.io.zip">
        Attempted to access a corrupt zip archive.
        </property>
    <property name="ibex.io.eof">
        End of file encountered unexpectedly
        </property>
    <property name="ibex.net.security.prohibitedHost">
        A piece of untrusted Ibex code attempted to contact a
        restricted host.  See <link appendix="Security Architecture and Considerations"/> for details.
        </property>
    <property name="ibex.net.dns.temporaryFailure">
        An attempt to resolve a hostname failed but it is not known
        for certain that the hostname is invalid.
        </property>
    <property name="ibex.net.dns.unknownHost">
        An attempt to resolve a hostname failed because the hostname
        was invalid.
        </property>
    <property name="ibex.net.socket.closed">
        A socket was closed unexpectedly.
        </property>
    <property name="ibex.net.socket.connectionFailed">
        A connection could not be made to the remote host.
        </property>
    <property name="ibex.net.url.malformed">
        Tried to parse a malformed URL.
        </property>
    <property name="ibex.net.ssl">
        General SSL protocol errors.
        </property>
    <property name="ibex.net.ssl.untrustedCertificate">
        The server's certificate was not signed by a CA trusted by Ibex.
        </property>
    <property name="ibex.net.http.">
        Thrown when an HTTP error code is returned during an
            operation.  The three characters [[**xyz**]] will be
            the three-digit HTTP status code.
        </property>
    <property name="ibex.net.xmlrpc.null">
        The caller attempted to transmit the [[null]] value via XML-RPC.
        </property>
    <property name="ibex.net.xmlrpc.circular">
        The caller attempted to transmit a circular data structure via XML-RPC.
        </property>
    <property name="ibex.net.xmlrpc.specialObject">
        The caller attempted to transmit a "special" object via
        XML-RPC (for example, a Box or the Ibex object).
        </property>
    <property name="ibex.null.put">
        A JavaScript attempted to put to a property on the [[null]] value
        </property>
    <property name="ibex.null.get">
        A JavaScript attempted to get from a property on the [[null]] value
        </property>
    <property name="ibex.null.call">
        A JavaScript attempted to call the [[null]] value
        </property>
    
    If an exception is thrown inside a trap, the exception will propagate
    to the script that triggered the trap.
    
    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
    never shown to the user.
    
  </section>


  <section title="Ibex self-emulation">

    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.
    
    <pre>
    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);
    </pre>

    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:
    
    <list type="unordered">
        
        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:

        <list>
            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.
        </list>
        
        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.

    </list>

    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:
    
    <pre>
    var newLoadFunction = function(url) { /* ... */ };
    var new_ibex = ibex.clone(ibex);
    new_ibex.load ++= function() { return newLoadFunction; }
    ibex.apply(ibex.box, .main, new_ibex);
    </pre>
</section>
</section>

<!-- ----------------------------------------------------------------------- -->
<appendix title="Security Architecture and Considerations">
    
    Due to the expense and hassle imposed by the commercial PKI code
    signing architecture, and the fact that it <link
    url="http://www.counterpane.com/pki-risks-ft.txt" text="doesn't
    really provide any security anyways"/>, Ibex user interfaces are
    distributed as unsigned, untrusted code. As such, they are handled
    very carefully by the Ibex Core, and assumed to be potentially
    malicious.
    
    Ibex's security architecture is divided into defenses against four
    major classes of attacks:
    
  <heading title="Malicious UI attempts to acquire or alter data on the client"/>
    
    Ibex user interfaces are run in an extremely restrictive sandbox. The
    environment does not provide primitives for accessing any data outside
    the Ibex core except via XML-RPC and SOAP calls. There are no
    facilities to allow Ibex user interfaces to access the client's
    operating system or to interact with other applications on the same
    host (unless they provide a public XML-RPC or SOAP interface).
    An Ibex script may only access a file on the user's hard disk if the
    user explicitly chooses that file from an "open file" or "save file"
    dialog. There is one exception to this rule: if all templates
    currently loaded in the Ibex core originated from the local
    filesystem, those templates can load additional .ibexs from the local
    filesystem.
    
    The Ibex Core is written in Java, so it is not possible for
    scripts to perform buffer overflow attacks against the core
    itself.
    
    Ibex applications may only read from the clipboard when the user
    middle-clicks (X11 paste), presses control-V (Windows paste), or
    presses alt-V (Macintosh paste; the command key is mapped to Ibex
    "alt"). This ensures that Ibex applications are only granted access to
    data that other applications have placed on the clipboard when the user
    specifically indicates that that information should be made available
    to the Ibex application.
    
  <heading title="Malicious UI attempts to use client to circumvent firewalls"/>
    
    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
    regular TCP sockets.
    
    Ibex will not allow a script to connect to a non-public IP address
    (10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16, as specified in <link
    url="http://www.cis.ohio-state.edu/cgi-bin/rfc/rfc1918.html" text="RFC
    1918"/>). There is one exception -- if all templates currently loaded
    in the core originated from the same IP address, those scripts may
    make calls to that IP address regardless of whether or not it is
    firewalled.  If Ibex does not have access to a DNS resolver (because it
    is using a proxy which performs DNS lookups), Ibex will provide the
    proxy with the appropriate <link
    url="http://www.ibex.org/x-requestorigin.html"
    text="X-RequestOrigin"/> header that the proxy needs in order
    to maintain security.
    
    The only remaining possible attack is against a XML-RPC or SOAP
    service running on a firewalled host with a public address. Assigning
    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]]".
    
  <heading title="Malicious UI attempts to trick user into divulging secret information"/>
    
    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.
    
  <heading title="Malicious network attempts to snoop or man-in-the-middle transactions"/>
    
    Ibex user interfaces may transmit network data using HTTPS (SSL 3.0)
    for encryption. Ibex will attempt 128-bit encryption, but will
    negotiate down to 40-bit if the server does not support strong
    crypto. Ibex's SSL implementation is currently provided by <link
    url="http://www.ibex.org/tinyssl" text="TinySSL"/> and <link
    url="http://www.bouncycastle.org" text="The Legion of the Bouncy
    Castle."/>
    
    All HTTPS connections must be authenticated by the server using a
    certificate whose name matches the domain name of the HTTPS URL. The
    certificate must be signed by a trusted root CA. Ibex trusts the same
    93 root CAs whose certificates are included as "trusted" in Microsoft
    Internet Explorer 5.5 SP2. This provides a minimal level of protection
    against man-in-the-middle attacks; you should not trust this
    connection with any data you would not normally trust an SSL-enabled
    web browser with.
    
</appendix>

<!-- ----------------------------------------------------------------------- -->
<appendix title="ECMAscript compliance">
    
    Ibex's scripts are written in a modified subset of ECMA-262, revision 3
    (aka JavaScript 1.5). The interpreter strays from the spec in a few
    ways.
    
  <section title="Omissions">
    
    The following ECMA features are not supported:
    
    <list type="unordered">

        The [[undefined]] value, [[===]], and [[!==]]
        
        The [[new]] keyword (and ECMAScript object inheritance)
        [[eval]]
        
        [[getter]] and [[setter]]
        
        The ECMA [[this]] keyword.
        
        The [[String]], [[Number]], and [[Boolean]]
        classes.  Note that [[string]], [[number]], and
        [[boolean]] values are supported, however.
        
        You may not [[throw]] the [[null]] value.

    </list>
    
    Additionally, you must declare all root-scope variables (with
    [[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.
    
    </section>

  <section title="Extensions">
    
    <list type="unordered">
    
        The token [[..]] is equivalent to [[[""]]].
    
        Trapping

        Cloning
    
        Extended [[catch]] syntax.  The following code:
        <pre>
        } catch(e propname "foo.bar.baz") {
           // ...
        }
        </pre>
        Is equivalent to:
        <pre>
        } catch(e) {
           if (e.propname != null and e.propname >= "foo.bar.baz" and
               "foo.bar.baz/" > e.propname) {
               // ...
           }
        }
        </pre>
        Multiple extended-catch blocks can appear at the end of a single try
        block.  However, at most one non-extended catch block may appear, and
        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 [[&lt;]], the lexical
        token "[[gt]]" is be interpreted as [[&gt;]], and the
        token "[[and]]" is interpreted as [[&amp;&amp;]].
        Thus these tokens cannot be used as variable names.
    
        The identifier [[static]] is a reserved word in
        ECMAScript, but not in Ibex.
    
        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]].
    
        To ensure that Ibex files appear the same in all text editors, tab
        characters are not allowed in Ibex files.

    </list>
    
    Some useful tutorials include:
    
    <list type="unordered">
        
        Netscape's <link
        url="http://developer.netscape.com/docs/manuals/communicator/jsref/index.htm"
        text=" JavaScript 1.2 Reference"/>. Although this document is
        out of date, it is arguably the best guide available for free
        on the Internet. The changes from JavaScript 1.2 (aka ECMA-262
        r1) to 1.5 were minimal, and many of them were <link
        url="ecmascriptcompliance" text="omitted"/> from Ibex.
        
        O'Reilly's <link
        url="http://search.barnesandnoble.com/booksearch/isbnInquiry.asp?isbn=0596000480"
        text=" JavaScript: The Definitive Guide"/>, by David Flanagan
        and Paula Ferguson. The latest edition of this book covers
        JavaScript 1.5 (ECMA-262 r3).
        
        The official <link
        url="http://www.ecma.ch/ecma1/STAND/ECMA-262.HTM"
        text="ECMA-262"/> specification. This is an extremely
        technical document.

    </list>
    </section>
</appendix>

<!-- ----------------------------------------------------------------------- -->
<appendix title="Logging and Command Line Invocation">
    
    <pre>
    Usage: ibex [-lawp] [ url | file | directory ]
        -l [level]      set logging level to { debug, info (default), warn, error, silent }
        -l rpc          log all XML-RPC and SOAP conversations
        -l user@host    email log to user@host
        -l host:port    emit log to TCP socket
        -l [file]       write log to a file on disk
        -a              check assertions
        -w [window-id]  reserved for libibex
        -p              dump profiling information [not yet supported]
    </pre>

    If Ibex encounters a serious problem before it starts logging
    information, or if it is unable to open the log file, it will abort
    immediately with a critical abort, which will be displayed on the
    console for POSIX-native cores and in a dialog box for JVM-based and
    Win32-native cores.

    Note that Microsoft Windows does not provide any mechanism for
    redirecting standard input/output of an application which is not
    compiled as a "console application".  Therefore, Ibex is compiled
    as a "console application", and will open a console window when
    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]]
    archive, or the path to a directory comprising an unpacked
    [[.ibex]] archive.
    
    The [[**initial-template**]] parameter is the stream name of
    a template to be used as the initial template. If ommitted, it
    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
    option will also substantially decrease Ibex's performance.
    
  </appendix>

<!-- ----------------------------------------------------------------------- -->
    <!--
<appendix title="Grammars">

    **Grammar support is experimental in this release
    and may not work properly.  It may change in incompatible ways or
    disappear completely from future releases**
    
    Grammars are defined with a statement in the following form:
    
    <pre>
    a ::= b { c }
    </pre>
    A grammar is really just another function; once defined you can't tell
    it apart from an ordinary function.  A grammar takes one argument,
    which can be a string or stream.  The argument is parsed and the
    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
    (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
    value is not a grammar, the value is discarded and a new grammar
    object is created.
    
    The value 'b' is a pattern, which may consist of seven simple
    primitives:
    
    <list type="unordered">
        string literals
         
        grouping parens [[()]]
         
        combinators:   [[ | + * ?]]
         
        references to other grammars
    </list>

    The value 'c' and the braces surrounding it are an *optional* code
    block, in which the following identifiers are bound:
    
    <list type="unordered">
         
       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; }]]".
         
       For every reference to another grammar which was matched in the
       pattern, the *name used to reference that other grammar* will
       be bound to the value returned by its code block.  Here's an
       example of this important distinction:
        
       <pre>
       var foo ::= 'a' | 'b';
       var bar ::= foo;
       var baz ::= 'c' | bar    {  /* foo is not defined here, but bar is */ };
       </pre>
        
       On the last line, the identifier 'bar' serves two purposes: it
       pulls in the definition of the pattern *and* acts as a binder
       within the scope of the braces.
        
       If a reference is matched multiple times (either because it
       appears multiple times in the pattern or because the * or +
       operator was applied to it) then its name will be bound to an
       array containing the matches.

    </list>

    Here is the metacircular definition of the grammar facility:
    
    <pre>
         grammar ::= identifier '::=' pattern (';' | '{' code '}' ';'?)
      identifier ::= ('a'..'z' | 'A'..'Z' | '_' | '$') (identifier | '0'..'9')*
            char ::= '\0x0000'..'\0xffff'
         literal ::= '\'' char+ '\''
                   | '\'' char '\'' '..' '\'' char '\''
         pattern ::= identifier
                   | literal
                   | '(' pattern ')'
                   | pattern '+'
                   | pattern '?'
                   | pattern '*'
                   | pattern pattern
                   | pattern '|' pattern
    </pre>
    -->
    
**
Copyright (C) 2004 Adam Megacz, verbatim redistribution permitted.
Ibex is a trademark of Adam Megacz
**

</ibex-doc>
