diff --git a/CHANGELOG b/CHANGELOG index 531481a..5ccc748 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,12 @@ *SVN* +* Change Element.insert syntax to allow multiple positions. [Thomas Fuchs] + Examples: + Element.insert('foo', {top:'bar', bottom:'baz'}); + $('foo').insert({after: new Element('p').update('bar')}); + Element.insert('foo', new Element('p').update('bar')); // defaults to bottom + Element.insert('foo', 'bar'); // defaults to bottom + * String.prototype.truncate now explicitly converts its return value into a string if no truncation takes place. This prevents possible issues with methods expecting input data that is typeof == 'string'. [Thomas Fuchs, Tobie Langel, Sam Stephenson] * Event.findElement behaves as expected when the element passed matches the given selector. Closes #8395. [Mislav Marohnić, Tobie Langel] diff --git a/src/ajax.js b/src/ajax.js index 94840e6..a868239 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -261,7 +261,7 @@ Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { if (receiver = $(receiver)) { if (options.insertion) { if (typeof options.insertion == 'string') - receiver.insert(response, options.insertion); + receiver.insert( {}[options.insertion] = response ); else options.insertion(receiver, response); } else receiver.update(response); diff --git a/src/deprecated.js b/src/deprecated.js index 5da4043..b320049 100644 --- a/src/deprecated.js +++ b/src/deprecated.js @@ -6,19 +6,19 @@ Element.Methods.childOf = Element.Methods.descendantOf; var Insertion = { Before: function(element, content) { - return Element.insert(element, content, 'before'); + return Element.insert(element, {before:content}); }, Top: function(element, content) { - return Element.insert(element, content, 'top'); + return Element.insert(element, {top:content}); }, Bottom: function(element, content) { - return Element.insert(element, content, 'bottom'); + return Element.insert(element, {bottom:content}); }, After: function(element, content) { - return Element.insert(element, content, 'after'); + return Element.insert(element, {after:content}); } } diff --git a/src/dom.js b/src/dom.js index b17999b..b2d7f2b 100644 --- a/src/dom.js +++ b/src/dom.js @@ -105,23 +105,33 @@ Element.Methods = { return element; }, - insert: function(element, content, position) { + insert: function(element, insertions) { element = $(element); - position = (position || 'bottom').toLowerCase(); - var t = Element._insertionTranslations[position], range; + + if(typeof insertions == 'string' || insertions.ownerDocument === document) + insertions = {bottom:insertions}; - if (content && content.ownerDocument === document) { - t.insert(element, content); - return element; + var content, t, range; + + for (position in insertions) { + content = insertions[position]; + position = position.toLowerCase(); + t = Element._insertionTranslations[position]; + + if (content && content.ownerDocument === document) { + t.insert(element, content); + continue; + } + + content = content.toString(); + + range = element.ownerDocument.createRange(); + t.initializeRange(element, range); + t.insert(element, range.createContextualFragment(content.stripScripts())); + + content.evalScripts.bind(content).defer(); } - content = content.toString(); - - range = element.ownerDocument.createRange(); - t.initializeRange(element, range); - t.insert(element, range.createContextualFragment(content.stripScripts())); - - content.evalScripts.bind(content).defer(); return element; }, @@ -622,28 +632,38 @@ Element._attributeTranslations = { if (!document.createRange || Prototype.Browser.Opera) { - Element.Methods.insert = function(element, content, position) { + Element.Methods.insert = function(element, insertions) { element = $(element); - position = (position || 'bottom').toLowerCase(); - var t = Element._insertionTranslations, pos = t[position], tagName; - if (content && content.ownerDocument === document) { - pos.insert(element, content); - return element; + if(typeof insertions == 'string' || insertions.ownerDocument === document) + insertions = {bottom:insertions}; + + var t = Element._insertionTranslations, content, position, pos, tagName; + + for (position in insertions) { + content = insertions[position]; + position = position.toLowerCase(); + pos = t[position]; + + if (content && content.ownerDocument === document) { + pos.insert(element, content); + continue; + } + + content = content.toString(); + tagName = ((position == 'before' || position == 'after') + ? element.parentNode : element).tagName.toUpperCase(); + + if (t.tags[tagName]) { + var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); + if (position == 'top' || position == 'after') fragments.reverse(); + fragments.each(pos.insert.curry(element)); + } + else element.insertAdjacentHTML(pos.adjacency, content.stripScripts()); + + content.evalScripts.bind(content).defer(); } - - content = content.toString(); - tagName = ((position == 'before' || position == 'after') - ? element.parentNode : element).tagName.toUpperCase(); - if (t.tags[tagName]) { - var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); - if (position == 'top' || position == 'after') fragments.reverse(); - fragments.each(pos.insert.curry(element)); - } - else element.insertAdjacentHTML(pos.adjacency, content.stripScripts()); - - content.evalScripts.bind(content).defer(); return element; } } diff --git a/test/unit/dom.html b/test/unit/dom.html index 55e9425..8813484 100644 --- a/test/unit/dom.html +++ b/test/unit/dom.html @@ -292,6 +292,7 @@

some content.

some content.

some content.

+

some content.

@@ -369,13 +370,13 @@ }}, testElementInsertWithHTML: function() {with(this) { - Element.insert('insertions-main', '

before text

more testing

', 'before'); + Element.insert('insertions-main', {before:'

before text

more testing

'}); assert(getInnerHTML('insertions-container').startsWith('

before text

more testing

')); - Element.insert('insertions-main', '

after text

more testing

', 'after'); + Element.insert('insertions-main', {after:'

after text

more testing

'}); assert(getInnerHTML('insertions-container').endsWith('

after text

more testing

')); - Element.insert('insertions-main', '

top text.

more testing

', 'top'); + Element.insert('insertions-main', {top:'

top text.

more testing

'}); assert(getInnerHTML('insertions-main').startsWith('

top text.

more testing

')); - Element.insert('insertions-main', '

bottom text.

more testing

', 'bottom'); + Element.insert('insertions-main', {bottom:'

bottom text.

more testing

'}); assert(getInnerHTML('insertions-main').endsWith('

bottom text.

more testing

')); }}, @@ -385,33 +386,33 @@ p.appendChild(document.createTextNode(text)); return p; } - Element.insert('insertions-node-main', createParagraph('node before'), 'before'); + Element.insert('insertions-node-main', {before: createParagraph('node before')}); assert(getInnerHTML('insertions-node-container').startsWith('

node before

')); - Element.insert('insertions-node-main', createParagraph('node after'), 'after'); + Element.insert('insertions-node-main', {after: createParagraph('node after')}); assert(getInnerHTML('insertions-node-container').endsWith('

node after

')); - Element.insert('insertions-node-main', createParagraph('node top'), 'top'); + Element.insert('insertions-node-main', {top:createParagraph('node top')}); assert(getInnerHTML('insertions-node-main').startsWith('

node top

')); - Element.insert('insertions-node-main', createParagraph('node bottom'), 'bottom'); + Element.insert('insertions-node-main', {bottom:createParagraph('node bottom')}); assert(getInnerHTML('insertions-node-main').endsWith('

node bottom

')); assertEqual($('insertions-node-main'), $('insertions-node-main').insert(document.createElement('p'))); }}, testElementInsertWithNonString: function() {with(this) { - Element.insert('insertions-main', 3, 'bottom'); + Element.insert('insertions-main', {bottom:3}); assert(getInnerHTML('insertions-main').endsWith('3')); }}, testElementInsertInTables: function() {with(this) { - Element.insert('second_row', 'Third Row', 'after'); + Element.insert('second_row', {after:'Third Row'}); assert($('second_row').descendantOf('table')); - $('a_cell').insert('hello world', 'top'); + $('a_cell').insert({top:'hello world'}); assert($('a_cell').innerHTML.startsWith('hello world')); - $('a_cell').insert('hi planet', 'after'); + $('a_cell').insert({after:'hi planet'}); assertEqual('hi planet', $('a_cell').next().innerHTML); $('table_for_insertions').insert('a cell!'); assert($('table_for_insertions').innerHTML.gsub('\r\n', '').toLowerCase().include('a cell!')); - $('row_1').insert('last', 'after'); + $('row_1').insert({after:'last'}); assertEqual('last', $A($('table_for_row_insertions').getElementsByTagName('tr')).last().lastChild.innerHTML); }}, @@ -419,25 +420,33 @@ var selectTop = $('select_for_insert_top'), selectBottom = $('select_for_insert_bottom'); selectBottom.insert(''); assertEqual('option 45', selectBottom.getValue()); - selectTop.insert('', 'top'); + selectTop.insert({top:''}); assertEqual(4, selectTop.options.length); }}, testElementMethodInsert: function() {with(this) { - $('element-insertions-main').insert('some text before','before'); + $('element-insertions-main').insert({before:'some text before'}); assert(getInnerHTML('element-insertions-container').startsWith('some text before')); - $('element-insertions-main').insert('some text after', 'after'); + $('element-insertions-main').insert({after:'some text after'}); assert(getInnerHTML('element-insertions-container').endsWith('some text after')); - $('element-insertions-main').insert('some text top', 'top'); + $('element-insertions-main').insert({top:'some text top'}); assert(getInnerHTML('element-insertions-main').startsWith('some text top')); - $('element-insertions-main').insert('some text bottom', 'bottom'); + $('element-insertions-main').insert({bottom:'some text bottom'}); assert(getInnerHTML('element-insertions-main').endsWith('some text bottom')); $('element-insertions-main').insert('some more text at the bottom'); assert(getInnerHTML('element-insertions-main').endsWith('some more text at the bottom')); - $('element-insertions-main').insert('some text uppercase top', 'TOP'); + $('element-insertions-main').insert({TOP:'some text uppercase top'}); assert(getInnerHTML('element-insertions-main').startsWith('some text uppercase top')); + + $('element-insertions-multiple-main').insert({ + top:'1', bottom:2, before: new Element('p').update('3'), after:'4' + }); + assert(getInnerHTML('element-insertions-multiple-main').startsWith('1')); + assert(getInnerHTML('element-insertions-multiple-main').endsWith('2')); + assert(getInnerHTML('element-insertions-multiple-container').startsWith('

3

')); + assert(getInnerHTML('element-insertions-multiple-container').endsWith('4')); }}, testInsertionBackwardsCompatibility: function() {with(this) {