+<section title="Advanced Topics">
+
+ <section title="Re-routing events">
+
+ At any point in the Event Context, you can write to the <t>mouse</t>
+ property on any box. The value written should be an object with two
+ properties, <t>x</t> and <t>y</t>. For example:
+
+ <pre>
+ _Press1 ++= function(p) {
+ mouse = { x: 32, y: 77 };
+ }
+ </pre>
+
+ The coordinates specified are relative to the box whose <t>mouse</t>
+ property is being written to. There is no need to supply the
+ <t>inside</t> property; it is computed automatically. Writing to
+ the <t>mouse</t> property causes Ibex to recompute the eventual
+ target box, and also alter the values returned by <t>mouse.x</t>,
+ <t>mouse.y</t>, and <t>mouse.inside</t> for any <i>descendants</i>
+ of the current box. Writing to the <t>mouse</t> 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>
+ <box>
+ _KeyPressed = function(k) { ibex.log.info("first"); }
+ KeyPressed = function(k) { ibex.log.info("sixth"); }
+ $recipient.target = $target;
+ <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"); }
+ <box id="excluded">
+ _KeyPressed = function(k) {
+ ibex.log.info("this never happens");
+ }
+ </box>
+ </box>
+ <box id="target">
+ _KeyPressed = function(k) { ibex.log.info("third"); }
+ KeyPressed = function(k) { ibex.log.info("fourth"); }
+ </box>
+ </box>
+ </pre>
+
+ </section>
+
+ <section title="Synthesizing Your Own Events">
+
+ You can create "fake events" by simply writing to the <t>mouse</t>
+ 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 title="Ibex self-emulation">
+
+ When the core first starts up, it clones the <t>ibex</t> object,
+ creates a stream for the initial .ibex, and then places a trap on the
+ cloned <t>ibex</t> object so that its empty-string property returns
+ the .ibex stream. The cloned Ibex object is then passed as the third
+ (optional) argument to <t>ibex.apply()</t>, making it the default
+ <t>ibex</t> 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 <t>ibex.bless()</t> 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
+ <i>monadic</i>).
+
+ 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
+ "<t>.ibex</t>" is appended.
+
+ If the stream is an image, the string "<t>.png</t>" is
+ appended. If no stream is found, "<t>.jpeg</t>" and
+ "<t>.gif</t>" are tried, in that order.
+
+ If the stream is an font, the string "<t>.ttf</t>" is
+ appended.
+ </list>
+
+ Every call to <t>ibex.bless()</t> 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 <t>ibex.clone()</t> 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>
+
+<!-- ----------------------------------------------------------------------- -->