Matt's DOM Utils Matt's DOM Utils (Utils)

HOWTO: Implementation

Table of Contents

  1. Introduction
  2. Defense
    1. Initial Assertion
    2. Wrappers
      1. Result Assertions
  3. Conclusions
    1. Demo

Introduction

Implementing a DOM library can be as simple as a method invocation. However, Utils requires care to implement properly.


Defense

In order to derive optimal success from Utils, defensive tactics must be used. They are listed below.

Initial Assertion

The most important step in implementing Utils is asserting its existence before running application code. The following example:

if (typeof Utils === "object" && Utils) {
	(function () {
		// application code
	}());
}

illustrates how one assertion can enable a script to gracefully degrade when its core dependency does not exist; whereas a similar script without the assertion can err.

Wrappers

Wrappers are an important step in implementing Utils. Their use enables safe degradation of the “dynamic interface”, meaning properties whose value is determined at run time. This example:

function createText(
	doc,
	text
)
{
	var result = null;
	if (Utils.create.text) {
		result = Utils.create.text(
			doc,
			text
		);
	}
	return result;
}

is one instance wherein a method of the “dynamic interface” can safely be called, and degrade if unavailable.

Result Assertions

However, results of API invocations should also be asserted before use. In conjunction with wrappers, this strategy should be a large factor in an implementation of Utils. The snippet below:

function createText(
	doc,
	text
)
{
	var result = null;
	if (Utils.create.text) {
		result = Utils.create.text(
			doc,
			text
		);
	}
	return result;
}

function appendNode(
	par,
	node
)
{
	return Utils.node.append(
		par,
		node
	);
}

function appendText(
	text,
	par
)
{
	var node = createText(
		global.document,
		text
	);
	if (node) {
		appendNode(
			par,
			node
		);
	}
}

is an example of wrappers used in conjuction with result assertions. A text node-like object is appended to a node-like object if the specified creational method exists with a successful result.


Conclusions

Whilst Graceful Degradation requires a great amount of effort to achieve, use of Utils simplifies degradation of scripts. The result is highly flexible code, which is unencumbered by respectable environments.

Demo

To demonstrate an implementation of Utils, a full example is provided below:

var global = global || this;
if (typeof Utils === "object" && Utils) {
	(function () {
		function createText(
			doc,
			text
		)
		{
			var result = null;
			if (Utils.create.text) {
				result = Utils.create.text(
					doc,
					text
				);
			}
			return result;
		}

		function appendNode(
			par,
			node
		)
		{
			return Utils.node.append(
				par,
				node
			);
		}

		function appendText(
			par,
			text
		)
		{
			var node = createText(
				global.document,
				text
			);
			if (node) {
				appendNode(
					par,
					node
				);
			}
		}

		function selectBody(
			doc
		)	
		{
			var result = null;
			if (Utils.select.body) {
				result = Utils.select.body(
					doc
				);
			}
			return result;
		}

		function addBodyText(
			text
		)
		{
			var body = selectBody(global.document);
			if (body) {
				appendText(
					body,
					text
				);
			}
		}

		addBodyText("foo\r\n");
		addBodyText("bar\r\n");
		addBodyText("baz\r\n");
	}());
}

which can be found in a test page[0].

Footnotes

[0]
Text Node Test