Fix IE7/8 txt setter for "style" element
[mootools.git] / Specs / Element / Element.js
blob9e5fcc2698986954f08cb9e6b4fd31770b5879b2
1 /*
2 ---
3 name: Element
4 requires: ~
5 provides: ~
6 ...
7 */
9 describe('Element constructor', function(){
11         it("should return an Element with the correct tag", function(){
12                 var element = new Element('div');
13                 expect(typeOf(element)).toEqual('element');
14                 expect(element.getFirst).toBeDefined();
15                 expect(element.tagName.toLowerCase()).toEqual('div');
16         });
18         it('should return an Element with various attributes', function(){
19                 var element = new Element('div', { 'id': 'divID', 'title': 'divTitle' });
20                 expect(element.id).toEqual('divID');
21                 expect(element.title).toEqual('divTitle');
22         });
24         it('should return an Element with for attribute', function(){
25                 var label = new Element('label', { 'for': 'myId' });
26                 expect(label.htmlFor).toEqual('myId');
27         });
29         it('should return an Element with class attribute', function(){
30                 var div1 = new Element('div', { 'class': 'class' });
31                 var div2 = new Element('div', { 'class': 'class1 class2 class3' });
33                 expect(div1.className).toEqual('class');
34                 expect(div2.className).toEqual('class1 class2 class3');
35         });
37         it('should return input Elements with name and type attributes', function(){
38                 var username = new Element('input', { type: 'text', name: 'username', value: 'username' });
39                 var password = new Element('input', { type: 'password', name: 'password', value: 'password' });
40                 expect(username.type).toEqual('text');
41                 expect(username.name).toEqual('username');
42                 expect(username.value).toEqual('username');
44                 expect(password.type).toEqual('password');
45                 expect(password.name).toEqual('password');
46                 expect(password.value).toEqual('password');
48                 var dad = new Element('div');
49                 dad.adopt(username, password);
50                 dad.inject(document.body);
51                 expect(document.getElementsByName('username')[0]).toEqual(username);
52                 expect(document.getElementsByName('password')[0]).toEqual(password);
53                 dad.dispose();
54         });
56         it('should be able to use all kinds of silly characters in your name attribute values', function(){
57                 ["foo","bar[]","b'a'z",'b"a"ng','boi ng'].each(function(name){
58                         var input = new Element('input', { type: 'text', name: name, value: name });
59                         expect(input.type).toEqual('text');
60                         expect(input.name).toEqual(name);
61                         expect(input.value).toEqual(name);
62                         var dad = new Element('div');
63                         dad.adopt(input);
64                         dad.inject(document.body);
65                         expect(document.getElementsByName(name)[0]).toEqual(input);
66                         dad.dispose();
67                 });
68         });
70         it('should create an element with type="email"', function(){
71                 var el = new Element('input', {type: 'email'});
72                 expect(el.get('type').match(/email|text/)).toBeTruthy();
73         });
75         it('should return input Elements that are checked', function(){
76                 var check1 = new Element('input', { type: 'checkbox' });
77                 var check2 = new Element('input', { type: 'checkbox', checked: true });
78                 var check3 = new Element('input', { type: 'checkbox', checked: 'checked' });
80                 expect(check1.checked).toBeFalsy();
81                 expect(check2.checked).toBeTruthy();
82                 expect(check3.checked).toBeTruthy();
83         });
85         it("should return a select Element that retains it's selected options", function(){
86                 var div = new Element('div', { 'html':
87                         '<select multiple="multiple" name="select[]">' +
88                                 '<option value="" name="none">--</option>' +
89                                 '<option value="volvo" name="volvo">Volvo</option>' +
90                                 '<option value="saab" name="saab" selected="selected">Saab</option>' +
91                                 '<option value="opel" name="opel" selected="selected">Opel</option>' +
92                                 '<option value="bmw" name="bmw">BMW</option>' +
93                         '</select>'
94                 });
96                 var select1 = div.getFirst();
97                 var select2 = new Element('select', { name: 'select[]', multiple: true }).adopt(
98                         new Element('option', { name: 'none', value: '', html: '--' }),
99                         new Element('option', { name: 'volvo', value: 'volvo', html: 'Volvo' }),
100                         new Element('option', { name: 'saab', value: 'saab', html: 'Saab', selected: true }),
101                         new Element('option', { name: 'opel', value: 'opel', html: 'Opel', selected: 'selected' }),
102                         new Element('option', { name: 'bmw', value: 'bmw', html: 'BMW' })
103                 );
105                 expect(select1.multiple).toBeTruthy();
106                 expect(select2.multiple).toBeTruthy();
108                 expect(select1.name).toEqual(select2.name);
109                 expect(select1.options.length).toEqual(select2.options.length);
110                 expect(select1.toQueryString()).toEqual(select2.toQueryString());
111         });
115 describe('Element.set', function(){
117         it("should set a single attribute of an Element", function(){
118                 var div = new Element('div').set('id', 'some_id');
119                 expect(div.id).toEqual('some_id');
120         });
122         it("should set the checked attribute of an Element", function(){
123                 var input1 = new Element('input', {type: 'checkbox'}).set('checked', 'checked');
124                 var input2 = new Element('input', {type: 'checkbox'}).set('checked', true);
125                 expect(input1.checked).toBeTruthy();
126                 expect(input2.checked).toBeTruthy();
127         });
129         it("should set the class name of an element", function(){
130                 var div = new Element('div').set('class', 'some_class');
131                 expect(div.className).toEqual('some_class');
132         });
134         it("should set the for attribute of an element", function(){
135                 var input = new Element('label', {type: 'text'}).set('for', 'some_element');
136                 expect(input.htmlFor).toEqual('some_element');
137         });
139         it("should set the html of an Element", function(){
140                 var html = '<a href="http://mootools.net/">Link</a>';
141                 var parent = new Element('div').set('html', html);
142                 expect(parent.innerHTML.toLowerCase()).toEqual(html.toLowerCase());
143         });
145         it("should set the html of an Element with multiple arguments", function(){
146                 var html = ['<p>Paragraph</p>', '<a href="http://mootools.net/">Link</a>'];
147                 var parent = new Element('div').set('html', html);
148                 expect(parent.innerHTML.toLowerCase()).toEqual(html.join('').toLowerCase());
149         });
151         it("should set the html of a select Element", function(){
152                 var html = '<option>option 1</option><option selected="selected">option 2</option>';
153                 var select = new Element('select').set('html', html);
154                 expect(select.getChildren().length).toEqual(2);
155                 expect(select.options.length).toEqual(2);
156                 expect(select.selectedIndex).toEqual(1);
157         });
159         it("should set the html of a table Element", function(){
160                 var html = '<tbody><tr><td>cell 1</td><td>cell 2</td></tr><tr><td class="cell">cell 1</td><td>cell 2</td></tr></tbody>';
161                 var table = new Element('table').set('html', html);
162                 expect(table.getChildren().length).toEqual(1);
163                 expect(table.getFirst().getFirst().getChildren().length).toEqual(2);
164                 expect(table.getFirst().getLast().getFirst().className).toEqual('cell');
165         });
167         it("should set the html of a tbody Element", function(){
168                 var html = '<tr><td>cell 1</td><td>cell 2</td></tr><tr><td class="cell">cell 1</td><td>cell 2</td></tr>';
169                 var tbody = new Element('tbody').inject(new Element('table')).set('html', html);
170                 expect(tbody.getChildren().length).toEqual(2);
171                 expect(tbody.getLast().getFirst().className).toEqual('cell');
172         });
174         it("should set the html of a tr Element", function(){
175                 var html = '<td class="cell">cell 1</td><td>cell 2</td>';
176                 var tr = new Element('tr').inject(new Element('tbody').inject(new Element('table'))).set('html', html);
177                 expect(tr.getChildren().length).toEqual(2);
178                 expect(tr.getFirst().className).toEqual('cell');
179         });
181         it("adopting should not change the parent of the element doing the adopting", function(){
182                 var baldGuy = new Element('div');
183                 var annie = new Element('span');
185                 gramps = baldGuy.getParent();
186                 baldGuy.adopt(annie);
187                 expect(baldGuy.getParent()).toEqual(gramps)
188         });
190         it("should set the html of a td Element", function(){
191                 var html = '<span class="span">Some Span</span><a href="#">Some Link</a>';
192                 var td = new Element('td').inject(new Element('tr').inject(new Element('tbody').inject(new Element('table')))).set('html', html);
193                 expect(td.getChildren().length).toEqual(2);
194                 expect(td.getFirst().className).toEqual('span');
195         });
197         it("should set the style attribute of an Element", function(){
198                 var style = 'font-size:12px;line-height:23px;';
199                 var div = new Element('div').set('style', style);
200                 expect(div.style.lineHeight).toEqual('23px');
201                 expect(div.style.fontSize).toEqual('12px');
202         });
204         it("should set the text of an element", function(){
205                 var div = new Element('div').set('text', 'some text content');
206                 expect(div.get('text')).toEqual('some text content');
207                 expect(div.innerHTML).toEqual('some text content');
208         });
210         it("should set multiple attributes of an Element", function(){
211                 var div = new Element('div').set({ id: 'some_id', 'title': 'some_title', 'html': 'some_content' });
212                 expect(div.id).toEqual('some_id');
213                 expect(div.title).toEqual('some_title');
214                 expect(div.innerHTML).toEqual('some_content');
215         });
217         it("should set various attributes of a script Element", function(){
218                 var script = new Element('script').set({ type: 'text/javascript', defer: 'defer' });
219                 expect(script.type).toEqual('text/javascript');
220                 expect(script.defer).toBeTruthy();
221         });
223         it("should set various attributes of a table Element", function(){
224                 var table1 = new Element('table').set({ border: '2', cellpadding: '3', cellspacing: '4', align: 'center' });
225                 var table2 = new Element('table').set({ cellPadding: '3', cellSpacing: '4' });
226                 expect(table1.border == 2).toBeTruthy();
227                 expect(table1.cellPadding == 3).toBeTruthy();
228                 expect(table2.cellPadding == 3).toBeTruthy();
229                 expect(table1.cellSpacing == 4).toBeTruthy();
230                 expect(table2.cellSpacing == 4).toBeTruthy();
231                 expect(table1.align).toEqual('center');
232         });
236 var myElements = new Elements([
237         new Element('div'),
238         document.createElement('a'),
239         new Element('div', {id: 'el-' + Date.now()})
242 describe('Elements', function(){
244         //<1.3compat>
245         it('should return an array type', function(){
246                 expect(Array.type(myElements)).toBeTruthy();
247         });
248         //</1.3compat>
250         it('should return an elements type', function(){
251                 expect(typeOf(myElements) == 'elements').toBeTruthy();
252         });
254         it('should return an array of Elements', function(){
255                 expect(myElements.every(function(e){ return typeOf(e) == 'element'; })).toBeTruthy();
256         });
258         it('should apply Element prototypes to the returned array', function(){
259                 expect(myElements.getFirst).toBeDefined();
260         });
262         it('should return all Elements that match the string matcher', function(){
263                 var filter = myElements.filter('div');
265                 expect(filter[0] == myElements[0] && filter[1] == myElements[2] && filter.length == 2).toBeTruthy();
266         });
268         it('should return all Elements that match the comparator', function(){
269                 var elements = myElements.filter(function(element){
270                         return element.match('a');
271                 });
272                 expect(elements[0] == myElements[1] && elements.length == 1).toBeTruthy();
273         });
277 describe('TextNode.constructor', function(){
279         it('should return a new textnode element', function(){
280                 var text = document.newTextNode('yo');
281                 expect(typeOf(text)).toEqual('textnode');
282         });
286 describe('IFrame constructor', function(){
288         it('should return a new IFrame', function(){
289                 var iFrame1 = document.createElement('iframe');
290                 var iFrame2 = new IFrame();
291                 expect(iFrame1.tagName).toEqual(iFrame2.tagName);
292         });
294         it('should return the same IFrame if passed', function(){
295                 var iFrame1 = document.createElement('iframe');
296                 var iFrame2 = new IFrame(iFrame1);
297                 expect(iFrame1).toEqual(iFrame2);
298         });
302 describe('$', function(){
304         beforeEach(function(){
305                 Container = document.createElement('div');
306                 Container.innerHTML = '<div id="dollar"></div>';
307                 document.body.appendChild(Container);
308         });
310         afterEach(function(){
311                 document.body.removeChild(Container);
312                 Container = null;
313         });
315         it('should return an extended Element by string id', function(){
316                 var dollar1 = document.getElementById('dollar');
317                 var dollar2 = $('dollar');
319                 expect(dollar1).toEqual(dollar2);
320                 expect(dollar1.getFirst).toBeDefined();
321         });
323         it('should return the window if passed', function(){
324                 var win = $(window);
325                 expect(win == window).toBeTruthy();
326         });
328         it('should return the document if passed', function(){
329                 expect($(document)).toEqual(document);
330         });
332         it('should return null if string not found or type mismatch', function(){
333                 expect($(1)).toBeNull();
334                 expect($('nonexistant')).toBeNull();
335         });
339 describe('$$', function(){
341         it('should return all Elements of a specific tag', function(){
342                 var divs1 = $$('div');
343                 var divs2 = new Elements(Array.from(document.getElementsByTagName('div')));
344                 expect(divs1).toEqual(divs2);
345         });
347         it('should return multiple Elements for each specific tag', function(){
348                 var uidOf = (typeof $uid != 'undefined') ? $uid : Slick.uidOf;
349                 var sortBy = function(a, b){
350                         a = uidOf(a); b = uidOf(b);
351                         return a > b ? 1 : -1;
352                 };
353                 var headers1 = $$('h3', 'h4').sort(sortBy);
354                 var headers2 = new Elements(Array.flatten([document.getElementsByTagName('h3'), document.getElementsByTagName('h4')])).sort(sortBy);
355                 expect(headers1).toEqual(headers2);
356         });
358         it('should return an empty array if not is found', function(){
359                 expect($$('not_found')).toEqual(new Elements([]));
360         });
364 describe('getDocument', function(){
366         it('should return the owner document for elements', function(){
367                 var doc = document.newElement('div').getDocument();
368                 expect(doc).toEqual(document);
369         });
371         it('should return the owned document for window', function(){
372                 var doc = window.getDocument();
373                 expect(doc).toEqual(document);
374         });
376         it('should return self for document', function(){
377                 var doc = document.getDocument();
378                 expect(doc).toEqual(document);
379         });
383 describe('getWindow', function(){
385         it('should return the owner window for elements', function(){
386                 var win = document.newElement('div').getWindow();
387                 expect(win == window).toBeTruthy();
388         });
390         it('should return the owner window for document', function(){
391                 var win = document.getWindow();
392                 expect(win == window).toBeTruthy();
393         });
395         it('should return self for window', function(){
396                 var win = window.getWindow();
397                 expect(win == window).toBeTruthy();
398         });
402 describe('Element.getElement', function(){
404         beforeEach(function(){
405                 Container = new Element('div');
406                 Container.innerHTML = '<div id="first"></div><div id="second"></div><p></p><a></a>';
407         });
409         afterEach(function(){
410                 Container = null;
411         });
413         it('should return the first Element to match the tag, otherwise null', function(){
414                 var child = Container.getElement('div');
415                 expect(child.id).toEqual('first');
416                 expect(Container.getElement('iframe')).toBeNull();
417         });
421 describe('Element.getElements', function(){
423         beforeEach(function(){
424                 Container = new Element('div');
425                 Container.innerHTML = '<div id="first"></div><div id="second"></div><p></p><a></a>';
426         });
428         afterEach(function(){
429                 Container = null;
430         });
432         it('should return all the elements that match the tag', function(){
433                 var children = Container.getElements('div');
434                 expect(children.length).toEqual(2);
435         });
437         it('should return all the elements that match the tags', function(){
438                 var children = Container.getElements('div,a');
439                 expect(children.length).toEqual(3);
440                 expect(children[2].tagName.toLowerCase()).toEqual('a');
441         });
445 describe('Document.getElement', function(){
447         it('should return the first Element to match the tag, otherwise null', function(){
448                 var div = document.getElement('div');
449                 var ndiv = document.getElementsByTagName('div')[0];
450                 expect(div).toEqual(ndiv);
452                 var notfound = document.getElement('canvas');
453                 expect(notfound).toBeNull();
454         });
458 describe('Document.getElements', function(){
460         it('should return all the elements that match the tag', function(){
461                 var divs = document.getElements('div');
462                 var ndivs = new Elements(document.getElementsByTagName('div'));
463                 expect(divs).toEqual(ndivs);
464         });
466         it('should return all the elements that match the tags', function(){
467                 var headers = document.getElements('h3,h4');
468                 var headers2 = new Elements(Array.flatten([document.getElementsByTagName('h3'), document.getElementsByTagName('h4')]));
469                 expect(headers.length).toEqual(headers2.length);
470         });
474 describe('Element.getElementById', function(){
476         beforeEach(function(){
477                 Container = new Element('div');
478                 Container.innerHTML = '<div id="first"></div><div id="second"></div><p></p><a></a>';
479                 document.body.appendChild(Container);
480         });
482         afterEach(function(){
483                 document.body.removeChild(Container);
484                 Container = null;
485         });
487         it('should getElementById that matches the id, otherwise null', function(){
488                 expect(Container.getElementById('first')).toEqual(Container.childNodes[0]);
489                 expect(Container.getElementById('not_found')).toBeNull();
490         });
494 describe('Element.get style', function(){
496         it("should return a CSS string representing the Element's styles", function(){
497                 var style = 'font-size:12px;color:rgb(255,255,255)';
498                 var myElement = new Element('div').set('style', style);
499                 expect(myElement.get('style').toLowerCase().replace(/\s/g, '').replace(/;$/, '')).toMatch(/(font-size:12px;color:rgb\(255,255,255\))|(color:rgb\(255,255,255\);font-size:12px)/);
500                 //I'm replacing these characters (space and the last semicolon) as they are not vital to the style, and browsers sometimes include them, sometimes not.
501         });
505 describe('Element.get tag', function(){
507         it("should return the Element's tag", function(){
508                 var myElement = new Element('div');
509                 expect(myElement.get('tag')).toEqual('div');
510         });
514 describe('Element.get', function(){
516         it("should get an absolute href", function(){
517                 var link = new Element('a', {href: "http://google.com/"});
518                 expect(link.get('href')).toEqual("http://google.com/");
519         });
521         it("should get an absolute href to the same domain", function(){
522                 var link = new Element('a', {href: window.location.href});
523                 expect(link.get('href')).toEqual(window.location.href);
524         });
526         it("should get a relative href", function(){
527                 var link = new Element('a', {href: "../index.html"});
528                 expect(link.get('href')).toEqual("../index.html");
529         });
531         it("should get a host absolute href", function(){
532                 var link = new Element('a', {href: "/developers"});
533                 expect(link.get('href')).toEqual("/developers");
534         });
536         it("should return null when attribute is missing", function(){
537                 var link = new Element('a');
538                 expect(link.get('href')).toBeNull();
539         });
543 describe('Element.erase', function(){
545         it("should erase an Element's property", function(){
546                 var myElement = new Element('a', {href: 'http://mootools.net/', title: 'mootools!'});
547                 expect(myElement.get('title')).toEqual('mootools!');
548                 expect(myElement.erase('title').get('title')).toBeNull();
549         });
551         it("should erase an Element's style", function(){
552                 var myElement = new Element('div', {style: "color:rgb(255, 255, 255); font-size:12px;"});
553                 myElement.erase('style');
554                 expect(myElement.get('style')).toEqual('');
555         });
559 describe('Element.match', function(){
561         it('should return true if tag is not provided', function(){
562                 var element = new Element('div');
563                 expect(element.match()).toBeTruthy();
564         });
566         it("should return true if the Element's tag matches", function(){
567                 var element = new Element('div');
568                 expect(element.match('div')).toBeTruthy();
569         });
573 describe('Element.inject', function(){
575         beforeEach(function(){
576                 var html = [
577                         '<div id="first"></div>',
578                         '<div id="second">',
579                                 '<div id="first-child"></div>',
580                                 '<div id="second-child"></div>',
581                         '</div>'
582                 ].join('');
583                 Container = new Element('div', {style: 'position:absolute;top:0;left:0;visibility:hidden;', html: html});
584                 document.body.appendChild(Container);
586                 test = new Element('div', {id:'inject-test'});
587         });
589         afterEach(function(){
590                 document.body.removeChild(Container);
591                 Container.set('html', '');
592                 Container = null;
593                 test = null;
594         });
596         it('should inject the Element before an Element', function(){
597                 test.inject($('first'), 'before');
598                 expect(Container.childNodes[0]).toEqual(test);
600                 test.inject($('second-child'), 'before');
601                 expect(Container.childNodes[1].childNodes[1]).toEqual(test);
602         });
604         it('should inject the Element after an Element', function(){
605                 test.inject($('first'), 'after');
606                 expect(Container.childNodes[1]).toEqual(test);
608                 test.inject($('first-child'), 'after');
609                 expect(Container.childNodes[1].childNodes[1]).toEqual(test);
610         });
612         it('should inject the Element at bottom of an Element', function(){
613                 var first = $('first');
614                 test.inject(first, 'bottom');
615                 expect(first.childNodes[0]).toEqual(test);
617                 var second = $('second');
618                 test.inject(second, 'bottom');
619                 expect(second.childNodes[2]).toEqual(test);
621                 test.inject(Container, 'bottom');
622                 expect(Container.childNodes[2]).toEqual(test);
623         });
625         it('should inject the Element inside an Element', function(){
626                 var first = $('first');
627                 test.inject(first, 'inside');
628                 expect(first.childNodes[0]).toEqual(test);
630                 var second = $('second');
631                 test.inject(second, 'inside');
632                 expect(second.childNodes[2]).toEqual(test);
634                 test.inject(Container, 'inside');
635                 expect(Container.childNodes[2]).toEqual(test);
636         });
638         it('should inject the Element at the top of an Element', function(){
639                 test.inject(Container, 'top');
640                 expect(Container.childNodes[0]).toEqual(test);
642                 var second = $('second');
643                 test.inject(second, 'top');
644                 expect(second.childNodes[0]).toEqual(test);
645         });
647         it('should inject the Element in an Element', function(){
648                 var first = $('first');
649                 test.inject(first);
650                 expect(first.childNodes[0]).toEqual(test);
652                 var second = $('second');
653                 test.inject(second);
654                 expect(second.childNodes[2]).toEqual(test);
656                 test.inject(Container);
657                 expect(Container.childNodes[2]).toEqual(test);
658         });
662 describe('Element.replaces', function(){
664         it('should replace an Element with the Element', function(){
665                 var parent = new Element('div');
666                 var div = new Element('div', {id: 'original'}).inject(parent);
667                 var el = new Element('div', {id: 'replaced'});
668                 el.replaces(div);
669                 expect(parent.childNodes[0]).toEqual(el);
670         });
674 describe('Element.grab', function(){
676         beforeEach(function(){
677                 var html = [
678                         '<div id="first"></div>',
679                         '<div id="second">',
680                                 '<div id="first-child"></div>',
681                                 '<div id="second-child"></div>',
682                         '</div>'
683                 ].join('');
684                 Container = new Element('div', {style: 'position:absolute;top:0;left:0;visibility:hidden;', html: html}).inject(document.body);
686                 test = new Element('div', {id:'grab-test'});
687         });
689         afterEach(function(){
690                 document.body.removeChild(Container);
691                 Container.set('html', '');
692                 Container = null;
693                 test = null;
694         });
696         it('should grab the Element before this Element', function(){
697                 $('first').grab(test, 'before');
698                 expect(Container.childNodes[0]).toEqual(test);
700                 $('second-child').grab(test, 'before');
701                 expect(Container.childNodes[1].childNodes[1]).toEqual(test);
702         });
704         it('should grab the Element after this Element', function(){
705                 $('first').grab(test, 'after');
706                 expect(Container.childNodes[1]).toEqual(test);
708                 $('first-child').grab(test, 'after');
709                 expect(Container.childNodes[1].childNodes[1]).toEqual(test);
710         });
712         it('should grab the Element at the bottom of this Element', function(){
713                 var first = $('first');
714                 first.grab(test, 'bottom');
715                 expect(first.childNodes[0]).toEqual(test);
717                 var second = $('second');
718                 second.grab(test, 'bottom');
719                 expect(second.childNodes[2]).toEqual(test);
721                 Container.grab(test, 'bottom');
722                 expect(Container.childNodes[2]).toEqual(test);
723         });
725         it('should grab the Element inside this Element', function(){
726                 var first = $('first');
727                 first.grab(test, 'inside');
728                 expect(first.childNodes[0]).toEqual(test);
730                 var second = $('second');
731                 second.grab(test, 'inside');
732                 expect(second.childNodes[2]).toEqual(test);
734                 Container.grab(test, 'inside');
735                 expect(Container.childNodes[2]).toEqual(test);
736         });
738         it('should grab the Element at the top of this Element', function(){
739                 Container.grab(test, 'top');
740                 expect(Container.childNodes[0]).toEqual(test);
742                 var second = $('second');
743                 second.grab(test, 'top');
744                 expect(second.childNodes[0]).toEqual(test);
745         });
747         it('should grab an Element in the Element', function(){
748                 var first = $('first').grab(test);
749                 expect(first.childNodes[0]).toEqual(test);
751                 var second = $('second').grab(test);
752                 expect(second.childNodes[2]).toEqual(test);
754                 Container.grab(test);
755                 expect(Container.childNodes[2]).toEqual(test);
756         });
760 describe('Element.wraps', function(){
762         it('should replace and adopt the Element', function(){
763                 var div = new Element('div');
764                 var child = new Element('p').inject(div);
766                 var wrapper = new Element('div', {id: 'wrapper'}).wraps(div.childNodes[0]);
767                 expect(div.childNodes[0]).toEqual(wrapper);
768                 expect(wrapper.childNodes[0]).toEqual(child);
769         });
773 describe('Element.appendText', function(){
775         beforeEach(function(){
776                 Container = new Element('div', {style: 'position:absolute;top:0;left:0;visibility:hidden;'}).inject(document.body);
777                 var html = [
778                         '<div id="first"></div>',
779                         '<div id="second">',
780                                 '<div id="first-child"></div>',
781                                 '<div id="second-child"></div>',
782                         '</div>'
783                 ].join('');
784                 Container.set('html', html);
785         });
787         afterEach(function(){
788                 document.body.removeChild(Container);
789                 Container.set('html', '');
790                 Container = null;
791                 test = null;
792         });
794         it('should append a TextNode before this Element', function(){
795                 $('first').appendText('test', 'before');
796                 expect(Container.childNodes[0].nodeValue).toEqual('test');
798                 $('second-child').appendText('test', 'before');
799                 expect(Container.childNodes[2].childNodes[1].nodeValue).toEqual('test');
800         });
802         it('should append a TextNode the Element after this Element', function(){
803                 $('first').appendText('test', 'after');
804                 expect(Container.childNodes[1].nodeValue).toEqual('test');
806                 $('first-child').appendText('test', 'after');
807                 expect(Container.childNodes[2].childNodes[1].nodeValue).toEqual('test');
808         });
810         it('should append a TextNode the Element at the bottom of this Element', function(){
811                 var first = $('first');
812                 first.appendText('test', 'bottom');
813                 expect(first.childNodes[0].nodeValue).toEqual('test');
815                 var second = $('second');
816                 second.appendText('test', 'bottom');
817                 expect(second.childNodes[2].nodeValue).toEqual('test');
819                 Container.appendText('test', 'bottom');
820                 expect(Container.childNodes[2].nodeValue).toEqual('test');
821         });
823         it('should append a TextNode the Element inside this Element', function(){
824                 var first = $('first');
825                 first.appendText('test', 'inside');
826                 expect(first.childNodes[0].nodeValue).toEqual('test');
828                 var second = $('second');
829                 second.appendText('test', 'inside');
830                 expect(second.childNodes[2].nodeValue).toEqual('test');
832                 Container.appendText('test', 'inside');
833                 expect(Container.childNodes[2].nodeValue).toEqual('test');
834         });
836         it('should append a TextNode the Element at the top of this Element', function(){
837                 Container.appendText('test', 'top');
838                 expect(Container.childNodes[0].nodeValue).toEqual('test');
840                 var second = $('second');
841                 second.appendText('test', 'top');
842                 expect(second.childNodes[0].nodeValue).toEqual('test');
843         });
845         it('should append a TextNode an Element in the Element', function(){
846                 var first = $('first').appendText('test');
847                 expect(first.childNodes[0].nodeValue).toEqual('test');
849                 var second = $('second').appendText('test');
850                 expect(second.childNodes[2].nodeValue).toEqual('test');
852                 Container.appendText('test');
853                 expect(Container.childNodes[2].nodeValue).toEqual('test');
854         });
858 describe('Element.adopt', function(){
861         beforeEach(function(){
862                 Container = new Element('div').inject(document.body);
863                 Container.empty();
864         });
866         afterEach(function(){
867                 document.body.removeChild(Container);
868                 Container.set('html', '');
869                 Container = null;
870         });
872         it('should adopt an Element by its id', function(){
873                 var child = new Element('div', {id: 'adopt-me'});
874                 document.body.appendChild(child);
875                 Container.adopt('adopt-me');
876                 expect(Container.childNodes[0]).toEqual(child);
877         });
879         it('should adopt an Element', function(){
880                 var child = new Element('p');
881                 Container.adopt(child);
882                 expect(Container.childNodes[0]).toEqual(child);
883         });
885         it('should adopt any number of Elements or ids', function(){
886                 var children = [];
887                 (100).times(function(i){ children[i] = new Element('span', {id: 'child-' + i}); });
888                 Container.adopt(children);
889                 expect(Container.childNodes.length).toEqual(100);
890                 expect(Container.childNodes[10]).toEqual(children[10]);
891         });
895 describe('Element.dispose', function(){
897         it('should dispose the Element from the DOM', function(){
898                 var Container = new Element('div').inject(document.body);
900                 var child = new Element('div').inject(Container);
901                 child.dispose();
902                 expect(Container.childNodes.length).toEqual(0);
904                 document.body.removeChild(Container);
905                 Container.set('html', '');
906                 Container = null;
907         });
911 describe('Element.clone', function(){
913         beforeEach(function(){
914                 Container = new Element('div', {'id': 'outer', 'class': 'moo'});
915                 Container.innerHTML = '<span class="foo" id="inner1"><div class="movie" id="sixfeet">under</div></span><span id="inner2"></span>';
916         });
918         afterEach(function(){
919                 Container = null;
920         });
922         it('should return a clone', function(){
923                 var div = new Element('div');
924                 var clone = div.clone();
925                 expect(div).not.toEqual(clone);
926                 expect(typeOf(div)).toEqual('element');
927                 expect(typeOf(clone)).toEqual('element');
928         });
930         it('should remove id from clone and clone children by default', function(){
931                 var clone = Container.clone();
932                 expect(clone.getElementsByTagName('*').length).toEqual(3);
933                 expect(clone.className).toEqual('moo');
934                 expect(clone.id).toEqual('');
935                 expect(Container.id).toEqual('outer');
936         });
938         it('should remove all ids', function(){
939                 var clone = Container.clone(true);
940                 expect(clone.id).toEqual('');
941                 expect(clone.childNodes.length).toEqual(2);
942                 expect(clone.childNodes[0].id).toEqual('');
943                 expect(clone.childNodes[0].childNodes[0].id).toEqual('');
944                 expect(clone.childNodes[0].className).toEqual('foo');
945         });
947         it('should keep id if specified', function(){
948                 var clone = Container.clone(true, true);
949                 expect(clone.id).toEqual('outer');
950                 expect(clone.childNodes.length).toEqual(2);
951                 expect(clone.childNodes[0].id).toEqual('inner1');
952                 expect(clone.childNodes[0].childNodes[0].id).toEqual('sixfeet');
953                 expect(clone.childNodes[0].className).toEqual('foo');
954         });
956         it('should clone empty href attribute', function(){
957                 var clone = new Element('div', {
958                         html: '<a href="">empty anchor</a>'
959                 }).getFirst().clone();
961                 expect(clone.getAttribute('href', 2)).toEqual('');
962         });
964         it('should not clone Element Storage', function(){
965                 Container.store('drink', 'milk');
966                 var clone = Container.clone();
967                 expect(clone.retrieve('drink')).toBeNull();
968                 expect(Container.retrieve('drink')).toEqual('milk');
969         });
971         //<1.2compat>
972         it('should clone child nodes and not copy their uid', function(){
973                 var cloned = Container.clone(true).getElements('*');
974                 var old = Container.getElements('*');
975                 expect(cloned.length).toEqual(3);
976                 expect(old.length).toEqual(3);
977                 expect($$(old, cloned).length).toEqual(6);
978         });
979         //</1.2compat>
981         var dit = /*<1.2compat>*/xit || /*</1.2compat>*/it; // don't run unless no compat
982         dit('should clone child nodes and not copy their uid', function(){
983                 var cloned = Container.clone(true).getElements('*');
984                 var old = Container.getElements('*');
985                 expect(cloned.length).toEqual(3);
986                 expect(old.length).toEqual(3);
987                 expect(new Elements([old, cloned]).length).toEqual(2);
988         });
990         it('should clone a text input and retain value', function(){
991                 var inputs = new Element('div', { 'html': '' +
992                         '<input id="input1" type="text" value="Some Value" />' +
993                         '<input id="input2" type="text" />'
994                 }).getChildren();
996                 var input1 = inputs[0].clone();
997                 var input2 = inputs[1].clone(false, true);
999                 expect(!input1.id).toBeTruthy();
1000                 expect(input2.id).toEqual('input2');
1001                 expect(input1.value).toEqual('Some Value');
1002                 expect(input2.value).toEqual('');
1003         });
1005         it('should clone a textarea and retain value', function(){
1006                 var textareas = new Element('div', { 'html': '' +
1007                         '<textarea id="textarea1"></textarea>' +
1008                         '<textarea id="textarea2">Some-Text-Here</textarea>'
1009                 }).getChildren();
1011                 var textarea1 = textareas[0].clone();
1012                 var textarea2 = textareas[1].clone(false, true);
1014                 expect(!textarea1.id).toBeTruthy();
1015                 expect(textarea2.id).toEqual('textarea2');
1016                 expect(textarea1.value).toEqual('');
1017                 expect(textarea2.value).toEqual('Some-Text-Here');
1018         });
1020         it('should clone a checkbox and retain checked state', function(){
1021                 var checks = new Element('div', { 'html': '' +
1022                         '<input id="check1" type="checkbox" />' +
1023                         '<input id="check2" type="checkbox" checked="checked" />'
1024                 }).getChildren();
1026                 var check1 = checks[0].clone();
1027                 var check2 = checks[1].clone(false, true);
1029                 expect(!check1.id).toBeTruthy();
1030                 expect(check2.id).toEqual('check2');
1031                 expect(check1.checked).toBeFalsy();
1032                 expect(check2.checked).toBeTruthy();
1033         });
1035         it('should clone a select and retain selected state', function(){
1036                 var selects = new Element('div', { 'html': '' +
1037                         '<select name="select" id="select1">' +
1038                                 '<option>--</option>' +
1039                                 '<option value="volvo">Volvo</option>' +
1040                                 '<option value="saab">Saab</option>' +
1041                                 '<option value="opel" selected="selected">Opel</option>' +
1042                                 '<option value="bmw">BMW</option>' +
1043                         '</select>' +
1044                         '<select name="select[]" id="select2" multiple="multiple">' +
1045                                 '<option>--</option>' +
1046                                 '<option value="volvo">Volvo</option>' +
1047                                 '<option value="saab">Saab</option>' +
1048                                 '<option value="opel" selected="selected">Opel</option>' +
1049                                 '<option value="bmw" selected="selected">BMW</option>' +
1050                         '</select>'
1051                 }).getChildren();
1053                 var select1 = selects[0].clone(true);
1054                 var select2 = selects[1].clone(true, true);
1056                 expect(!select1.id).toBeTruthy();
1057                 expect(select2.id).toEqual('select2');
1058                 expect(select1.selectedIndex).toEqual(3);
1059                 expect(select2.options[3].selected).toBeTruthy();
1060                 expect(select2.options[4].selected).toBeTruthy();
1061         });
1063         it('should clone custom attributes', function(){
1064                 var div = new Element('div');
1065                 div.setAttribute('foo', 'FOO');
1067                 expect(div.clone().getAttribute('foo')).toEqual('FOO');
1068         });
1072 describe('Element className methods', function(){
1074         it('should return true if the Element has the given class', function(){
1075                 var div = new Element('div', {'class': 'header bold\tunderline'});
1076                 expect(div.hasClass('header')).toBeTruthy();
1077                 expect(div.hasClass('bold')).toBeTruthy();
1078                 expect(div.hasClass('underline')).toBeTruthy();
1079         });
1081         it('should return false if the element does not have the given class', function(){
1082                 var div = new Element('div', {'class': 'header bold'});
1083                 expect(div.hasClass('italics')).toBeFalsy();
1084                 expect(div.hasClass('head')).toBeFalsy();
1085         });
1087         it('should add the class to the Element', function(){
1088                 var div = new Element('div');
1089                 div.addClass('myclass');
1090                 expect(div.hasClass('myclass')).toBeTruthy();
1091         });
1093         it('should append classes to the Element', function(){
1094                 var div = new Element('div', {'class': 'myclass'});
1095                 div.addClass('aclass');
1096                 expect(div.hasClass('aclass')).toBeTruthy();
1097         });
1099         it('should remove the class in the Element', function(){
1100                 var div = new Element('div', {'class': 'myclass'});
1101                 div.removeClass('myclass');
1102                 expect(div.hasClass('myclass')).toBeFalsy();
1103         });
1105         it('should only remove the specific class', function(){
1106                 var div = new Element('div', {'class': 'myclass aclass'});
1107                 div.removeClass('myclass');
1108                 expect(div.hasClass('myclass')).toBeFalsy();
1109         });
1111         it('should not remove any class if the class is not found', function(){
1112                 var div = new Element('div', {'class': 'myclass'});
1113                 div.removeClass('extra');
1114                 expect(div.hasClass('myclass')).toBeTruthy();
1115         });
1117         it('should add the class if the Element does not have the class', function(){
1118                 var div = new Element('div');
1119                 div.toggleClass('myclass');
1120                 expect(div.hasClass('myclass')).toBeTruthy();
1121         });
1123         it('should remove the class if the Element does have the class', function(){
1124                 var div = new Element('div', {'class': 'myclass'});
1125                 div.toggleClass('myclass');
1126                 expect(div.hasClass('myclass')).toBeFalsy();
1127         });
1131 describe('Element.empty', function(){
1133         it('should remove all children', function(){
1134                 var children = [];
1135                 (5).times(function(i){ children[i] = new Element('p'); });
1136                 var div = new Element('div').adopt(children);
1137                 div.empty();
1138                 expect(div.get('html')).toEqual('');
1139         });
1143 describe('Element.destroy', function(){
1145         it('should obliterate the Element from the universe', function(){
1146                 var div = new Element('div', {id: 'destroy-test'}).inject(document.body);
1147                 var result = div.destroy();
1148                 expect(result).toBeNull();
1149                 expect($('destroy-test')).toBeNull();
1150         });
1154 describe('Element.toQueryString', function(){
1156         it('should return an empty string for an Element that does not have form Elements', function(){
1157                 var div = new Element('div');
1158                 expect(div.toQueryString()).toEqual('');
1159         });
1161         it('should ignore any form Elements that do not have a name, disabled, or whose value is false', function(){
1162                 var form = new Element('form').adopt(
1163                         new Element('input', { name: 'input', disabled: true, type: 'checkbox', checked: true, value: 'checked' }),
1164                         new Element('select').adopt(
1165                                 new Element('option', { name: 'volvo', value: false, html: 'Volvo' }),
1166                                 new Element('option', { value: 'saab', html: 'Saab', selected: true })
1167                         ),
1168                         new Element('textarea', { name: 'textarea', disabled: true, value: 'textarea-value' })
1169                 );
1170                 expect(form.toQueryString()).toEqual('');
1171         });
1173         it("should return a query string containing even empty values, multiple select may have no selected options", function(){
1174                 var form = new Element('form',{'html':
1175                         '<input type="checkbox" name="input" value="" checked="checked" />' +
1176                         '<select name="select[]" multiple="multiple" size="5">' +
1177                                 '<option name="none" value="">--</option>' +
1178                                 '<option name="volvo" value="volvo">Volvo</option>' +
1179                                 '<option name="saab" value="saab">Saab</option>' +
1180                                 '<option name="opel" value="opel">Opel</option>' +
1181                                 '<option name="bmw" value="bmw">BMW</option>' +
1182                         '</select>' +
1183                         '<textarea name="textarea"></textarea>'
1184                 });
1185                 expect(form.toQueryString()).toEqual('input=&textarea=');
1186         });
1188         it("should return a query string ignoring submit, reset and file form Elements", function(){
1189                 var form = new Element('form', { 'html': '' +
1190                         '<input type="checkbox" name="input" value="checked" checked="checked" />' +
1191                         '<input type="file" name="file" />' +
1192                         '<textarea name="textarea">textarea-value</textarea>' +
1193                         '<input type="submit" name="go" value="Go" />' +
1194                         '<input type="reset" name="cancel" value="Reset" />'
1195                 });
1196                 expect(form.toQueryString()).toEqual('input=checked&textarea=textarea-value');
1197         });
1201 describe('Element.getProperty', function(){
1203         it('should getProperty from an Element', function(){
1204                 var anchor1 = new Element('a');
1205                 anchor1.href = 'http://mootools.net';
1206                 expect(anchor1.getProperty('href')).toEqual('http://mootools.net');
1208                 var anchor2 = new Element('a');
1209                 anchor2.href = '#someLink';
1210                 expect(anchor2.getProperty('href')).toEqual('#someLink');
1211         });
1213         it('should getProperty type of an input Element', function(){
1214                 var input1 = new Element('input', {type: 'text'});
1215                 expect(input1.getProperty('type')).toEqual('text');
1217                 var input2 = new Element('input', {type: 'checkbox'});
1218                 expect(input2.getProperty('type')).toEqual('checkbox');
1220                 var div = new Element('div', {'html':
1221                         '<select name="test" id="test" multiple="multiple">' +
1222                                 '<option value="1">option-value</option>' +
1223                         '</select>'
1224                 });
1225                 var input3 = div.getElement('select');
1226                 expect(input3.getProperty('type')).toEqual('select-multiple');
1227                 expect(input3.getProperty('name')).toEqual('test');
1228         });
1230         it('should getPropety checked from an input Element', function(){
1231                 var checked1 = new Element('input', { type: 'checkbox' });
1232                 checked1.checked = 'checked';
1233                 expect(checked1.getProperty('checked')).toBeTruthy();
1235                 var checked2 = new Element('input', { type: 'checkbox' });
1236                 checked2.checked = true;
1237                 expect(checked2.getProperty('checked')).toBeTruthy();
1239                 var checked3 = new Element('input', { type: 'checkbox' });
1240                 checked3.checked = false;
1241                 expect(checked3.getProperty('checked')).toBeFalsy();
1242         });
1244         it('should getProperty disabled from an input Element', function(){
1245                 var disabled1 = new Element('input', { type: 'text' });
1246                 disabled1.disabled = 'disabled';
1247                 expect(disabled1.getProperty('disabled')).toBeTruthy();
1249                 var disabled2 = new Element('input', { type: 'text' });
1250                 disabled2.disabled = true;
1251                 expect(disabled2.getProperty('disabled')).toBeTruthy();
1253                 var disabled3 = new Element('input', { type: 'text' });
1254                 disabled3.disabled = false;
1255                 expect(disabled3.getProperty('disabled')).toBeFalsy();
1256         });
1258         it('should getProperty readonly from an input Element', function(){
1259                 var readonly1 = new Element('input', { type: 'text' });
1260                 readonly1.readOnly = 'readonly';
1261                 expect(readonly1.getProperty('readonly')).toBeTruthy();
1263                 var readonly2 = new Element('input', { type: 'text' });
1264                 readonly2.readOnly = true;
1265                 expect(readonly2.getProperty('readonly')).toBeTruthy();
1267                 var readonly3 = new Element('input', { type: 'text' });
1268                 readonly3.readOnly = false;
1269                 expect(readonly3.getProperty('readonly')).toBeFalsy();
1270         });
1274 describe('Element.setProperty', function(){
1276         it('should setProperty from an Element', function(){
1277                 var anchor1 = new Element('a').setProperty('href', 'http://mootools.net/');
1278                 expect(anchor1.getProperty('href')).toEqual('http://mootools.net/');
1280                 var anchor2 = new Element('a').setProperty('href', '#someLink');
1281                 expect(anchor2.getProperty('href')).toEqual('#someLink');
1282         });
1284         it('should setProperty type of an input Element', function(){
1285                 var input1 = new Element('input').setProperty('type', 'text');
1286                 expect(input1.getProperty('type')).toEqual('text');
1288                 var input2 = new Element('input').setProperty('type', 'checkbox');
1289                 expect(input2.getProperty('type')).toEqual('checkbox');
1290         });
1292         it('should setProperty checked from an input Element', function(){
1293                 var checked1 = new Element('input', { type: 'checkbox' }).setProperty('checked', 'checked');
1294                 expect(checked1.getProperty('checked')).toBeTruthy();
1296                 var checked2 = new Element('input', { type: 'checkbox' }).setProperty('checked', true);
1297                 expect(checked2.getProperty('checked')).toBeTruthy();
1299                 var checked3 = new Element('input', { type: 'checkbox' }).setProperty('checked', false);
1300                 expect(checked3.getProperty('checked')).toBeFalsy();
1301         });
1303         it('should setProperty disabled of an input Element', function(){
1304                 var disabled1 = new Element('input', { type: 'text' }).setProperty('disabled', 'disabled');
1305                 expect(disabled1.getProperty('disabled')).toBeTruthy();
1307                 var disabled2 = new Element('input', { type: 'text' }).setProperty('disabled', true);
1308                 expect(disabled2.getProperty('disabled')).toBeTruthy();
1310                 var disabled3 = new Element('input', { type: 'text' }).setProperty('disabled', false);
1311                 expect(disabled3.getProperty('disabled')).toBeFalsy();
1312         });
1314         it('should setProperty readonly of an input Element', function(){
1315                 var readonly1 = new Element('input', { type: 'text' }).setProperty('readonly', 'readonly');
1316                 expect(readonly1.getProperty('readonly')).toBeTruthy();
1318                 var readonly2 = new Element('input', { type: 'text' }).setProperty('readonly', true);
1319                 expect(readonly2.getProperty('readonly')).toBeTruthy();
1321                 var readonly3 = new Element('input', { type: 'text' }).setProperty('readonly', false);
1322                 expect(readonly3.getProperty('readonly')).toBeFalsy();
1323         });
1325         it('should setProperty defaultValue of an input Element', function(){
1326                 var form = new Element('form');
1327                 var defaultValue = new Element('input', {'type': 'text', 'value': '321'});
1328                 expect(defaultValue.getProperty('value')).toEqual('321');
1329                 defaultValue.setProperty('defaultValue', '123');
1330                 form.grab(defaultValue);
1331                 form.reset();
1332                 expect(defaultValue.getProperty('value')).toEqual('123');
1333         });
1337 describe('Element.getProperties', function(){
1339         it('should return an object associate with the properties passed', function(){
1340                 var readonly = new Element('input', { type: 'text', readonly: 'readonly' });
1341                 var props = readonly.getProperties('type', 'readonly');
1342                 expect(props).toEqual({ type: 'text', readonly: true });
1343         });
1347 describe('Element.setProperties', function(){
1349         it('should set each property to the Element', function(){
1350                 var readonly = new Element('input').setProperties({ type: 'text', readonly: 'readonly' });
1351                 var props = readonly.getProperties('type', 'readonly');
1352                 expect(props).toEqual({ type: 'text', readonly: true });
1353         });
1357 describe('Element.removeProperties', function(){
1359         it('should remove each property from the Element', function(){
1360                 var anchor = new Element('a', {href: '#', title: 'title', rel: 'left'});
1361                 anchor.removeProperties('title', 'rel');
1362                 expect(anchor.getProperties('href', 'title', 'rel')).toEqual({ href: '#', title: null, rel: null });
1363         });
1367 describe('Element.getPrevious', function(){
1369         it('should return the previous Element, otherwise null', function(){
1370                 var container = new Element('div');
1371                 var children = [new Element('div'), new Element('div'), new Element('div')];
1372                 container.adopt(children);
1373                 expect(children[1].getPrevious()).toEqual(children[0]);
1374                 expect(children[0].getPrevious()).toBeNull();
1375         });
1377         it('should return the previous Element that matches, otherwise null', function(){
1378                 var container = new Element('div');
1379                 var children = [new Element('a'), new Element('div'), new Element('div'), new Element('div')];
1380                 container.adopt(children);
1381                 expect(children[1].getPrevious('a')).toEqual(children[0]);
1382                 expect(children[1].getPrevious('span')).toBeNull();
1383         });
1387 describe('Element.getAllPrevious', function(){
1389         it('should return all the previous Elements, otherwise an empty array', function(){
1390                 var container = new Element('div');
1391                 var children = [new Element('div'), new Element('div'), new Element('div')];
1392                 container.adopt(children);
1393                 expect(children[2].getAllPrevious()).toEqual(new Elements([children[1], children[0]]));
1394                 expect(children[0].getAllPrevious()).toEqual(new Elements([]));
1395         });
1397         it('should return all the previous Elements that match, otherwise an empty array', function(){
1398                 var container = new Element('div');
1399                 var children = [new Element('a'), new Element('div'), new Element('a'), new Element('div')];
1400                 container.adopt(children);
1401                 expect(children[3].getAllPrevious('a')).toEqual(new Elements([children[2], children[0]]));
1402                 expect(children[1].getAllPrevious('span')).toEqual(new Elements([]));
1403         });
1407 describe('Element.getNext', function(){
1409         it('should return the next Element, otherwise null', function(){
1410                 var container = new Element('div');
1411                 var children = [new Element('div'), new Element('div'), new Element('div')];
1412                 container.adopt(children);
1413                 expect(children[1].getNext()).toEqual(children[2]);
1414                 expect(children[2].getNext()).toBeNull();
1415         });
1417         it('should return the previous Element that matches, otherwise null', function(){
1418                 var container = new Element('div');
1419                 var children = [new Element('div'), new Element('div'), new Element('div'), new Element('a')];
1420                 container.adopt(children);
1421                 expect(children[1].getNext('a')).toEqual(children[3]);
1422                 expect(children[1].getNext('span')).toBeNull();
1423         });
1427 describe('Element.getAllNext', function(){
1429         it('should return all the next Elements, otherwise an empty array', function(){
1430                 var container = new Element('div');
1431                 var children = [new Element('div'), new Element('div'), new Element('div')];
1432                 container.adopt(children);
1433                 expect(children[0].getAllNext()).toEqual(new Elements(children.slice(1)));
1434                 expect(children[2].getAllNext()).toEqual(new Elements([]));
1435         });
1437         it('should return all the next Elements that match, otherwise an empty array', function(){
1438                 var container = new Element('div');
1439                 var children = [new Element('div'), new Element('a'), new Element('div'), new Element('a')];
1440                 container.adopt(children);
1441                 expect(children[0].getAllNext('a')).toEqual(new Elements([children[1], children[3]]));
1442                 expect(children[0].getAllNext('span')).toEqual(new Elements([]));
1443         });
1447 describe('Element.getFirst', function(){
1449         it('should return the first Element in the Element, otherwise null', function(){
1450                 var container = new Element('div');
1451                 var children = [new Element('div'), new Element('a'), new Element('div')];
1452                 container.adopt(children);
1453                 expect(container.getFirst()).toEqual(children[0]);
1454                 expect(children[0].getFirst()).toBeNull();
1455         });
1459 describe('Element.getLast', function(){
1461         it('should return the last Element in the Element, otherwise null', function(){
1462                 var container = new Element('div');
1463                 var children = [new Element('div'), new Element('a'), new Element('div')];
1464                 container.adopt(children);
1465                 expect(container.getLast()).toEqual(children[2]);
1466                 expect(children[0].getLast()).toBeNull();
1467         });
1469         it('should return the last Element in the Element that matches, otherwise null', function(){
1470                 var container = new Element('div');
1471                 var children = [new Element('div'), new Element('a'), new Element('div'), new Element('a')];
1472                 container.adopt(children);
1473                 expect(container.getLast('a')).toEqual(children[3]);
1474                 expect(container.getLast('span')).toBeNull();
1475         });
1479 describe('Element.getParent', function(){
1481         it('should return the parent of the Element, otherwise null', function(){
1482                 var container = new Element('p');
1483                 var children = [new Element('div'), new Element('div'), new Element('div')];
1484                 container.adopt(children);
1485                 expect(children[1].getParent()).toEqual(container);
1486                 expect(container.getParent()).toBeNull();
1487         });
1489         it('should return the parent of the Element that matches, otherwise null', function(){
1490                 var container = new Element('p');
1491                 var children = [new Element('div'), new Element('div'), new Element('div')];
1492                 container.adopt(new Element('div').adopt(children));
1493                 expect(children[1].getParent('p')).toEqual(container);
1494                 expect(children[1].getParent('table')).toBeNull();
1495         });
1499 describe('Element.getParents', function(){
1501         it('should return the parents of the Element, otherwise returns an empty array', function(){
1502                 var container = new Element('p');
1503                 var children = [new Element('div'), new Element('div'), new Element('div')];
1504                 container.adopt(new Element('div').adopt(new Element('div').adopt(children)));
1505                 expect(children[1].getParents()).toEqual(new Elements([container.getFirst().getFirst(), container.getFirst(), container]));
1506                 expect(container.getParents()).toEqual(new Elements([]));
1507         });
1509         it('should return the parents of the Element that match, otherwise returns an empty array', function(){
1510                 var container = new Element('p');
1511                 var children = [new Element('div'), new Element('div'), new Element('div')];
1512                 container.adopt(new Element('div').adopt(new Element('div').adopt(children)));
1513                 expect(children[1].getParents('div')).toEqual(new Elements([container.getFirst().getFirst(), container.getFirst()]));
1514                 expect(children[1].getParents('table')).toEqual(new Elements([]));
1515         });
1519 describe('Element.getChildren', function(){
1521         it("should return the Element's children, otherwise returns an empty array", function(){
1522                 var container = new Element('div');
1523                 var children = [new Element('div'), new Element('div'), new Element('div')];
1524                 container.adopt(children);
1525                 expect(container.getChildren()).toEqual(new Elements(children));
1526                 expect(children[0].getChildren()).toEqual(new Elements([]));
1527         });
1529         it("should return the Element's children that match, otherwise returns an empty array", function(){
1530                 var container = new Element('div');
1531                 var children = [new Element('div'), new Element('a'), new Element('a')];
1532                 container.adopt(children);
1533                 expect(container.getChildren('a')).toEqual(new Elements([children[1], children[2]]));
1534                 expect(container.getChildren('span')).toEqual(new Elements([]));
1535         });
1539 describe('Element.hasChild', function(){
1541         beforeEach(function(){
1542                 Local = {};
1543                 Local.container = new Element('div');
1544                 Local.children = [new Element('div'), new Element('div'), new Element('div')];
1545                 Local.container.adopt(Local.children);
1546                 Local.grandchild = new Element('div').inject(Local.children[1]);
1547         });
1549         afterEach(function(){
1550                 Local = null;
1551         });
1553         //<1.3compat>
1554         it("should return true if the Element is a child or grandchild", function(){
1555                 expect(Local.container.hasChild(Local.children[0])).toBeTruthy();
1556                 expect(Local.container.hasChild(Local.children[2])).toBeTruthy();
1557                 expect(Local.container.hasChild(Local.grandchild)).toBeTruthy();
1558         });
1560         it("should return false if it's the Element itself", function(){
1561                 expect(Local.container.hasChild(Local.container)).toBeFalsy();
1562         });
1564         it("should return false if the Element is the parent or a sibling", function(){
1565                 expect(Local.children[2].hasChild(Local.container)).toBeFalsy();
1566                 expect(Local.children[2].hasChild(Local.children[1])).toBeFalsy();
1567         });
1568         //</1.3compat>
1570         it("should return true if the Element is a child or grandchild", function(){
1571                 expect(Local.container.contains(Local.children[0])).toBeTruthy();
1572                 expect(Local.container.contains(Local.children[2])).toBeTruthy();
1573                 expect(Local.container.contains(Local.grandchild)).toBeTruthy();
1574         });
1576         it("should return true if it's the Element itself", function(){
1577                 expect(Local.container.contains(Local.container)).toBeTruthy();
1578         });
1580         it("should return false if the Element is the parent or a sibling", function(){
1581                 expect(Local.children[2].contains(Local.container)).toBeFalsy();
1582                 expect(Local.children[2].contains(Local.children[1])).toBeFalsy();
1583         });
1587 describe('Elements.extend', function(){
1589         //<1.2compat>
1590         it('should be able to extend a collection', function(){
1591                 var items = [
1592                         new Element('span'),
1593                         new Element('span'),
1594                         new Element('p'),
1595                         new Element('p')
1596                 ];
1597                 var container = new Element('div').adopt(items);
1599                 container.getElements('span').extend(container.getElements('p'));
1600                 expect($$(items)).toEqual(container.getElements('*'));
1601                 expect(items.length).toEqual(4);
1602         });
1603         //</1.2compat>
1605         it('should be able to append a collection', function(){
1606                 var items = [
1607                         new Element('span'),
1608                         new Element('span'),
1609                         new Element('p'),
1610                         new Element('p')
1611                 ];
1612                 var container = new Element('div').adopt(items);
1614                 container.getElements('span').append(container.getElements('p'));
1615                 expect(new Elements(items)).toEqual(container.getElements('*'));
1616                 expect(items.length).toEqual(4);
1617         });
1621 describe('document.id', function(){
1623         it('should find IDs with special characters', function(){
1624                 var element = new Element('div#id\\.part.class').inject(document.body);
1626                 var found = document.id('id.part');
1627                 expect(found).toBe(element);
1628                 expect(found.id).toBe('id.part');
1629                 expect(found.className).toBe('class');
1631                 element.destroy();
1633                 element = new Element('div#id\\#part').inject(document.body);
1635                 found = document.id('id#part');
1636                 expect(found).toBe(element);
1637                 expect(found.id).toBe('id#part');
1638         });
1642 describe('Element.getElementById', function(){
1644         it('should find IDs with special characters', function(){
1645                 var inner = new Element('div#id\\.part');
1646                 var outer = new Element('div').adopt(inner);
1648                 expect(outer.getElementById('id.part')).toBe(inner);
1649                 expect(inner.id).toBe('id.part');
1650         });
1654 describe('Element.removeProperty', function(){
1656         it('should removeProperty from an Element', function (){
1657                 var readonly = new Element('input', { type: 'text', readonly: 'readonly', maxlength: 10 });
1658                 readonly.removeProperty('readonly');
1659                 readonly.removeProperty('maxlength');
1660                 var props = readonly.getProperties('type', 'readonly');
1661                 expect(props).toEqual({type: 'text', readonly: false});
1663                 var maxlength = readonly.getProperty('maxlength');
1664                 expect(!maxlength || maxlength == 2147483647).toBeTruthy(); // ie6/7 Bug
1665         });
1669 describe('Element.toQueryString', function(){
1671         it("should return a query string from the Element's form Elements", function(){
1672                 var form = new Element('form', { 'html': '' +
1673                         '<input type="checkbox" name="input" value="checked" checked="checked" />' +
1674                         '<select name="select[]" multiple="multiple" size="5">' +
1675                                 '<option name="none" value="">--</option>' +
1676                                 '<option name="volvo" value="volvo">Volvo</option>' +
1677                                 '<option name="saab" value="saab" selected="selected">Saab</option>' +
1678                                 '<option name="opel" value="opel" selected="selected">Opel</option>' +
1679                                 '<option name="bmw" value="bmw">BMW</option>' +
1680                         '</select>' +
1681                         '<textarea name="textarea">textarea-value</textarea>'
1682                 });
1683                 expect(form.toQueryString()).toEqual('input=checked&select%5B%5D=saab&select%5B%5D=opel&textarea=textarea-value');
1684         });
1686         it("should return a query string containing even empty values, single select must have a selected option", function(){
1687                 var form = new Element('form').adopt(
1688                         new Element('input', {name: 'input', type: 'checkbox', checked: true, value: ''}),
1689                         new Element('select', {name: 'select[]'}).adopt(
1690                                 new Element('option', {name: 'none', value: '', html: '--', selected: true}),
1691                                 new Element('option', {name: 'volvo', value: 'volvo', html: 'Volvo'}),
1692                                 new Element('option', {name: 'saab', value: 'saab', html: 'Saab'}),
1693                                 new Element('option', {name: 'opel', value: 'opel', html: 'Opel'}),
1694                                 new Element('option', {name: 'bmw', value: 'bmw', html: 'BMW'})
1695                         ),
1696                         new Element('textarea', {name: 'textarea', value: ''})
1697                 );
1698                 expect(form.toQueryString()).toEqual('input=&select%5B%5D=&textarea=');
1699                 expect(form.getElementsByTagName('select')[0].selectedIndex).toEqual(0);
1700         });
1704 describe('Element.clone', function(){
1706         it('should clone children of object elements', function(){
1707                 var div = new Element('div').set('html', '<div id="swfobject-video" class="video">' +
1708                         '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="425" height="344">' +
1709                                 '<param name="movie" value="http://www.youtube.com/v/6nOVQDMOvvE&amp;rel=0&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" />' +
1710                                 '<param name="wmode" value="opaque" />' +
1711                                 '<param name="quality" value="high" />' +
1712                                 '<param name="bgcolor" value="#000616" />' +
1713                                 '<param name="allowFullScreen" value="true" />' +
1714                                 '<!--[if !IE]>-->' +
1715                                 '<object type="application/x-shockwave-flash" data="http://www.youtube.com/v/6nOVQDMOvvE&amp;rel=0&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" width="425" height="344">' +
1716                                 '<param name="wmode" value="opaque" />' +
1717                                 '<param name="quality" value="high" />' +
1718                                 '<param name="bgcolor" value="#000616" />' +
1719                                 '<param name="allowFullScreen" value="true" />' +
1720                                 '<!--<![endif]-->' +
1721                                 '<p class="flash-required">Flash is required to view this video.</p>' +
1722                                 '<!--[if !IE]>-->' +
1723                                 '</object>' +
1724                                 '<!--<![endif]-->' +
1725                         '</object>' +
1726                 '</div>');
1728                 expect(div.clone().getElementsByTagName('param').length).toBeGreaterThan(0);
1730                 div = new Element('div').set('html', '<div id="ie-video" class="video">' +
1731                         '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="425" height="344">' +
1732                                 '<param name="movie" value="http://www.youtube.com/v/6nOVQDMOvvE&amp;rel=0&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" />' +
1733                                 '<param name="wmode" value="opaque" />' +
1734                                 '<param name="quality" value="high" />' +
1735                                 '<param name="bgcolor" value="#000616" />' +
1736                                 '<param name="allowFullScreen" value="true" />' +
1737                         '</object>' +
1738                 '</div>');
1740                 expect(div.clone().getElementsByTagName('param').length).toBeGreaterThan(0);
1741         });
1743         it('should set the ID of the cloned element and then fetch it with document.id', function(){
1744                 var cloneMe = new Element('div', {id: 'cloneMe', text: 'cloneMe'}).inject(document.body);
1745                 var cloned = $('cloneMe').clone();
1746                 expect(cloned.get('id')).toEqual(null);
1747                 cloned.set('id', 'sauce').inject(cloneMe.parentNode);
1748                 expect(cloned.get('id')).toEqual('sauce');
1749                 var sauceHTML = new Element('div').adopt($('sauce')).get('html');
1750                 var cloneHTML = new Element('div').adopt(cloned).get('html');
1751                 expect(sauceHTML).toEqual(cloneHTML);
1752                 cloneMe.destroy();
1753                 cloned.destroy();
1754         });
1758 describe('Elements implement order', function(){
1760         it('should give precedence to Array over Element', function(){
1761                 var anchor = new Element('a');
1763                 var element = new Element('div').adopt(
1764                         new Element('span'),
1765                         anchor
1766                 );
1768                 expect(element.getLast()).toBe(anchor);
1770                 expect(new Elements([element, anchor]).getLast()).toBe(anchor);
1771         });
1775 describe('Element traversal', function(){
1777         it('should match against all provided selectors', function(){
1778                 var div = new Element('div').adopt(
1779                         new Element('span').adopt(
1780                                 new Element('a')
1781                         )
1782                 );
1784                 var span = div.getElement('span');
1785                 var anchor = span.getElement('a');
1787                 expect(anchor.getParent('div, span')).toBe(div);
1788                 expect(anchor.getParent('span, div')).toBe(span);
1790                 expect(anchor.getParent('tagname, div')).toBe(div);
1791                 expect(anchor.getParent('div > span')).toBe(span);
1792         });
1796 describe('Elements.prototype.erase', function(){
1798         var element = new Element('div', {
1799                 html: '<div></div><p></p><span></span>'
1800         });
1802         var original = element.getChildren();
1803         var altered = element.getChildren().erase(original[1]);
1805         it('should decrease the length of the collection', function(){
1806                 expect(altered.length).toEqual(2);
1807         });
1809         it('should remove an element from the collection', function(){
1810                 expect(altered[1]).toEqual(original[2]);
1811         });
1813         it('should remove the last element from the collection', function(){
1814                 expect(altered[2]).toEqual(undefined);
1815         });
1819 describe('Element.set("html")', function(){
1821         it("should set the html of a tr Element, even when it has no parentNode", function(){
1822                 var html = '<td class="cell c">cell 1</td><td>cell 2</td>';
1823                 var tr = new Element('tr');
1824                 expect(tr.parentNode).toEqual(null);
1825                 // In IE using appendChild like in set('html') sets the parentNode to a documentFragment
1826                 tr.set('html', html).inject(new Element('tbody').inject(new Element('table')));
1827                 expect(tr.get('html').toLowerCase().replace(/>\s+</, '><')).toEqual(html);
1828                 expect(tr.getChildren().length).toEqual(2);
1829                 expect(tr.getFirst().className).toEqual('cell c');
1830         });
1832         it("should set the html of a style Element", function(){
1834                 var styleElement = document.createElement('style');
1835                 var def = 'body {color: red;}';
1836                 styleElement.setAttribute("type", "text/css");
1837                 var docHead = document.getElementsByTagName('head')[0];
1838                 docHead.appendChild(styleElement);
1839                 if (styleElement.styleSheet){       // IE
1840                         styleElement.styleSheet.cssText = def;
1841                 } else {                             // the world
1842                         var node = document.createTextNode(def);
1843                         styleElement.appendChild(node);
1844                 }
1846                 styleElement = $(styleElement),
1847                         innerStyleA = '* { color: #a0a}',
1848                         innerStyleB = '.testStyling { font: 44px/44px Courier}';
1850                 function fixString(s){
1851                         // because browsers return content with different case/space formatting
1852                         return s.toLowerCase().replace(/\t|\s/g,'');
1853                 }
1854                 function getStyles(){
1855                         return fixString(styleElement.get('html'));
1856                 }
1858                 styleElement.set('html', innerStyleA);
1859                 expect(getStyles()).toEqual(fixString(innerStyleA));
1861                 styleElement.erase('html');
1862                 expect(getStyles()).toEqual('');
1864                 styleElement.set('html', innerStyleB);
1865                 expect(getStyles()).toEqual(fixString(innerStyleB));
1866                 styleElement.destroy();
1867         });
1869         it('should set the text of a style Element', function(){
1870                 
1871                 var docHead = $(document.head);
1872                 var styleElement = new Element('style', {type: 'text/css'}).inject(docHead);
1873                 var definition = [
1874                         '.pos-abs-left {',
1875                                 'position: absolute;',
1876                                 'width: 200px;',
1877                                 'height: 200px;',
1878                                 'left: 10%;',
1879                                 'background: red;',
1880                         '}'
1881                 ].join('');
1882                 styleElement.set('text', definition);
1883                 var returned = styleElement.get('text').toLowerCase();
1884                 expect(returned.indexOf('position: absolute')).not.toEqual(-1);
1885                 expect(returned.indexOf('width: 200px')).not.toEqual(-1);
1886                 expect(returned.indexOf('height: 200px')).not.toEqual(-1);
1887                 expect(returned.indexOf('left: 10%')).not.toEqual(-1);
1888                 expect(returned.indexOf('background: red')).not.toEqual(-1);
1889                 styleElement.destroy();
1890         });
1894 describe('Elements.empty', function(){
1896         it('should empty the Elements collection', function(){
1897                 var list = $$('div').empty();
1899                 expect(list.length).toEqual(0);
1900                 expect(list[0]).toBe(undefined);
1901         });
1905 describe('Elements.append', function(){
1907         it('should append an Elements collection', function(){
1908                 var list = new Element('div').adopt(
1909                         new Element('div'),
1910                         new Element('div')
1911                 ).getChildren();
1913                 var p = new Element('div').adopt(
1914                         new Element('p'),
1915                         new Element('p')
1916                 ).getChildren();
1918                 var appended = list.append(p);
1920                 expect(appended).toBe(list);
1921                 expect(appended).toEqual(new Elements([list[0], list[1], p[0], p[1]]));
1922         });
1926 describe('Elements.concat', function(){
1928         it('should concat an Elements collection', function(){
1929                 var list = new Element('div').adopt(
1930                         new Element('div'),
1931                         new Element('div')
1932                 ).getChildren();
1934                 var p = new Element('div').adopt(
1935                         new Element('p'),
1936                         new Element('p')
1937                 ).getChildren();
1939                 var concatenated = list.concat(p[0], p[1]);
1941                 expect(concatenated).not.toBe(list);
1942                 expect(concatenated).toEqual(new Elements([list[0], list[1], p[0], p[1]]));
1944                 expect(typeOf(concatenated)).toBe('elements');
1945         });
1949 describe('Element.getElement', function(){
1951         it('should return null', function(){
1952                 var div = new Element('div'),
1953                         a = new Element('a'),
1954                         span = new Element('span'),
1955                         p = new Element('span');
1957                 p.adopt(span, a);
1958                 div.adopt(p);
1960                 var element = div.getElement();
1961                 expect(element).toBe(null);
1962         });
1966 describe('Element.getElements', function(){
1968         it('should return an empty collection', function(){
1969                 var div = new Element('div'),
1970                         a = new Element('a'),
1971                         span = new Element('span'),
1972                         p = new Element('span');
1974                 p.adopt(span, a);
1975                 div.adopt(p);
1977                 var elements = div.getElements();
1978                 expect(elements.length).toBe(0);
1979         });
1981         it('should return an empty collection if called on document.body', function(){
1982                 expect($(document.body).getElements()).toEqual(new Elements);
1983         });
1987 describe('Element.getFirst', function(){
1989         it('should return last the first element only if it matches the expression', function(){
1990                 var container = new Element('div');
1991                 var children = [new Element('div').adopt(new Element('a')), new Element('a'), new Element('div')];
1992                 container.adopt(children);
1993                 expect(container.getFirst('div')).toBe(children[0]);
1994                 expect(container.getFirst('a')).toBe(children[1]);
1995                 expect(container.getFirst('span')).toBeNull();
1996         });
1999 describe('Element.getLast', function(){
2001         it('should return the last element only if it matches the expression', function(){
2002                 var container = new Element('div');
2003                 var children = [new Element('div').adopt(new Element('a')), new Element('a'), new Element('div')];
2004                 container.adopt(children);
2005                 expect(container.getLast('div')).toBe(children[2]);
2006                 expect(container.getLast('a')).toBe(children[1]);
2007                 expect(container.getLast('span')).toBeNull();
2008         });
2011 describe('Elements.unshift', function(){
2013         it('should not allow to unshift any value', function(){
2014                 var container = new Element('div').adopt(
2015                         new Element('span'),
2016                         new Element('p')
2017                 );
2019                 var collection = container.getElements('*'),
2020                         length = collection.length;
2021                 collection.unshift('someRandomValue');
2023                 expect(collection.length).toBe(length);
2025                 collection.unshift(new Element('p'), new Element('span'));
2026                 expect(collection.length).toBe(length + 2);
2027                 expect(collection.filter('p').length).toBe(2);
2028                 expect(collection.filter('span').length).toBe(2);
2029         });
2033 describe('Element.getProperty', function(){
2035         it('should get the attrubte of a form when the form has an input with as ID the attribute name', function(){
2036                 var div = new Element('div');
2037                 div.innerHTML = '<form action="s"><input id="action"></form>';
2038                 expect($(div.firstChild).getProperty('action')).toEqual('s');
2039         });
2041         it('should ignore expandos', function(){
2042                 var div = new Element('div');
2043                 expect(div.getProperty('inject')).toBeNull();
2044         });
2046         it('should work in collaboration with setProperty', function(){
2047                 var div = new Element('div', {random: 'attribute'});
2048                 expect(div.getProperty('random')).toEqual('attribute');
2049         });
2051         it('should get custom attributes in html', function(){
2052                 var div = new Element('div', {html: '<div data-load="typical"></div>'}).getFirst();
2053                 expect(div.get('data-load')).toEqual('typical');
2055                 div = new Element('div', {html: '<div data-custom></div>'}).getFirst();
2056                 expect(div.get('data-custom')).toEqual('');
2058                 div = new Element('div', {html: '<div data-custom="nested"><a data-custom="other"></a></div>'}).getFirst();
2059                 expect(div.get('data-custom')).toEqual('nested');
2061                 div = new Element('div', {html: '<div><a data-custom="other"></a></div>'}).getFirst();
2062                 expect(div.get('data-custom')).toEqual(null);
2064                 div = new Element('div', {html: '<a data-custom="singular" href="#">href</a>'}).getFirst();
2065                 expect(div.get('data-custom')).toEqual('singular');
2067                 div = new Element('div', {html: '<div class="><" data-custom="evil attribute values"></div>'}).getFirst();
2068                 expect(div.get('data-custom')).toEqual('evil attribute values');
2070                 div = new Element('div', {html: '<div class="> . <" data-custom="aggrevated evil attribute values"></div>'}).getFirst();
2071                 expect(div.get('data-custom')).toEqual('aggrevated evil attribute values');
2073                 div = new Element('div', {html: '<a href="#"> data-custom="singular"</a>'}).getFirst();
2074                 expect(div.get('data-custom')).toEqual(null);
2075         });
2079 describe('Element.set', function(){
2081         describe('value', function(){
2083                 it('should return `null` when the value of a input element is set to `undefined`', function(){
2084                         var value;
2085                         expect(new Element('input', {value: value}).get('value')).toEqual('');
2086                 });
2088                 it('should set a falsey value and not an empty string', function(){
2089                         expect(new Element('input', {value: false}).get('value')).toEqual('false');
2090                         expect(new Element('input', {value: 0}).get('value')).toEqual('0');
2091                 });
2093                 it('should set the selected option for a select element to matching string w/o falsy matches', function(){
2094                         var form = new Element('form');
2095                         form.set('html', '<select>\
2096                                 <option value="">no value</option>\
2097                                 <option value="0">value 0</option>\
2098                                 <option value="1">value 1</option>\
2099                                 </select>');
2100                         expect(form.getElement('select').set('value', 0).get('value')).toEqual('0');
2101                 });
2103         });
2105         describe('type', function(){
2107                 it('should set the type of a button', function(){
2108                         expect(new Element('button', {type: 'button'}).get('type')).toEqual('button');
2109                 });
2111         });
2113         describe('value as object with toString()', function(){
2115                 it('should call the toString() method of a passed object', function(){
2116                         var a = new Element('a').set('href', {toString: function(){ return '1'; }});
2117                         expect(a.get('href')).toEqual('1');
2118                 });
2120         });
2124 describe("Element.setProperty('type')", function(){
2126         it('should keep the input value after setting a input field to another type (submit button)', function(){
2127                 var input = new Element('input', {value: 'myValue', type: 'text'});
2128                 input.setProperty('type', 'submit');
2129                 expect(input.getProperty('value')).toEqual('myValue');
2130         });
2132         it('should set the right type and value of input fields when a input field is created with CSS selectors', function(){
2133                 var input = new Element('input[type="submit"]', {value: 'myValue'});
2134                 expect(input.getProperty('value')).toEqual('myValue');
2135         });
2139 describe('Element.get', function(){
2141         describe('value', function(){
2143                 it('should get the value of a option element when it does not have the value attribute', function(){
2144                         var select = new Element('select').set('html', '<option>s</option>');
2145                         expect(select.getElement('option').get('value')).toEqual('s');
2146                 });
2148                 it('should return the text of the selected option for a select element', function(){
2149                         var form = new Element('form');
2150                         form.set('html', '<select>\
2151                                 <option>value 1</option>\
2152                                 <option>value 2</option>\
2153                                 <option selected>value 3</option>\
2154                                 <option>value 4</option>\
2155                                 </select>');
2156                         expect(form.getElement('select').get('value')).toEqual('value 3');
2157                 });
2159                 it('should return the text of the selected option for a multiple select element', function(){
2160                         var form = new Element('form');
2161                         form.set('html', '<select multiple>\
2162                                 <option>value 1</option>\
2163                                 <option selected>value 2</option>\
2164                                 <option selected>value 3</option>\
2165                                 <option>value 4</option>\
2166                                 </select>');
2167                         expect(form.getElement('select').get('value')).toEqual('value 2');
2168                 });
2170                 it('should return the text of the first option of aselect element', function(){
2171                         var form = new Element('form');
2172                         form.set('html', '<select>\
2173                                 <option>value 1</option>\
2174                                 <option>value 2</option>\
2175                                 </select>');
2176                         expect(form.getElement('select').get('value')).toEqual('value 1');
2177                 });
2179                 it('should return value of a select element', function(){
2180                         var form = new Element('form');
2181                         form.set('html', '<select multiple>\
2182                                 <option value="one">value 1</option>\
2183                                 <option selected value="two">value 2</option>\
2184                                 </select>');
2185                         expect(form.getElement('select').get('value')).toEqual('two');
2186                 });
2188         });
2190         describe('text', function(){
2192                 it('should return the original text with `text-transform: uppercase`', function(){
2193                         var div = new Element('div', {html: '<div style="text-transform: uppercase">text</div>'});
2194                         div.inject(document.body);
2195                         expect($(div.firstChild).get('text')).toEqual('text');
2196                         div.destroy();
2197                 });
2199         });
2203 describe('tabIndex', function(){
2205         it('should get and set the correct tabIndex', function(){
2206                 var div = document.createElement('div');
2207                 div.innerHTML = '<input tabindex="2">';
2208                 expect($(div.firstChild).get('tabindex')).toEqual(2);
2209                 expect($(div.firstChild).set('tabindex', 3).get('tabindex')).toEqual(3);
2210         });
2214 if (document.createElement('video').canPlayType){
2215         describe('Video/Audio loop, controls, and autoplay set/get attributes', function(){
2217                 it('should set/get the boolean value of loop, controls, and autoplay', function(){
2218                         try{
2219                                 var div = new Element('div', {html: '<video loop controls autoplay>'}),
2220                                         video = div.getElement('video');
2222                                 if ('loop' in video){
2223                                         expect(video.getProperty('loop')).toBe(true);
2224                                         expect(video.setProperty('loop', false).getProperty('loop')).toBe(false);
2225                                 }
2226                                 expect(video.getProperty('controls')).toBe(true);
2227                                 expect(video.setProperty('controls', false).getProperty('controls')).toBe(false);
2228                                 expect(video.getProperty('autoplay')).toBe(true);
2229                                 expect(video.setProperty('autoplay', false).getProperty('autoplay')).toBe(false);
2230                         }catch(O_o){
2231                                 if(O_o.message.indexOf('Not implemented') == -1){
2232                                         expect(O_o.message + " : "+O_o).toBe("")
2233                                 }
2234                         }
2235         });
2237         });
2240 describe("Element.set('html')", function(){
2242         describe('HTML5 tags', function(){
2244                 it('should create childNodes for html5 tags', function(){
2245                         expect(new Element('div', {html: '<nav>Muu</nav><p>Tuuls</p><section>!</section>'}).childNodes.length).toEqual(3);
2246                 });
2248         });
2250         describe('Numbers', function(){
2252                 it('should set a number (so no string) as html', function(){
2253                         expect(new Element('div', {html: 20}).innerHTML).toEqual('20');
2254                 });
2256         });
2258         describe('Arrays', function(){
2260                 it('should allow an Array as input, the text is concatenated', function(){
2261                         expect(new Element('div', {html: ['moo', 'rocks', 'your', 'socks', 1]}).innerHTML).toEqual('moorocksyoursocks1');
2262                 });
2264         });
2268 describe("Element.erase('html')", function(){
2270         it('should empty the html inside an element', function(){
2271                 expect(new Element('div', {html: '<p>foo bar</p>'}).erase('html').innerHTML).toEqual('');
2272         });
2276 describe('Element.clone', function(){
2278         it('should not crash IE for multiple clones', function(){
2279                 new Element('div', {
2280                         html: '<ul id="testContainer"><li id="template"></li></ul>'
2281                 }).inject(document.body);
2283                 var container = $('testContainer'),
2284                 template = container.getElement('li#template').dispose();
2286                 template.clone().set('html', 'Clone #1').inject('testContainer');
2287                 template.clone().set('html', 'Clone #2').inject('testContainer');
2289                 container.destroy();
2290         });
2294 describe('Element.erase', function(){
2296         var elements, subject, image, textarea;
2298         beforeEach(function(){
2299                 elements = [
2300                         subject = new Element('div'),
2301                         image = new Element('img'),
2302                         textarea = new Element('div', {html: '<textarea id="t1">hello</textarea>'}).getFirst()
2303                 ].invoke('inject', document.body);
2304         });
2306         afterEach(function(){
2307                 elements.invoke('destroy');
2308         });
2310         it('should erase the class of an Element', function(){
2311                 subject.set('class', 'test');
2312                 subject.erase('class');
2313                 expect(subject.get('class')).toEqual(null);
2314         });
2316         it('should erase the id of an Element', function(){
2317                 subject.set('id', 'test');
2318                 subject.erase('id');
2319                 expect(subject.get('id')).toEqual(null);
2320         });
2322         it('should erase the random attribute of an Element', function(){
2323                 subject.set('random', 'test');
2324                 subject.erase('random');
2325                 expect(subject.get('random')).toEqual(null);
2326         });
2328         it('should erase the value attribute of a textarea', function(){
2329                 textarea.erase('value');
2330                 expect(textarea.get('value')).toEqual('');
2331         });
2335 describe('Element.appendHTML', function(){
2337         var check, base, baseFallBack;
2339         beforeEach(function(){
2340                 check = new Element('span', {
2341                         html: '<div>content</div><div>content</div>',
2342                         styles: {
2343                                 display: 'none'
2344                         }
2345                 });
2347                 check.inject(document.documentElement);
2348                 base = $(check.getChildren()[0]);
2349                 baseFallBack = $(check.getChildren()[1]);
2351                 base.set('rel', '0');
2352                 baseFallBack.set('rel', '1');
2353         });
2355         afterEach(function(){
2356                 baseFallBack = baseFallBack.destroy();
2357                 base = base.destroy();
2358                 check = check.destroy();
2359         });
2361         it('should insert element before', function(){
2363                 base.appendHTML('<span>HI!</span>', 'before');
2364                 baseFallBack.appendHTML('<span>HI!</span>', 'before');
2366                 var children = check.getElements('span');
2368                 expect(children.length).toBe(2);
2369                 children.each(function(child, i){
2370                         expect(child.get('text')).toBe('HI!');
2371                         expect(child.nextSibling.getAttribute('rel')).toBe('' + i);
2372                 });
2373         });
2375         it('should insert element after', function(){
2376                 base.appendHTML('<span>HI!</span>', 'after');
2377                 baseFallBack.appendHTML('<span>HI!</span>', 'after');
2379                 var children = check.getElements('span');
2381                 expect(children.length).toBe(2);
2382                 children.each(function(child, i){
2383                         expect(child.get('text')).toBe('HI!');
2384                         expect(child.previousSibling.getAttribute('rel')).toBe('' + i);
2385                 });
2386         });
2388         it('should insert element on bottom', function(){
2389                 base.appendHTML('<span>HI!</span>', 'bottom');
2390                 baseFallBack.appendHTML('<span>HI!</span>', 'bottom');
2392                 var children = check.getElements('span');
2394                 expect(children.length).toBe(2);
2395                 expect(children.each(function(child, i){
2396                         expect(child.get('text')).toBe('HI!');
2397                         expect(child.parentNode.getAttribute('rel')).toBe('' + i);
2398                         expect(child.parentNode.get('text')).toBe('contentHI!');
2399                 }));
2400         });
2402         it('should insert element on top', function(){
2403                 base.appendHTML('<span>HI!</span>', 'top');
2404                 baseFallBack.appendHTML('<span>HI!</span>', 'top');
2406                 var children = check.getElements('span');
2408                 expect(children.length).toBe(2);
2409                 children.each(function(child, i){
2410                         expect(child.get('text')).toBe('HI!');
2411                         expect(child.parentNode.getAttribute('rel')).toBe('' + i);
2412                         expect(child.parentNode.get('text')).toBe('HI!content');
2413                 });
2414         });
2416         it('should insert element on inside (bottom)', function(){
2417                 base.appendHTML('<span>HI!</span>', 'inside');
2418                 baseFallBack.appendHTML('<span>HI!</span>', 'inside');
2420                 var children = check.getElements('span');
2422                 expect(children.length).toBe(2);
2423                 children.each(function(child, i){
2424                         expect(child.get('text')).toBe('HI!');
2425                         expect(child.parentNode.getAttribute('rel')).toBe('' + i);
2426                         expect(child.parentNode.get('text')).toBe('contentHI!');
2427                 });
2428         });
2432 describe('IFrame', function(){
2434         it('(async) should call onload', function(){
2435                 runs(function(){
2436                         this.onComplete = jasmine.createSpy('IFrame onComplete');
2438                         this.iframe = new IFrame({
2439                                 src: 'http://' + document.location.host + '/random',
2440                                 onload: this.onComplete
2441                         }).inject(document.body);
2442                 });
2444                 waitsFor(1000, function(){
2445                         return this.onComplete.wasCalled;
2446                 });
2448                 runs(function(){
2449                         this.iframe.destroy();
2450                 });
2451         });
2455 describe('new Element(expression)', function(){
2457         it('should create a new div element', function(){
2458                 var div = new Element('div');
2460                 expect(div.tagName.toLowerCase()).toEqual('div');
2461                 expect(!div.className && div.className.length == 0).toBeTruthy();
2462                 expect(!div.id && div.id.length == 0).toBeTruthy();
2463                 expect(typeOf(div)).toEqual('element');
2464         });
2466         it('should create a new element with id and class', function(){
2467                 var p = new Element('p', {
2468                         id: 'myParagraph',
2469                         'class': 'test className'
2470                 });
2472                 expect(p.tagName.toLowerCase()).toEqual('p');
2473                 expect(p.className).toEqual('test className');
2474         });
2476         it('should create a new element with id and class from css expression', function(){
2477                 var p = new Element('p#myParagraph.test.className');
2479                 expect(p.tagName.toLowerCase()).toEqual('p');
2480                 expect(p.className).toEqual('test className');
2481         });
2483         it('should create attributes from css expression', function(){
2484                 var input = new Element('input[type=text][readonly=true][value=Some Text]');
2486                 expect(input.tagName.toLowerCase()).toEqual('input');
2487                 expect(input.type).toEqual('text');
2488                 expect(input.readOnly).toEqual(true);
2489                 expect(input.value).toEqual('Some Text');
2490         });
2492         it('should overwrite ids and classes', function(){
2493                 var div = new Element('div#myDiv.myClass', {
2494                         id: 'myOverwrittenId',
2495                         'class': 'overwrittenClass'
2496                 });
2498                 expect(div.tagName.toLowerCase()).toEqual('div');
2499                 expect(div.id).toEqual('myOverwrittenId');
2500                 expect(div.className).toEqual('overwrittenClass');
2501         });
2503         it('should overwrite attributes', function(){
2504                 var a = new Element('a[href=http://dojotoolkit.org/]', {
2505                         href: 'http://mootools.net/'
2506                 });
2508                 expect(a.tagName.toLowerCase()).toEqual('a');
2509                 expect(a.href).toEqual('http://mootools.net/');
2510         });
2512         it('should reset attributes and classes with empty string', function(){
2513                 var div = new Element('div#myDiv.myClass', {
2514                         id: '',
2515                         'class': ''
2516                 });
2518                 expect(div.tagName.toLowerCase()).toEqual('div');
2519                 expect(div.id).toEqual('');
2520                 expect(div.className).toEqual('');
2521         });
2523         it('should not reset attributes and classes with null', function(){
2524                 var div = new Element('div#myDiv.myClass', {
2525                         id: null,
2526                         'class': null
2527                 });
2529                 expect(div.tagName.toLowerCase()).toEqual('div');
2530                 expect(div.id).toEqual('myDiv');
2531                 expect(div.className).toEqual('myClass');
2532         });
2534         it('should not reset attributes and classes with undefined', function(){
2535                 var div = new Element('div#myDiv.myClass', {
2536                         id: undefined,
2537                         'class': undefined
2538                 });
2540                 expect(div.tagName.toLowerCase()).toEqual('div');
2541                 expect(div.id).toEqual('myDiv');
2542                 expect(div.className).toEqual('myClass');
2543         });
2545         it('should fall back to a div tag', function(){
2546                 var someElement = new Element('#myId');
2548                 expect(someElement.tagName.toLowerCase()).toEqual('div');
2549                 expect(someElement.id).toEqual('myId');
2550         });
2552         it('should allow zero (0) values', function(){
2553                 var table = new Element('table[cellpadding=0]');
2555                 expect(table.tagName.toLowerCase()).toEqual('table');
2556                 expect(table.cellPadding == 0).toBeTruthy();
2557         });
2559         it('should allow empty boolean attributes', function(){
2560                 var script = new Element('script[async]');
2561                 expect(script.get('async')).toBeTruthy();
2562         });
2564         it('should allow false to be passed for checked', function(){
2565                 var input = new Element('input', {
2566                         type: 'checkbox',
2567                         checked: false
2568                 });
2570                 expect(input.checked).toEqual(false);
2571         });
2575 describe('Element', function(){
2577         describe('classList', function(){
2579                 it('should not fail for empty strings', function(){
2580                         var element = new Element('div');
2581                         element.addClass('');
2582                         expect(element.className).toEqual('');
2583                 });
2585                 it('should trim whitespaces', function(){
2586                         var element = new Element('div');
2587                         element.addClass(' bar ');
2588                         expect(element.className).toEqual('bar');
2589                 });
2591                 it('should add multiple classes', function(){
2592                         var element = new Element('div');
2593                         element.addClass(' bar foo');
2594                         expect(element.className).toEqual('bar foo');
2595                 });
2597                 it('should add multiple equal classes', function(){
2598                         var element = new Element('div');
2599                         element.addClass('bar bar ');
2600                         expect(element.className).toEqual('bar');
2601                 });
2603                 it('should add class with some newline', function(){
2604                         var element = new Element('div');
2605                         element.addClass('bar\nfoo');
2606                         expect(element.className).toEqual('bar foo');
2607                 });
2609         });
2612 describe('normalize value for new Element type == checkbox || radio', function(){
2614         it('value of new created checkbox should be "on" if none specified', function() {
2615                 var input = new Element('input', {
2616                         type: 'checkbox'
2617                 });
2618                 input.set('checked', true);
2619                 expect(input.get('value')).toEqual('on');
2620         });
2621         it('value of new created checkbox should be the specified in constructor', function() {
2622                 var input = new Element('input', {
2623                         type: 'checkbox',
2624                         value: 'someValue'
2625                 });
2626                 input.set('checked', true);
2627                 expect(input.get('value')).toEqual('someValue');
2628         });
2629         it('value of new created radio button should be "on" if none specified', function() {
2630                 var input = new Element('input', {
2631                         type: 'radio'
2632                 });
2633                 input.set('checked', true);
2634                 expect(input.get('value')).toEqual('on');
2635         });
2636         it('value of new created radio should be the specified in constructor', function() {
2637                 var input = new Element('input', {
2638                         type: 'radio',
2639                         value: 'someValue'
2640                 });
2641                 input.set('checked', true);
2642                 expect(input.get('value')).toEqual('someValue');
2643         });