Changeset 6638
- Timestamp:
- 04/30/07 09:31:54 (2 years ago)
- Files:
-
- spinoffs/prototype/branches/dom/CHANGELOG (modified) (1 diff)
- spinoffs/prototype/branches/dom/src/dom.js (modified) (7 diffs)
- spinoffs/prototype/branches/dom/test/unit/dom.html (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
spinoffs/prototype/branches/dom/CHANGELOG
r6636 r6638 1 1 *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] 2 4 3 5 * 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 38 38 /*--------------------------------------------------------------------------*/ 39 39 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 57 Element.cache = {}; 42 58 Element.extend = function(element) { 43 59 var F = Prototype.BrowserFeatures; … … 263 279 if (Prototype.Browser.IE) { 264 280 if (!element.attributes) return null; 265 var t = Element._attributeTranslations ;281 var t = Element._attributeTranslations.read; 266 282 if (t.values[name]) return t.values[name](element, name); 267 283 if (t.names[name]) name = t.names[name]; … … 270 286 } 271 287 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; 272 307 }, 273 308 … … 463 498 childElements: Element.Methods.immediateDescendants 464 499 }); 500 501 Element._attributeTranslations = { 502 write: { 503 names: { 504 className: 'class', 505 htmlFor: 'for' 506 }, 507 values: {} 508 } 509 }; 465 510 466 511 if (Prototype.Browser.Opera) { … … 544 589 html.evalScripts.bind(html).defer(); 545 590 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); 547 652 } 548 653 else if (Prototype.Browser.Gecko) { … … 594 699 Element._insertionTranslations.top.initializeRange; 595 700 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._flag635 });636 }).call(Element._attributeTranslations.values);637 638 701 Element.Methods.Simulated = { 639 702 hasAttribute: function(element, attribute) { 640 var t = Element._attributeTranslations , node;703 var t = Element._attributeTranslations.read, node; 641 704 attribute = t.names[attribute] || attribute; 642 705 node = $(element).getAttributeNode(attribute); … … 743 806 Object.extend(Element, Element.Methods); 744 807 delete Element.ByTag; 808 Element.cache = {}; 745 809 }; 746 810 spinoffs/prototype/branches/dom/test/unit/dom.html
r6636 r6638 224 224 </form> 225 225 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 226 246 <div id="dom_attribute_precedence"> 227 247 <form action="blech" method="post"> … … 490 510 }}, 491 511 492 493 512 testElementReplaceWithScript: function() {with(this) { 494 513 $('testdiv-replace-4').replace('hello from div!<script>testVarReplace="hello!"</'+'script>'); … … 900 919 }}, 901 920 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 902 1033 testElementGetHeight: function() {with(this) { 903 1034 assertIdentical(100, $('dimensions-visible').getHeight());