Skip to content

Introduction

StephenCote edited this page Sep 27, 2013 · 7 revisions

Introduction to Engine v. 3.x: Hemi Javascript Framework

Hemi JavaScript Framework is the third major version of Engine for Web Applications. Hemi includes services and utilities for bootstrapping rich Web applications and abstracting functionality from content.

Loading the Framework

Hemi is easy to load. If Hemi is saved to its context root of "/Hemi", then the following statement would load the core framework and features individually:

<script type = "text/javascript" src = "/Hemi/hemi.js"></script>

Or, to load everything at once:

<script type = "text/javascript" src = "/Hemi/hemi.comp.js"></script>

If another location is preferred, use the HemiConfig structure to specify the hemi_base path prior to loading the framework:

<script type = "text/javascript">
HemiConfig = { hemi_base : "/AlternatePath/" };
</script>
<script type = "text/javascript" src = "/AlternatePath/hemi.comp.js"></script>

Relative Framework Paths

Paths in Hemi are relative to the hemi_base path, particularly the Hemi.xml utility. This is a departure from the libXmlRequest library and previous versions of Engine for Web Applications.

When referencing any resource within the hemi_base path, a relative path may be used no matter where the framework is being used. However, when referencing a resource relative to another location, it is necessary to prefix the path reference to that resource.

For example, consider the following Web Site structure:

/
   /Hemi/
   /SomeApp/
      /SomeDir/
         /Data/
            data.xml
            data.html
            someTemplate.xml
   index.html
   index_config.xml

To access index_config.xml from index.html:

<script type = "text/javascript">
var oXml = Hemi.xml.getXml("/index_config.xml");
</script>

And to access data.xml from either data.html or index.html:

<script type = "text/javascript">
var oXml = Hemi.xml.getXml("/SomeApp/SomeDir/Data/data.xml");
</script>

The advantage to this behavior is all references to framework dependencies are then easily accessible from any context. This applies to all external framework files, including libraries, templates, components, modules, tests, fragments, and workers.

Working with the Framework

Hemi is designed to abstract direct scripting requirements. When using the Application Space service, Application Components, Modules, Templates, and Tests can be loaded without needing to learn the core API features. The complexity introduced with the Data, Form, Message, Registry, Space, Storage, Task, Transaction, Worker, and XML services is managed with XHTMLComponents and Application Components through the Application Space service.

  • [Core Core Features]

XHTML Components

XHTML Components are framework objects that represent XML or HTML nodes for the purpose of discovery, binding, and management. When the Application Space service is included, many HTML nodes are automatically instrumented with XHTML Component instances.

The following example shows how an XHTMLComponent is created for an XHTML node.

Hemi.include("hemi.object.xhtml"); var oHtmlNode = document.createElement("div"); document.body.appendChild(oHtmlNode); var oNodeObject = Hemi.object.xhtml.newInstance(oHtmlNode, true);

Quick-Fixes

XHTML Components include a Quick-Fix feature for integrating Application Components, Modules, and Templates with an existing HTML Node. A Quick-Fix is implemented with the following attributes and syntax.

  • component: The name of the component. The component must be placed in the Components/ directory, named component.name.xml, and the component id must be name.
  • acid/appcomp_path: If component doesn't work in a particular context, such as with Application Component definitions saved to a different location or when multiple components are defined in a single file, use the acid attribute to identify the component identifier, and the appcomp_path to identify the path to the Application Component XML file.
  • template: Either name of a template that exists in the Templates/ directory, or the path to a template.
  • module: The name of a module that exists in the Modules/ directory. To work with modules located in other locations, script must be used to specify an alternate path.
  • is-dwac: When specified, the Distributed Component control is loaded and accepts configuration from the following attributes.
  • DWacControlUri: The path to the published DWAC project.
  • DWacControlTask: The id of a TaskList to run, where the TaskList and dependent Tasks are included in the project.
  • DWacTemplateId: The id of a template included in the project.

API: XHTMLComponent

Data Stack

The Data Stack is a class for storing and retrieving values that may or may not have unique identifiers, and which don't qualify for or need to be stored in the Hemi.registry service. API: Data Stack

Wiring

The Primitive Wire Service is used to connect two disparate functions together. The Wire Service is used to chain multiple Primitive Wires (which connect disparate functions). Wires include auto signaling (aka a signals and slots variation). API: Wires and API: Primitive Wires

Transactions

The Transaction Service is an object-level communication bus. Unlike events, delegates, and message subscriptions and publications, the transaction service coordinates dissimilar objects on a common band. Non Framework Objects may be decorated with the Transaction Participant API, and allow cross-Framework coordination. API: Transaction Service

Tasks

The Task Service orchestrates Task evaluation and dependency management. The Task Service is useful for bootstrapping complex asynchronous operations. API: Task Service

Data IO

The Data IO service uses a interchange format for coordinating data between external sources and the framework. Data IO Providers interpret the request format for a particular implementation, and exchange the external response format for the Data IO format.

API: Data IO

Spaces

Application Spaces are managed domains in which content drives implementation. The Application Space Service orchestrates Hemi Framework services and compartmentalizes implementation details.

API: Application Space Service

Virtual Forms

When a form field (text field, button, checkbox, select, etc) is encountered by the Application Space service, the field is virtualized through the XHTML Form service. Virtual Forms are automatically created for Application Spaces, and can likewise be created at any time, for any reason. The Form Service synchronizes virtual form elements as corresponding form fields are created and destroyed.

The end result is that a series of form templates can be chained together, and the values collated into a single form, even when the form fields have been removed from the page.

(http://www.whitefrost.com/Hemi/api/hemi.data.form.html)[API: Form Service]

Application Components

Application Components are externalized code fragments that can be run independently, be bound to an HTML node, and work within an application space. Application Components connect many framework elements together, including:

  • Automate instrumentation of DOM events,
  • Setup transaction participation,
  • Internalize new application spaces for hosting templates
  • Resolve template tokenization

The easiest setup is declarative:

<div component = "demo">Click here</div>

And the backing component is stored in an XML file named component.demo.xml:

<application-component id = "demo"><![CDATA[
   // event handler is automatically instrumented
   //
   _handle_click : function(){
      Hemi.xml.setInnerXHTML(this.getContainer(), "Clicked!");
   }
]]></application-component>

API: Application Component

Templates and Fragments

Templates are Application Spaces that encompass reusable blocks of XHTML and context-sensitive script. Fragments are blocks of reusable XHTML and context-sensitive script that can be loaded by other Fragments or templates. Templates and fragments are very similar where Templates support an additional set of API callbacks. Both include special tokens that resolve to instance-sensitive pointers.

API: Application Component

Modules

Modules are blocks of JavaScript that are loaded as module objects and otherwise treated anonymously. A few basic APIs are injected into the host object such that the script may run without interacting with the framework, or via the injected object references and API callbacks.

<div module="demo">Test</div>

And, in an external script file:

/// Modules/demo.js
this.Initialize = function(){
   Hemi.xml.setInnerXHTML(Container, "Example");
}

function SomeScript(){
   // ...
}
SomeScript();

API: Module Service

Test Modules

Test Modules include additional APIs that instrument a Module as a set of unit tests. Additional features include:

  • Adding the logger utility

  • Scanning for Test functions

  • Injecting EndTest functions for asynchronous testing

  • Instrumenting the Task Service for correlating all tests into a test suite.

  • Injecting an Assert API.

  • Invoking callback functions on execution and completion of tests and the suite.

    function TestSomethingSync(){ this.Assert(true, "It's true"); } function TestSomethingAsync(){ return false; } function TestCompletingAsyncTest(){ EndTestSomethingAsync(); }

API: Test Module Service

Distributed Components

Distributed Components are pre-packaged sets of Application Components, Templates, Fragments, and Tasks for re-usability. The Distributed Component utility interprets the XML package and resolves in-document tokenization.

This allows widgets and features to be delivered with all the constituent parts assembled into a single file. API: Distributed Component

Threading

The Thread class provides a thread implementation for Framework Objects. Each thread is sensitive to the object lifecycle, and can stop itself when the object is destroyed or when the framework is shutdown.

API: Thread Utility

Monitoring

The Monitor service provides a passive client-side monitor framework. Monitors collect and aggregate data per page view and send that data to a server for Web analytics processing. The Account Manager 4 project includes a reference implementation.

API: Monitor Service

HTML5

Hemi includes a number of HTML 5 services and utilities for working with offline storage, canvas, and Workers.

Offline Storage

The offline storage service masks different DOM storage implementations and provides a downlevel version for older versions of Internet Explorer. API: Storage Service

Canvas

The canvas utility provides an object oriented approach to working with canvas objects. Downlevel support for browsers that don't support canvas natively is provided through an as-needed injection of an external canvas provider.

API: Canvas Utility

Workers

The Worker Service includes a wrapper bootstrap for emulating a worker thread in browsers that do not support the HTML 5 Worker. Workers are also loaded as Modules, so that an external Worker script can not only leverage the rest of the framework, but can also be used for browsers that do not otherwise support workers.

Given some worker,

/// Workers/test.worker.js
function test() {
   postMessage('test at 1 sec');
};

function onmessage(v) {
   postMessage("Got it");
   setTimeout(test, 1000);
};

The Worker Service instruments support for the framework into the worker script, and adds downlevel support.

Hemi.include("hemi.worker");
var oWorker = Hemi.worker.service.NewWorker("worker.test");
oWorker.onmessage = function (v) {
   Hemi.log("Received message: " + v.data);
}
oWorker.postMessage("Example message");

With the Hemi framework automatically instrumented into the worker script, and the Worker treated as a Module, all of the additional Framework and Module features are accessible (with the restrictions of the underlying Worker in effect).

Hemi.include("hemi.data.io");
Hemi.include("hemi.framework.io.provider");
/// Module API callback
this.Initialize = function(){
   // Setup data IO
};
function test() {
   postMessage('test at 1 sec');
};

function onmessage(v) {
   postMessage("Got it");
   setTimeout(test, 1000);
};

API: Worker Service

Utilities

Hemi uses feature interrogation to extend DOM, CSS, and Event interactions.

Developer Features

Hemi includes a number of packaged Templates, Components, and Fragments to test and develop features, and to provide an initial set of widgets.

Components

Hemi includes a number of components for augmenting HTML nodes. The following are a few examples:

Testable

The testable component is used to declare inline unit tests to be attached to an HTML node. A test status bar is rendered above the node with a color coded indicator for each specified test.

<p component = "testable" tests = "test.node,test.somethingelse">Node to test</p>

Window

The window component is used to create a dynamic pop-in window which uses a Template for its contents. The window is managed by a Window Manager component.

Hemi.include("hemi.app");
var oWindow = Hemi.app.createWindow("Some Window", "/path/to/template.xml", "WindowName");

Window Control

The window_control component is a small wrapper to create a new Hemi window component in response to a click event. Note: the Application Component quick-fix takes precedence over the Template quick-fix.

<p component = "window_control" template = "/Path/Template.xml">Open Window</p>

Framework Profiler

The Framework Profiler is a Template that encapsulates several fragments into a tabbed toolset for interacting with the Web page and the Hemi framework. The profiler is loaded by specifying the template, and as such can be loaded inline for a specified node, or via the createWindow method.

Framework Statistics

The Framework Statistics includes several views into the running framework.

  • Filter Results Checkbox: When this checkbox is checked, the framework registry prefix is changed and all results are filtered by the alternate prefix. This allows specific items to be investigated without having to wade through the rest of the object space.
  • Registry: All objects currently registered. Complex framework types are broken down into sub trees for ease of navigation and exploration. Clicking on an item will allow for further drill-down or cross-linking between related components (eg: SpaceObjects -> XHTMLComponents -> ApplicationComponents)
  • Send To Active Source: When an item is selected in the registry, the Send To Active Source link will shift focus to the Active Source tab and store a temporary reference to the object for ease of interaction. Instructions are included for the object type on how to interact with it.
  • Spaces: All running Application Spaces
  • Modules: All registered Modules and Module instances.
  • Tasks: All task lists and the status for each list.
  • Transactions: All transactions and the status for each transaction.
  • IO: All Data IO requests and responses.
  • XML: All XML requests and cache status
  • Messages: All current messages sent to the onsendmessage Message Service subscription via the sendMessage method. Note: The logger utility uses scoped sendMessage calls, so, in effect, this is a view into all current messages. Also note: The message service caps the message stack to a fixed amount after which older items are removed.

API Browser

The API browser can be used to interact with the framework API documentation.

Javascript Profiler

The JavaScript Profiler profiles other scripts on the page and allows interaction with discovered functions.

  • Register: Instruments a selected function with the Function Monitor for performance analysis.
  • Metrics: Prints out performance metrics for registered functions.
  • Deobfuscate: Expands space-compressed script.

Active Source

Active Source is a window into the live DOM, allowing for immediate interaction with the running scripts and objects.

XML/XSL

The XML/XSL utility is a convience for testing XML and XSL syntax and transformation.

Runtime Container

The Runtime Container is a special sandbox for testing framework features. The container includes auto instrumentation for Distributed Components, Components, Templates, Fragments, Tasks, and Tests.

Framework Designer

The Framework Designer is a suite of tools for working with Hemi.

Offline, Static, and Online browsing modes.

The designer modes are driven by available Data IO providers by bus type support. Hemi includes an online Data Provider for persisting changes with Account Manager, and a static Data Provider for browsing the provided framework content.

  • Offline: Intended for use with offline storage
  • Static: For viewing static content provided with the framework.
  • Online: For use with an online Data IO provider that can persist and query custom framework code.

Builders for interactively designing custom features.

Builders provide user interfaces for creating new Hemi features with example implementations, and editing existing features.

  • Component Builder: For editing Application Components.
  • Fragment Builder: For editing Fragments.
  • Project Builder: For creating and publishing Distributed Web Application Component project files. Distributed Web Application Component projects are loaded with the Distributed Component class.
  • Task Builder: For editing Task Lists and Tasks.
  • Template Builder: For editing Templates.

Integration with Framework Profiler and Runtime Container

Each builder includes integration with the Framework Profiler and Runtime Container. When combined with a persisting Data IO provider, this allows Hemi features to be created, edited, and tested in the Web page.

Test Suite Runner

The Test Suite Runner Template and Fragment provide a user interface for running groups of in-page unit tests and viewing the results.

General Framework Architecture

The Hemi framework is easily extended by following the framework architecture conventions.

Clone this wiki locally