static/builder.js
changeset 13 a0cb32f3de3d
equal deleted inserted replaced
12:aa6b83c94528 13:a0cb32f3de3d
       
     1 // script.aculo.us builder.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
       
     2 
       
     3 // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
       
     4 //
       
     5 // script.aculo.us is freely distributable under the terms of an MIT-style license.
       
     6 // For details, see the script.aculo.us web site: http://script.aculo.us/
       
     7 
       
     8 var Builder = {
       
     9   NODEMAP: {
       
    10     AREA: 'map',
       
    11     CAPTION: 'table',
       
    12     COL: 'table',
       
    13     COLGROUP: 'table',
       
    14     LEGEND: 'fieldset',
       
    15     OPTGROUP: 'select',
       
    16     OPTION: 'select',
       
    17     PARAM: 'object',
       
    18     TBODY: 'table',
       
    19     TD: 'table',
       
    20     TFOOT: 'table',
       
    21     TH: 'table',
       
    22     THEAD: 'table',
       
    23     TR: 'table'
       
    24   },
       
    25   // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
       
    26   //       due to a Firefox bug
       
    27   node: function(elementName) {
       
    28     elementName = elementName.toUpperCase();
       
    29     
       
    30     // try innerHTML approach
       
    31     var parentTag = this.NODEMAP[elementName] || 'div';
       
    32     var parentElement = document.createElement(parentTag);
       
    33     try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
       
    34       parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
       
    35     } catch(e) {}
       
    36     var element = parentElement.firstChild || null;
       
    37       
       
    38     // see if browser added wrapping tags
       
    39     if(element && (element.tagName.toUpperCase() != elementName))
       
    40       element = element.getElementsByTagName(elementName)[0];
       
    41     
       
    42     // fallback to createElement approach
       
    43     if(!element) element = document.createElement(elementName);
       
    44     
       
    45     // abort if nothing could be created
       
    46     if(!element) return;
       
    47 
       
    48     // attributes (or text)
       
    49     if(arguments[1])
       
    50       if(this._isStringOrNumber(arguments[1]) ||
       
    51         (arguments[1] instanceof Array) ||
       
    52         arguments[1].tagName) {
       
    53           this._children(element, arguments[1]);
       
    54         } else {
       
    55           var attrs = this._attributes(arguments[1]);
       
    56           if(attrs.length) {
       
    57             try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
       
    58               parentElement.innerHTML = "<" +elementName + " " +
       
    59                 attrs + "></" + elementName + ">";
       
    60             } catch(e) {}
       
    61             element = parentElement.firstChild || null;
       
    62             // workaround firefox 1.0.X bug
       
    63             if(!element) {
       
    64               element = document.createElement(elementName);
       
    65               for(attr in arguments[1]) 
       
    66                 element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
       
    67             }
       
    68             if(element.tagName.toUpperCase() != elementName)
       
    69               element = parentElement.getElementsByTagName(elementName)[0];
       
    70           }
       
    71         } 
       
    72 
       
    73     // text, or array of children
       
    74     if(arguments[2])
       
    75       this._children(element, arguments[2]);
       
    76 
       
    77      return element;
       
    78   },
       
    79   _text: function(text) {
       
    80      return document.createTextNode(text);
       
    81   },
       
    82 
       
    83   ATTR_MAP: {
       
    84     'className': 'class',
       
    85     'htmlFor': 'for'
       
    86   },
       
    87 
       
    88   _attributes: function(attributes) {
       
    89     var attrs = [];
       
    90     for(attribute in attributes)
       
    91       attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) +
       
    92           '="' + attributes[attribute].toString().escapeHTML().gsub(/"/,'&quot;') + '"');
       
    93     return attrs.join(" ");
       
    94   },
       
    95   _children: function(element, children) {
       
    96     if(children.tagName) {
       
    97       element.appendChild(children);
       
    98       return;
       
    99     }
       
   100     if(typeof children=='object') { // array can hold nodes and text
       
   101       children.flatten().each( function(e) {
       
   102         if(typeof e=='object')
       
   103           element.appendChild(e)
       
   104         else
       
   105           if(Builder._isStringOrNumber(e))
       
   106             element.appendChild(Builder._text(e));
       
   107       });
       
   108     } else
       
   109       if(Builder._isStringOrNumber(children))
       
   110         element.appendChild(Builder._text(children));
       
   111   },
       
   112   _isStringOrNumber: function(param) {
       
   113     return(typeof param=='string' || typeof param=='number');
       
   114   },
       
   115   build: function(html) {
       
   116     var element = this.node('div');
       
   117     $(element).update(html.strip());
       
   118     return element.down();
       
   119   },
       
   120   dump: function(scope) { 
       
   121     if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope 
       
   122   
       
   123     var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
       
   124       "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
       
   125       "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+
       
   126       "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+
       
   127       "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+
       
   128       "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
       
   129   
       
   130     tags.each( function(tag){ 
       
   131       scope[tag] = function() { 
       
   132         return Builder.node.apply(Builder, [tag].concat($A(arguments)));  
       
   133       } 
       
   134     });
       
   135   }
       
   136 }