Tests/Specs: Replace Chai with expect.js for assertions, because of browser support.
[mootools.git] / Specs / Element / Element.js
blob8455a312b69ea3857800f286222ca0118daa32e3
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)).to.equal('element');
14                 expect(element.getFirst).to.not.equal(undefined);
15                 expect(element.tagName.toLowerCase()).to.equal('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).to.equal('divID');
21                 expect(element.title).to.equal('divTitle');
22         });
24         it('should return an Element with for attribute', function(){
25                 var label = new Element('label', { 'for': 'myId' });
26                 expect(label.htmlFor).to.equal('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).to.equal('class');
34                 expect(div2.className).to.equal('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).to.equal('text');
41                 expect(username.name).to.equal('username');
42                 expect(username.value).to.equal('username');
44                 expect(password.type).to.equal('password');
45                 expect(password.name).to.equal('password');
46                 expect(password.value).to.equal('password');
48                 var dad = new Element('div');
49                 dad.adopt(username, password);
50                 dad.inject(document.body);
51                 expect(document.getElementsByName('username')[0]).to.equal(username);
52                 expect(document.getElementsByName('password')[0]).to.equal(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).to.equal('text');
60                         expect(input.name).to.equal(name);
61                         expect(input.value).to.equal(name);
62                         var dad = new Element('div');
63                         dad.adopt(input);
64                         dad.inject(document.body);
65                         expect(document.getElementsByName(name)[0]).to.equal(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')).to.match(/email|text/);
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).to.not.be.ok();
81                 expect(check2.checked).to.be.ok();
82                 expect(check3.checked).to.be.ok();
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).to.be.ok();
106                 expect(select2.multiple).to.be.ok();
108                 expect(select1.name).to.equal(select2.name);
109                 expect(select1.options.length).to.equal(select2.options.length);
110                 expect(select1.toQueryString()).to.equal(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).to.equal('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).to.be.ok();
126                 expect(input2.checked).to.be.ok();
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).to.equal('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).to.equal('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()).to.equal(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()).to.equal(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).to.equal(2);
155                 expect(select.options.length).to.equal(2);
156                 expect(select.selectedIndex).to.equal(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).to.equal(1);
163                 expect(table.getFirst().getFirst().getChildren().length).to.equal(2);
164                 expect(table.getFirst().getLast().getFirst().className).to.equal('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).to.equal(2);
171                 expect(tbody.getLast().getFirst().className).to.equal('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).to.equal(2);
178                 expect(tr.getFirst().className).to.equal('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()).to.equal(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).to.equal(2);
194                 expect(td.getFirst().className).to.equal('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).to.equal('23px');
201                 expect(div.style.fontSize).to.equal('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')).to.equal('some text content');
207                 expect(div.innerHTML).to.equal('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).to.equal('some_id');
213                 expect(div.title).to.equal('some_title');
214                 expect(div.innerHTML).to.equal('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).to.equal('text/javascript');
220                 expect(script.defer).to.be.ok();
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).to.be.ok();
227                 expect(table1.cellPadding == 3).to.be.ok();
228                 expect(table2.cellPadding == 3).to.be.ok();
229                 expect(table1.cellSpacing == 4).to.be.ok();
230                 expect(table2.cellSpacing == 4).to.be.ok();
231                 expect(table1.align).to.equal('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)).to.equal(true);
247         });
248         //</1.3compat>
250         it('should return an elements type', function(){
251                 expect(typeOf(myElements)).to.equal('elements');
252         });
254         it('should return an array of Elements', function(){
255                 expect(myElements.every(function(e){ return typeOf(e) == 'element'; })).to.equal(true);
256         });
258         it('should apply Element prototypes to the returned array', function(){
259                 expect(myElements.getFirst).to.not.equal(undefined);
260         });
262         it('should return all Elements that match the string matcher', function(){
263                 var filter = myElements.filter('div');
265                 expect(filter[0]).to.equal(myElements[0]);
266                 expect(filter[1]).to.equal(myElements[2]);
267                 expect(filter.length).to.equal(2);
268         });
270         it('should return all Elements that match the comparator', function(){
271                 var elements = myElements.filter(function(element){
272                         return element.match('a');
273                 });
274                 expect(elements[0]).to.equal(myElements[1]);
275                 expect(elements.length).to.equal(1);
276         });
280 describe('TextNode.constructor', function(){
282         it('should return a new textnode element', function(){
283                 var text = document.newTextNode('yo');
284                 expect(typeOf(text)).to.equal('textnode');
285         });
289 describe('IFrame constructor', function(){
291         it('should return a new IFrame', function(){
292                 var iFrame1 = document.createElement('iframe');
293                 var iFrame2 = new IFrame();
294                 expect(iFrame1.tagName).to.equal(iFrame2.tagName);
295         });
297         it('should return the same IFrame if passed', function(){
298                 var iFrame1 = document.createElement('iframe');
299                 var iFrame2 = new IFrame(iFrame1);
300                 expect(iFrame1).to.equal(iFrame2);
301         });
305 describe('$', function(){
307         beforeEach(function(){
308                 Container = document.createElement('div');
309                 Container.innerHTML = '<div id="dollar"></div>';
310                 document.body.appendChild(Container);
311         });
313         afterEach(function(){
314                 document.body.removeChild(Container);
315                 Container = null;
316         });
318         it('should return an extended Element by string id', function(){
319                 var dollar1 = document.getElementById('dollar');
320                 var dollar2 = $('dollar');
322                 expect(dollar1).to.equal(dollar2);
323                 expect(dollar1.getFirst).to.not.equal(undefined);
324         });
326         it('should return the window if passed', function(){
327                 var win = $(window);
328                 expect(win == window).to.equal(true);
329         });
331         it('should return the document if passed', function(){
332                 expect($(document)).to.equal(document);
333         });
335         it('should return null if string not found or type mismatch', function(){
336                 expect($(1)).to.equal(null);
337                 expect($('nonexistant')).to.equal(null);
338         });
342 describe('$$', function(){
344         beforeEach(function(){
345                 this.elements = [
346                         document.createElement('div'),
347                         document.createElement('h3'),
348                         document.createElement('h4')
349                 ];
350                 for (var i = 0, l = this.elements.length; i < l; ++i){
351                         document.body.appendChild(this.elements[i]);
352                 }
353         });
355         it('should return all Elements of a specific tag', function(){
356                 var divs1 = $$('div');
357                 var divs2 = new Elements(Array.from(document.getElementsByTagName('div')));
358                 expect(divs1).to.eql(divs2);
359         });
361         it('should return multiple Elements for each specific tag', function(){
362                 var uidOf = (typeof $uid != 'undefined') ? $uid : Slick.uidOf;
363                 var sortBy = function(a, b){
364                         a = uidOf(a); b = uidOf(b);
365                         return a > b ? 1 : -1;
366                 };
367                 var headers1 = $$('h3, h4').sort(sortBy);
368                 var headers2 = new Elements(Array.flatten([document.getElementsByTagName('h3'), document.getElementsByTagName('h4')])).sort(sortBy);
369                 expect(headers1).to.eql(headers2);
370         });
372         it('should return an empty array if not is found', function(){
373                 expect($$('not_found')).to.eql(new Elements([]));
374         });
376         afterEach(function(){
377                 for (var i = 0, l = this.elements.length; i < l; ++i){
378                         document.body.removeChild(this.elements[i]);
379                 }
380         });
384 describe('getDocument', function(){
386         it('should return the owner document for elements', function(){
387                 var doc = document.newElement('div').getDocument();
388                 expect(doc).to.equal(document);
389         });
391         it('should return the owned document for window', function(){
392                 var doc = window.getDocument();
393                 expect(doc).to.equal(document);
394         });
396         it('should return self for document', function(){
397                 var doc = document.getDocument();
398                 expect(doc).to.equal(document);
399         });
403 describe('getWindow', function(){
405         it('should return the owner window for elements', function(){
406                 var win = document.newElement('div').getWindow();
407                 expect(win).to.equal(window);
408         });
410         it('should return the owner window for document', function(){
411                 var win = document.getWindow();
412                 expect(win).to.equal(window);
413         });
415         it('should return self for window', function(){
416                 var win = window.getWindow();
417                 expect(win == window).to.equal(true);
418         });
422 describe('Element.getElement', function(){
424         beforeEach(function(){
425                 Container = new Element('div');
426                 Container.innerHTML = '<div id="first"></div><div id="second"></div><p></p><a></a>';
427         });
429         afterEach(function(){
430                 Container = null;
431         });
433         it('should return the first Element to match the tag, otherwise null', function(){
434                 var child = Container.getElement('div');
435                 expect(child.id).to.equal('first');
436                 expect(Container.getElement('iframe')).to.equal(null);
437         });
441 describe('Element.getElements', function(){
443         beforeEach(function(){
444                 Container = new Element('div');
445                 Container.innerHTML = '<div id="first"></div><div id="second"></div><p></p><a></a>';
446         });
448         afterEach(function(){
449                 Container = null;
450         });
452         it('should return all the elements that match the tag', function(){
453                 var children = Container.getElements('div');
454                 expect(children.length).to.equal(2);
455         });
457         it('should return all the elements that match the tags', function(){
458                 var children = Container.getElements('div,a');
459                 expect(children.length).to.equal(3);
460                 expect(children[2].tagName.toLowerCase()).to.equal('a');
461         });
465 describe('Document.getElement', function(){
467         it('should return the first Element to match the tag, otherwise null', function(){
468                 var div = document.getElement('div');
469                 var ndiv = document.getElementsByTagName('div')[0];
470                 expect(div).to.equal(ndiv);
472                 var notfound = document.getElement('canvas');
473                 expect(notfound).to.equal(null);
474         });
478 describe('Document.getElements', function(){
480         it('should return all the elements that match the tag', function(){
481                 var divs = document.getElements('div');
482                 var ndivs = new Elements(document.getElementsByTagName('div'));
483                 expect(divs).to.eql(ndivs);
484         });
486         it('should return all the elements that match the tags', function(){
487                 var headers = document.getElements('h3,h4');
488                 var headers2 = new Elements(Array.flatten([document.getElementsByTagName('h3'), document.getElementsByTagName('h4')]));
489                 expect(headers.length).to.equal(headers2.length);
490         });
494 describe('Element.getElementById', function(){
496         beforeEach(function(){
497                 Container = new Element('div');
498                 Container.innerHTML = '<div id="first"></div><div id="second"></div><p></p><a></a>';
499                 document.body.appendChild(Container);
500         });
502         afterEach(function(){
503                 document.body.removeChild(Container);
504                 Container = null;
505         });
507         it('should getElementById that matches the id, otherwise null', function(){
508                 expect(Container.getElementById('first')).to.equal(Container.childNodes[0]);
509                 expect(Container.getElementById('not_found')).to.equal(null);
510         });
514 describe('Element.get style', function(){
516         it("should return a CSS string representing the Element's styles", function(){
517                 var style = 'font-size:12px;color:rgb(255,255,255)';
518                 var myElement = new Element('div').set('style', style);
519                 expect(myElement.get('style').toLowerCase().replace(/\s/g, '').replace(/;$/, '')).to.match(/(font-size:12px;color:rgb\(255,255,255\))|(color:rgb\(255,255,255\);font-size:12px)/);
520                 //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.
521         });
525 describe('Element.get tag', function(){
527         it("should return the Element's tag", function(){
528                 var myElement = new Element('div');
529                 expect(myElement.get('tag')).to.equal('div');
530         });
534 describe('Element.get', function(){
536         it("should get an absolute href", function(){
537                 var link = new Element('a', {href: "http://google.com/"});
538                 expect(link.get('href')).to.equal("http://google.com/");
539         });
541         it("should get an absolute href to the same domain", function(){
542                 var link = new Element('a', {href: window.location.href});
543                 expect(link.get('href')).to.equal(window.location.href);
544         });
546         it("should get a relative href", function(){
547                 var link = new Element('a', {href: "../index.html"});
548                 expect(link.get('href')).to.equal("../index.html");
549         });
551         it("should get a host absolute href", function(){
552                 var link = new Element('a', {href: "/developers"});
553                 expect(link.get('href')).to.equal("/developers");
554         });
556         it("should return null when attribute is missing", function(){
557                 var link = new Element('a');
558                 expect(link.get('href')).to.equal(null);
559         });
563 describe('Element.erase', function(){
565         it("should erase an Element's property", function(){
566                 var myElement = new Element('a', {href: 'http://mootools.net/', title: 'mootools!'});
567                 expect(myElement.get('title')).to.equal('mootools!');
568                 expect(myElement.erase('title').get('title')).to.equal(null);
569         });
571         it("should erase an Element's style", function(){
572                 var myElement = new Element('div', {style: "color:rgb(255, 255, 255); font-size:12px;"});
573                 myElement.erase('style');
574                 expect(myElement.get('style')).to.equal('');
575         });
579 describe('Element.match', function(){
581         it('should return true if tag is not provided', function(){
582                 var element = new Element('div');
583                 expect(element.match()).to.equal(true);
584         });
586         it("should return true if the Element's tag matches", function(){
587                 var element = new Element('div');
588                 expect(element.match('div')).to.equal(true);
589         });
593 describe('Element.inject', function(){
595         beforeEach(function(){
596                 var html = [
597                         '<div id="first"></div>',
598                         '<div id="second">',
599                                 '<div id="first-child"></div>',
600                                 '<div id="second-child"></div>',
601                         '</div>'
602                 ].join('');
603                 Container = new Element('div', {style: 'position:absolute;top:0;left:0;visibility:hidden;', html: html});
604                 document.body.appendChild(Container);
606                 test = new Element('div', {id:'inject-test'});
607         });
609         afterEach(function(){
610                 document.body.removeChild(Container);
611                 Container.set('html', '');
612                 Container = null;
613                 test = null;
614         });
616         it('should inject the Element before an Element', function(){
617                 test.inject($('first'), 'before');
618                 expect(Container.childNodes[0]).to.equal(test);
620                 test.inject($('second-child'), 'before');
621                 expect(Container.childNodes[1].childNodes[1]).to.equal(test);
622         });
624         it('should inject the Element after an Element', function(){
625                 test.inject($('first'), 'after');
626                 expect(Container.childNodes[1]).to.equal(test);
628                 test.inject($('first-child'), 'after');
629                 expect(Container.childNodes[1].childNodes[1]).to.equal(test);
630         });
632         it('should inject the Element at bottom of an Element', function(){
633                 var first = $('first');
634                 test.inject(first, 'bottom');
635                 expect(first.childNodes[0]).to.equal(test);
637                 var second = $('second');
638                 test.inject(second, 'bottom');
639                 expect(second.childNodes[2]).to.equal(test);
641                 test.inject(Container, 'bottom');
642                 expect(Container.childNodes[2]).to.equal(test);
643         });
645         it('should inject the Element inside an Element', function(){
646                 var first = $('first');
647                 test.inject(first, 'inside');
648                 expect(first.childNodes[0]).to.equal(test);
650                 var second = $('second');
651                 test.inject(second, 'inside');
652                 expect(second.childNodes[2]).to.equal(test);
654                 test.inject(Container, 'inside');
655                 expect(Container.childNodes[2]).to.equal(test);
656         });
658         it('should inject the Element at the top of an Element', function(){
659                 test.inject(Container, 'top');
660                 expect(Container.childNodes[0]).to.equal(test);
662                 var second = $('second');
663                 test.inject(second, 'top');
664                 expect(second.childNodes[0]).to.equal(test);
665         });
667         it('should inject the Element in an Element', function(){
668                 var first = $('first');
669                 test.inject(first);
670                 expect(first.childNodes[0]).to.equal(test);
672                 var second = $('second');
673                 test.inject(second);
674                 expect(second.childNodes[2]).to.equal(test);
676                 test.inject(Container);
677                 expect(Container.childNodes[2]).to.equal(test);
678         });
682 describe('Element.replaces', function(){
684         it('should replace an Element with the Element', function(){
685                 var parent = new Element('div');
686                 var div = new Element('div', {id: 'original'}).inject(parent);
687                 var el = new Element('div', {id: 'replaced'});
688                 el.replaces(div);
689                 expect(parent.childNodes[0]).to.equal(el);
690         });
694 describe('Element.grab', function(){
696         beforeEach(function(){
697                 var html = [
698                         '<div id="first"></div>',
699                         '<div id="second">',
700                                 '<div id="first-child"></div>',
701                                 '<div id="second-child"></div>',
702                         '</div>'
703                 ].join('');
704                 Container = new Element('div', {style: 'position:absolute;top:0;left:0;visibility:hidden;', html: html}).inject(document.body);
706                 test = new Element('div', {id:'grab-test'});
707         });
709         afterEach(function(){
710                 document.body.removeChild(Container);
711                 Container.set('html', '');
712                 Container = null;
713                 test = null;
714         });
716         it('should grab the Element before this Element', function(){
717                 $('first').grab(test, 'before');
718                 expect(Container.childNodes[0]).to.equal(test);
720                 $('second-child').grab(test, 'before');
721                 expect(Container.childNodes[1].childNodes[1]).to.equal(test);
722         });
724         it('should grab the Element after this Element', function(){
725                 $('first').grab(test, 'after');
726                 expect(Container.childNodes[1]).to.equal(test);
728                 $('first-child').grab(test, 'after');
729                 expect(Container.childNodes[1].childNodes[1]).to.equal(test);
730         });
732         it('should grab the Element at the bottom of this Element', function(){
733                 var first = $('first');
734                 first.grab(test, 'bottom');
735                 expect(first.childNodes[0]).to.equal(test);
737                 var second = $('second');
738                 second.grab(test, 'bottom');
739                 expect(second.childNodes[2]).to.equal(test);
741                 Container.grab(test, 'bottom');
742                 expect(Container.childNodes[2]).to.equal(test);
743         });
745         it('should grab the Element inside this Element', function(){
746                 var first = $('first');
747                 first.grab(test, 'inside');
748                 expect(first.childNodes[0]).to.equal(test);
750                 var second = $('second');
751                 second.grab(test, 'inside');
752                 expect(second.childNodes[2]).to.equal(test);
754                 Container.grab(test, 'inside');
755                 expect(Container.childNodes[2]).to.equal(test);
756         });
758         it('should grab the Element at the top of this Element', function(){
759                 Container.grab(test, 'top');
760                 expect(Container.childNodes[0]).to.equal(test);
762                 var second = $('second');
763                 second.grab(test, 'top');
764                 expect(second.childNodes[0]).to.equal(test);
765         });
767         it('should grab an Element in the Element', function(){
768                 var first = $('first').grab(test);
769                 expect(first.childNodes[0]).to.equal(test);
771                 var second = $('second').grab(test);
772                 expect(second.childNodes[2]).to.equal(test);
774                 Container.grab(test);
775                 expect(Container.childNodes[2]).to.equal(test);
776         });
780 describe('Element.wraps', function(){
782         it('should replace and adopt the Element', function(){
783                 var div = new Element('div');
784                 var child = new Element('p').inject(div);
786                 var wrapper = new Element('div', {id: 'wrapper'}).wraps(div.childNodes[0]);
787                 expect(div.childNodes[0]).to.equal(wrapper);
788                 expect(wrapper.childNodes[0]).to.equal(child);
789         });
793 describe('Element.appendText', function(){
795         beforeEach(function(){
796                 Container = new Element('div', {style: 'position:absolute;top:0;left:0;visibility:hidden;'}).inject(document.body);
797                 var html = [
798                         '<div id="first"></div>',
799                         '<div id="second">',
800                                 '<div id="first-child"></div>',
801                                 '<div id="second-child"></div>',
802                         '</div>'
803                 ].join('');
804                 Container.set('html', html);
805         });
807         afterEach(function(){
808                 document.body.removeChild(Container);
809                 Container.set('html', '');
810                 Container = null;
811                 test = null;
812         });
814         it('should append a TextNode before this Element', function(){
815                 $('first').appendText('test', 'before');
816                 expect(Container.childNodes[0].nodeValue).to.equal('test');
818                 $('second-child').appendText('test', 'before');
819                 expect(Container.childNodes[2].childNodes[1].nodeValue).to.equal('test');
820         });
822         it('should append a TextNode the Element after this Element', function(){
823                 $('first').appendText('test', 'after');
824                 expect(Container.childNodes[1].nodeValue).to.equal('test');
826                 $('first-child').appendText('test', 'after');
827                 expect(Container.childNodes[2].childNodes[1].nodeValue).to.equal('test');
828         });
830         it('should append a TextNode the Element at the bottom of this Element', function(){
831                 var first = $('first');
832                 first.appendText('test', 'bottom');
833                 expect(first.childNodes[0].nodeValue).to.equal('test');
835                 var second = $('second');
836                 second.appendText('test', 'bottom');
837                 expect(second.childNodes[2].nodeValue).to.equal('test');
839                 Container.appendText('test', 'bottom');
840                 expect(Container.childNodes[2].nodeValue).to.equal('test');
841         });
843         it('should append a TextNode the Element inside this Element', function(){
844                 var first = $('first');
845                 first.appendText('test', 'inside');
846                 expect(first.childNodes[0].nodeValue).to.equal('test');
848                 var second = $('second');
849                 second.appendText('test', 'inside');
850                 expect(second.childNodes[2].nodeValue).to.equal('test');
852                 Container.appendText('test', 'inside');
853                 expect(Container.childNodes[2].nodeValue).to.equal('test');
854         });
856         it('should append a TextNode the Element at the top of this Element', function(){
857                 Container.appendText('test', 'top');
858                 expect(Container.childNodes[0].nodeValue).to.equal('test');
860                 var second = $('second');
861                 second.appendText('test', 'top');
862                 expect(second.childNodes[0].nodeValue).to.equal('test');
863         });
865         it('should append a TextNode an Element in the Element', function(){
866                 var first = $('first').appendText('test');
867                 expect(first.childNodes[0].nodeValue).to.equal('test');
869                 var second = $('second').appendText('test');
870                 expect(second.childNodes[2].nodeValue).to.equal('test');
872                 Container.appendText('test');
873                 expect(Container.childNodes[2].nodeValue).to.equal('test');
874         });
878 describe('Element.adopt', function(){
881         beforeEach(function(){
882                 Container = new Element('div').inject(document.body);
883                 Container.empty();
884         });
886         afterEach(function(){
887                 document.body.removeChild(Container);
888                 Container.set('html', '');
889                 Container = null;
890         });
892         it('should adopt an Element by its id', function(){
893                 var child = new Element('div', {id: 'adopt-me'});
894                 document.body.appendChild(child);
895                 Container.adopt('adopt-me');
896                 expect(Container.childNodes[0]).to.equal(child);
897         });
899         it('should adopt an Element', function(){
900                 var child = new Element('p');
901                 Container.adopt(child);
902                 expect(Container.childNodes[0]).to.equal(child);
903         });
905         it('should adopt any number of Elements or ids', function(){
906                 var children = [];
907                 (100).times(function(i){ children[i] = new Element('span', {id: 'child-' + i}); });
908                 Container.adopt(children);
909                 expect(Container.childNodes.length).to.equal(100);
910                 expect(Container.childNodes[10]).to.equal(children[10]);
911         });
915 describe('Element.dispose', function(){
917         it('should dispose the Element from the DOM', function(){
918                 var Container = new Element('div').inject(document.body);
920                 var child = new Element('div').inject(Container);
921                 child.dispose();
922                 expect(Container.childNodes.length).to.equal(0);
924                 document.body.removeChild(Container);
925                 Container.set('html', '');
926                 Container = null;
927         });
931 describe('Element.clone', function(){
933         beforeEach(function(){
934                 Container = new Element('div', {'id': 'outer', 'class': 'moo'});
935                 Container.innerHTML = '<span class="foo" id="inner1"><div class="movie" id="sixfeet">under</div></span><span id="inner2"></span>';
936         });
938         afterEach(function(){
939                 Container = null;
940         });
942         it('should return a clone', function(){
943                 var div = new Element('div');
944                 var clone = div.clone();
945                 expect(div).to.not.equal(clone);
946                 expect(typeOf(div)).to.equal('element');
947                 expect(typeOf(clone)).to.equal('element');
948         });
950         it('should remove id from clone and clone children by default', function(){
951                 var clone = Container.clone();
952                 expect(clone.getElementsByTagName('*').length).to.equal(3);
953                 expect(clone.className).to.equal('moo');
954                 expect(clone.id).to.equal('');
955                 expect(Container.id).to.equal('outer');
956         });
958         it('should remove all ids', function(){
959                 var clone = Container.clone(true);
960                 expect(clone.id).to.equal('');
961                 expect(clone.childNodes.length).to.equal(2);
962                 expect(clone.childNodes[0].id).to.equal('');
963                 expect(clone.childNodes[0].childNodes[0].id).to.equal('');
964                 expect(clone.childNodes[0].className).to.equal('foo');
965         });
967         it('should keep id if specified', function(){
968                 var clone = Container.clone(true, true);
969                 expect(clone.id).to.equal('outer');
970                 expect(clone.childNodes.length).to.equal(2);
971                 expect(clone.childNodes[0].id).to.equal('inner1');
972                 expect(clone.childNodes[0].childNodes[0].id).to.equal('sixfeet');
973                 expect(clone.childNodes[0].className).to.equal('foo');
974         });
976         it('should clone empty href attribute', function(){
977                 var clone = new Element('div', {
978                         html: '<a href="">empty anchor</a>'
979                 }).getFirst().clone();
981                 expect(clone.getAttribute('href', 2)).to.equal('');
982         });
984         it('should not clone Element Storage', function(){
985                 Container.store('drink', 'milk');
986                 var clone = Container.clone();
987                 expect(clone.retrieve('drink')).to.equal(null);
988                 expect(Container.retrieve('drink')).to.equal('milk');
989         });
991         //<1.2compat>
992         it('should clone child nodes and not copy their uid', function(){
993                 var cloned = Container.clone(true).getElements('*');
994                 var old = Container.getElements('*');
995                 expect(cloned.length).to.equal(3);
996                 expect(old.length).to.equal(3);
997                 expect($$(old, cloned).length).to.equal(6);
998         });
999         //</1.2compat>
1001         var dit = /*<1.2compat>*/xit || /*</1.2compat>*/it; // don't run unless no compat
1002         dit('should clone child nodes and not copy their uid', function(){
1003                 var cloned = Container.clone(true).getElements('*');
1004                 var old = Container.getElements('*');
1005                 expect(cloned.length).to.equal(3);
1006                 expect(old.length).to.equal(3);
1007                 expect(new Elements([old, cloned]).length).to.equal(2);
1008         });
1010         it('should clone a text input and retain value', function(){
1011                 var inputs = new Element('div', { 'html': '' +
1012                         '<input id="input1" type="text" value="Some Value" />' +
1013                         '<input id="input2" type="text" />'
1014                 }).getChildren();
1016                 var input1 = inputs[0].clone();
1017                 var input2 = inputs[1].clone(false, true);
1019                 expect(input1.id).to.not.be.ok();
1020                 expect(input2.id).to.equal('input2');
1021                 expect(input1.value).to.equal('Some Value');
1022                 expect(input2.value).to.equal('');
1023         });
1025         it('should clone a textarea and retain value', function(){
1026                 var textareas = new Element('div', { 'html': '' +
1027                         '<textarea id="textarea1"></textarea>' +
1028                         '<textarea id="textarea2">Some-Text-Here</textarea>'
1029                 }).getChildren();
1031                 var textarea1 = textareas[0].clone();
1032                 var textarea2 = textareas[1].clone(false, true);
1034                 expect(textarea1.id).to.not.be.ok();
1035                 expect(textarea2.id).to.equal('textarea2');
1036                 expect(textarea1.value).to.equal('');
1037                 expect(textarea2.value).to.equal('Some-Text-Here');
1038         });
1040         it('should clone a checkbox and retain checked state', function(){
1041                 var checks = new Element('div', { 'html': '' +
1042                         '<input id="check1" type="checkbox" />' +
1043                         '<input id="check2" type="checkbox" checked="checked" />'
1044                 }).getChildren();
1046                 var check1 = checks[0].clone();
1047                 var check2 = checks[1].clone(false, true);
1049                 expect(check1.id).to.not.be.ok();
1050                 expect(check2.id).to.equal('check2');
1051                 expect(check1.checked).to.not.be.ok();
1052                 expect(check2.checked).to.be.ok();
1053         });
1055         it('should clone a select and retain selected state', function(){
1056                 var selects = new Element('div', { 'html': '' +
1057                         '<select name="select" id="select1">' +
1058                                 '<option>--</option>' +
1059                                 '<option value="volvo">Volvo</option>' +
1060                                 '<option value="saab">Saab</option>' +
1061                                 '<option value="opel" selected="selected">Opel</option>' +
1062                                 '<option value="bmw">BMW</option>' +
1063                         '</select>' +
1064                         '<select name="select[]" id="select2" multiple="multiple">' +
1065                                 '<option>--</option>' +
1066                                 '<option value="volvo">Volvo</option>' +
1067                                 '<option value="saab">Saab</option>' +
1068                                 '<option value="opel" selected="selected">Opel</option>' +
1069                                 '<option value="bmw" selected="selected">BMW</option>' +
1070                         '</select>'
1071                 }).getChildren();
1073                 var select1 = selects[0].clone(true);
1074                 var select2 = selects[1].clone(true, true);
1076                 expect(select1.id).to.not.be.ok();
1077                 expect(select2.id).to.equal('select2');
1078                 expect(select1.selectedIndex).to.equal(3);
1079                 expect(select2.options[3].selected).to.be.ok();
1080                 expect(select2.options[4].selected).to.be.ok();
1081         });
1083         it('should clone custom attributes', function(){
1084                 var div = new Element('div');
1085                 div.setAttribute('foo', 'FOO');
1087                 expect(div.clone().getAttribute('foo')).to.equal('FOO');
1088         });
1092 describe('Element className methods', function(){
1094         it('should return true if the Element has the given class', function(){
1095                 var div = new Element('div', {'class': 'header bold\tunderline'});
1096                 expect(div.hasClass('header')).to.equal(true);
1097                 expect(div.hasClass('bold')).to.equal(true);
1098                 expect(div.hasClass('underline')).to.equal(true);
1099         });
1101         it('should return false if the element does not have the given class', function(){
1102                 var div = new Element('div', {'class': 'header bold'});
1103                 expect(div.hasClass('italics')).to.equal(false);
1104                 expect(div.hasClass('head')).to.equal(false);
1105         });
1107         it('should add the class to the Element', function(){
1108                 var div = new Element('div');
1109                 div.addClass('myclass');
1110                 expect(div.hasClass('myclass')).to.equal(true);
1111         });
1113         it('should append classes to the Element', function(){
1114                 var div = new Element('div', {'class': 'myclass'});
1115                 div.addClass('aclass');
1116                 expect(div.hasClass('aclass')).to.equal(true);
1117         });
1119         it('should remove the class in the Element', function(){
1120                 var div = new Element('div', {'class': 'myclass'});
1121                 div.removeClass('myclass');
1122                 expect(div.hasClass('myclass')).to.equal(false);
1123         });
1125         it('should only remove the specific class', function(){
1126                 var div = new Element('div', {'class': 'myclass aclass'});
1127                 div.removeClass('myclass');
1128                 expect(div.hasClass('myclass')).to.equal(false);
1129                 expect(div.hasClass('aclass')).to.equal(true);
1130         });
1132         it('should not remove any class if the class is not found', function(){
1133                 var div = new Element('div', {'class': 'myclass'});
1134                 div.removeClass('extra');
1135                 expect(div.hasClass('myclass')).to.equal(true);
1136         });
1138         it('should add the class if the Element does not have the class', function(){
1139                 var div = new Element('div');
1140                 div.toggleClass('myclass');
1141                 expect(div.hasClass('myclass')).to.equal(true);
1142         });
1144         it('should remove the class if the Element does have the class', function(){
1145                 var div = new Element('div', {'class': 'myclass'});
1146                 div.toggleClass('myclass');
1147                 expect(div.hasClass('myclass')).to.equal(false);
1148         });
1152 describe('Element.empty', function(){
1154         it('should remove all children', function(){
1155                 var children = [];
1156                 (5).times(function(i){ children[i] = new Element('p'); });
1157                 var div = new Element('div').adopt(children);
1158                 div.empty();
1159                 expect(div.get('html')).to.equal('');
1160         });
1164 describe('Element.destroy', function(){
1166         it('should obliterate the Element from the universe', function(){
1167                 var div = new Element('div', {id: 'destroy-test'}).inject(document.body);
1168                 var result = div.destroy();
1169                 expect(result).to.equal(null);
1170                 expect($('destroy-test')).to.equal(null);
1171         });
1175 describe('Element.toQueryString', function(){
1177         it('should return an empty string for an Element that does not have form Elements', function(){
1178                 var div = new Element('div');
1179                 expect(div.toQueryString()).to.equal('');
1180         });
1182         it('should ignore any form Elements that do not have a name, disabled, or whose value is false', function(){
1183                 var form = new Element('form').adopt(
1184                         new Element('input', { name: 'input', disabled: true, type: 'checkbox', checked: true, value: 'checked' }),
1185                         new Element('select').adopt(
1186                                 new Element('option', { name: 'volvo', value: false, html: 'Volvo' }),
1187                                 new Element('option', { value: 'saab', html: 'Saab', selected: true })
1188                         ),
1189                         new Element('textarea', { name: 'textarea', disabled: true, value: 'textarea-value' })
1190                 );
1191                 expect(form.toQueryString()).to.equal('');
1192         });
1194         it("should return a query string containing even empty values, multiple select may have no selected options", function(){
1195                 var form = new Element('form',{'html':
1196                         '<input type="checkbox" name="input" value="" checked="checked" />' +
1197                         '<select name="select[]" multiple="multiple" size="5">' +
1198                                 '<option name="none" value="">--</option>' +
1199                                 '<option name="volvo" value="volvo">Volvo</option>' +
1200                                 '<option name="saab" value="saab">Saab</option>' +
1201                                 '<option name="opel" value="opel">Opel</option>' +
1202                                 '<option name="bmw" value="bmw">BMW</option>' +
1203                         '</select>' +
1204                         '<textarea name="textarea"></textarea>'
1205                 });
1206                 expect(form.toQueryString()).to.equal('input=&textarea=');
1207         });
1209         it("should return a query string ignoring submit, reset and file form Elements", function(){
1210                 var form = new Element('form', { 'html': '' +
1211                         '<input type="checkbox" name="input" value="checked" checked="checked" />' +
1212                         '<input type="file" name="file" />' +
1213                         '<textarea name="textarea">textarea-value</textarea>' +
1214                         '<input type="submit" name="go" value="Go" />' +
1215                         '<input type="reset" name="cancel" value="Reset" />'
1216                 });
1217                 expect(form.toQueryString()).to.equal('input=checked&textarea=textarea-value');
1218         });
1222 describe('Element.getProperty', function(){
1224         it('should getProperty from an Element', function(){
1225                 var anchor1 = new Element('a');
1226                 anchor1.href = 'http://mootools.net';
1227                 expect(anchor1.getProperty('href')).to.equal('http://mootools.net');
1229                 var anchor2 = new Element('a');
1230                 anchor2.href = '#someLink';
1231                 expect(anchor2.getProperty('href')).to.equal('#someLink');
1232         });
1234         it('should getProperty type of an input Element', function(){
1235                 var input1 = new Element('input', {type: 'text'});
1236                 expect(input1.getProperty('type')).to.equal('text');
1238                 var input2 = new Element('input', {type: 'checkbox'});
1239                 expect(input2.getProperty('type')).to.equal('checkbox');
1241                 var div = new Element('div', {'html':
1242                         '<select name="test" id="test" multiple="multiple">' +
1243                                 '<option value="1">option-value</option>' +
1244                         '</select>'
1245                 });
1246                 var input3 = div.getElement('select');
1247                 expect(input3.getProperty('type')).to.equal('select-multiple');
1248                 expect(input3.getProperty('name')).to.equal('test');
1249         });
1251         it('should getPropety checked from an input Element', function(){
1252                 var checked1 = new Element('input', { type: 'checkbox' });
1253                 checked1.checked = 'checked';
1254                 expect(checked1.getProperty('checked')).to.be.ok();
1256                 var checked2 = new Element('input', { type: 'checkbox' });
1257                 checked2.checked = true;
1258                 expect(checked2.getProperty('checked')).to.be.ok();
1260                 var checked3 = new Element('input', { type: 'checkbox' });
1261                 checked3.checked = false;
1262                 expect(checked3.getProperty('checked')).to.not.be.ok();
1263         });
1265         it('should getProperty disabled from an input Element', function(){
1266                 var disabled1 = new Element('input', { type: 'text' });
1267                 disabled1.disabled = 'disabled';
1268                 expect(disabled1.getProperty('disabled')).to.be.ok();
1270                 var disabled2 = new Element('input', { type: 'text' });
1271                 disabled2.disabled = true;
1272                 expect(disabled2.getProperty('disabled')).to.be.ok();
1274                 var disabled3 = new Element('input', { type: 'text' });
1275                 disabled3.disabled = false;
1276                 expect(disabled3.getProperty('disabled')).to.not.be.ok();
1277         });
1279         it('should getProperty readonly from an input Element', function(){
1280                 var readonly1 = new Element('input', { type: 'text' });
1281                 readonly1.readOnly = 'readonly';
1282                 expect(readonly1.getProperty('readonly')).to.be.ok();
1284                 var readonly2 = new Element('input', { type: 'text' });
1285                 readonly2.readOnly = true;
1286                 expect(readonly2.getProperty('readonly')).to.be.ok();
1288                 var readonly3 = new Element('input', { type: 'text' });
1289                 readonly3.readOnly = false;
1290                 expect(readonly3.getProperty('readonly')).to.not.be.ok();
1291         });
1295 describe('Element.setProperty', function(){
1297         it('should setProperty from an Element', function(){
1298                 var anchor1 = new Element('a').setProperty('href', 'http://mootools.net/');
1299                 expect(anchor1.getProperty('href')).to.equal('http://mootools.net/');
1301                 var anchor2 = new Element('a').setProperty('href', '#someLink');
1302                 expect(anchor2.getProperty('href')).to.equal('#someLink');
1303         });
1305         it('should setProperty type of an input Element', function(){
1306                 var input1 = new Element('input').setProperty('type', 'text');
1307                 expect(input1.getProperty('type')).to.equal('text');
1309                 var input2 = new Element('input').setProperty('type', 'checkbox');
1310                 expect(input2.getProperty('type')).to.equal('checkbox');
1311         });
1313         it('should setProperty checked from an input Element', function(){
1314                 var checked1 = new Element('input', { type: 'checkbox' }).setProperty('checked', 'checked');
1315                 expect(checked1.getProperty('checked')).to.be.ok();
1317                 var checked2 = new Element('input', { type: 'checkbox' }).setProperty('checked', true);
1318                 expect(checked2.getProperty('checked')).to.be.ok();
1320                 var checked3 = new Element('input', { type: 'checkbox' }).setProperty('checked', false);
1321                 expect(checked3.getProperty('checked')).to.not.be.ok();
1322         });
1324         it('should setProperty disabled of an input Element', function(){
1325                 var disabled1 = new Element('input', { type: 'text' }).setProperty('disabled', 'disabled');
1326                 expect(disabled1.getProperty('disabled')).to.be.ok();
1328                 var disabled2 = new Element('input', { type: 'text' }).setProperty('disabled', true);
1329                 expect(disabled2.getProperty('disabled')).to.be.ok();
1331                 var disabled3 = new Element('input', { type: 'text' }).setProperty('disabled', false);
1332                 expect(disabled3.getProperty('disabled')).to.not.be.ok();
1333         });
1335         it('should setProperty readonly of an input Element', function(){
1336                 var readonly1 = new Element('input', { type: 'text' }).setProperty('readonly', 'readonly');
1337                 expect(readonly1.getProperty('readonly')).to.be.ok();
1339                 var readonly2 = new Element('input', { type: 'text' }).setProperty('readonly', true);
1340                 expect(readonly2.getProperty('readonly')).to.be.ok();
1342                 var readonly3 = new Element('input', { type: 'text' }).setProperty('readonly', false);
1343                 expect(readonly3.getProperty('readonly')).to.not.be.ok();
1344         });
1346         it('should setProperty defaultValue of an input Element', function(){
1347                 var form = new Element('form');
1348                 var defaultValue = new Element('input', {'type': 'text', 'value': '321'});
1349                 expect(defaultValue.getProperty('value')).to.equal('321');
1350                 defaultValue.setProperty('defaultValue', '123');
1351                 form.grab(defaultValue);
1352                 form.reset();
1353                 expect(defaultValue.getProperty('value')).to.equal('123');
1354         });
1358 describe('Element.getProperties', function(){
1360         it('should return an object associate with the properties passed', function(){
1361                 var readonly = new Element('input', { type: 'text', readonly: 'readonly' });
1362                 var props = readonly.getProperties('type', 'readonly');
1363                 expect(props).to.eql({ type: 'text', readonly: true });
1364         });
1368 describe('Element.setProperties', function(){
1370         it('should set each property to the Element', function(){
1371                 var readonly = new Element('input').setProperties({ type: 'text', readonly: 'readonly' });
1372                 var props = readonly.getProperties('type', 'readonly');
1373                 expect(props).to.eql({ type: 'text', readonly: true });
1374         });
1378 describe('Element.removeProperties', function(){
1380         it('should remove each property from the Element', function(){
1381                 var anchor = new Element('a', {href: '#', title: 'title', rel: 'left'});
1382                 anchor.removeProperties('title', 'rel');
1383                 expect(anchor.getProperties('href', 'title', 'rel')).to.eql({ href: '#', title: null, rel: null });
1384         });
1388 describe('Element.getPrevious', function(){
1390         it('should return the previous Element, otherwise null', function(){
1391                 var container = new Element('div');
1392                 var children = [new Element('div'), new Element('div'), new Element('div')];
1393                 container.adopt(children);
1394                 expect(children[1].getPrevious()).to.equal(children[0]);
1395                 expect(children[0].getPrevious()).to.equal(null);
1396         });
1398         it('should return the previous Element that matches, otherwise null', function(){
1399                 var container = new Element('div');
1400                 var children = [new Element('a'), new Element('div'), new Element('div'), new Element('div')];
1401                 container.adopt(children);
1402                 expect(children[1].getPrevious('a')).to.equal(children[0]);
1403                 expect(children[1].getPrevious('span')).to.equal(null);
1404         });
1408 describe('Element.getAllPrevious', function(){
1410         it('should return all the previous Elements, otherwise an empty array', function(){
1411                 var container = new Element('div');
1412                 var children = [new Element('div'), new Element('div'), new Element('div')];
1413                 container.adopt(children);
1414                 expect(children[2].getAllPrevious()).to.eql(new Elements([children[1], children[0]]));
1415                 expect(children[0].getAllPrevious()).to.eql(new Elements([]));
1416         });
1418         it('should return all the previous Elements that match, otherwise an empty array', function(){
1419                 var container = new Element('div');
1420                 var children = [new Element('a'), new Element('div'), new Element('a'), new Element('div')];
1421                 container.adopt(children);
1422                 expect(children[3].getAllPrevious('a')).to.eql(new Elements([children[2], children[0]]));
1423                 expect(children[1].getAllPrevious('span')).to.eql(new Elements([]));
1424         });
1428 describe('Element.getNext', function(){
1430         it('should return the next Element, otherwise null', function(){
1431                 var container = new Element('div');
1432                 var children = [new Element('div'), new Element('div'), new Element('div')];
1433                 container.adopt(children);
1434                 expect(children[1].getNext()).to.equal(children[2]);
1435                 expect(children[2].getNext()).to.equal(null);
1436         });
1438         it('should return the previous Element that matches, otherwise null', function(){
1439                 var container = new Element('div');
1440                 var children = [new Element('div'), new Element('div'), new Element('div'), new Element('a')];
1441                 container.adopt(children);
1442                 expect(children[1].getNext('a')).to.equal(children[3]);
1443                 expect(children[1].getNext('span')).to.equal(null);
1444         });
1448 describe('Element.getAllNext', function(){
1450         it('should return all the next Elements, otherwise an empty array', function(){
1451                 var container = new Element('div');
1452                 var children = [new Element('div'), new Element('div'), new Element('div')];
1453                 container.adopt(children);
1454                 expect(children[0].getAllNext()).to.eql(new Elements(children.slice(1)));
1455                 expect(children[2].getAllNext()).to.eql(new Elements([]));
1456         });
1458         it('should return all the next Elements that match, otherwise an empty array', function(){
1459                 var container = new Element('div');
1460                 var children = [new Element('div'), new Element('a'), new Element('div'), new Element('a')];
1461                 container.adopt(children);
1462                 expect(children[0].getAllNext('a')).to.eql(new Elements([children[1], children[3]]));
1463                 expect(children[0].getAllNext('span')).to.eql(new Elements([]));
1464         });
1468 describe('Element.getFirst', function(){
1470         it('should return the first Element in the Element, otherwise null', function(){
1471                 var container = new Element('div');
1472                 var children = [new Element('div'), new Element('a'), new Element('div')];
1473                 container.adopt(children);
1474                 expect(container.getFirst()).to.equal(children[0]);
1475                 expect(children[0].getFirst()).to.equal(null);
1476         });
1480 describe('Element.getLast', function(){
1482         it('should return the last Element in the Element, otherwise null', function(){
1483                 var container = new Element('div');
1484                 var children = [new Element('div'), new Element('a'), new Element('div')];
1485                 container.adopt(children);
1486                 expect(container.getLast()).to.equal(children[2]);
1487                 expect(children[0].getLast()).to.equal(null);
1488         });
1490         it('should return the last Element in the Element that matches, otherwise null', function(){
1491                 var container = new Element('div');
1492                 var children = [new Element('div'), new Element('a'), new Element('div'), new Element('a')];
1493                 container.adopt(children);
1494                 expect(container.getLast('a')).to.equal(children[3]);
1495                 expect(container.getLast('span')).to.equal(null);
1496         });
1500 describe('Element.getParent', function(){
1502         it('should return the parent of the Element, otherwise null', function(){
1503                 var container = new Element('p');
1504                 var children = [new Element('div'), new Element('div'), new Element('div')];
1505                 container.adopt(children);
1506                 expect(children[1].getParent()).to.equal(container);
1507                 expect(container.getParent()).to.equal(null);
1508         });
1510         it('should return the parent of the Element that matches, otherwise null', function(){
1511                 var container = new Element('p');
1512                 var children = [new Element('div'), new Element('div'), new Element('div')];
1513                 container.adopt(new Element('div').adopt(children));
1514                 expect(children[1].getParent('p')).to.equal(container);
1515                 expect(children[1].getParent('table')).to.equal(null);
1516         });
1520 describe('Element.getParents', function(){
1522         it('should return the parents of the Element, otherwise returns an empty array', function(){
1523                 var container = new Element('p');
1524                 var children = [new Element('div'), new Element('div'), new Element('div')];
1525                 container.adopt(new Element('div').adopt(new Element('div').adopt(children)));
1526                 expect(children[1].getParents()).to.eql(new Elements([container.getFirst().getFirst(), container.getFirst(), container]));
1527                 expect(container.getParents()).to.eql(new Elements([]));
1528         });
1530         it('should return the parents of the Element that match, otherwise returns an empty array', function(){
1531                 var container = new Element('p');
1532                 var children = [new Element('div'), new Element('div'), new Element('div')];
1533                 container.adopt(new Element('div').adopt(new Element('div').adopt(children)));
1534                 expect(children[1].getParents('div')).to.eql(new Elements([container.getFirst().getFirst(), container.getFirst()]));
1535                 expect(children[1].getParents('table')).to.eql(new Elements([]));
1536         });
1540 describe('Element.getChildren', function(){
1542         it("should return the Element's children, otherwise returns an empty array", function(){
1543                 var container = new Element('div');
1544                 var children = [new Element('div'), new Element('div'), new Element('div')];
1545                 container.adopt(children);
1546                 expect(container.getChildren()).to.eql(new Elements(children));
1547                 expect(children[0].getChildren()).to.eql(new Elements([]));
1548         });
1550         it("should return the Element's children that match, otherwise returns an empty array", function(){
1551                 var container = new Element('div');
1552                 var children = [new Element('div'), new Element('a'), new Element('a')];
1553                 container.adopt(children);
1554                 expect(container.getChildren('a')).to.eql(new Elements([children[1], children[2]]));
1555                 expect(container.getChildren('span')).to.eql(new Elements([]));
1556         });
1560 describe('Element.hasChild', function(){
1562         beforeEach(function(){
1563                 Local = {};
1564                 Local.container = new Element('div');
1565                 Local.children = [new Element('div'), new Element('div'), new Element('div')];
1566                 Local.container.adopt(Local.children);
1567                 Local.grandchild = new Element('div').inject(Local.children[1]);
1568         });
1570         afterEach(function(){
1571                 Local = null;
1572         });
1574         //<1.3compat>
1575         it("should return true if the Element is a child or grandchild", function(){
1576                 expect(Local.container.hasChild(Local.children[0])).to.equal(true);
1577                 expect(Local.container.hasChild(Local.children[2])).to.equal(true);
1578                 expect(Local.container.hasChild(Local.grandchild)).to.equal(true);
1579         });
1581         it("should return false if it's the Element itself", function(){
1582                 expect(Local.container.hasChild(Local.container)).to.equal(false);
1583         });
1585         it("should return false if the Element is the parent or a sibling", function(){
1586                 expect(Local.children[2].hasChild(Local.container)).to.equal(false);
1587                 expect(Local.children[2].hasChild(Local.children[1])).to.equal(false);
1588         });
1589         //</1.3compat>
1591         it("should return true if the Element is a child or grandchild", function(){
1592                 expect(Local.container.contains(Local.children[0])).to.equal(true);
1593                 expect(Local.container.contains(Local.children[2])).to.equal(true);
1594                 expect(Local.container.contains(Local.grandchild)).to.equal(true);
1595         });
1597         it("should return true if it's the Element itself", function(){
1598                 expect(Local.container.contains(Local.container)).to.equal(true);
1599         });
1601         it("should return false if the Element is the parent or a sibling", function(){
1602                 expect(Local.children[2].contains(Local.container)).to.equal(false);
1603                 expect(Local.children[2].contains(Local.children[1])).to.equal(false);
1604         });
1608 describe('Elements.extend', function(){
1610         //<1.2compat>
1611         it('should be able to extend a collection', function(){
1612                 var items = [
1613                         new Element('span'),
1614                         new Element('span'),
1615                         new Element('p'),
1616                         new Element('p')
1617                 ];
1618                 var container = new Element('div').adopt(items);
1620                 container.getElements('span').extend(container.getElements('p'));
1621                 expect($$(items)).to.eql(container.getElements('*'));
1622                 expect(items.length).to.equal(4);
1623         });
1624         //</1.2compat>
1626         it('should be able to append a collection', function(){
1627                 var items = [
1628                         new Element('span'),
1629                         new Element('span'),
1630                         new Element('p'),
1631                         new Element('p')
1632                 ];
1633                 var container = new Element('div').adopt(items);
1635                 container.getElements('span').append(container.getElements('p'));
1636                 expect(new Elements(items)).to.eql(container.getElements('*'));
1637                 expect(items.length).to.equal(4);
1638         });
1642 describe('document.id', function(){
1644         it('should find IDs with special characters', function(){
1645                 var element = new Element('div#id\\.part.class').inject(document.body);
1647                 var found = document.id('id.part');
1648                 expect(found).to.equal(element);
1649                 expect(found.id).to.equal('id.part');
1650                 expect(found.className).to.equal('class');
1652                 element.destroy();
1654                 element = new Element('div#id\\#part').inject(document.body);
1656                 found = document.id('id#part');
1657                 expect(found).to.equal(element);
1658                 expect(found.id).to.equal('id#part');
1659         });
1663 describe('Element.getElementById', function(){
1665         it('should find IDs with special characters', function(){
1666                 var inner = new Element('div#id\\.part');
1667                 var outer = new Element('div').adopt(inner);
1669                 expect(outer.getElementById('id.part')).to.equal(inner);
1670                 expect(inner.id).to.equal('id.part');
1671         });
1675 describe('Element.removeProperty', function(){
1677         it('should removeProperty from an Element', function (){
1678                 var readonly = new Element('input', { type: 'text', readonly: 'readonly', maxlength: 10 });
1679                 readonly.removeProperty('readonly');
1680                 readonly.removeProperty('maxlength');
1681                 var props = readonly.getProperties('type', 'readonly');
1682                 expect(props).to.eql({type: 'text', readonly: false});
1684                 var maxlength = readonly.getProperty('maxlength');
1685                 expect(!maxlength || maxlength == 2147483647).to.be.ok(); // ie6/7 Bug
1686         });
1690 describe('Element.toQueryString', function(){
1692         it("should return a query string from the Element's form Elements", function(){
1693                 var form = new Element('form', { 'html': '' +
1694                         '<input type="checkbox" name="input" value="checked" checked="checked" />' +
1695                         '<select name="select[]" multiple="multiple" size="5">' +
1696                                 '<option name="none" value="">--</option>' +
1697                                 '<option name="volvo" value="volvo">Volvo</option>' +
1698                                 '<option name="saab" value="saab" selected="selected">Saab</option>' +
1699                                 '<option name="opel" value="opel" selected="selected">Opel</option>' +
1700                                 '<option name="bmw" value="bmw">BMW</option>' +
1701                         '</select>' +
1702                         '<textarea name="textarea">textarea-value</textarea>'
1703                 });
1704                 expect(form.toQueryString()).to.equal('input=checked&select%5B%5D=saab&select%5B%5D=opel&textarea=textarea-value');
1705         });
1707         it("should return a query string containing even empty values, single select must have a selected option", function(){
1708                 var form = new Element('form').adopt(
1709                         new Element('input', {name: 'input', type: 'checkbox', checked: true, value: ''}),
1710                         new Element('select', {name: 'select[]'}).adopt(
1711                                 new Element('option', {name: 'none', value: '', html: '--', selected: true}),
1712                                 new Element('option', {name: 'volvo', value: 'volvo', html: 'Volvo'}),
1713                                 new Element('option', {name: 'saab', value: 'saab', html: 'Saab'}),
1714                                 new Element('option', {name: 'opel', value: 'opel', html: 'Opel'}),
1715                                 new Element('option', {name: 'bmw', value: 'bmw', html: 'BMW'})
1716                         ),
1717                         new Element('textarea', {name: 'textarea', value: ''})
1718                 );
1719                 expect(form.toQueryString()).to.equal('input=&select%5B%5D=&textarea=');
1720                 expect(form.getElementsByTagName('select')[0].selectedIndex).to.equal(0);
1721         });
1725 describe('Element.clone', function(){
1727         it('should clone children of object elements', function(){
1728                 var div = new Element('div').set('html', '<div id="swfobject-video" class="video">' +
1729                         '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="425" height="344">' +
1730                                 '<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" />' +
1731                                 '<param name="wmode" value="opaque" />' +
1732                                 '<param name="quality" value="high" />' +
1733                                 '<param name="bgcolor" value="#000616" />' +
1734                                 '<param name="allowFullScreen" value="true" />' +
1735                                 '<!--[if !IE]>-->' +
1736                                 '<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">' +
1737                                 '<param name="wmode" value="opaque" />' +
1738                                 '<param name="quality" value="high" />' +
1739                                 '<param name="bgcolor" value="#000616" />' +
1740                                 '<param name="allowFullScreen" value="true" />' +
1741                                 '<!--<![endif]-->' +
1742                                 '<p class="flash-required">Flash is required to view this video.</p>' +
1743                                 '<!--[if !IE]>-->' +
1744                                 '</object>' +
1745                                 '<!--<![endif]-->' +
1746                         '</object>' +
1747                 '</div>');
1749                 expect(div.clone().getElementsByTagName('param').length).to.be.greaterThan(0);
1751                 div = new Element('div').set('html', '<div id="ie-video" class="video">' +
1752                         '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="425" height="344">' +
1753                                 '<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" />' +
1754                                 '<param name="wmode" value="opaque" />' +
1755                                 '<param name="quality" value="high" />' +
1756                                 '<param name="bgcolor" value="#000616" />' +
1757                                 '<param name="allowFullScreen" value="true" />' +
1758                         '</object>' +
1759                 '</div>');
1761                 expect(div.clone().getElementsByTagName('param').length).to.be.greaterThan(0);
1762         });
1764         it('should set the ID of the cloned element and then fetch it with document.id', function(){
1765                 var cloneMe = new Element('div', {id: 'cloneMe', text: 'cloneMe'}).inject(document.body);
1766                 var cloned = $('cloneMe').clone();
1767                 expect(cloned.get('id')).to.equal(null);
1768                 cloned.set('id', 'sauce').inject(cloneMe.parentNode);
1769                 expect(cloned.get('id')).to.equal('sauce');
1770                 var sauceHTML = new Element('div').adopt($('sauce')).get('html');
1771                 var cloneHTML = new Element('div').adopt(cloned).get('html');
1772                 expect(sauceHTML).to.equal(cloneHTML);
1773                 cloneMe.destroy();
1774                 cloned.destroy();
1775         });
1779 describe('Elements implement order', function(){
1781         it('should give precedence to Array over Element', function(){
1782                 var anchor = new Element('a');
1784                 var element = new Element('div').adopt(
1785                         new Element('span'),
1786                         anchor
1787                 );
1789                 expect(element.getLast()).to.equal(anchor);
1791                 expect(new Elements([element, anchor]).getLast()).to.equal(anchor);
1792         });
1796 describe('Element traversal', function(){
1798         it('should match against all provided selectors', function(){
1799                 var div = new Element('div').adopt(
1800                         new Element('span').adopt(
1801                                 new Element('a')
1802                         )
1803                 );
1805                 var span = div.getElement('span');
1806                 var anchor = span.getElement('a');
1808                 expect(anchor.getParent('div, span')).to.equal(div);
1809                 expect(anchor.getParent('span, div')).to.equal(span);
1811                 expect(anchor.getParent('tagname, div')).to.equal(div);
1812                 expect(anchor.getParent('div > span')).to.equal(span);
1813         });
1817 describe('Elements.prototype.erase', function(){
1819         var element = new Element('div', {
1820                 html: '<div></div><p></p><span></span>'
1821         });
1823         var original = element.getChildren();
1824         var altered = element.getChildren().erase(original[1]);
1826         it('should decrease the length of the collection', function(){
1827                 expect(altered.length).to.equal(2);
1828         });
1830         it('should remove an element from the collection', function(){
1831                 expect(altered[1]).to.equal(original[2]);
1832         });
1834         it('should remove the last element from the collection', function(){
1835                 expect(altered[2]).to.equal(undefined);
1836         });
1840 describe('Element.set("html")', function(){
1842         it("should set the html of a tr Element, even when it has no parentNode", function(){
1843                 var html = '<td class="cell c">cell 1</td><td>cell 2</td>';
1844                 var tr = new Element('tr');
1845                 expect(tr.parentNode).to.equal(null);
1846                 // In IE using appendChild like in set('html') sets the parentNode to a documentFragment
1847                 tr.set('html', html).inject(new Element('tbody').inject(new Element('table')));
1848                 expect(tr.get('html').toLowerCase().replace(/>\s+</, '><')).to.equal(html);
1849                 expect(tr.getChildren().length).to.equal(2);
1850                 expect(tr.getFirst().className).to.equal('cell c');
1851         });
1853         it("should set the html of a style Element", function(){
1855                 var styleElement = document.createElement('style');
1856                 var def = 'body {color: red;}';
1857                 styleElement.setAttribute("type", "text/css");
1858                 var docHead = document.getElementsByTagName('head')[0];
1859                 docHead.appendChild(styleElement);
1860                 if (styleElement.styleSheet){       // IE
1861                         styleElement.styleSheet.cssText = def;
1862                 } else {                             // the world
1863                         var node = document.createTextNode(def);
1864                         styleElement.appendChild(node);
1865                 }
1867                 styleElement = $(styleElement),
1868                         innerStyleA = '* { color: #a0a}',
1869                         innerStyleB = '.testStyling { font: 44px/44px Courier}';
1871                 function fixString(s){
1872                         // because browsers return content with different case/space formatting
1873                         return s.toLowerCase().replace(/\t|\s/g,'');
1874                 }
1875                 function getStyles(){
1876                         return fixString(styleElement.get('html'));
1877                 }
1879                 styleElement.set('html', innerStyleA);
1880                 expect(getStyles()).to.equal(fixString(innerStyleA));
1882                 styleElement.erase('html');
1883                 expect(getStyles()).to.equal('');
1885                 styleElement.set('html', innerStyleB);
1886                 expect(getStyles()).to.equal(fixString(innerStyleB));
1887                 styleElement.destroy();
1888         });
1890         it('should set the text of a style Element', function(){
1891                 
1892                 var docHead = $(document.head);
1893                 var styleElement = new Element('style', {type: 'text/css'}).inject(docHead);
1894                 var definition = [
1895                         '.pos-abs-left {',
1896                                 'position: absolute;',
1897                                 'width: 200px;',
1898                                 'height: 200px;',
1899                                 'left: 10%;',
1900                                 'background: red;',
1901                         '}'
1902                 ].join('');
1903                 styleElement.set('text', definition);
1904                 var returned = styleElement.get('text').toLowerCase();
1905                 expect(returned.indexOf('position: absolute')).to.not.equal(-1);
1906                 expect(returned.indexOf('width: 200px')).to.not.equal(-1);
1907                 expect(returned.indexOf('height: 200px')).to.not.equal(-1);
1908                 expect(returned.indexOf('left: 10%')).to.not.equal(-1);
1909                 expect(returned.indexOf('background: red')).to.not.equal(-1);
1910                 styleElement.destroy();
1911         });
1915 describe('Elements.empty', function(){
1917         it('should empty the Elements collection', function(){
1918                 var list = $$('div').empty();
1920                 expect(list.length).to.equal(0);
1921                 expect(list[0]).to.equal(undefined);
1922         });
1926 describe('Elements.append', function(){
1928         it('should append 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 appended = list.append(p);
1941                 expect(appended).to.equal(list);
1942                 expect(appended).to.eql(new Elements([list[0], list[1], p[0], p[1]]));
1943         });
1947 describe('Elements.concat', function(){
1949         it('should concat an Elements collection', function(){
1950                 var list = new Element('div').adopt(
1951                         new Element('div'),
1952                         new Element('div')
1953                 ).getChildren();
1955                 var p = new Element('div').adopt(
1956                         new Element('p'),
1957                         new Element('p')
1958                 ).getChildren();
1960                 var concatenated = list.concat(p[0], p[1]);
1962                 expect(concatenated).to.not.equal(list);
1963                 expect(concatenated).to.eql(new Elements([list[0], list[1], p[0], p[1]]));
1965                 expect(typeOf(concatenated)).to.equal('elements');
1966         });
1970 describe('Element.getElement', function(){
1972         it('should return null', function(){
1973                 var div = new Element('div'),
1974                         a = new Element('a'),
1975                         span = new Element('span'),
1976                         p = new Element('span');
1978                 p.adopt(span, a);
1979                 div.adopt(p);
1981                 var element = div.getElement();
1982                 expect(element).to.equal(null);
1983         });
1987 describe('Element.getElements', function(){
1989         it('should return an empty collection', function(){
1990                 var div = new Element('div'),
1991                         a = new Element('a'),
1992                         span = new Element('span'),
1993                         p = new Element('span');
1995                 p.adopt(span, a);
1996                 div.adopt(p);
1998                 var elements = div.getElements();
1999                 expect(elements.length).to.equal(0);
2000         });
2002         it('should return an empty collection if called on document.body', function(){
2003                 expect($(document.body).getElements()).to.eql(new Elements);
2004         });
2008 describe('Element.getFirst', function(){
2010         it('should return last the first element only if it matches the expression', function(){
2011                 var container = new Element('div');
2012                 var children = [new Element('div').adopt(new Element('a')), new Element('a'), new Element('div')];
2013                 container.adopt(children);
2014                 expect(container.getFirst('div')).to.equal(children[0]);
2015                 expect(container.getFirst('a')).to.equal(children[1]);
2016                 expect(container.getFirst('span')).to.equal(null);
2017         });
2020 describe('Element.getLast', function(){
2022         it('should return the last element only if it matches the expression', function(){
2023                 var container = new Element('div');
2024                 var children = [new Element('div').adopt(new Element('a')), new Element('a'), new Element('div')];
2025                 container.adopt(children);
2026                 expect(container.getLast('div')).to.equal(children[2]);
2027                 expect(container.getLast('a')).to.equal(children[1]);
2028                 expect(container.getLast('span')).to.equal(null);
2029         });
2032 describe('Elements.unshift', function(){
2034         it('should not allow to unshift any value', function(){
2035                 var container = new Element('div').adopt(
2036                         new Element('span'),
2037                         new Element('p')
2038                 );
2040                 var collection = container.getElements('*'),
2041                         length = collection.length;
2042                 collection.unshift('someRandomValue');
2044                 expect(collection.length).to.equal(length);
2046                 collection.unshift(new Element('p'), new Element('span'));
2047                 expect(collection.length).to.equal(length + 2);
2048                 expect(collection.filter('p').length).to.equal(2);
2049                 expect(collection.filter('span').length).to.equal(2);
2050         });
2054 describe('Element.getProperty', function(){
2056         it('should get the attrubte of a form when the form has an input with as ID the attribute name', function(){
2057                 var div = new Element('div');
2058                 div.innerHTML = '<form action="s"><input id="action"></form>';
2059                 expect($(div.firstChild).getProperty('action')).to.equal('s');
2060         });
2062         it('should ignore expandos', function(){
2063                 var div = new Element('div');
2064                 expect(div.getProperty('inject')).to.equal(null);
2065         });
2067         it('should work in collaboration with setProperty', function(){
2068                 var div = new Element('div', {random: 'attribute'});
2069                 expect(div.getProperty('random')).to.equal('attribute');
2070         });
2072         it('should get custom attributes in html', function(){
2073                 var div = new Element('div', {html: '<div data-load="typical"></div>'}).getFirst();
2074                 expect(div.get('data-load')).to.equal('typical');
2076                 div = new Element('div', {html: '<div data-custom></div>'}).getFirst();
2077                 expect(div.get('data-custom')).to.equal('');
2079                 div = new Element('div', {html: '<div data-custom="nested"><a data-custom="other"></a></div>'}).getFirst();
2080                 expect(div.get('data-custom')).to.equal('nested');
2082                 div = new Element('div', {html: '<div><a data-custom="other"></a></div>'}).getFirst();
2083                 expect(div.get('data-custom')).to.equal(null);
2085                 div = new Element('div', {html: '<a data-custom="singular" href="#">href</a>'}).getFirst();
2086                 expect(div.get('data-custom')).to.equal('singular');
2088                 div = new Element('div', {html: '<div class="><" data-custom="evil attribute values"></div>'}).getFirst();
2089                 expect(div.get('data-custom')).to.equal('evil attribute values');
2091                 div = new Element('div', {html: '<div class="> . <" data-custom="aggrevated evil attribute values"></div>'}).getFirst();
2092                 expect(div.get('data-custom')).to.equal('aggrevated evil attribute values');
2094                 div = new Element('div', {html: '<a href="#"> data-custom="singular"</a>'}).getFirst();
2095                 expect(div.get('data-custom')).to.equal(null);
2096         });
2100 describe('Element.set', function(){
2102         describe('value', function(){
2104                 it('should return `null` when the value of a input element is set to `undefined`', function(){
2105                         var value;
2106                         expect(new Element('input', {value: value}).get('value')).to.equal('');
2107                 });
2109                 it('should set a falsey value and not an empty string', function(){
2110                         expect(new Element('input', {value: false}).get('value')).to.equal('false');
2111                         expect(new Element('input', {value: 0}).get('value')).to.equal('0');
2112                 });
2114                 it('should set the selected option for a select element to matching string w/o falsy matches', function(){
2115                         var form = new Element('form');
2116                         form.set('html', '<select>\
2117                                 <option value="">no value</option>\
2118                                 <option value="0">value 0</option>\
2119                                 <option value="1">value 1</option>\
2120                                 </select>');
2121                         expect(form.getElement('select').set('value', 0).get('value')).to.equal('0');
2122                 });
2124         });
2126         describe('type', function(){
2128                 it('should set the type of a button', function(){
2129                         expect(new Element('button', {type: 'button'}).get('type')).to.equal('button');
2130                 });
2132         });
2134         describe('value as object with toString()', function(){
2136                 it('should call the toString() method of a passed object', function(){
2137                         var a = new Element('a').set('href', {toString: function(){ return '1'; }});
2138                         expect(a.get('href')).to.equal('1');
2139                 });
2141         });
2145 describe("Element.setProperty('type')", function(){
2147         it('should keep the input value after setting a input field to another type (submit button)', function(){
2148                 var input = new Element('input', {value: 'myValue', type: 'text'});
2149                 input.setProperty('type', 'submit');
2150                 expect(input.getProperty('value')).to.equal('myValue');
2151         });
2153         it('should set the right type and value of input fields when a input field is created with CSS selectors', function(){
2154                 var input = new Element('input[type="submit"]', {value: 'myValue'});
2155                 expect(input.getProperty('value')).to.equal('myValue');
2156         });
2160 describe('Element.get', function(){
2162         describe('value', function(){
2164                 it('should get the value of a option element when it does not have the value attribute', function(){
2165                         var select = new Element('select').set('html', '<option>s</option>');
2166                         expect(select.getElement('option').get('value')).to.equal('s');
2167                 });
2169                 it('should return the text of the selected option for a select element', function(){
2170                         var form = new Element('form');
2171                         form.set('html', '<select>\
2172                                 <option>value 1</option>\
2173                                 <option>value 2</option>\
2174                                 <option selected>value 3</option>\
2175                                 <option>value 4</option>\
2176                                 </select>');
2177                         expect(form.getElement('select').get('value')).to.equal('value 3');
2178                 });
2180                 it('should return the text of the selected option for a multiple select element', function(){
2181                         var form = new Element('form');
2182                         form.set('html', '<select multiple>\
2183                                 <option>value 1</option>\
2184                                 <option selected>value 2</option>\
2185                                 <option selected>value 3</option>\
2186                                 <option>value 4</option>\
2187                                 </select>');
2188                         expect(form.getElement('select').get('value')).to.equal('value 2');
2189                 });
2191                 it('should return the text of the first option of aselect element', function(){
2192                         var form = new Element('form');
2193                         form.set('html', '<select>\
2194                                 <option>value 1</option>\
2195                                 <option>value 2</option>\
2196                                 </select>');
2197                         expect(form.getElement('select').get('value')).to.equal('value 1');
2198                 });
2200                 it('should return value of a select element', function(){
2201                         var form = new Element('form');
2202                         form.set('html', '<select multiple>\
2203                                 <option value="one">value 1</option>\
2204                                 <option selected value="two">value 2</option>\
2205                                 </select>');
2206                         expect(form.getElement('select').get('value')).to.equal('two');
2207                 });
2209         });
2211         describe('text', function(){
2213                 it('should return the original text with `text-transform: uppercase`', function(){
2214                         var div = new Element('div', {html: '<div style="text-transform: uppercase">text</div>'});
2215                         div.inject(document.body);
2216                         expect($(div.firstChild).get('text')).to.equal('text');
2217                         div.destroy();
2218                 });
2220         });
2224 describe('tabIndex', function(){
2226         it('should get and set the correct tabIndex', function(){
2227                 var div = document.createElement('div');
2228                 div.innerHTML = '<input tabindex="2">';
2229                 expect($(div.firstChild).get('tabindex')).to.equal(2);
2230                 expect($(div.firstChild).set('tabindex', 3).get('tabindex')).to.equal(3);
2231         });
2235 if (document.createElement('video').canPlayType){
2236         describe('Video/Audio loop, controls, and autoplay set/get attributes', function(){
2238                 it('should set/get the boolean value of loop, controls, and autoplay', function(){
2239                         try{
2240                                 var div = new Element('div', {html: '<video loop controls autoplay>'}),
2241                                         video = div.getElement('video');
2243                                 if ('loop' in video){
2244                                         expect(video.getProperty('loop')).to.equal(true);
2245                                         expect(video.setProperty('loop', false).getProperty('loop')).to.equal(false);
2246                                 }
2247                                 expect(video.getProperty('controls')).to.equal(true);
2248                                 expect(video.setProperty('controls', false).getProperty('controls')).to.equal(false);
2249                                 expect(video.getProperty('autoplay')).to.equal(true);
2250                                 expect(video.setProperty('autoplay', false).getProperty('autoplay')).to.equal(false);
2251                         }catch(O_o){
2252                                 if(O_o.message.indexOf('Not implemented') == -1){
2253                                         expect(O_o.message + " : "+O_o).to.equal('')
2254                                 }
2255                         }
2256         });
2258         });
2261 describe("Element.set('html')", function(){
2263         describe('HTML5 tags', function(){
2265                 it('should create childNodes for html5 tags', function(){
2266                         expect(new Element('div', {html: '<nav>Muu</nav><p>Tuuls</p><section>!</section>'}).childNodes.length).to.equal(3);
2267                 });
2269         });
2271         describe('Numbers', function(){
2273                 it('should set a number (so no string) as html', function(){
2274                         expect(new Element('div', {html: 20}).innerHTML).to.equal('20');
2275                 });
2277         });
2279         describe('Arrays', function(){
2281                 it('should allow an Array as input, the text is concatenated', function(){
2282                         expect(new Element('div', {html: ['moo', 'rocks', 'your', 'socks', 1]}).innerHTML).to.equal('moorocksyoursocks1');
2283                 });
2285         });
2289 describe("Element.erase('html')", function(){
2291         it('should empty the html inside an element', function(){
2292                 expect(new Element('div', {html: '<p>foo bar</p>'}).erase('html').innerHTML).to.equal('');
2293         });
2297 describe('Element.clone', function(){
2299         it('should not crash IE for multiple clones', function(){
2300                 new Element('div', {
2301                         html: '<ul id="testContainer"><li id="template"></li></ul>'
2302                 }).inject(document.body);
2304                 var container = $('testContainer'),
2305                 template = container.getElement('li#template').dispose();
2307                 template.clone().set('html', 'Clone #1').inject('testContainer');
2308                 template.clone().set('html', 'Clone #2').inject('testContainer');
2310                 container.destroy();
2311         });
2315 describe('Element.erase', function(){
2317         var elements, subject, image, textarea;
2319         beforeEach(function(){
2320                 elements = [
2321                         subject = new Element('div'),
2322                         image = new Element('img'),
2323                         textarea = new Element('div', {html: '<textarea id="t1">hello</textarea>'}).getFirst()
2324                 ].invoke('inject', document.body);
2325         });
2327         afterEach(function(){
2328                 elements.invoke('destroy');
2329         });
2331         it('should erase the class of an Element', function(){
2332                 subject.set('class', 'test');
2333                 subject.erase('class');
2334                 expect(subject.get('class')).to.equal(null);
2335         });
2337         it('should erase the id of an Element', function(){
2338                 subject.set('id', 'test');
2339                 subject.erase('id');
2340                 expect(subject.get('id')).to.equal(null);
2341         });
2343         it('should erase the random attribute of an Element', function(){
2344                 subject.set('random', 'test');
2345                 subject.erase('random');
2346                 expect(subject.get('random')).to.equal(null);
2347         });
2349         it('should erase the value attribute of a textarea', function(){
2350                 textarea.erase('value');
2351                 expect(textarea.get('value')).to.equal('');
2352         });
2356 describe('Element.appendHTML', function(){
2358         var check, base, baseFallBack;
2360         beforeEach(function(){
2361                 check = new Element('span', {
2362                         html: '<div>content</div><div>content</div>',
2363                         styles: {
2364                                 display: 'none'
2365                         }
2366                 });
2368                 check.inject(document.documentElement);
2369                 base = $(check.getChildren()[0]);
2370                 baseFallBack = $(check.getChildren()[1]);
2372                 base.set('rel', '0');
2373                 baseFallBack.set('rel', '1');
2374         });
2376         afterEach(function(){
2377                 baseFallBack = baseFallBack.destroy();
2378                 base = base.destroy();
2379                 check = check.destroy();
2380         });
2382         it('should insert element before', function(){
2384                 base.appendHTML('<span>HI!</span>', 'before');
2385                 baseFallBack.appendHTML('<span>HI!</span>', 'before');
2387                 var children = check.getElements('span');
2389                 expect(children.length).to.equal(2);
2390                 children.each(function(child, i){
2391                         expect(child.get('text')).to.equal('HI!');
2392                         expect(child.nextSibling.getAttribute('rel')).to.equal('' + i);
2393                 });
2394         });
2396         it('should insert element after', function(){
2397                 base.appendHTML('<span>HI!</span>', 'after');
2398                 baseFallBack.appendHTML('<span>HI!</span>', 'after');
2400                 var children = check.getElements('span');
2402                 expect(children.length).to.equal(2);
2403                 children.each(function(child, i){
2404                         expect(child.get('text')).to.equal('HI!');
2405                         expect(child.previousSibling.getAttribute('rel')).to.equal('' + i);
2406                 });
2407         });
2409         it('should insert element on bottom', function(){
2410                 base.appendHTML('<span>HI!</span>', 'bottom');
2411                 baseFallBack.appendHTML('<span>HI!</span>', 'bottom');
2413                 var children = check.getElements('span');
2415                 expect(children.length).to.equal(2);
2416                 children.each(function(child, i){
2417                         expect(child.get('text')).to.equal('HI!');
2418                         expect(child.parentNode.getAttribute('rel')).to.equal('' + i);
2419                         expect(child.parentNode.get('text')).to.equal('contentHI!');
2420                 });
2421         });
2423         it('should insert element on top', function(){
2424                 base.appendHTML('<span>HI!</span>', 'top');
2425                 baseFallBack.appendHTML('<span>HI!</span>', 'top');
2427                 var children = check.getElements('span');
2429                 expect(children.length).to.equal(2);
2430                 children.each(function(child, i){
2431                         expect(child.get('text')).to.equal('HI!');
2432                         expect(child.parentNode.getAttribute('rel')).to.equal('' + i);
2433                         expect(child.parentNode.get('text')).to.equal('HI!content');
2434                 });
2435         });
2437         it('should insert element on inside (bottom)', function(){
2438                 base.appendHTML('<span>HI!</span>', 'inside');
2439                 baseFallBack.appendHTML('<span>HI!</span>', 'inside');
2441                 var children = check.getElements('span');
2443                 expect(children.length).to.equal(2);
2444                 children.each(function(child, i){
2445                         expect(child.get('text')).to.equal('HI!');
2446                         expect(child.parentNode.getAttribute('rel')).to.equal('' + i);
2447                         expect(child.parentNode.get('text')).to.equal('contentHI!');
2448                 });
2449         });
2453 describe('IFrame', function(){
2455         beforeEach(function(done){
2456                 this.onComplete = sinon.spy(function(){ done(); });
2458                 this.iframe = new IFrame({
2459                         src: 'http://' + document.location.host + '/random',
2460                         onload: this.onComplete
2461                 }).inject(document.body);
2462         });
2464         it('(async) should call onload', function(){
2465                 expect(this.onComplete.called).to.equal(true);
2466         }, 1000);
2468         afterEach(function(){
2469                 this.iframe.destroy();
2470         });
2474 describe('new Element(expression)', function(){
2476         it('should create a new div element', function(){
2477                 var div = new Element('div');
2479                 expect(div.tagName.toLowerCase()).to.equal('div');
2480                 expect(!div.className && div.className.length == 0).to.equal(true);
2481                 expect(!div.id && div.id.length == 0).to.equal(true);
2482                 expect(typeOf(div)).to.equal('element');
2483         });
2485         it('should create a new element with id and class', function(){
2486                 var p = new Element('p', {
2487                         id: 'myParagraph',
2488                         'class': 'test className'
2489                 });
2491                 expect(p.tagName.toLowerCase()).to.equal('p');
2492                 expect(p.className).to.equal('test className');
2493         });
2495         it('should create a new element with id and class from css expression', function(){
2496                 var p = new Element('p#myParagraph.test.className');
2498                 expect(p.tagName.toLowerCase()).to.equal('p');
2499                 expect(p.className).to.equal('test className');
2500         });
2502         it('should create attributes from css expression', function(){
2503                 var input = new Element('input[type=text][readonly=true][value=Some Text]');
2505                 expect(input.tagName.toLowerCase()).to.equal('input');
2506                 expect(input.type).to.equal('text');
2507                 expect(input.readOnly).to.equal(true);
2508                 expect(input.value).to.equal('Some Text');
2509         });
2511         it('should overwrite ids and classes', function(){
2512                 var div = new Element('div#myDiv.myClass', {
2513                         id: 'myOverwrittenId',
2514                         'class': 'overwrittenClass'
2515                 });
2517                 expect(div.tagName.toLowerCase()).to.equal('div');
2518                 expect(div.id).to.equal('myOverwrittenId');
2519                 expect(div.className).to.equal('overwrittenClass');
2520         });
2522         it('should overwrite attributes', function(){
2523                 var a = new Element('a[href=http://dojotoolkit.org/]', {
2524                         href: 'http://mootools.net/'
2525                 });
2527                 expect(a.tagName.toLowerCase()).to.equal('a');
2528                 expect(a.href).to.equal('http://mootools.net/');
2529         });
2531         it('should reset attributes and classes with empty string', function(){
2532                 var div = new Element('div#myDiv.myClass', {
2533                         id: '',
2534                         'class': ''
2535                 });
2537                 expect(div.tagName.toLowerCase()).to.equal('div');
2538                 expect(div.id).to.equal('');
2539                 expect(div.className).to.equal('');
2540         });
2542         it('should not reset attributes and classes with null', function(){
2543                 var div = new Element('div#myDiv.myClass', {
2544                         id: null,
2545                         'class': null
2546                 });
2548                 expect(div.tagName.toLowerCase()).to.equal('div');
2549                 expect(div.id).to.equal('myDiv');
2550                 expect(div.className).to.equal('myClass');
2551         });
2553         it('should not reset attributes and classes with undefined', function(){
2554                 var div = new Element('div#myDiv.myClass', {
2555                         id: undefined,
2556                         'class': undefined
2557                 });
2559                 expect(div.tagName.toLowerCase()).to.equal('div');
2560                 expect(div.id).to.equal('myDiv');
2561                 expect(div.className).to.equal('myClass');
2562         });
2564         it('should fall back to a div tag', function(){
2565                 var someElement = new Element('#myId');
2567                 expect(someElement.tagName.toLowerCase()).to.equal('div');
2568                 expect(someElement.id).to.equal('myId');
2569         });
2571         it('should allow zero (0) values', function(){
2572                 var table = new Element('table[cellpadding=0]');
2574                 expect(table.tagName.toLowerCase()).to.equal('table');
2575                 expect(table.cellPadding == 0).to.be.ok();
2576         });
2578         it('should allow empty boolean attributes', function(){
2579                 var script = new Element('script[async]');
2580                 expect(script.get('async')).to.be.ok();
2581         });
2583         it('should allow false to be passed for checked', function(){
2584                 var input = new Element('input', {
2585                         type: 'checkbox',
2586                         checked: false
2587                 });
2589                 expect(input.checked).to.equal(false);
2590         });
2594 describe('Element', function(){
2596         describe('classList', function(){
2598                 it('should not fail for empty strings', function(){
2599                         var element = new Element('div');
2600                         element.addClass('');
2601                         expect(element.className).to.equal('');
2602                 });
2604                 it('should trim whitespaces', function(){
2605                         var element = new Element('div');
2606                         element.addClass(' bar ');
2607                         expect(element.className).to.equal('bar');
2608                 });
2610                 it('should add multiple classes', function(){
2611                         var element = new Element('div');
2612                         element.addClass(' bar foo');
2613                         expect(element.className).to.equal('bar foo');
2614                 });
2616                 it('should add multiple equal classes', function(){
2617                         var element = new Element('div');
2618                         element.addClass('bar bar ');
2619                         expect(element.className).to.equal('bar');
2620                 });
2622                 it('should add class with some newline', function(){
2623                         var element = new Element('div');
2624                         element.addClass('bar\nfoo');
2625                         expect(element.className).to.equal('bar foo');
2626                 });
2628         });
2631 describe('normalize value for new Element type == checkbox || radio', function(){
2633         it('value of new created checkbox should be "on" if none specified', function() {
2634                 var input = new Element('input', {
2635                         type: 'checkbox'
2636                 });
2637                 input.set('checked', true);
2638                 expect(input.get('value')).to.equal('on');
2639         });
2640         it('value of new created checkbox should be the specified in constructor', function() {
2641                 var input = new Element('input', {
2642                         type: 'checkbox',
2643                         value: 'someValue'
2644                 });
2645                 input.set('checked', true);
2646                 expect(input.get('value')).to.equal('someValue');
2647         });
2648         it('value of new created radio button should be "on" if none specified', function() {
2649                 var input = new Element('input', {
2650                         type: 'radio'
2651                 });
2652                 input.set('checked', true);
2653                 expect(input.get('value')).to.equal('on');
2654         });
2655         it('value of new created radio should be the specified in constructor', function() {
2656                 var input = new Element('input', {
2657                         type: 'radio',
2658                         value: 'someValue'
2659                 });
2660                 input.set('checked', true);
2661                 expect(input.get('value')).to.equal('someValue');
2662         });