Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 6638

Show
Ignore:
Timestamp:
04/30/07 09:31:54 (2 years ago)
Author:
tobie
Message:

Make Element into a constructor: new Element(tagName, attributes). Add Element#writeAttribute which accepts a hash of attributes or a name/value pair. ref. #7476.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • spinoffs/prototype/branches/dom/CHANGELOG

    r6636 r6638  
    11*SVN* 
     2 
     3* Make Element into a constructor: new Element(tagName, attributes). Add Element#writeAttribute which accepts a hash of attributes or a name/value pair. Closes #7476. [Mislav Marohnić, haraldmartin, Tobie Langel] 
    24 
    35* Insertion overhaul: Add Element.insert(content[, position = 'Bottom']). Deprecate Insertion (kept for backwards compatibility). Make Ajax.Updater option.insertion accept both Insertion.Top or the now preferred 'Top'. Closes #7907. [Tobie Langel] 
  • spinoffs/prototype/branches/dom/src/dom.js

    r6636 r6638  
    3838/*--------------------------------------------------------------------------*/ 
    3939 
    40 if (!window.Element) var Element = {}; 
    41  
     40(function() { 
     41  var element = this.Element; 
     42  this.Element = function(tagName, attributes) { 
     43    attributes = attributes || {}; 
     44    tagName = tagName.toLowerCase(); 
     45    var cache = Element.cache; 
     46    if (Prototype.Browser.IE && attributes.name) { 
     47      tagName = '<' + tagName + ' name="' + attributes.name + '">'; 
     48      delete attributes.name; 
     49      return Element.writeAttribute(document.createElement(tagName), attributes); 
     50    } 
     51    if(!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); 
     52    return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); 
     53  }; 
     54  Object.extend(this.Element, element || {}); 
     55}).call(window); 
     56 
     57Element.cache = {}; 
    4258Element.extend = function(element) { 
    4359  var F = Prototype.BrowserFeatures; 
     
    263279    if (Prototype.Browser.IE) { 
    264280      if (!element.attributes) return null; 
    265       var t = Element._attributeTranslations
     281      var t = Element._attributeTranslations.read
    266282      if (t.values[name]) return t.values[name](element, name); 
    267283      if (t.names[name])  name = t.names[name]; 
     
    270286    }     
    271287    return element.getAttribute(name); 
     288  }, 
     289   
     290  writeAttribute: function(element, name, value) { 
     291    element = $(element); 
     292    var attributes = {}, t = Element._attributeTranslations.write; 
     293     
     294    if (typeof name == 'object') attributes = name; 
     295    else attributes[name] = value === undefined ? true : value; 
     296     
     297    for (var attr in attributes) { 
     298      var name = t.names[attr] || attr, value = attributes[attr]; 
     299      if(t.values[attr]) name = t.values[attr](element, value); 
     300      if (value === false || value === null) 
     301        element.removeAttribute(name); 
     302      else if (value === true) 
     303        element.setAttribute(name, name); 
     304      else element.setAttribute(name, value); 
     305    } 
     306    return element; 
    272307  }, 
    273308   
     
    463498  childElements: Element.Methods.immediateDescendants 
    464499}); 
     500 
     501Element._attributeTranslations = { 
     502  write: { 
     503    names: { 
     504      className: 'class', 
     505      htmlFor:   'for'       
     506    },  
     507    values: {} 
     508  } 
     509}; 
    465510 
    466511if (Prototype.Browser.Opera) {  
     
    544589    html.evalScripts.bind(html).defer(); 
    545590    return element; 
    546   } 
     591  }; 
     592   
     593  Element._attributeTranslations = { 
     594    read: { 
     595      names: { 
     596        colspan:   "colSpan", 
     597        rowspan:   "rowSpan", 
     598        valign:    "vAlign", 
     599        datetime:  "dateTime", 
     600        accesskey: "accessKey", 
     601        tabindex:  "tabIndex", 
     602        enctype:   "encType", 
     603        maxlength: "maxLength", 
     604        readonly:  "readOnly", 
     605        longdesc:  "longDesc" 
     606      }, 
     607      values: { 
     608        _getAttr: function(element, attribute) { 
     609          return element.getAttribute(attribute, 2); 
     610        }, 
     611        _flag: function(element, attribute) { 
     612          return $(element).hasAttribute(attribute) ? attribute : null; 
     613        }, 
     614        style: function(element) { 
     615          return element.style.cssText.toLowerCase(); 
     616        }, 
     617        title: function(element) { 
     618          var node = element.getAttributeNode('title'); 
     619          return node.specified ? node.nodeValue : null; 
     620        } 
     621      } 
     622    } 
     623  }; 
     624   
     625  Element._attributeTranslations.write = { 
     626    names: Object.extend({ 
     627        'class': 'className', 
     628        'for':   'htmlFor'     
     629      }, Element._attributeTranslations.read.names), 
     630    values: { 
     631      checked: function(element, value) { 
     632        element.checked = !!value; 
     633      }, 
     634       
     635      style: function(element, value) { 
     636        element.style.cssText = value ? value : ''; 
     637      } 
     638    } 
     639  }; 
     640   
     641  (function() { 
     642    Object.extend(this, { 
     643      href: this._getAttr, 
     644      src:  this._getAttr, 
     645      type: this._getAttr, 
     646      disabled: this._flag, 
     647      checked:  this._flag, 
     648      readonly: this._flag, 
     649      multiple: this._flag 
     650    }); 
     651  }).call(Element._attributeTranslations.read.values); 
    547652} 
    548653else if (Prototype.Browser.Gecko) { 
     
    594699Element._insertionTranslations.top.initializeRange; 
    595700 
    596 Element._attributeTranslations = { 
    597   names: { 
    598     colspan:   "colSpan", 
    599     rowspan:   "rowSpan", 
    600     valign:    "vAlign", 
    601     datetime:  "dateTime", 
    602     accesskey: "accessKey", 
    603     tabindex:  "tabIndex", 
    604     enctype:   "encType", 
    605     maxlength: "maxLength", 
    606     readonly:  "readOnly", 
    607     longdesc:  "longDesc" 
    608   }, 
    609   values: { 
    610     _getAttr: function(element, attribute) { 
    611       return element.getAttribute(attribute, 2); 
    612     }, 
    613     _flag: function(element, attribute) { 
    614       return $(element).hasAttribute(attribute) ? attribute : null; 
    615     }, 
    616     style: function(element) { 
    617       return element.style.cssText.toLowerCase(); 
    618     }, 
    619     title: function(element) { 
    620       var node = element.getAttributeNode('title'); 
    621       return node.specified ? node.nodeValue : null; 
    622     } 
    623   } 
    624 }; 
    625  
    626 (function() { 
    627   Object.extend(this, { 
    628     href: this._getAttr, 
    629     src:  this._getAttr, 
    630     type: this._getAttr, 
    631     disabled: this._flag, 
    632     checked:  this._flag, 
    633     readonly: this._flag, 
    634     multiple: this._flag 
    635   }); 
    636 }).call(Element._attributeTranslations.values); 
    637  
    638701Element.Methods.Simulated = { 
    639702  hasAttribute: function(element, attribute) { 
    640     var t = Element._attributeTranslations, node; 
     703    var t = Element._attributeTranslations.read, node; 
    641704    attribute = t.names[attribute] || attribute; 
    642705    node = $(element).getAttributeNode(attribute); 
     
    743806  Object.extend(Element, Element.Methods); 
    744807  delete Element.ByTag; 
     808  Element.cache = {}; 
    745809}; 
    746810 
  • spinoffs/prototype/branches/dom/test/unit/dom.html

    r6636 r6638  
    224224</form> 
    225225 
     226<!-- writeAttributes  --> 
     227<p id="write_attribute_para"></a> 
     228<a id="write_attribute_link" href="test.html"></a> 
     229<form action="/dev/null" id="write_attribute_form" method="get" accept-charset="utf-8"> 
     230  <label id="write_attribute_label"></label> 
     231  <input type="checkbox" name="write_attribute_checkbox" value="" id="write_attribute_checkbox"> 
     232  <input type="checkbox" checked="checked" name="write_attribute_checked_checkbox" value="" id="write_attribute_checked_checkbox"> 
     233  <input type="text" name="write_attribute_input" value="" id="write_attribute_input"> 
     234  <select id="write_attribute_select"> 
     235    <option>Cat</option> 
     236    <option>Dog</option> 
     237  </select> 
     238</form> 
     239 
     240<table id="write_attribute_table"> 
     241  <tr><td id="write_attribute_td">A</td><td>B</td></tr> 
     242  <tr><td>C</td></tr> 
     243  <tr><td>D</td><td>E</td><td>F</td></tr> 
     244</table> 
     245 
    226246<div id="dom_attribute_precedence"> 
    227247  <form action="blech" method="post"> 
     
    490510    }}, 
    491511     
    492  
    493512    testElementReplaceWithScript: function() {with(this) { 
    494513      $('testdiv-replace-4').replace('hello from div!<script>testVarReplace="hello!"</'+'script>'); 
     
    900919    }}, 
    901920     
     921    testElementWriteAttribute: function() {with(this) { 
     922      var element = Element.extend(document.body.appendChild(document.createElement('p'))); 
     923      assertRespondsTo('writeAttribute', element); 
     924      assertEqual(element, element.writeAttribute('id', 'write_attribute_test')); 
     925      assertEqual('write_attribute_test', element.id); 
     926      assertEqual('http://prototypejs.org/', $('write_attribute_link'). 
     927        writeAttribute({href: 'http://prototypejs.org/', title: 'Home of Prototype'}).href); 
     928      assertEqual('Home of Prototype', $('write_attribute_link').title); 
     929       
     930      var element2 = Element.extend(document.createElement('p')); 
     931      element2.writeAttribute('id', 'write_attribute_without_hash'); 
     932      assertEqual('write_attribute_without_hash', element2.id); 
     933      element2.writeAttribute('animal', 'cat'); 
     934      assertEqual('cat', element2.readAttribute('animal')); 
     935    }}, 
     936     
     937    testElementWriteAttributeWithBooleans: function() {with(this) { 
     938      var input = $('write_attribute_input'), 
     939        select = $('write_attribute_select'), 
     940        checkbox = $('write_attribute_checkbox'), 
     941        checkedCheckbox = $('write_attribute_checked_checkbox'); 
     942      assert( input.          writeAttribute('readonly').            hasAttribute('readonly')); 
     943      assert(!input.          writeAttribute('readonly', false).     hasAttribute('readonly')); 
     944      assert( input.          writeAttribute('readonly', true).      hasAttribute('readonly')); 
     945      assert(!input.          writeAttribute('readonly', null).      hasAttribute('readonly')); 
     946      assert( input.          writeAttribute('readonly', 'readonly').hasAttribute('readonly')); 
     947      assert( select.         writeAttribute('multiple').            hasAttribute('multiple')); 
     948      assert( input.          writeAttribute('disabled').            hasAttribute('disabled')); 
     949      assert( checkbox.       writeAttribute('checked').             checked); 
     950      assert(!checkedCheckbox.writeAttribute('checked', false).      checked); 
     951    }}, 
     952 
     953    testElementWriteAttributeWithIssues: function() {with(this) { 
     954      var input = $('write_attribute_input').writeAttribute({maxlength: 90, tabindex: 10}), 
     955        td = $('write_attribute_td').writeAttribute({valign: 'bottom', colspan: 2, rowspan: 2}); 
     956      assertEqual(90, input.readAttribute('maxlength')); 
     957      assertEqual(10, input.readAttribute('tabindex')); 
     958      assertEqual(2,  td.readAttribute('colspan')); 
     959      assertEqual(2,  td.readAttribute('rowspan')); 
     960      assertEqual('bottom', td.readAttribute('valign')); 
     961       
     962      var p = $('write_attribute_para'), label = $('write_attribute_label'); 
     963      assertEqual('some-class',     p.    writeAttribute({'class':   'some-class'}).    readAttribute('class')); 
     964      assertEqual('some-className', p.    writeAttribute({className: 'some-className'}).readAttribute('class')); 
     965      assertEqual('some-id',        label.writeAttribute({'for':     'some-id'}).       readAttribute('for')); 
     966      assertEqual('some-other-id',  label.writeAttribute({htmlFor:   'some-other-id'}). readAttribute('for')); 
     967       
     968      assert(p.writeAttribute({style: 'width: 5px;'}).readAttribute('style').toLowerCase().include('width'));       
     969    }}, 
     970     
     971    testElementWriteAttributeWithCustom: function() {with(this) { 
     972      var p = $('write_attribute_para').writeAttribute({name: 'martin', location: 'stockholm', age: 26}); 
     973      assertEqual('martin',    p.readAttribute('name')); 
     974      assertEqual('stockholm', p.readAttribute('location')); 
     975      assertEqual('26',        p.readAttribute('age')); 
     976    }}, 
     977     
     978    testNewElement: function() {with(this) { 
     979      assert(new Element('h1')); 
     980       
     981      var XHTML_TAGS = $w( 
     982        'a abbr acronym address area '+ 
     983        'b bdo big blockquote br button caption '+ 
     984        'cite code col colgroup dd del dfn div dl dt '+ 
     985        'em fieldset form h1 h2 h3 h4 h5 h6 hr '+ 
     986        'i iframe img input ins kbd label legend li '+ 
     987        'map object ol optgroup option p param pre q samp '+ 
     988        'script select small span strong style sub sup '+ 
     989        'table tbody td textarea tfoot th thead tr tt ul var'); 
     990         
     991      XHTML_TAGS.each(function(tag, index) { 
     992        var id = tag + '_' + index, element = document.body.appendChild(new Element(tag, {id: id})); 
     993        assertEqual(tag, element.tagName.toLowerCase()); 
     994        assertEqual(element, document.body.lastChild); 
     995        assertEqual(id, element.id); 
     996      }); 
     997       
     998       
     999      assertRespondsTo('update', new Element('div')); 
     1000      Element.addMethods({ 
     1001        cheeseCake: function(){ 
     1002          return 'Cheese cake'; 
     1003        } 
     1004      }); 
     1005       
     1006      assertRespondsTo('cheeseCake', new Element('div')); 
     1007       
     1008      /* window.ElementOld = function(tagName, attributes) {  
     1009        if (Prototype.Browser.IE && attributes && attributes.name) {  
     1010          tagName = '<' + tagName + ' name="' + attributes.name + '">';  
     1011          delete attributes.name;  
     1012        }  
     1013        return Element.extend(document.createElement(tagName)).writeAttribute(attributes || {});  
     1014      }; 
     1015       
     1016      benchmark(function(){ 
     1017        XHTML_TAGS.each(function(tagName){new Element(tagName)}); 
     1018      }, 5); 
     1019       
     1020      benchmark(function(){ 
     1021        XHTML_TAGS.each(function(tagName){new ElementOld(tagName)}); 
     1022      }, 5); */ 
     1023       
     1024      assertEqual('foobar', new Element('a', {custom: 'foobar'}).readAttribute('custom')); 
     1025      var input = document.body.appendChild(new Element('input',  
     1026        {id: 'my_input_field_id', name: 'my_input_field'})); 
     1027      assertEqual(input, document.body.lastChild); 
     1028      assertEqual('my_input_field', $(document.body.lastChild).name); 
     1029      if (Prototype.Browser.IE) 
     1030        assertMatch(/name=["']?my_input_field["']?/, $('my_input_field').outerHTML); 
     1031    }}, 
     1032 
    9021033    testElementGetHeight: function() {with(this) { 
    9031034      assertIdentical(100, $('dimensions-visible').getHeight());