User:Mike Dillon/Scripts/easydom.js: Difference between revisions

Content deleted Content added
m skip nulls passed to easyDOM functions
fix broken browsers without createElementNS
 
(21 intermediate revisions by the same user not shown)
Line 1:
// <pre><nowiki>
 
function createEasyDomFunctionbuildEasyDomNamespace(namenamespace, options) {
var stringTypeisType = function (o, t) { return typeof ''o == t };
var functionTypeisBool = typeof function (o) { return isType(o, typeof true); };
var isString = function (o) { return isType(o, typeof ''); };
var isNumber = function (o) { return isType(o, typeof 0); };
var isFunction = function (o) { return isType(o, typeof function () {}); };
var isObject = function (o) { return isType(o, typeof new Object()); };
var isUndefined = function (o) { return isType(o, (function (x) { return typeof x })()); };
var isDefined = function (o) { return !isUndefined(o); }; // NOTE: null is "defined"
var isPrimitive = function (o) {
return isString(o) || isNumber(o) || isBool(o) || isFunction(o);
}
var isNode = function (o) { return isDefined(o) && o != null && isNumber(o.nodeType); }
 
// Default tag names to be installed into the namespace as functions
// Creates the DOM element
var createDomElementdefaultTagNames = function(name) {[
"bdo", "script", "style", "object", "param", "iframe", "link", "meta", "p",
var elem = document.createElement(name);
"pre", "a", "div", "span", "ul", "ol", "li", "img", "hr", "br", "em", "strong",
return elem;
"sup", "sub", "tt", "abbr", "acronym", "del", "ins", "cite", "blockquote",
};
"code", "table", "tbody", "tfoot", "tr", "th", "td", "col", "colgroup", "caption",
"form", "input", "select", "option", "optgroup", "button", "textarea",
"h1", "h2", "h3", "h4", "h5", "h6", "label", "canvas", "fieldset", "legend"
];
 
// Default event types
var attrNameTranslations = {
var defaultEventTypes = [
// Aliases for old common HTML attribute typos
"onClick"// :HTML "onclick"4.0
"Abort", "Blur", "Change", "Click", "DblClick", "DragDrop", "Error",
};
"Focus", "KeyDown", "KeyPress", "KeyUp", "Load", "MouseDown",
"MouseMove", "MouseOut", "MouseOver", "MouseUp", "Move", "Reset",
"Resize", "Select", "Submit", "Unload"
];
 
// Create an anonymous namespace if none was provided
// Conditionally add I.E. name overrides
if (isUndefined(namespace)) namespace = {};
/*@cc_on
attrNameTranslations["for"] = "htmlFor";
attrNameTranslations["maxlength"] = "maxLength";
attrNameTranslations["class"] = "className";
attrNameTranslations["accesskey"] = "accessKey";
@*/
 
// Settings
var processSingleDomAttribute = function(elem, attrName, attrValue) {
var settings = {
// Translate DOM attribute name to match implementation
"namespaceUri": "http://www.w3.org/1999/xhtml",
if (attrNameTranslations[attrName] != null) {
"invokeFunctions": true,
attrName = attrNameTranslations[attrName];
"tagNames": defaultTagNames,
"eventTypes": defaultEventTypes
};
 
// Override default settings with specified options
if (options) {
for (var p in options) {
settings[p] = options[p];
}
}
 
// If the browser doesn't understand createElementNS, fake it (God help them...)
// Invoke function callbacks and use their result as the value,
if (isUndefined(document.createElementNS)) {
// unless the attribute name starts with "on" (i.e. an event handler)
ifdocument.createElementNS (typeof= attrValuefunction ==(ns, functionTypename) {
return document.createElement(name);
// Use direct object property assignment for "on" attributes
};
if (attrName.indexOf("on") == 0) {
}
elem[attrName] = attrValue;
 
return;
// Creates the DOM }element
var createDomElement = function(name) {
return document.createElementNS(settings.namespaceUri, name);
};
 
var defaultAttributeHandler = function (elem, attrName, attrValue) {
// Invoke the callback otherwise, passing null for "this"
// Invoke function callbacks of zero or one argument and use their result as the new attrValue
attrValue = attrValue.call(null, elem);
if (settings.invokeFunctions && isFunction(attrValue) && attrValue.length <= 1) {
attrValue = attrValue(elem);
}
 
Line 46 ⟶ 73:
if (attrValue == null) {
return;
}
 
// Stringify non-string values
if (!isString(attrValue)) {
attrValue = attrValue.toString();
}
 
Line 51 ⟶ 83:
elem.setAttribute(attrName, attrValue);
};
 
var createAttributeOverrideHandler = function (overrideName) {
return function (elem, attrName, attrValue) {
defaultAttributeHandler(elem, overrideName, attrValue);
};
};
 
var createEventHandlerAttributeHandler = function (overrideName) {
return function (elem, attrName, attrValue) {
if (!isFunction(attrValue)) {
attrValue = new Function(attrValue);
}
elem[overrideName || attrName] = attrValue;
};
};
 
var attributeHandlers = {};
 
for (var i in settings.eventTypes) {
var handlerName = "on" + settings.eventTypes[i];
var internalName = handlerName.toLowerCase();
// Force lower case
attributeHandlers[internalName] = createEventHandlerAttributeHandler();
// Allow mixed case (with lower case internal name)
attributeHandlers[handlerName] = createEventHandlerAttributeHandler(internalName);
}
 
// Conditionally add I.E. name overrides
/*@cc_on
attributeHandlers["for"] = createAttributeOverrideHandler("htmlFor");
attributeHandlers["maxlength"] = createAttributeOverrideHandler("maxLength");
attributeHandlers["class"] = createAttributeOverrideHandler("className");
attributeHandlers["accesskey"] = createAttributeOverrideHandler("accessKey");
 
attributeHandlers["style"] = function (elem, attrName, attrValue) {
elem.style.cssText = attrValue;
};
@*/
 
// Detects if the first element is a hash of attributes and if so,
Line 62 ⟶ 132:
}
 
// No attributes to process if null is the first argument
// Detect string arguments
var firstArgType = typeofif (args[0]; == null) {
if (firstArgType == stringType) {
return 0;
}
 
// No attributes to process if a "primitive" is the first argument
// Detect function arguments
if (firstArgType == functionTypeisPrimitive(args[0])) {
return 0;
}
 
// DetectNo attributes to process if a DOM nodesnode is the first argument
if (typeof isNode(args[0].nodeType != 'undefined')) {
return 0;
}
 
// AssumeProcess thatthe wefirst gotargument as a hash of attributes as the first arg...
var attrs = args[0];
for (var attrName in attrs) {
processSingleDomAttribute(elem,if attrName, attrs(isUndefined(attributeHandlers[attrName]);) {
defaultAttributeHandler(elem, attrName, attrs[attrName]);
} else {
attributeHandlers[attrName](elem, attrName, attrs[attrName]);
}
}
 
Line 88 ⟶ 161:
};
 
// ReturnCreate the function that creates new DOM elementselement builders
returnvar createDomElementBuilder = function (name) {
varreturn elem = createDomElementfunction(name); {
var elem = createDomElement(name);
 
// Process attribute hash, if any and skip the argument count returned
var firstChild = processDomAttributes(elem, arguments);
 
// Process the remaining children, if any
for (var i = firstChild; i < arguments.length; i++) {
var child = arguments[i];
if (child == null) {
continue;
}
// Convert any non-DOM nodes to text nodes with toString()
if (!isNode(child)) {
child = document.createTextNode(child.toString());
}
elem.appendChild(child);
}
if (typeof child == stringType) {
child = document.createTextNode(child);
}
elem.appendChild(child);
}
 
return elem;
};
};
}
 
// Populate the namespace
var easyDomTags = [
for (var i in settings.tagNames) {
"bdo",
var tagName = settings.tagNames[i];
"script",
namespace[tagName] = createDomElementBuilder(tagName);
"object", "param",
"iframe",}
"link", "meta",
"p", "pre",
"a",
"div", "span",
"ul", "ol", "li",
"img",
"hr",
"br",
"em", "strong", "sup", "sub", "tt", "abbr", "acronym",
"del", "ins", "cite", "blockquote",
"table", "tbody", "tfoot", "tr", "th", "td", "col", "colgroup", "caption",
"form", "input", "select", "option", "optgroup", "button",
"h1", "h2", "h3", "h4", "h5", "h6",
"label"
];
 
// Return the namespace for those relying on anonymous creation
var easyDom = {};
return namespace;
for (var i in easyDomTags) {
easyDom[easyDomTags[i]] = createEasyDomFunction(easyDomTags[i]);
}
 
// Build the Easy DOM functions in an anonymous namespace
easyDom = buildEasyDomNamespace();
 
// Namespace pollution
var easydom = easyDOM = easyDom;
var easyDOM = easyDom;
 
// </nowiki></pre>