1 | // Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) |
---|
2 | // |
---|
3 | // See scriptaculous.js for full license. |
---|
4 | |
---|
5 | var Builder = { |
---|
6 | NODEMAP: { |
---|
7 | AREA: 'map', |
---|
8 | CAPTION: 'table', |
---|
9 | COL: 'table', |
---|
10 | COLGROUP: 'table', |
---|
11 | LEGEND: 'fieldset', |
---|
12 | OPTGROUP: 'select', |
---|
13 | OPTION: 'select', |
---|
14 | PARAM: 'object', |
---|
15 | TBODY: 'table', |
---|
16 | TD: 'table', |
---|
17 | TFOOT: 'table', |
---|
18 | TH: 'table', |
---|
19 | THEAD: 'table', |
---|
20 | TR: 'table' |
---|
21 | }, |
---|
22 | // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken, |
---|
23 | // due to a Firefox bug |
---|
24 | node: function(elementName) { |
---|
25 | elementName = elementName.toUpperCase(); |
---|
26 | |
---|
27 | // try innerHTML approach |
---|
28 | var parentTag = this.NODEMAP[elementName] || 'div'; |
---|
29 | var parentElement = document.createElement(parentTag); |
---|
30 | try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707 |
---|
31 | parentElement.innerHTML = "<" + elementName + "></" + elementName + ">"; |
---|
32 | } catch(e) {} |
---|
33 | var element = parentElement.firstChild || null; |
---|
34 | |
---|
35 | // see if browser added wrapping tags |
---|
36 | if(element && (element.tagName != elementName)) |
---|
37 | element = element.getElementsByTagName(elementName)[0]; |
---|
38 | |
---|
39 | // fallback to createElement approach |
---|
40 | if(!element) element = document.createElement(elementName); |
---|
41 | |
---|
42 | // abort if nothing could be created |
---|
43 | if(!element) return; |
---|
44 | |
---|
45 | // attributes (or text) |
---|
46 | if(arguments[1]) |
---|
47 | if(this._isStringOrNumber(arguments[1]) || |
---|
48 | (arguments[1] instanceof Array)) { |
---|
49 | this._children(element, arguments[1]); |
---|
50 | } else { |
---|
51 | var attrs = this._attributes(arguments[1]); |
---|
52 | if(attrs.length) { |
---|
53 | try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707 |
---|
54 | parentElement.innerHTML = "<" +elementName + " " + |
---|
55 | attrs + "></" + elementName + ">"; |
---|
56 | } catch(e) {} |
---|
57 | element = parentElement.firstChild || null; |
---|
58 | // workaround firefox 1.0.X bug |
---|
59 | if(!element) { |
---|
60 | element = document.createElement(elementName); |
---|
61 | for(attr in arguments[1]) |
---|
62 | element[attr == 'class' ? 'className' : attr] = arguments[1][attr]; |
---|
63 | } |
---|
64 | if(element.tagName != elementName) |
---|
65 | element = parentElement.getElementsByTagName(elementName)[0]; |
---|
66 | } |
---|
67 | } |
---|
68 | |
---|
69 | // text, or array of children |
---|
70 | if(arguments[2]) |
---|
71 | this._children(element, arguments[2]); |
---|
72 | |
---|
73 | return element; |
---|
74 | }, |
---|
75 | _text: function(text) { |
---|
76 | return document.createTextNode(text); |
---|
77 | }, |
---|
78 | _attributes: function(attributes) { |
---|
79 | var attrs = []; |
---|
80 | for(attribute in attributes) |
---|
81 | attrs.push((attribute=='className' ? 'class' : attribute) + |
---|
82 | '="' + attributes[attribute].toString().escapeHTML() + '"'); |
---|
83 | return attrs.join(" "); |
---|
84 | }, |
---|
85 | _children: function(element, children) { |
---|
86 | if(typeof children=='object') { // array can hold nodes and text |
---|
87 | children.flatten().each( function(e) { |
---|
88 | if(typeof e=='object') |
---|
89 | element.appendChild(e) |
---|
90 | else |
---|
91 | if(Builder._isStringOrNumber(e)) |
---|
92 | element.appendChild(Builder._text(e)); |
---|
93 | }); |
---|
94 | } else |
---|
95 | if(Builder._isStringOrNumber(children)) |
---|
96 | element.appendChild(Builder._text(children)); |
---|
97 | }, |
---|
98 | _isStringOrNumber: function(param) { |
---|
99 | return(typeof param=='string' || typeof param=='number'); |
---|
100 | } |
---|
101 | } |
---|