TIBET Logo

The TIBET Tag System

Markup

wins

  • Componentize development within and across projects with reusable tags.
  • Accelerate development through improved tooling and top-down workflows.
  • Integrate seamlessly with business and government XML standards.
  • Minimize risk associated with hiring and retaining JavaScript coders.
  • Simplify training and onboarding of your developers and QA personnel.

contents

concepts

cookbook

Tags
Signals
Namespaces

code

TIBET's tag system is the foundation of TIBET's tag-based development approach.

By focusing your development effort on creating components as tags each new component you define reduces the amount of JavaScript code you have to write in the future. This approach is in stark contrast to frameworks whose component consumption model is code-centric and it's one of the pillars of TIBET's authoring pyramid.

Tag-driven development in TIBET is a top-down process with drag-and-drop simplicity, not one driven by cumbersome code-compile-reload cycles.

"Prototype-to-production". That's the iterative development model we designed TIBET to support, a model that allows you to rough in components and then iterate on their structure, style, and behavior without reloads, compilers, or a heavy focus on code.

Tag Creation

The TIBET CLI supports tag creation via the tibet type command. This command lets you specify "dna" via a --dna flag. Common tag-specific dna options are templatedtag, compiledtag, actiontag, and infotag. See the Cookbook for details.

An easier and more interactive approach is to use the Sherpa.

With the Sherpa loaded and active you can create tags "from thin air" or from existing elements in the page. Creating new tags from scratch lets you build out new functionality in a prototyping fashion. Coalesing existing tags lets you refactor your UI as you go.

from thin air...

Drag a new "tofu" element from the inspector's lower toolbar and drop it in your page where you envision the new tag. The tofu dispenser is the white rectangle with the dotted top edge at the bottom center in the image below:


Tofu Dispenser

The Tofu Dispenser


Dragging out a new tofu element shifts the display to show you the outlines of the various elements you can target. Hold down the Option key and the display will rotate as you drag, allowing you to drop into elements that otherwise might be inaccessible. You can also drop the tofu element into the Sherpa's DOM sidebar either onto or between elements (the top-left HUD sidebar in the image below):


Tofu Positioning

Tofu Positioning


Once you drop the tofu element in your desired location one of two things will occur. If you dropped into a compiled tag context you'll be presented with that tag's tagCompile method for editing. If you dropped into a templated tag context a dialog will prompt you for information about the new tag insertion via the "New Tag" panel:


Tofu Insertion

Insert New Tag Dialog


Entering a non-existent tag name in the new tag dialog does not trigger an error, instead it causes the system to render a placeholder like the following one:


tofu

This kind of response to new or unknown information is a central theme of TIBET's design. Rather than throwing an error TIBET will often simply prompt you to teach it about the new tag, type, test, or other element you intend to build.

In this case you can define your new tag and click 'Create Type':


Type Assistant

Type Assistant Dialog


Once the tag has been created the new type's code will automatically load, replacing the tofu placeholder with your new tag. Note that what you see will vary based on the supertype you choose for your new tag and its implementation of tagCompile.

from existing elements...

Start by using the Halo to select the root element for your planned tag's template. The Halo display is toggled by the "boxed A" icon on the inspector's lower toolbar, via Shift-Right-Click, or by clicking an element in the Sherpa's DOM sidebar.

Sherpa Halo

Halo / HUD Display


Right-click inside the Halo to bring up the Halo's context menu and pick "Make Custom Tag".


tofu

Halo Context Menu


As with the 'from thin air' case, you will be presented with the 'Type Assistant' dialog (shown in the 'thin air' example) so you can describe your new tag's supertype, namespace, etc.

Once your type has been created your Halo'd selection will be replaced with a version of the newly created tag, fully rendered and ready for additional alteration via the Halo.

Tag Modification

As you select elements with the halo the Sherpa's four core HUD sidebar panels will automatically show you DOM position, style rules, signal responders, and bindings.

For example, in the image below we've selected an <html:div> which is a child of the app tag, itself a child of the body, which is a child of the html element. This div has four style rules applied to it, 3 responders, and a data binding reference:

Sherpa Halo

Selecting elements in a sidebar will trigger a context-sensitive operation:

  • Clicking a DOM element causes the halo to focus on that element.
  • Clicking a style rule will take you to that rule, allowing you to edit it.
  • Clicking a responder tile lets you view signal handlers on that responder.
  • Clicking a binding reference lets you adjust the data bindings.

Each operation is context-sensitive and any edits you make can be applied immediately without reloading, allowing you to work quickly and interatively.

You can also use the halo's context menu to access common operations like inspecting the tag's type, emptying it, removing it, etc.

Future versions will allow you to perform true "GUI builder" operations on the element such as cloning, resizing, styling, and so on.

Thanks to the halo and HUD the Sherpa keeps your development focused on your tags, their structure, their style, and their behavior.


concepts

If the web had been forced to rely on JavaScript programming to produce web sites, blogs, articles, etc. we'd have never seen a billion pages much less the estimated 4.6 billion indexed today. The web grew to scale because it relied on markup for authoring.

When we look at the millions of custom applications which need to be ported to the web we can't help but think that we need to take the same scalable approach to application development - markup augmented by JavaScript, not authored in it.

Unfortunately there are no tags in HTML5 for menubars, toolbars, status bars, tabs, dialog panels, drawers, tree-grids, or enterprise-level data tables. There are no tags for business graphics such as bar chart, line chart, etc. Building these out of native HTML5 is possible, but that's an approach entirely devoid of leverage and semantics.

The TIBET Tag System builds on TIBET's OO/Traits and Signaling functionality to support creation, composition, and reuse of semantic markup in the form of smart tags.

Tags All The Way Down

We often say TIBET is 'tags all the way down'. We're not kidding. From the moment your application starts you're running a system whose focus is processing tags.

The default starting point for every TIBET application is the <tibet:root> tag.

The <tibet:root> tag decides whether to render itself as a <tibet:sherpa> tag or the content of your application's home.xhtml page based on the profile you are loading. If you're configured to run the Sherpa the <tibet:sherpa> tag renders and loads your application home page inside the Sherpa, otherwise your home page loads directly.

Typical TIBET home pages are almost empty, the <body> tag normally contains a single "app tag" representing your application. Typical application tags might render as header, nav, content, and footer tags, which themselves render subcomponent tags and so on until tag expansion completes. At each layer, functionality is modularized into tags.

XHTML/XML

For maximum power and flexibility TIBET is a strict XHTML5 framework. This choice greatly enhances interoperability and toolability, making it easier to ensure quality.

As an XHTML framework TIBET fully supports XML namespaces. Your application's tags are automatically created in their own namespace to keep them separate and sharable. For example, when you tibet clone a new project named hello TIBET will automatically ensure there's a hello namespace ready for that project's tags and types.

TIBET ensures all rendering surfaces are XHTML surfaces, meaning TIBET can render XML directly, without conversion or templating. This feature makes integrating XML services almost frictionless. XML can be used without conversion as a data source or sink for Data Binding. With TIBET there's no need to convert ATOM or other XML formats for use.

Finally, TIBET handles namespaced attributes. TIBET recognizes prefixed attributes and delegates their processing to the namespace's root type, allowing "cross-cutting" behavior to be applied to your tags. The TIBET on: namespace is the most common example of a cross-cutting attribute. The TIBET bind: namespace is another great example.

Tag Types

We skipped over it earlier but when we say 'tag' there are really two halves to the story. There's the authored markup in the page and there's a matching TIBET Type responsible for that markup both at compile time and at runtime.

Most tags in TIBET inherit from CompiledTag, TemplatedTag, ActionTag, or InfoTag. Ultimately all tags are subtypes of TP.core.ElementNode meaning they all have an associated DOM element, but keep in mind not all DOM elements are visual UI elements.

Templated tags, the most common form, do all their transformation through external template files. Templates can be authored in XHTML, SVG, or other XML dialects and can take advantage of all of the features of TIBET Templating, from substitutions to formatters.

A compiled tag is a tag whose replacement element(s) are produced by its implementation of a tagCompile method. While a templated tag gets its replacement element(s) from a template file, compiled tags build them via code. As a result, compiled tags tend to leverage TIBET Node Objects and TIBET Primitives to create their expanded forms.

Action tags are tags without a UI which can be used to trigger activity. In a page context a common example is the tibet:service tag which can communicate with a remote service. You won't see the tag in your UI but other UI elements can bind to it to set parameter values or access the result data directly from markup.

All commands executed in the TIBET Shell are action tags. For example, entering :help actually executes the tsh:help action tag. This unique feature of TSH means you can place TSH commands in the form of action tags directly in pages and trigger them via your UI. The Sherpa is built in this fashion, triggering TSH operations from much of its UI.

Info tags, like action tags, typically have no UI. Instead, they provide a way to factor common data into a single location used by other tags in the page. Info tags are particularly useful in anchoring static data like state or country lists in support of TIBET Data Binding.

An additional feature of TIBET's tag system is that native HTML5 tags also have types and can leverage all the features available to custom tag types.

Phased Processing

TIBET's tag processing engine, the collected logic which converts your tag "macros" into their runtime equivalents, works in a phased fashion.

At a large-grained level there are 3 conceptual phases: compilation, attachment, and detachment. Within each large-grained conceptual phase TIBET has a set of fine-grained phases it uses to process tags to ensure proper operation.

Here's the default list taken from the current codebase:

//  A set of phase types used when 'compiling' or transforming content from one
//  representation into another.
TP.core.TagProcessor.Type.defineConstant(
    'COMPILE_PHASES', TP.ac(
    'TP.core.IncludesPhase',        //  xi:includes, CSS @imports, etc.
    'TP.core.InstructionsPhase',    //  ?tibet, ?xsl-stylesheet, etc.
    'TP.core.PrecompilePhase',      //  conversion to compilable form
    'TP.core.CompilePhase',         //  tag/macro expansion (ACT)
    'TP.core.TidyPhase',            //  move non-DTD content out of html:head
                                    //  etc.
    'TP.core.ResolvePhase',         //  resolve xml:base TP.core.URI references,
                                    //  decode etc.
    'TP.core.LocalizePhase'         //  adjust for browser, lang, etc.
));

//  A set of phase types used when 'attaching' content to a visual DOM
TP.core.TagProcessor.Type.defineConstant(
    'ATTACH_PHASES', TP.ac(
    'TP.core.AttachDOMPhase',       //  Late additions to the DOM needed for
                                    //  visual structuring
    'TP.core.AttachEventsPhase',    //  ev: namespace. NOTE others can generate
    'TP.core.AttachSignalsPhase',   //  on: namespace (for non-native events)
    'TP.core.AttachDataPhase',      //  model construct et. al.
    'TP.core.AttachInfoPhase',      //  other info tags (acl:, dnd:, etc)
    'TP.core.AttachBindsPhase',     //  data bindings in the bind: namespace
    'TP.core.AttachStylePhase',     //  CSS is near end so display: none can
                                    //  flip late
    'TP.core.AttachCompletePhase'
));

//  A set of phase types used when 'detaching' content from a visual DOM
//  Note how these are reversed from the attach phases, to give things that rely
//  on these phases chance to unwind in reverse order.
TP.core.TagProcessor.Type.defineConstant(
    'DETACH_PHASES', TP.ac(
    'TP.core.DetachStylePhase',
    'TP.core.DetachDataPhase',
    'TP.core.DetachBindsPhase',
    'TP.core.DetachInfoPhase',
    'TP.core.DetachSignalsPhase',
    'TP.core.DetachEventsPhase',
    'TP.core.DetachDOMPhase',
    'TP.core.DetachCompletePhase'
));

Looking at the COMPILE_PHASES we can see that TIBET first processes any includes or imports which might alter the target DOM. We then handle any processing instructions. Next is any pre-compilation needed to get the DOM ready for the core tag conversion process. Tags are then converted. Once that has completed the DOM can tidy up, resolve any URL-sensitive attributes, and perform browser and/or language specific localizations.

The ordering of TIBET's fine-grained compile phases is consistent with web standard ordering used by browsers when processing pages. If you load a page into the browser, for example, it will first process includes and imports per W3C standard requirements. Then it will handle any processing instructions and so on. TIBET's tag processor follows the same sequencing.

Phase processing is object-oriented. Each phase's processing is delegated by the engine to a TIBET type associated with that phase. For example, the TP.core.CompilePhase type handles the 'compile' step. Phase types typically implement a queryForNodes method and provide a targetMethod name to be invoked on nodes in their result set.

Tags which match a phase's query and implement a phase's target method have it invoked during that phase, allowing each tag type to control if and when it will be messaged.

Here's the core list of method names tag authors can leverage by default:

tagAttachDOM
tagAttachEvents
tagAttachSignals
tagAttachData
tagAttachInfo
tagAttachBinds
tagAttachStyle
tagAttachComplete

tagDetachStyle
tagDetachData
tagDetachBinds
tagDetachInfo
tagDetachSignals
tagDetachEvents
tagDetachDOM
tagDetachComplete

tagIncludes
tagInstructions
tagPrecompile
tagCompile
tagTidy
tagResolve
tagLocalize
tagCompileComplete

Most tags only implement a handful of phase methods, tagCompile, tagAttachDOM, and tagDetachDOM being the most common.

Event Handling

TIBET tags are full participants in TIBET's signaling system and benefit from a number of unique aspects of that infrastructure. To get a full sense of what's possible we recommend you read up on signaling in TIBET, particularly responder signaling.

As a quick summary/recap:

  • DOM signals in TIBET all start with DOM such as TP.sig.DOMClick. DOM signals use a DOM_FIRING policy which implements a full capture/target/bubble "V" in accordance with W3C standards for DOM Level 2 event firing.
  • Responder signals can have any name, but common ones mapped to DOM events start with UI. The names are often parallel, e.g. UIFocus vs. DOMFocus, but a notable exception is TP.sig.UIActivate the typical signal for unifying click and keyup.
  • You can map a DOM signal to a Responder signal using on: attributes. For example: <button on:click="Save">Save</button>. With this simple syntax a DOM 'click' will result in a Signal of 'Save' and a search for 'Save' handlers, not click handlers.
  • Responder signal firing extends beyond the DOM and includes the application's current controller stack, the application object, and the Sherpa if it's running. Like DOM firing, responder firing also implements a full capture/target/bubble "V".
  • The DOM portion of responder signal chains is computed using any tibet:ctrl and tibet:tag attribute values found from the target to the document along the ancestor chain. DOM elements without tibet:ctrl or tibet:tag are skipped. Any tibet:ctrl value found is invoked before tibet:tag to support instance-specific controllers.

Using TIBET's defineHandler method you can create handlers on your various tag and controller objects which will automatically be invoked by TIBET for matching events, eliminating event-related boilerplate and helping to organize your code.

It's important to remember that UI-generated signal handlers are almost always invoked on instances rather than types, so you want to target .Inst with your handler:

APP.demo.Application.Inst.defineHandler('Save', function(aSignal) {
    APP.info('Application: ' + aSignal.getSignalName();
});

Combining the above handler definition with the earlier on:click="Save" is all it takes to tie a control to the handler. There's no add/remove listener overhead and naming conventions help organize the code automatically. If you want to refactor the behavior to a tag or a separate controller just move the handler to the desired target object.

Handlers can be tied to specific signals, specific origins, specific application states, or can target variations such as all signals from a specific origin, all signals of a certain type regardless of origin, etc. See TIBET Signaling for details.

Type vs. Inst

One of the organizing principles behind TIBET's tag layer is that "compile time" (pre-attach) operations are normally handled by type methods while "runtime" operations such as responding to user events are handled as instance methods.

The decision to use type methods for operations such as tagCompile doesn't negatively impact your ability to reuse supertype functionality in your tag hierarchy. TIBET's OO layer fully supports inheritance of type methods and attributes.

The split between type and inst responsibilities is something to keep in mind when overriding the various phase methods or defining signal handlers. Be sure to use the proper .Type or .Inst qualifier for the target functionality. You can also leave the qualifier off if you want a "local" method only the specific object you're messaging will implement.

Tooling

TIBET does a lot of sugaring behind the scenes to keep your authoring simple and largely unburdened by XML's quirks. In addition, TIBET's CLI and Sherpa™ make tags easy.

From the CLI you can use the tibet tag command to create new tags and add them to your project. You can also use tibet reflect and tibet apropos to find and learn new tags.

The Sherpa makes tag-based development even easier. With the Sherpa you can create new tags directly in your UI, combine existing tags into new ones, edit tag templates, styles, and behavior, and much more...all without a single reload.


cookbook

Tags

Create/Use A Templated Tag

Templated tags are tags whose DOM representation is produced by an external template file rather than JavaScript. Common template formats are XHTML and SVG but you can use other forms of XML as well.

Templates undergo initial interpolation during tag processing to resolve any TIBET Templating syntax. This process is independent of any data binding syntax in your template.

To create a templated tag type along with a matching stylesheet, template, and test file, use the tibet type command with --dna templatedtag:

$ tibet type demo:sample --dna templatedtag
working in: /Users/ss/temporary/demo/_sample_
processing directories...
processing templates...
templating complete...
positioning files...
positioning complete...
adjusting package entries...
<script src="~app_tags/APP.demo.sample/APP.demo.sample.js"/> (added)
<script src="~app_tags/APP.demo.sample/APP.demo.sample_test.js"/> (added)
New configuration entries created. Review/Rebuild as needed.
Cleaning up working directory.
Type DNA 'templatedtag' cloned to ~app_src/tags as 'sample'.

Once your tag has been created edit the tag's default template file, usually found in ~app/public/src/tags, and provide the content your tag requires.

You can adjust the style for your tag by editing the stylesheet created for the tag by the type command, normally found in the same location as your tag type.

Be careful to use valid XML syntax in your template files (XHTML, SVG, etc).

Also, if you convert your tag to XHTML, be sure to include a tibet:tag attribute with the original tag name in your template markup to tie it back to your type:

<div tibet:tag="demo:sample">
Hello World!
</div>

Note that you're not required to define the tibet namespace (or other common namespaces), TIBET will do that automatically. However, if you want to validate your templates via XML Schema you'll need to author them as fully-compliant XML.

Using your new tag is easy, just inject it where you need it, either within another tag's template, or by generating it from a tagCompile method. Recall that tag style sheets are pulled in as soon as TIBET sees your tag, there's no need to add them yourself.

Create/Use A Compiled Tag

Compiled tags are the common alternative to templated tags when you need more control over production of your tag's DOM replacement content.

To create a compiled tag type along with a stub stylesheet and test file, use the tibet type command with --dna compiledtag:

$ tibet type demo:sample --dna compiledtag
working in: /Users/ss/temporary/demo/_sample_
processing directories...
processing templates...
templating complete...
positioning files...
positioning complete...
adjusting package entries...
<script src="~app_src/tags/APP.demo.sample/APP.demo.sample.js"/> (added)
<script src="~app_src/tags/APP.demo.sample/APP.demo.sample_test.js"/> (added)
New configuration entries created. Review/Rebuild as needed.
Cleaning up working directory.
Type DNA 'compiledtag' cloned to ~app_src/tags as 'sample'.

Compiled tags generate their DOM representation by overriding tagCompile and returning any DOM elements to be used in place of the originating tag in the DOM. This approach gives you complete control over how your DOM will be modified by the tag.

Each tagCompile method receives a TP.sig.Request object containing the node which is being compiled. You can use TIBET's TP.wrap routine to convert that node to a TIBET node object, or use TIBET's DOM primitives to work with it directly. These APIs can also be used to create new element(s) to be used in replacing the initiating node.

It's important to use TIBET APIs for all your tagCompile operations. Native browser APIs have a variety of bugs and limitations which TIBET addresses in a portable fashion. For example, to build new elements you'd want to use TP.documentConstructElement rather than document.createElement to ensure consistent results.

The tagCompile method should always return an element or document fragment used as the replacement for the triggering element in the DOM. You can return the same element if you don't want to replace, but simply want to alter, the current element.

For example, to update the content of a <demo:sample/> tag with the current timestamp you might implement:

APP.demo.sample.Type.defineMethod('tagCompile',
function(aRequest) {

    /**
     * @method tagCompile
     * @summary Convert instances of the tag into their XHTML form.
     * @param {TP.sig.Request} aRequest A request containing the tag element
     *     to convert along with other optional processing parameters.
     * @returns {Element|Array<Element>} The element(s) to replace the inbound
     *     element with in the final DOM.
     */

    var elem;

    //  Get the initiating element.
    if (!TP.isElement(elem = aRequest.at('node'))) {
        return;
    }

    //  Set its content to the date.
    TP.nodeSetContent(elem, (new Date()).toString());

    //  Return the element.
    return elem;
});

With a working tagCompile implementation in place you can use your new tag by placing it in another tag's template file or generating it in another tag's tagCompile method. (Remember, TIBET is tag based, not page based, so usage centers on editing tags, not pages).

As with templated tags, your compiled tag will have a matching style sheet which you can edit to adjust how your tag and its replacement element(s) should be styled.

Create/Use An Action Tag

Action tags are one of the more interesting facets of TIBET and the TIBET tag system since they let you encapsulate logic you can leverage from both your pages and the TSH.

To create an action tag type along with a matching test file (action tags don't have templates or stylesheets by default), use the tibet type command with --dna actiontag:

$ tibet type demo:doit --dna actiontag
working in: /Users/ss/temporary/demo/_doit_
processing directories...
processing templates...
templating complete...
positioning files...
positioning complete...
adjusting package entries...
<script src="~app_src/tags/APP.demo.doit/APP.demo.doit.js"/> (added)
<script src="~app_src/tags/APP.demo.doit/APP.demo.doit_test.js"/> (added)
New configuration entries created. Review/Rebuild as needed.
Cleaning up working directory.
Type DNA 'actiontag' cloned to ~app_src/tags as 'doit'.

Action tags rarely need to convert their DOM element. As a result you normally don't implement tagCompile. On the other hand, to get them to actually execute you should override tshExecute, the method used by the TIBET Shell (TSH) to invoke them.

APP.demo.doit.Type.defineMethod('tshExecute',
function(aRequest) {

    /**
     * @method tshExecute
     * @summary Runs the receiver, effectively invoking its action.
     * @param {TP.sig.Request} aRequest The request containing command input for
     *     the shell.
     * @returns {Object} A value which controls how the outer TSH processing
     *     loop should continue. Common values are TP.CONTINUE, TP.DESCEND, and
     *     TP.BREAK.
     */

    APP.info('did it');

    aRequest.complete();

    return;
});

The sample implementation above follows the normal pattern for most tag methods. Your method receives a Request instance you query for data and message when the request is complete, when it has failed, etc.

In our sample we invoke the APP.info logging method and complete the request. Running this action should log did it to the JS console (and Sherpa TDC if it's running).

Run An Action Tag Interactively

Action tags are the fundamental input to the TIBET Shell. As a result, you can run your action tags in the TIBET Console by entering them with or without bracketing. For example:

tsh> demo:doit

// OR

tsh> <demo:doit/>

Use Shift-Return to execute the tag and you should see did it in response.

Run An Action Tag Via The UI

To trigger an action tag from your UI the easiest thing to do is target it with a signal. Action tags have a default handler for TP.sig.Signal instances which causes them to activate.

To see this in action, put your action tag in the DOM via template or tagCompile:

<demo:doit id="doit"/>

Next, set up a control or other element with an on:click or similar trigger, providing it with a signal descriptor as the value. A signal descriptor is a simplified JS-like string containing keys to define the signal's origin, signal name, and other parameters. To trigger the action you need origin to point to your action tag's ID and a signal, conventionally 'Act':

<button on:click="{origin: 'doit', signal: 'Act'}">click me</button>

With both the action tag and trigger in your UI, click the 'click me' button and you should see your action tag execute.

Action tags provide a way to not only expose UI-centric behavior in the form of markup but to create reusable application logic consumers can use without having to write JavaScript.

Create/Use An Info Tag

An info tag is the simplest of all TIBET tags in that they have neither a UI or a particular method or methods you need to implement. They're largely just reference points other tags can use to share data.

As with action tags an info tag has no stylesheet or template, just the type and test files.

You create info tags using tibet type with --dna infotag as follows:

$ tibet type data --dna infotag
working in: /Users/ss/temporary/t2/_data_
processing directories...
processing templates...
templating complete...
positioning files...
positioning complete...
adjusting package entries...
<script src="~app_src/tags/APP.t2.data/APP.t2.data.js"/> (added)
<script src="~app_src/tags/APP.t2.data/APP.t2.data_test.js"/> (added)
New configuration entries created. Review/Rebuild as needed.
Cleaning up working directory.
Type DNA 'infotag' cloned to ~app_src/tags as 'data'.

That's it. You can now put your new info tag anywhere in the page you'd like.

Since they're used for sharing data you'll typically want to assign info tags an id so they're easy to reference. You can then point to that ID in a TIBET binding expression to access the data from multiple locations in the page:

<demo:info id="info">Hello World!</demo:info>
...
<input type="text" bind:in="#info"></input>
<button bind:in="#info"></button>

Info Tags

A common use for info tags is sharing static information such as state codes, country codes, or other data which might be duplicated across multiple parts of a form.

Signals (Events)

Remap A Signal Name

Low-level events such as click have very little semantic value. A more organized and maintainable approach is to map low-level native events to semantic signal names.

In TIBET you use the on: namespace to remap signals. This approach works on both native elements as well as custom tags:

<button on:click="Save">Save</button>
...
<hello:now on:click="Refresh"/>

With the on: namespace you can remap any low-level native event to a signal that has more semantic value for your application and developers.

Coupling a remapped Signal with a proper signal handler defined within the event originators responder chain is a simple way to create more maintainable code.

NOTE that remapped signals leverage TIBET's RESPONDER_FIRING signal firing policy.

Add A Signal Handler

Signal handlers should typically be defined using defineHandler on either a tag or a controller object. Handlers are typically invoked on instances so it's key to use the proper .Inst qualifier when defining your handler:

APP.demo.sample.Inst.defineHandler('Aha', function(aSignal) {
    APP.info('demo:sample received an ' + aSignal.getSignalName();
});

Assuming you put the following markup in place clicking your <demo:sample/> tag should result in invocation of your handler.

<demo:sample on:click="Aha"/>

Add A Controller

By default TIBET will search a node's ancestor chain for event handlers. When using a DOM signal the entire chain is searched. When using a "Responder" signal the search uses the same ancestor chain but filters it by eliminating any ancestors without either a tibet:ctrl or tibet:tag reference (unless it's a custom XML tag...those are always retained).

The tibet:ctrl attribute allows you to refer to any object TIBET can resolve correctly, usually via a TIBET URN reference or type name. When a controller is provided it is used before any tag type, allowing you to override tag behavior with specific controller logic.

<hello:now tibet:ctrl="APP.hello.Application"/>

Above we tell our <hello:now> instance it should use the application as a controller (it turns out this happens automatically in TIBET but it makes this example easier).

If we then define a signal handler on our application object for UIActivate we'll see it gets invoked automatically when we click or keyup on our tag:

APP.hello.Application.Inst.defineHandler('UIActivate', function(aSignal) {
    TP.info('Application: ' + aSignal.getSignalName());
});

Namespaces

As an XHTML framework TIBET both leverages and supports full XML namespaces.

When you create a new project TIBET will automatically create and register a namespace URL for your project in public/src/APP..js.

For a project named demo you'll see content similar to:

/**
 * @type {Namespace}
 * @summary Defines namespace-level objects and functionality for the project.
 */

/**
 * Define the JavaScript namespace object which will hold application code.
 */
TP.defineNamespace('APP.demo');

/**
 * Define the XML namespace and prefix for any tags in the application.
 */
TP.w3.Xmlns.registerNSInfo('urn:app:demo', TP.hc('prefix', 'demo'));

Normally this is all you need to begin development, but if you will be working with other tag sets unfamiliar to TIBET, or want to place your tags in multiple namespaces you can tell TIBET about those namespaces very easily.

Define A New Namespace

TIBET automatically creates a root APP global which serves as a containing namespace for all application-level components. In addition, each new project automatically gets a namespace specific to that project. For example, if you create the hello project TIBET will ensure there's an APP.hello namespace with a hello prefix.

If you want to create new types or tags in a separate namespace you can create and register one using the following steps:

//  Create the namespace object itself.
TP.defineNamespace('APP.sample');

//  Register it via a URN and provide a canonical prefix.
TP.w3.Xmlns.registerNSInfo('urn:app:sample', TP.hc('prefix', 'sample'));

Once these steps are complete you can create new tags or types in that namespace by using it or its prefix depending on context.

List Namespaces

Information for all registered namespaces can be found on the TP.w3.Xmlns object, in particular in that object's info property.

Below is a sample code snippet that will access that data, filter out any data without a prefix value, and produce a list of known namespace prefix/uri pairs:

TP.w3.Xmlns.get('info').getValues().filter(function(item) {
    return TP.notEmpty(item.at('prefix'));
}).collect(function(item) {
    return item.at('prefix') + '\t' + item.at('uri');
});

Here's the list of industry standard namespaces we currently register and support:

cat         urn:oasis:names:tc:entity:xmlns:xml:catalog
ev          http://www.w3.org/2001/xml-events
html        http://www.w3.org/1999/xhtml
kml         http://www.opengis.net/kml/2.2
mml         http://www.w3.org/1998/Math/MathML
rdf         http://www.w3.org/1999/02/22-rdf-syntax-ns#
rss         http://backend.userland.com/rss2
svg         http://www.w3.org/2000/svg
tmx         http://www.lisa.org/tmx14
v           urn:schemas-microsoft-com:vml
vcard       urn:ietf:params:xml:ns:vcard-4.0
wsdl        http://schemas.xmlsoap.org/wsdl
xforms      http://www.w3.org/2002/xforms
xi          http://www.w3.org/2001/XInclude
xlink       http://www.w3.org/1999/xlink
xml         http://www.w3.org/XML/1998/namespace
xmlns       http://www.w3.org/2000/xmlns/
xs          http://www.w3.org/2001/XMLSchema
xsi         http://www.w3.org/2001/XMLSchema-instance
xsl         http://www.w3.org/1999/XSL/Transform
xul         http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul

Here's the subset we've defined for the various functional aspects of TIBET for which we couldn't find an appropriate standard to implement.

acl         http://www.technicalpursuit.com/2005/acl
acp         http://www.technicalpursuit.com/1999/acp
bind        http://www.technicalpursuit.com/2005/binding
css         http://www.technicalpursuit.com/2008/cssml
dnd         http://www.technicalpursuit.com/2005/drag-and-drop
drag        http://www.technicalpursuit.com/2005/drag
on          http://www.technicalpursuit.com/2014/on
sherpa      http://www.technicalpursuit.com/2014/sherpa
tibet       http://www.technicalpursuit.com/1999/tibet
tsh         http://www.technicalpursuit.com/1999/tshell
ui          http://www.technicalpursuit.com/2015/ui
vcard-ext   http://www.technicalpursuit.com/vcard-ext
xctrls      http://www.technicalpursuit.com/2005/xcontrols

And a couple of simple URN prefixes we use:

pclass      urn:tibet:pseudoclass
yak         urn:yak

code

~lib/src/tibet/kernel/TIBETDOMTypes.js contains the base logic for all DOM types in TIBET including TP.core.ElementNode which is the common root ancestor for the four major tag types. You'll find ActionTag and InfoTag in that file.

~lib/src/tibet/kernel/TIBETCoreTags.js contains the base logic for the UI-based tags, CompiledTag and TemplatedTag as well as their common supertype 'CustomTag'.

~lib/src/tibet/kernel/TIBETWorkflowDOMTypes.js contains the TP.core.TagProcessor and the various phase definitions used for tag processing.

~lib/src/tibet/kernel/TIBETSignalTypes.js contains a number of the more common signals in the DOM and Responder hierarchy for reference.

~lib/src/tibet/kernel/TIBETWWWTypes.js houses key types related to W3C standards including the TP.w3.Xmlns type.

Specific examples of custom tags of various forms can be found in the Sherpa source tree rooted at ~lib/src/tibet/tools/sherpa.