Changeset 6636
- Timestamp:
- 04/30/07 09:02:01 (2 years ago)
- Files:
-
- spinoffs/prototype/branches/dom/CHANGELOG (modified) (1 diff)
- spinoffs/prototype/branches/dom/src/ajax.js (modified) (1 diff)
- spinoffs/prototype/branches/dom/src/dom.js (modified) (6 diffs)
- spinoffs/prototype/branches/dom/src/enumerable.js (modified) (1 diff)
- spinoffs/prototype/branches/dom/src/prototype.js (modified) (1 diff)
- spinoffs/prototype/branches/dom/test/unit/ajax.html (modified) (3 diffs)
- spinoffs/prototype/branches/dom/test/unit/dom.html (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
spinoffs/prototype/branches/dom/CHANGELOG
r6626 r6636 1 1 *SVN* 2 3 * 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] 2 4 3 5 * Add Function#curry, Function#delay, Function#defer, and Function#wrap. Closes #8134. [Andrew Dupont, Tobie Langel, sam] spinoffs/prototype/branches/dom/src/ajax.js
r6626 r6636 255 255 updateContent: function() { 256 256 var receiver = this.container[this.success() ? 'success' : 'failure']; 257 var response = this.transport.responseText ;258 259 if (! this.options.evalScripts) response = response.stripScripts();257 var response = this.transport.responseText, options = this.options; 258 259 if (!options.evalScripts) response = response.stripScripts(); 260 260 261 261 if (receiver = $(receiver)) { 262 if (this.options.insertion) 263 new this.options.insertion(receiver, response); 264 else 265 receiver.update(response); 262 if (options.insertion) { 263 if(typeof options.insertion == 'string') 264 receiver.insert(response, options.insertion) 265 else options.insertion(receiver, response); 266 } 267 else receiver.update(response); 266 268 } 267 269 spinoffs/prototype/branches/dom/src/dom.js
r6626 r6636 125 125 }, 126 126 127 insert: function(element, content, position) { 128 element = $(element); 129 position = (position || 'bottom').toLowerCase(); 130 var t = Element._insertionTranslations[position], fragments, stripped; 131 132 if(content && content.ownerDocument === document) 133 return t.insert(element, content); 134 135 content = content.toString(); 136 stripped = content.stripScripts(); 137 138 if (element.insertAdjacentHTML) { 139 try { 140 element.insertAdjacentHTML(t.adjacency, stripped); 141 } catch (e) { 142 var tagName = element.tagName.toUpperCase(); 143 if (['THEAD','TBODY','TR','TD'].include(tagName)) { 144 fragments = Element._getContentFromAnonymousTable(content, tagName); 145 if(position == 'top') fragments.reverse(); 146 fragments.each(t.insert.curry(element)); 147 } else { throw e } 148 } 149 } else { 150 var range = element.ownerDocument.createRange(); 151 t.initializeRange(element, range); 152 fragments = [range.createContextualFragment(stripped)]; 153 if(position == 'top') fragments.reverse(); 154 fragments.each(t.insert.curry(element)); 155 } 156 content.evalScripts.bind(content).defer(); 157 return element; 158 }, 159 127 160 inspect: function(element) { 128 161 element = $(element); … … 428 461 429 462 Object.extend(Element.Methods, { 430 childOf: Element.Methods.descendantOf,431 463 childElements: Element.Methods.immediateDescendants 432 464 }); … … 446 478 } 447 479 else if (Prototype.Browser.IE) { 480 Element._getContentFromAnonymousTable = function(html, tagName) { 481 var div = document.createElement('div'), depth; 482 switch (tagName) { 483 case 'THEAD': 484 case 'TBODY': 485 div.innerHTML = '<table><tbody>' + html + '</tbody></table>'; 486 depth = 2; 487 break; 488 case 'TR': 489 div.innerHTML = '<table><tbody><tr>' + html + '</tr></tbody></table>'; 490 depth = 3; 491 break; 492 case 'TD': 493 div.innerHTML = '<table><tbody><tr><td>' + html + '</td></tr></tbody></table>'; 494 depth = 4; 495 } 496 depth.times(function() { div = div.firstChild }); 497 return $A(div.childNodes); 498 }; 499 448 500 Element.Methods.getStyle = function(element, style) { 449 501 element = $(element); … … 484 536 var tagName = element.tagName.toUpperCase(); 485 537 if (['THEAD','TBODY','TR','TD'].include(tagName)) { 486 var div = document.createElement('div');487 switch (tagName) {488 case 'THEAD':489 case 'TBODY':490 div.innerHTML = '<table><tbody>' + html.stripScripts() + '</tbody></table>';491 depth = 2;492 break;493 case 'TR':494 div.innerHTML = '<table><tbody><tr>' + html.stripScripts() + '</tr></tbody></table>';495 depth = 3;496 break;497 case 'TD':498 div.innerHTML = '<table><tbody><tr><td>' + html.stripScripts() + '</td></tr></tbody></table>';499 depth = 4;500 }501 538 $A(element.childNodes).each(function(node) { element.removeChild(node) }); 502 depth.times(function() { div = div.firstChild });503 $A(div.childNodes).each(function(node) { element.appendChild(node) });539 Element._getContentFromAnonymousTable(html.stripScripts(), tagName).each( 540 element.appendChild); 504 541 } else { 505 542 element.innerHTML = html.stripScripts(); … … 517 554 }; 518 555 } 556 557 Element._insertionTranslations = { 558 before: { 559 adjacency: 'beforeBegin', 560 insert: function(element, node) { 561 element.parentNode.insertBefore(node, element); 562 }, 563 initializeRange: function(element, range) { 564 range.setStartBefore(element); 565 } 566 }, 567 top: { 568 adjacency: 'afterBegin', 569 insert: function(element, node) { 570 element.insertBefore(node, element.firstChild); 571 }, 572 initializeRange: function(element, range) { 573 range.selectNodeContents(element); 574 range.collapse(true); 575 } 576 }, 577 bottom: { 578 adjacency: 'beforeEnd', 579 insert: function(element, node) { 580 element.appendChild(node); 581 } 582 }, 583 after: { 584 adjacency: 'afterEnd', 585 insert: function(element, node) { 586 element.parentNode.insertBefore(node, element.nextSibling); 587 }, 588 initializeRange: function(element, range) { 589 range.setStartAfter(element); 590 } 591 } 592 }; 593 Element._insertionTranslations.bottom.initializeRange = 594 Element._insertionTranslations.top.initializeRange; 519 595 520 596 Element._attributeTranslations = { … … 669 745 }; 670 746 671 var Toggle = { display: Element.toggle };672 673 /*--------------------------------------------------------------------------*/674 675 Abstract.Insertion = function(adjacency) {676 this.adjacency = adjacency;677 }678 679 Abstract.Insertion.prototype = {680 initialize: function(element, content) {681 this.element = $(element);682 this.content = content.stripScripts();683 684 if (this.adjacency && this.element.insertAdjacentHTML) {685 try {686 this.element.insertAdjacentHTML(this.adjacency, this.content);687 } catch (e) {688 var tagName = this.element.tagName.toUpperCase();689 if (['TBODY', 'TR'].include(tagName)) {690 this.insertContent(this.contentFromAnonymousTable());691 } else {692 throw e;693 }694 }695 } else {696 this.range = this.element.ownerDocument.createRange();697 if (this.initializeRange) this.initializeRange();698 this.insertContent([this.range.createContextualFragment(this.content)]);699 }700 701 content.evalScripts.bind(content).defer();702 },703 704 contentFromAnonymousTable: function() {705 var div = document.createElement('div');706 div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';707 return $A(div.childNodes[0].childNodes[0].childNodes);708 }709 }710 711 var Insertion = new Object();712 713 Insertion.Before = Class.create();714 Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {715 initializeRange: function() {716 this.range.setStartBefore(this.element);717 },718 719 insertContent: function(fragments) {720 fragments.each((function(fragment) {721 this.element.parentNode.insertBefore(fragment, this.element);722 }).bind(this));723 }724 });725 726 Insertion.Top = Class.create();727 Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {728 initializeRange: function() {729 this.range.selectNodeContents(this.element);730 this.range.collapse(true);731 },732 733 insertContent: function(fragments) {734 fragments.reverse(false).each((function(fragment) {735 this.element.insertBefore(fragment, this.element.firstChild);736 }).bind(this));737 }738 });739 740 Insertion.Bottom = Class.create();741 Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {742 initializeRange: function() {743 this.range.selectNodeContents(this.element);744 this.range.collapse(this.element);745 },746 747 insertContent: function(fragments) {748 fragments.each((function(fragment) {749 this.element.appendChild(fragment);750 }).bind(this));751 }752 });753 754 Insertion.After = Class.create();755 Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {756 initializeRange: function() {757 this.range.setStartAfter(this.element);758 },759 760 insertContent: function(fragments) {761 fragments.each((function(fragment) {762 this.element.parentNode.insertBefore(fragment,763 this.element.nextSibling);764 }).bind(this));765 }766 });767 768 747 /*--------------------------------------------------------------------------*/ 769 748 spinoffs/prototype/branches/dom/src/enumerable.js
r6601 r6636 1 var $break = {} , $continue = new Error('"throw $continue" is deprecated, use "return" instead');1 var $break = {}; 2 2 3 3 var Enumerable = { spinoffs/prototype/branches/dom/src/prototype.js
r6556 r6636 30 30 <%= include 'enumerable.js', 'array.js', 'hash.js', 'range.js' %> 31 31 32 <%= include 'ajax.js', 'dom.js', 'selector.js', 'form.js', 'event.js', 'position.js' %>32 <%= include 'ajax.js', 'dom.js', 'selector.js', 'form.js', 'event.js', 'position.js', 'deprecated.js' %> 33 33 34 34 Element.addMethods(); spinoffs/prototype/branches/dom/test/unit/ajax.html
r6558 r6636 30 30 // <![CDATA[ 31 31 var responderCounter = 0; 32 32 33 // lowercase comparison because of MSIE which presents HTML tags in uppercase 34 var sentence = ("Pack my box with <em>five dozen</em> liquor jugs! " + 35 "Oh, how <strong>quickly</strong> daft jumping zebras vex...").toLowerCase(); 36 33 37 new Test.Unit.Runner({ 34 38 … … 77 81 new Ajax.Updater("content", "fixtures/content.html", { method:'get' }); 78 82 79 // lowercase comparison because of MSIE which presents HTML tags in uppercase80 var sentence = ("Pack my box with <em>five dozen</em> liquor jugs! " +81 "Oh, how <strong>quickly</strong> daft jumping zebras vex...").toLowerCase();82 83 83 wait(1000,function(){ 84 84 assertEqual(sentence, $("content").innerHTML.strip().toLowerCase()); … … 96 96 assertEqual("", $("content2").innerHTML); 97 97 }); 98 }); 99 }}, 100 101 testUpdaterWithInsertion: function() {with(this) { 102 $('content').update(); 103 new Ajax.Updater("content", "fixtures/content.html", { method:'get', insertion: Insertion.Top }); 104 wait(1000,function(){ 105 assertEqual(sentence, $("content").innerHTML.strip().toLowerCase()); 106 $('content').update(); 107 new Ajax.Updater("content", "fixtures/content.html", { method:'get', insertion: 'bottom' }); 108 wait(1000,function(){ 109 assertEqual(sentence, $("content").innerHTML.strip().toLowerCase()); 110 }); 98 111 }); 99 112 }}, 100 113 101 114 testResponders: function(){with(this) { 102 115 // check for internal responder spinoffs/prototype/branches/dom/test/unit/dom.html
r6597 r6636 268 268 <div id="ancestor"><div id="child"><div><div id="great-grand-child"></div></div></div></div> 269 269 <div id="not-in-the-family"></div> 270 271 <div id="insertions-container"><div id="insertions-main"><p>some content.</p></div></div> 272 <div id="insertions-node-container"><div id="insertions-node-main"><p>some content.</p></div></div> 273 <div id="element-insertions-container"><div id="element-insertions-main"><p>some content.</p></div></div> 274 <div id="wrap-container"><p id="wrap"></p></div> 270 275 <!-- Tests follow --> 271 276 <script type="text/javascript" language="javascript" charset="utf-8"> … … 273 278 274 279 var testVar = 'to be updated', testVar2 = ''; 275 280 var getInnerHTML = function(id) { 281 return $(id).innerHTML.toString().toLowerCase().gsub(/[\r\n\t]/, ''); 282 }; 276 283 Element.addMethods({ 277 284 hashBrowns: function(element) { return 'hash browns'; } … … 314 321 assertElementsMatch(document.getElementsByClassName('B', 'class_names_ul')); 315 322 }}, 316 317 testInsertWithTR: function() {with(this) { 318 new Insertion.After('second_row', '<tr id="third_row"><td>Third Row</td></tr>'); 323 324 testElementInsertWithHTML: function() {with(this) { 325 Element.insert('insertions-main', '<p><em>before</em> text</p><p>more testing</p>', 'before'); 326 assert(getInnerHTML('insertions-container').startsWith('<p><em>before</em> text</p><p>more testing</p>')); 327 Element.insert('insertions-main', '<p><em>after</em> text</p><p>more testing</p>', 'after'); 328 assert(getInnerHTML('insertions-container').endsWith('<p><em>after</em> text</p><p>more testing</p>')); 329 Element.insert('insertions-main', '<p><em>top</em> text.</p><p>more testing</p>', 'top'); 330 assert(getInnerHTML('insertions-main').startsWith('<p><em>top</em> text.</p><p>more testing</p>')); 331 Element.insert('insertions-main', '<p><em>bottom</em> text.</p><p>more testing</p>', 'bottom'); 332 assert(getInnerHTML('insertions-main').endsWith('<p><em>bottom</em> text.</p><p>more testing</p>')); 333 }}, 334 335 testElementInsertWithDOMNode: function() {with(this) { 336 var createParagraph = function(text) { 337 var p = document.createElement('p'); 338 p.appendChild(document.createTextNode(text)); 339 return p; 340 } 341 Element.insert('insertions-node-main', createParagraph('node before'), 'before');; 342 assert(getInnerHTML('insertions-node-container').startsWith('<p>node before</p>')); 343 Element.insert('insertions-node-main', createParagraph('node after'), 'after');; 344 assert(getInnerHTML('insertions-node-container').endsWith('<p>node after</p>')); 345 Element.insert('insertions-node-main', createParagraph('node top'), 'top');; 346 assert(getInnerHTML('insertions-node-main').startsWith('<p>node top</p>')); 347 Element.insert('insertions-node-main', createParagraph('node bottom'), 'bottom');; 348 assert(getInnerHTML('insertions-node-main').endsWith('<p>node bottom</p>')); 349 }}, 350 351 testElementInsertWithNonString: function() {with(this) { 352 Element.insert('insertions-main', 3, 'bottom'); 353 assert(getInnerHTML('insertions-main').endsWith('3')); 354 }}, 355 356 testElementInsertWithTR: function() {with(this) { 357 Element.insert('second_row', '<tr id="third_row"><td>Third Row</td></tr>', 'after'); 319 358 assert($('second_row').descendantOf('table')); 320 359 }}, 321 360 361 testElementMethodInsert: function() {with(this) { 362 $('element-insertions-main').insert('some text before','before'); 363 assert(getInnerHTML('element-insertions-container').startsWith('some text before')); 364 $('element-insertions-main').insert('some text after', 'after'); 365 assert(getInnerHTML('element-insertions-container').endsWith('some text after')); 366 $('element-insertions-main').insert('some text top', 'top'); 367 assert(getInnerHTML('element-insertions-main').startsWith('some text top')); 368 $('element-insertions-main').insert('some text bottom', 'bottom'); 369 assert(getInnerHTML('element-insertions-main').endsWith('some text bottom')); 370 371 $('element-insertions-main').insert('some more text at the bottom'); 372 assert(getInnerHTML('element-insertions-main').endsWith('some more text at the bottom')); 373 }}, 374 375 testInsertionBackwardsCompatibility: function() {with(this) { 376 new Insertion.Before('element-insertions-main', 'some backward-compatibility testing before'); 377 assert(getInnerHTML('element-insertions-container').include('some backward-compatibility testing before')); 378 new Insertion.After('element-insertions-main', 'some backward-compatibility testing after'); 379 assert(getInnerHTML('element-insertions-container').include('some backward-compatibility testing after')); 380 new Insertion.Top('element-insertions-main', 'some backward-compatibility testing top'); 381 assert(getInnerHTML('element-insertions-main').startsWith('some backward-compatibility testing top')); 382 new Insertion.Bottom('element-insertions-main', 'some backward-compatibility testing bottom'); 383 assert(getInnerHTML('element-insertions-main').endsWith('some backward-compatibility testing bottom')); 384 }}, 385 322 386 testElementVisible: function(){with(this) { 323 387 assertNotEqual('none', $('test-visible').style.display); … … 442 506 }); 443 507 }}, 444 508 445 509 testElementSelectorMethod: function() {with(this) { 446 510 var testSelector = $('container').getElementsBySelector('p.test');