X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=test%2Funit%2Fcore.js;h=e5339e54c4d2bdd7550bc01e2bbf945a0eaa3e55;hb=bca576550249e9b79b1097669dff6d4ddd0d65cf;hp=f40f3b02ec8c58ddd302bdd891048091b49f6127;hpb=d938c6bbd6b220f122c50f5f828b8f0cd818c168;p=jquery.git diff --git a/test/unit/core.js b/test/unit/core.js index f40f3b0..811d13f 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -8,59 +8,306 @@ test("Basic requirements", function() { ok( document.getElementsByTagName, "getElementsByTagName" ); ok( RegExp, "RegExp" ); ok( jQuery, "jQuery" ); - ok( $, "$()" ); + ok( $, "$" ); }); -test("$()", function() { - expect(5); - - var main = $("#main"); - isSet( $("div p", main).get(), q("sndp", "en", "sap"), "Basic selector with jQuery object as context" ); - +test("jQuery()", function() { + expect(23); + + // Basic constructor's behavior + + equals( jQuery().length, 0, "jQuery() === jQuery([])" ); + equals( jQuery(undefined).length, 0, "jQuery(undefined) === jQuery([])" ); + equals( jQuery(null).length, 0, "jQuery(null) === jQuery([])" ); + equals( jQuery("").length, 0, "jQuery('') === jQuery([])" ); + + var obj = jQuery("div") + equals( jQuery(obj).selector, "div", "jQuery(jQueryObj) == jQueryObj" ); + + // can actually yield more than one, when iframes are included, the window is an array as well + equals( jQuery(window).length, 1, "Correct number of elements generated for jQuery(window)" ); + + + var main = jQuery("#main"); + same( jQuery("div p", main).get(), q("sndp", "en", "sap"), "Basic selector with jQuery object as context" ); + +/* + // disabled since this test was doing nothing. i tried to fix it but i'm not sure + // what the expected behavior should even be. FF returns "\n" for the text node // make sure this is handled - $('

\r\n

'); - ok( true, "Check for \\r and \\n in jQuery()" ); - + var crlfContainer = jQuery('

\r\n

'); + var x = crlfContainer.contents().get(0).nodeValue; + equals( x, what???, "Check for \\r and \\n in jQuery()" ); +*/ + /* // Disabled until we add this functionality in var pass = true; try { - $("
Testing
").appendTo(document.getElementById("iframe").contentDocument.body); + jQuery("
Testing
").appendTo(document.getElementById("iframe").contentDocument.body); } catch(e){ pass = false; } - ok( pass, "$('<tag>') needs optional document parameter to ease cross-frame DOM wrangling, see #968" );*/ + ok( pass, "jQuery('<tag>') needs optional document parameter to ease cross-frame DOM wrangling, see #968" );*/ - var code = $(""); + var code = jQuery(""); equals( code.length, 1, "Correct number of elements generated for code" ); - var img = $(""); + equals( code.parent().length, 0, "Make sure that the generated HTML has no parent." ); + var img = jQuery(""); equals( img.length, 1, "Correct number of elements generated for img" ); - var div = $("

"); + equals( img.parent().length, 0, "Make sure that the generated HTML has no parent." ); + var div = jQuery("

"); equals( div.length, 4, "Correct number of elements generated for div hr code b" ); + equals( div.parent().length, 0, "Make sure that the generated HTML has no parent." ); + + equals( jQuery([1,2,3]).get(1), 2, "Test passing an array to the factory" ); + + equals( jQuery(document.body).get(0), jQuery('body').get(0), "Test passing an html node to the factory" ); + + var exec = false; + + var elem = jQuery("
", { + width: 10, + css: { paddingLeft:1, paddingRight:1 }, + click: function(){ ok(exec, "Click executed."); }, + text: "test", + "class": "test2", + id: "test3" + }); + + equals( elem[0].style.width, '10px', 'jQuery() quick setter width'); + equals( elem[0].style.paddingLeft, '1px', 'jQuery quick setter css'); + equals( elem[0].style.paddingRight, '1px', 'jQuery quick setter css'); + equals( elem[0].childNodes.length, 1, 'jQuery quick setter text'); + equals( elem[0].firstChild.nodeValue, "test", 'jQuery quick setter text'); + equals( elem[0].className, "test2", 'jQuery() quick setter class'); + equals( elem[0].id, "test3", 'jQuery() quick setter id'); + + exec = true; + elem.click(); }); -test("noConflict", function() { - expect(6); +test("selector state", function() { + expect(31); + + var test; + + test = jQuery(undefined); + equals( test.selector, "", "Empty jQuery Selector" ); + equals( test.context, undefined, "Empty jQuery Context" ); + + test = jQuery(document); + equals( test.selector, "", "Document Selector" ); + equals( test.context, document, "Document Context" ); + + test = jQuery(document.body); + equals( test.selector, "", "Body Selector" ); + equals( test.context, document.body, "Body Context" ); + + test = jQuery("#main"); + equals( test.selector, "#main", "#main Selector" ); + equals( test.context, document, "#main Context" ); + + test = jQuery("#notfoundnono"); + equals( test.selector, "#notfoundnono", "#notfoundnono Selector" ); + equals( test.context, document, "#notfoundnono Context" ); + + test = jQuery("#main", document); + equals( test.selector, "#main", "#main Selector" ); + equals( test.context, document, "#main Context" ); + + test = jQuery("#main", document.body); + equals( test.selector, "#main", "#main Selector" ); + equals( test.context, document.body, "#main Context" ); + + // Test cloning + test = jQuery(test); + equals( test.selector, "#main", "#main Selector" ); + equals( test.context, document.body, "#main Context" ); + + test = jQuery(document.body).find("#main"); + equals( test.selector, "#main", "#main find Selector" ); + equals( test.context, document.body, "#main find Context" ); + + test = jQuery("#main").filter("div"); + equals( test.selector, "#main.filter(div)", "#main filter Selector" ); + equals( test.context, document, "#main filter Context" ); + + test = jQuery("#main").not("div"); + equals( test.selector, "#main.not(div)", "#main not Selector" ); + equals( test.context, document, "#main not Context" ); + + test = jQuery("#main").filter("div").not("div"); + equals( test.selector, "#main.filter(div).not(div)", "#main filter, not Selector" ); + equals( test.context, document, "#main filter, not Context" ); + + test = jQuery("#main").filter("div").not("div").end(); + equals( test.selector, "#main.filter(div)", "#main filter, not, end Selector" ); + equals( test.context, document, "#main filter, not, end Context" ); + + test = jQuery("#main").parent("body"); + equals( test.selector, "#main.parent(body)", "#main parent Selector" ); + equals( test.context, document, "#main parent Context" ); + + test = jQuery("#main").eq(0); + equals( test.selector, "#main.slice(0,1)", "#main eq Selector" ); + equals( test.context, document, "#main eq Context" ); - var old = jQuery; - var newjQuery = jQuery.noConflict(); + var d = "
"; + equals( + jQuery(d).appendTo(jQuery(d)).selector, + jQuery(d).appendTo(d).selector, + "manipulation methods make same selector for jQuery objects" + ); +}); + +if ( !isLocal ) { +test("browser", function() { + stop(); + + jQuery.get("data/ua.txt", function(data){ + var uas = data.split("\n"); + expect( (uas.length - 1) * 2 ); + + jQuery.each(uas, function(){ + var parts = this.split("\t"); + if ( parts[2] ) { + var ua = jQuery.uaMatch( parts[2] ); + equals( ua.browser, parts[0], "Checking browser for " + parts[2] ); + equals( ua.version, parts[1], "Checking version string for " + parts[2] ); + } + }); + + start(); + }); +}); +} + +test("noConflict", function() { + expect(7); + + var $$ = jQuery; + + equals( jQuery, jQuery.noConflict(), "noConflict returned the jQuery object" ); + equals( jQuery, $$, "Make sure jQuery wasn't touched." ); + equals( $, original$, "Make sure $ was reverted." ); - ok( newjQuery == old, "noConflict returned the jQuery object" ); - ok( jQuery == old, "Make sure jQuery wasn't touched." ); - ok( $ == "$", "Make sure $ was reverted." ); + jQuery = $ = $$; - jQuery = $ = old; + equals( jQuery.noConflict(true), $$, "noConflict returned the jQuery object" ); + equals( jQuery, originaljQuery, "Make sure jQuery was reverted." ); + equals( $, original$, "Make sure $ was reverted." ); + ok( $$("#main").html("test"), "Make sure that jQuery still works." ); - newjQuery = jQuery.noConflict(true); + jQuery = $$; +}); + +test("trim", function() { + expect(9); + + var nbsp = String.fromCharCode(160); - ok( newjQuery == old, "noConflict returned the jQuery object" ); - ok( jQuery == "jQuery", "Make sure jQuery was reverted." ); - ok( $ == "$", "Make sure $ was reverted." ); + equals( jQuery.trim("hello "), "hello", "trailing space" ); + equals( jQuery.trim(" hello"), "hello", "leading space" ); + equals( jQuery.trim(" hello "), "hello", "space on both sides" ); + equals( jQuery.trim(" " + nbsp + "hello " + nbsp + " "), "hello", " " ); - jQuery = $ = old; + equals( jQuery.trim(), "", "Nothing in." ); + equals( jQuery.trim( undefined ), "", "Undefined" ); + equals( jQuery.trim( null ), "", "Null" ); + equals( jQuery.trim( 5 ), "5", "Number" ); + equals( jQuery.trim( false ), "false", "Boolean" ); +}); + +test("type", function() { + expect(18); + + equals( jQuery.type(null), "null", "null" ); + equals( jQuery.type(undefined), "undefined", "undefined" ); + equals( jQuery.type(true), "boolean", "Boolean" ); + equals( jQuery.type(false), "boolean", "Boolean" ); + equals( jQuery.type(Boolean(true)), "boolean", "Boolean" ); + equals( jQuery.type(0), "number", "Number" ); + equals( jQuery.type(1), "number", "Number" ); + equals( jQuery.type(Number(1)), "number", "Number" ); + equals( jQuery.type(""), "string", "String" ); + equals( jQuery.type("a"), "string", "String" ); + equals( jQuery.type(String("a")), "string", "String" ); + equals( jQuery.type({}), "object", "Object" ); + equals( jQuery.type(/foo/), "regexp", "RegExp" ); + equals( jQuery.type(new RegExp("asdf")), "regexp", "RegExp" ); + equals( jQuery.type([1]), "array", "Array" ); + equals( jQuery.type(new Date()), "date", "Date" ); + equals( jQuery.type(new Function("return;")), "function", "Function" ); + equals( jQuery.type(function(){}), "function", "Function" ); +}); + +test("isPlainObject", function() { + expect(14); + + stop(); + + // The use case that we want to match + ok(jQuery.isPlainObject({}), "{}"); + + // Not objects shouldn't be matched + ok(!jQuery.isPlainObject(""), "string"); + ok(!jQuery.isPlainObject(0) && !jQuery.isPlainObject(1), "number"); + ok(!jQuery.isPlainObject(true) && !jQuery.isPlainObject(false), "boolean"); + ok(!jQuery.isPlainObject(null), "null"); + ok(!jQuery.isPlainObject(undefined), "undefined"); + + // Arrays shouldn't be matched + ok(!jQuery.isPlainObject([]), "array"); + + // Instantiated objects shouldn't be matched + ok(!jQuery.isPlainObject(new Date), "new Date"); + + var fn = function(){}; + + // Functions shouldn't be matched + ok(!jQuery.isPlainObject(fn), "fn"); + + // Again, instantiated objects shouldn't be matched + ok(!jQuery.isPlainObject(new fn), "new fn (no methods)"); + + // Makes the function a little more realistic + // (and harder to detect, incidentally) + fn.prototype = {someMethod: function(){}}; + + // Again, instantiated objects shouldn't be matched + ok(!jQuery.isPlainObject(new fn), "new fn"); + + // DOM Element + ok(!jQuery.isPlainObject(document.createElement("div")), "DOM Element"); + + // Window + ok(!jQuery.isPlainObject(window), "window"); + + try { + var iframe = document.createElement("iframe"); + document.body.appendChild(iframe); + + window.iframeDone = function(otherObject){ + // Objects from other windows should be matched + ok(jQuery.isPlainObject(new otherObject), "new otherObject"); + document.body.removeChild( iframe ); + start(); + }; + + var doc = iframe.contentDocument || iframe.contentWindow.document; + doc.open(); + doc.write(""); + doc.close(); + } catch(e) { + document.body.removeChild( iframe ); + + ok(true, "new otherObject - iframes not supported"); + start(); + } }); test("isFunction", function() { - expect(21); + expect(19); // Make sure that false values return false ok( !jQuery.isFunction(), "No Value" ); @@ -71,10 +318,10 @@ test("isFunction", function() { // Check built-ins // Safari uses "(Internal Function)" - ok( jQuery.isFunction(String), "String Function" ); - ok( jQuery.isFunction(Array), "Array Function" ); - ok( jQuery.isFunction(Object), "Object Function" ); - ok( jQuery.isFunction(Function), "Function Function" ); + ok( jQuery.isFunction(String), "String Function("+String+")" ); + ok( jQuery.isFunction(Array), "Array Function("+Array+")" ); + ok( jQuery.isFunction(Object), "Object Function("+Object+")" ); + ok( jQuery.isFunction(Function), "Function Function("+Function+")" ); // When stringified, this could be misinterpreted var mystr = "function"; @@ -98,7 +345,8 @@ test("isFunction", function() { ok( !jQuery.isFunction(obj), "Object Element" ); // IE says this is an object - ok( jQuery.isFunction(obj.getAttribute), "getAttribute Function" ); + // Since 1.3, this isn't supported (#2968) + //ok( jQuery.isFunction(obj.getAttribute), "getAttribute Function" ); var nodes = document.body.childNodes; @@ -106,7 +354,7 @@ test("isFunction", function() { ok( !jQuery.isFunction(nodes), "childNodes Property" ); var first = document.body.firstChild; - + // Normal elements are reported ok everywhere ok( !jQuery.isFunction(first), "A normal DOM Element" ); @@ -115,7 +363,8 @@ test("isFunction", function() { document.body.appendChild( input ); // IE says this is an object - ok( jQuery.isFunction(input.focus), "A default function property" ); + // Since 1.3, this isn't supported (#2968) + //ok( jQuery.isFunction(input.focus), "A default function property" ); document.body.removeChild( input ); @@ -136,744 +385,336 @@ test("isFunction", function() { ok( jQuery.isFunction(fn), "Recursive Function Call" ); - fn({ some: "data" }); + fn({ some: "data" }); }; callme(function(){ - callme(function(){}); + callme(function(){}); }); }); -var foo = false; - -test("$('html')", function() { +test("isXMLDoc - HTML", function() { expect(4); - - reset(); - foo = false; - var s = $("")[0]; - ok( s, "Creating a script" ); - ok( !foo, "Make sure the script wasn't executed prematurely" ); - $("body").append(s); - ok( foo, "Executing a scripts contents in the right context" ); - - reset(); - ok( $("")[0], "Creating a link" ); - - reset(); -}); - -test("length", function() { - expect(1); - ok( $("p").length == 6, "Get Number of Elements Found" ); -}); -test("size()", function() { - expect(1); - ok( $("p").size() == 6, "Get Number of Elements Found" ); -}); + ok( !jQuery.isXMLDoc( document ), "HTML document" ); + ok( !jQuery.isXMLDoc( document.documentElement ), "HTML documentElement" ); + ok( !jQuery.isXMLDoc( document.body ), "HTML Body Element" ); -test("get()", function() { - expect(1); - isSet( $("p").get(), q("firstp","ap","sndp","en","sap","first"), "Get All Elements" ); -}); + var iframe = document.createElement("iframe"); + document.body.appendChild( iframe ); -test("get(Number)", function() { - expect(1); - ok( $("p").get(0) == document.getElementById("firstp"), "Get A Single Element" ); -}); + try { + var body = jQuery(iframe).contents()[0]; -test("add(String|Element|Array)", function() { - expect(7); - isSet( $("#sndp").add("#en").add("#sap").get(), q("sndp", "en", "sap"), "Check elements from document" ); - isSet( $("#sndp").add( $("#en")[0] ).add( $("#sap") ).get(), q("sndp", "en", "sap"), "Check elements from document" ); - ok( $([]).add($("#form")[0].elements).length >= 13, "Check elements from array" ); - - var x = $([]).add($("

xxx

")).add($("

xxx

")); - ok( x[0].id == "x1", "Check on-the-fly element1" ); - ok( x[1].id == "x2", "Check on-the-fly element2" ); - - var x = $([]).add("

xxx

").add("

xxx

"); - ok( x[0].id == "x1", "Check on-the-fly element1" ); - ok( x[1].id == "x2", "Check on-the-fly element2" ); -}); + try { + ok( !jQuery.isXMLDoc( body ), "Iframe body element" ); + } catch(e) { + ok( false, "Iframe body element exception" ); + } -test("each(Function)", function() { - expect(1); - var div = $("div"); - div.each(function(){this.foo = 'zoo';}); - var pass = true; - for ( var i = 0; i < div.size(); i++ ) { - if ( div.get(i).foo != "zoo" ) pass = false; + } catch(e) { + ok( true, "Iframe body element - iframe not working correctly" ); } - ok( pass, "Execute a function, Relative" ); -}); - -test("index(Object)", function() { - expect(8); - ok( $([window, document]).index(window) == 0, "Check for index of elements" ); - ok( $([window, document]).index(document) == 1, "Check for index of elements" ); - var inputElements = $('#radio1,#radio2,#check1,#check2'); - ok( inputElements.index(document.getElementById('radio1')) == 0, "Check for index of elements" ); - ok( inputElements.index(document.getElementById('radio2')) == 1, "Check for index of elements" ); - ok( inputElements.index(document.getElementById('check1')) == 2, "Check for index of elements" ); - ok( inputElements.index(document.getElementById('check2')) == 3, "Check for index of elements" ); - ok( inputElements.index(window) == -1, "Check for not found index" ); - ok( inputElements.index(document) == -1, "Check for not found index" ); -}); -test("attr(String)", function() { - expect(20); - ok( $('#text1').attr('value') == "Test", 'Check for value attribute' ); - ok( $('#text1').attr('value', "Test2").attr('defaultValue') == "Test", 'Check for defaultValue attribute' ); - ok( $('#text1').attr('type') == "text", 'Check for type attribute' ); - ok( $('#radio1').attr('type') == "radio", 'Check for type attribute' ); - ok( $('#check1').attr('type') == "checkbox", 'Check for type attribute' ); - ok( $('#simon1').attr('rel') == "bookmark", 'Check for rel attribute' ); - ok( $('#google').attr('title') == "Google!", 'Check for title attribute' ); - ok( $('#mark').attr('hreflang') == "en", 'Check for hreflang attribute' ); - ok( $('#en').attr('lang') == "en", 'Check for lang attribute' ); - ok( $('#simon').attr('class') == "blog link", 'Check for class attribute' ); - ok( $('#name').attr('name') == "name", 'Check for name attribute' ); - ok( $('#text1').attr('name') == "action", 'Check for name attribute' ); - ok( $('#form').attr('action').indexOf("formaction") >= 0, 'Check for action attribute' ); - ok( $('#text1').attr('maxlength') == '30', 'Check for maxlength attribute' ); - ok( $('#text1').attr('maxLength') == '30', 'Check for maxLength attribute' ); - ok( $('#area1').attr('maxLength') == '30', 'Check for maxLength attribute' ); - ok( $('#select2').attr('selectedIndex') == 3, 'Check for selectedIndex attribute' ); - ok( $('#foo').attr('nodeName') == 'DIV', 'Check for nodeName attribute' ); - ok( $('#foo').attr('tagName') == 'DIV', 'Check for tagName attribute' ); - - $('').attr('href', '#5').appendTo('#main'); // using innerHTML in IE causes href attribute to be serialized to the full path - ok( $('#tAnchor5').attr('href') == "#5", 'Check for non-absolute href (an anchor)' ); + document.body.removeChild( iframe ); }); if ( !isLocal ) { - test("attr(String) in XML Files", function() { - expect(2); - stop(); - $.get("data/dashboard.xml", function(xml) { - ok( $("locations", xml).attr("class") == "foo", "Check class attribute in XML document" ); - ok( $("location", xml).attr("for") == "bar", "Check for attribute in XML document" ); - start(); - }); - }); +test("isXMLDoc - XML", function() { + expect(3); + stop(); + jQuery.get('data/dashboard.xml', function(xml) { + ok( jQuery.isXMLDoc( xml ), "XML document" ); + ok( jQuery.isXMLDoc( xml.documentElement ), "XML documentElement" ); + ok( jQuery.isXMLDoc( jQuery("tab", xml)[0] ), "XML Tab Element" ); + start(); + }); +}); } -test("attr(String, Function)", function() { - expect(2); - ok( $('#text1').attr('value', function() { return this.id })[0].value == "text1", "Set value from id" ); - ok( $('#text1').attr('title', function(i) { return i }).attr('title') == "0", "Set value with an index"); -}); +test("jQuery('html')", function() { + expect(15); -test("attr(Hash)", function() { - expect(1); - var pass = true; - $("div").attr({foo: 'baz', zoo: 'ping'}).each(function(){ - if ( this.getAttribute('foo') != "baz" && this.getAttribute('zoo') != "ping" ) pass = false; - }); - ok( pass, "Set Multiple Attributes" ); -}); + QUnit.reset(); + jQuery.foo = false; + var s = jQuery("")[0]; + ok( s, "Creating a script" ); + ok( !jQuery.foo, "Make sure the script wasn't executed prematurely" ); + jQuery("body").append(""); + ok( jQuery.foo, "Executing a scripts contents in the right context" ); -test("attr(String, Object)", function() { - expect(16); - var div = $("div"); - div.attr("foo", "bar"); - var pass = true; - for ( var i = 0; i < div.size(); i++ ) { - if ( div.get(i).getAttribute('foo') != "bar" ) pass = false; - } - ok( pass, "Set Attribute" ); + // Test multi-line HTML + var div = jQuery("
\r\nsome text\n

some p

\nmore text\r\n
")[0]; + equals( div.nodeName.toUpperCase(), "DIV", "Make sure we're getting a div." ); + equals( div.firstChild.nodeType, 3, "Text node." ); + equals( div.lastChild.nodeType, 3, "Text node." ); + equals( div.childNodes[1].nodeType, 1, "Paragraph." ); + equals( div.childNodes[1].firstChild.nodeType, 3, "Paragraph text." ); - ok( $("#foo").attr({"width": null}), "Try to set an attribute to nothing" ); - - $("#name").attr('name', 'something'); - ok( $("#name").attr('name') == 'something', 'Set name attribute' ); - $("#check2").attr('checked', true); - ok( document.getElementById('check2').checked == true, 'Set checked attribute' ); - $("#check2").attr('checked', false); - ok( document.getElementById('check2').checked == false, 'Set checked attribute' ); - $("#text1").attr('readonly', true); - ok( document.getElementById('text1').readOnly == true, 'Set readonly attribute' ); - $("#text1").attr('readonly', false); - ok( document.getElementById('text1').readOnly == false, 'Set readonly attribute' ); - $("#name").attr('maxlength', '5'); - ok( document.getElementById('name').maxLength == '5', 'Set maxlength attribute' ); - $("#name").attr('maxLength', '10'); - ok( document.getElementById('name').maxLength == '10', 'Set maxlength attribute' ); - - // for #1070 - $("#name").attr('someAttr', '0'); - equals( $("#name").attr('someAttr'), '0', 'Set attribute to a string of "0"' ); - $("#name").attr('someAttr', 0); - equals( $("#name").attr('someAttr'), 0, 'Set attribute to the number 0' ); - $("#name").attr('someAttr', 1); - equals( $("#name").attr('someAttr'), 1, 'Set attribute to the number 1' ); - - reset(); - - var type = $("#check2").attr('type'); - var thrown = false; - try { - $("#check2").attr('type','hidden'); - } catch(e) { - thrown = true; - } - ok( thrown, "Exception thrown when trying to change type property" ); - equals( type, $("#check2").attr('type'), "Verify that you can't change the type of an input element" ); + QUnit.reset(); + ok( jQuery("")[0], "Creating a link" ); - var check = document.createElement("input"); - var thrown = true; - try { - $(check).attr('type','checkbox'); - } catch(e) { - thrown = false; - } - ok( thrown, "Exception thrown when trying to change type property" ); - equals( "checkbox", $(check).attr('type'), "Verify that you can change the type of an input element that isn't in the DOM" ); -}); + ok( !jQuery("'); + equals( jQuery.makeArray([1,2,3]).join(""), "123", "Pass makeArray a real array" ); - $("#main").html('foo
'); + equals( jQuery.makeArray().length, 0, "Pass nothing to makeArray and expect an empty array" ); - $("#main").html("