Changeset 6048
- Timestamp:
- 01/27/07 19:45:34 (2 years ago)
- Files:
-
- spinoffs/prototype/trunk/CHANGELOG (modified) (1 diff)
- spinoffs/prototype/trunk/src/dom.js (modified) (4 diffs)
- spinoffs/prototype/trunk/src/form.js (modified) (2 diffs)
- spinoffs/prototype/trunk/src/prototype.js (modified) (1 diff)
- spinoffs/prototype/trunk/test/unit/dom.html (modified) (4 diffs)
- spinoffs/prototype/trunk/test/unit/form.html (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
spinoffs/prototype/trunk/CHANGELOG
r6047 r6048 1 1 *SVN* 2 3 * Fix $(form).serialize() in Safari and add support for extending specific tags to Element.addMethods. Closes #7358. [Andrew Dupont] 2 4 3 5 * Add String.prototype.startsWith, String.prototype.endsWith, and String.prototype.include. Closes #7075. [Tobie Langel] spinoffs/prototype/trunk/src/dom.js
r6002 r6048 42 42 var Element = new Object(); 43 43 44 44 45 Element.extend = function(element) { 45 if (!element || _nativeExtensions || element.nodeType == 3) return element; 46 47 if (!element._extended && element.tagName && element != window) { 48 var methods = Object.clone(Element.Methods), cache = Element.extend.cache; 49 50 if (element.tagName == 'FORM') 51 Object.extend(methods, Form.Methods); 52 if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName)) 53 Object.extend(methods, Form.Element.Methods); 54 55 Object.extend(methods, Element.Methods.Simulated); 56 57 for (var property in methods) { 58 var value = methods[property]; 59 if (typeof value == 'function' && !(property in element)) 60 element[property] = cache.findOrStore(value); 61 } 62 } 63 46 var F = Prototype.BrowserFeatures; 47 if (!element || !element.tagName || element.nodeType == 3 || 48 element._extended || F.SpecificElementExtensions || element == window) 49 return element; 50 51 var methods = {}, tagName = element.tagName, cache = Element.extend.cache, 52 T = Element.Methods.ByTag; 53 54 // extend methods for all tags (Safari doesn't need this) 55 if (!F.ElementExtensions) { 56 Object.extend(methods, Element.Methods), 57 Object.extend(methods, Element.Methods.Simulated); 58 } 59 60 // extend methods for specific tags 61 if (T[tagName]) Object.extend(methods, T[tagName]); 62 63 for (var property in methods) { 64 var value = methods[property]; 65 if (typeof value == 'function' && !(property in element)) 66 element[property] = cache.findOrStore(value); 67 } 68 64 69 element._extended = true; 65 70 return element; … … 471 476 } 472 477 }; 478 479 Element.Methods.ByTag = {}; 473 480 474 481 // IE is missing .innerHTML support for TABLE-related elements … … 511 518 Object.extend(Element, Element.Methods); 512 519 513 var _nativeExtensions = false; 514 515 if(/Konqueror|Safari|KHTML/.test(navigator.userAgent)) 516 ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) { 517 var className = 'HTML' + tag + 'Element'; 518 if(window[className]) return; 519 var klass = window[className] = {}; 520 klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__; 521 }); 520 if (!Prototype.BrowserFeatures.ElementExtensions && 521 document.createElement('div').__proto__) { 522 window.HTMLElement = {}; 523 window.HTMLElement.prototype = document.createElement('div').__proto__; 524 Prototype.BrowserFeatures.ElementExtensions = true; 525 } 522 526 523 527 Element.addMethods = function(methods) { 524 Object.extend(Element.Methods, methods || {}); 525 528 var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; 529 if (arguments.length == 2) { 530 var tagName = methods; 531 methods = arguments[1]; 532 } 533 534 if (!tagName) 535 Object.extend(Element.Methods, methods || {}); 536 else { 537 if (tagName.constructor == Array) { 538 tagName.each(extend); 539 } 540 else extend(tagName); 541 } 542 543 function extend(tagName) { 544 tagName = tagName.toUpperCase(); 545 if (!Element.Methods.ByTag[tagName]) 546 Element.Methods.ByTag[tagName] = {}; 547 Object.extend(Element.Methods.ByTag[tagName], methods); 548 } 549 526 550 function copy(methods, destination, onlyIfAbsent) { 527 551 onlyIfAbsent = onlyIfAbsent || false; … … 534 558 } 535 559 536 if (typeof HTMLElement != 'undefined') { 560 function findDOMClass(tagName) { 561 var klass; 562 var trans = { 563 "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", 564 "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", 565 "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", 566 "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", 567 "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": 568 "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": 569 "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": 570 "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": 571 "FrameSet", "IFRAME": "IFrame" 572 }; 573 if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; 574 if (window[klass]) return window[klass]; 575 klass = 'HTML' + tagName + 'Element'; 576 if (window[klass]) return window[klass]; 577 klass = 'HTML' + tagName.capitalize() + 'Element'; 578 if (window[klass]) return window[klass]; 579 580 window[klass] = {}; 581 window[klass].prototype = document.createElement(tagName).__proto__; 582 return window[klass]; 583 } 584 585 if (F.ElementExtensions) { 537 586 copy(Element.Methods, HTMLElement.prototype); 538 587 copy(Element.Methods.Simulated, HTMLElement.prototype, true); 539 copy(Form.Methods, HTMLFormElement.prototype); 540 [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) { 541 copy(Form.Element.Methods, klass.prototype); 542 }); 543 _nativeExtensions = true; 544 } 545 } 588 } 589 590 if (F.SpecificElementExtensions) { 591 for (var tag in Element.Methods.ByTag) { 592 var klass = findDOMClass(tag); 593 if (typeof klass == "undefined") continue; 594 copy(T[tag], klass.prototype); 595 } 596 } 597 }; 546 598 547 599 var Toggle = new Object(); spinoffs/prototype/trunk/src/form.js
r5997 r6048 157 157 158 158 Object.extend(Form.Element, Form.Element.Methods); 159 Object.extend(Element.Methods.ByTag, { 160 "FORM": Object.clone(Form.Methods), 161 "INPUT": Object.clone(Form.Element.Methods), 162 "SELECT": Object.clone(Form.Element.Methods), 163 "TEXTAREA": Object.clone(Form.Element.Methods) 164 }); 165 166 /*--------------------------------------------------------------------------*/ 167 159 168 var Field = Form.Element; 160 169 var $F = Form.Element.getValue; … … 305 314 } 306 315 }); 307 spinoffs/prototype/trunk/src/prototype.js
r5102 r6048 4 4 Version: '<%= PROTOTYPE_VERSION %>', 5 5 BrowserFeatures: { 6 XPath: !!document.evaluate 6 XPath: !!document.evaluate, 7 ElementExtensions: !!window.HTMLElement, 8 SpecificElementExtensions: 9 (document.createElement('div').__proto__ !== 10 document.createElement('form').__proto__) 7 11 }, 8 12 spinoffs/prototype/trunk/test/unit/dom.html
r6002 r6048 257 257 var testVar = 'to be updated'; 258 258 259 Element.addMethods("LI", { 260 pancakes: function(element) { return "pancakes"; } 261 }); 262 263 Element.addMethods("DIV", { 264 waffles: function(element) { return "waffles"; } 265 }); 266 267 Element.addMethods($w("li div"), { 268 orangeJuice: function(element) { return "orange juice"; } 269 }); 270 259 271 new Test.Unit.Runner({ 260 272 … … 272 284 assertIdentical(elt, $(elt)); 273 285 assertRespondsTo('hide', elt); 286 assertRespondsTo('childOf', elt); 274 287 }}, 275 288 … … 283 296 testInsertWithTR: function() {with(this) { 284 297 new Insertion.After('second_row', '<tr id="third_row"><td>Third Row</td></tr>'); 285 assert($('second_row'). childOf('table'));298 assert($('second_row').descendantOf('table')); 286 299 }}, 287 300 … … 802 815 assertEqual(Position.page(elem)[1], 0); 803 816 window.scrollTo(0, 0); 804 }} 805 817 }}, 818 819 testSpecificElementMethods: function() {with(this) { 820 var elem = $('navigation_test_f'); 821 822 assert(Element.Methods.ByTag[elem.tagName]); 823 assertRespondsTo('pancakes', elem); 824 assertEqual("pancakes", elem.pancakes()); 825 826 var elem2 = $('test-visible'); 827 828 assert(Element.Methods.ByTag[elem2.tagName]); 829 assertUndefined(elem2.pancakes); 830 assertRespondsTo('waffles', elem2); 831 assertEqual("waffles", elem2.waffles()); 832 833 assertRespondsTo('orangeJuice', elem); 834 assertRespondsTo('orangeJuice', elem2); 835 assertEqual("orange juice", elem.orangeJuice()); 836 assertEqual("orange juice", elem2.orangeJuice()); 837 }} 806 838 }, 'testlog'); 807 839 spinoffs/prototype/trunk/test/unit/form.html
r5997 r6048 281 281 assertEqual('nvm%5B%5D=One&nvm%5B%5D=Three&evu=&evm%5B%5D=&evm%5B%5D=Three', Form.serialize('form_fieldset')); 282 282 assertEqual('vu=1&vm%5B%5D=1&vm%5B%5D=3&nvu=One&nvm%5B%5D=One&nvm%5B%5D=Three&evu=&evm%5B%5D=&evm%5B%5D=Three', Form.serialize('form_wrapper')); 283 }} 283 }}, 284 285 testFormMethodsOnExtendedElements: function() {with(this) { 286 assertEqual(Form.serialize('form'), $('form').serialize()); 287 assertEqual(Form.Element.serialize('input_enabled'), $('input_enabled').serialize()); 288 assertNotEqual($('form').serialize, $('input_enabled').serialize); 289 290 Element.addMethods('INPUT', { anInputMethod: function(input) { return 'input' } }); 291 Element.addMethods('SELECT', { aSelectMethod: function(select) { return 'select' } }); 292 293 document.getElementById('tf_text')._extended = false; 294 document.getElementById('tf_selectOne')._extended = false; 295 296 assert($('tf_text').anInputMethod); 297 assert(!$('tf_text').aSelectMethod); 298 assertEqual('input', $('tf_text').anInputMethod()); 299 300 assert($('tf_selectOne').aSelectMethod); 301 assert(!$('tf_selectOne').anInputMethod); 302 assertEqual('select', $('tf_selectOne').aSelectMethod()); 303 }} 284 304 285 305 }, 'testlog');