Prototype: Change Element.insert syntax to allow multiple positions.

This commit is contained in:
Thomas Fuchs 2007-06-02 15:08:50 +00:00
parent 67783190f4
commit d4d4fddc7c
5 changed files with 91 additions and 55 deletions

View File

@ -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]

View File

@ -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);

View File

@ -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});
}
}

View File

@ -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;
}
}

View File

@ -292,6 +292,7 @@
<div id="insertions-container"><div id="insertions-main"><p>some content.</p></div></div>
<div id="insertions-node-container"><div id="insertions-node-main"><p>some content.</p></div></div>
<div id="element-insertions-container"><div id="element-insertions-main"><p>some content.</p></div></div>
<div id="element-insertions-multiple-container"><div id="element-insertions-multiple-main"><p>some content.</p></div></div>
<table id="table_for_insertions"></table>
<table id="table_for_row_insertions"><tr id="row_1"></tr></table>
<form method="post" action="blah">
@ -369,13 +370,13 @@
}},
testElementInsertWithHTML: function() {with(this) {
Element.insert('insertions-main', '<p><em>before</em> text</p><p>more testing</p>', 'before');
Element.insert('insertions-main', {before:'<p><em>before</em> text</p><p>more testing</p>'});
assert(getInnerHTML('insertions-container').startsWith('<p><em>before</em> text</p><p>more testing</p>'));
Element.insert('insertions-main', '<p><em>after</em> text</p><p>more testing</p>', 'after');
Element.insert('insertions-main', {after:'<p><em>after</em> text</p><p>more testing</p>'});
assert(getInnerHTML('insertions-container').endsWith('<p><em>after</em> text</p><p>more testing</p>'));
Element.insert('insertions-main', '<p><em>top</em> text.</p><p>more testing</p>', 'top');
Element.insert('insertions-main', {top:'<p><em>top</em> text.</p><p>more testing</p>'});
assert(getInnerHTML('insertions-main').startsWith('<p><em>top</em> text.</p><p>more testing</p>'));
Element.insert('insertions-main', '<p><em>bottom</em> text.</p><p>more testing</p>', 'bottom');
Element.insert('insertions-main', {bottom:'<p><em>bottom</em> text.</p><p>more testing</p>'});
assert(getInnerHTML('insertions-main').endsWith('<p><em>bottom</em> text.</p><p>more testing</p>'));
}},
@ -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('<p>node before</p>'));
Element.insert('insertions-node-main', createParagraph('node after'), 'after');
Element.insert('insertions-node-main', {after: createParagraph('node after')});
assert(getInnerHTML('insertions-node-container').endsWith('<p>node after</p>'));
Element.insert('insertions-node-main', createParagraph('node top'), 'top');
Element.insert('insertions-node-main', {top:createParagraph('node top')});
assert(getInnerHTML('insertions-node-main').startsWith('<p>node top</p>'));
Element.insert('insertions-node-main', createParagraph('node bottom'), 'bottom');
Element.insert('insertions-node-main', {bottom:createParagraph('node bottom')});
assert(getInnerHTML('insertions-node-main').endsWith('<p>node bottom</p>'));
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', '<tr id="third_row"><td>Third Row</td></tr>', 'after');
Element.insert('second_row', {after:'<tr id="third_row"><td>Third Row</td></tr>'});
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('<td>hi planet</td>', 'after');
$('a_cell').insert({after:'<td>hi planet</td>'});
assertEqual('hi planet', $('a_cell').next().innerHTML);
$('table_for_insertions').insert('<tr><td>a cell!</td></tr>');
assert($('table_for_insertions').innerHTML.gsub('\r\n', '').toLowerCase().include('<tr><td>a cell!</td></tr>'));
$('row_1').insert('<tr></tr><tr></tr><tr><td>last</td></tr>', 'after');
$('row_1').insert({after:'<tr></tr><tr></tr><tr><td>last</td></tr>'});
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('<option value="33">option 33</option><option selected="selected">option 45</option>');
assertEqual('option 45', selectBottom.getValue());
selectTop.insert('<option value="A">option A</option><option value="B" selected="selected">option B</option>', 'top');
selectTop.insert({top:'<option value="A">option A</option><option value="B" selected="selected">option B</option>'});
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('<p>3</p>'));
assert(getInnerHTML('element-insertions-multiple-container').endsWith('4'));
}},
testInsertionBackwardsCompatibility: function() {with(this) {