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

Content deleted Content added
m check .arity of function-typed attrValue
fix broken browsers without createElementNS
 
(8 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;
return;
}
 
// Creates the DOM element
// Invoke the callback otherwise if it has zero or one argument
var createDomElement = function(name) {
if (attrValue.arity <= 1) {
return document.createElementNS(settings.namespaceUri, name);
attrValue = attrValue(elem);
};
 
var defaultAttributeHandler = function (elem, attrName, attrValue) {
// 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 88 ⟶ 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 117 ⟶ 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 148 ⟶ 185:
};
};
 
// Create an anonymous namespace if none was provided
if (isUndefined(namespace)) namespace = {};
 
// Populate the namespace
for (var i in tagssettings.tagNames) {
namespace[tags[i]]var tagName = createDomElementBuilder(tagssettings.tagNames[i]);
namespace[tagName] = createDomElementBuilder(tagName);
}