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

Content deleted Content added
m reduce top level declarations to 2 (+2 minor namespace pollutions)
fix broken browsers without createElementNS
 
(13 intermediate revisions by the same user not shown)
Line 1:
// <pre><nowiki>
 
function buildEasyDomNamespace(namespace, options) {
var isType = function (o, t) { return typeof o == t };
var isBool = function (o) { return isType(o, typeof true); };
Line 15:
var isNode = function (o) { return isDefined(o) && o != null && isNumber(o.nodeType); }
 
// TheDefault tag names that willto be createdinstalled ininto the namespace as functions
var tagsdefaultTagNames = [
"bdo", "script", "style", "object", "param", "iframe", "link", "meta", "p",
"bdo",
"pre", "a", "div", "span", "ul", "ol", "li", "img", "hr", "br", "em", "strong",
"script",
"sup", "sub", "tt", "abbr", "acronym", "del", "ins", "cite", "blockquote",
"object", "param",
"code", "table", "tbody", "tfoot", "tr", "th", "td", "col", "colgroup", "caption",
"iframe",
"form", "input", "select", "option", "optgroup", "button", "textarea",
"link", "meta",
"h1", "h2", "h3", "h4", "h5", "h6", "label", "canvas", "fieldset", "legend"
"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"
];
 
// CreatesDefault theevent DOM elementtypes
var createDomElementdefaultEventTypes = function(name) {[
var// elemHTML = document4.createElement(name);0
"Abort", "Blur", "Change", "Click", "DblClick", "DragDrop", "Error",
return elem;
"Focus", "KeyDown", "KeyPress", "KeyUp", "Load", "MouseDown",
};
"MouseMove", "MouseOut", "MouseOver", "MouseUp", "Move", "Reset",
"Resize", "Select", "Submit", "Unload"
];
 
// Create an anonymous namespace if none was provided
var attrNameTranslations = {};
if (isUndefined(namespace)) namespace = {};
 
// Settings
// Conditionally add I.E. name overrides
var settings = {
/*@cc_on
"namespaceUri": "http://www.w3.org/1999/xhtml",
attrNameTranslations["for"] = "htmlFor";
"invokeFunctions": true,
attrNameTranslations["maxlength"] = "maxLength";
"tagNames": defaultTagNames,
attrNameTranslations["class"] = "className";
"eventTypes": defaultEventTypes
attrNameTranslations["accesskey"] = "accessKey";
@*/};
 
// Override default settings with specified options
var processSingleDomAttribute = function(elem, attrName, attrValue) {
if (options) {
// Translate DOM attribute name to match implementation
iffor (attrNameTranslations[attrName]var !=p nullin options) {
attrNamesettings[p] = attrNameTranslationsoptions[attrNamep];
}
}
 
// 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)
document.createElementNS = function (ns, name) {
if (isFunction(attrValue)) {
return document.createElement(name);
// Use direct object property assignment for "on" attributes
};
// These properties will not be copied by Node.cloneNode
}
if (attrName.indexOf("on") == 0) {
 
elem[attrName] = attrValue;
// Creates the DOM return;element
var createDomElement = function(name) {
}
return document.createElementNS(settings.namespaceUri, name);
};
 
var defaultAttributeHandler = function (elem, attrName, attrValue) {
// Invoke the callback otherwise
// Invoke function callbacks of zero or one argument and use their result as the new attrValue
if (settings.invokeFunctions && isFunction(attrValue) && attrValue.length <= 1) {
attrValue = attrValue(elem);
}
Line 86 ⟶ 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 115 ⟶ 150:
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 122 ⟶ 161:
};
 
// Create the function that creates new DOM elementselement builders
var 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);
}
// Convert any non-DOM nodes to text nodes with toString()
if (!isNode(child)) {
child = document.createTextNode(child.toString());
}
elem.appendChild(child);
}
 
return elem;
};
};
 
// Populate the namespace
for (var i in settings.tagNames) {
if (isUndefined(namespace)) namespace = {};
var tagName = settings.tagNames[i];
for (var i in tags) {
namespace[easyDomTags[i]tagName] = createDomElementBuilder(easyDomTags[i]tagName);
}