michael@0: var browser; michael@0: michael@0: function doc() browser.contentDocument; michael@0: michael@0: function setHandlerFunc(aResultFunc) { michael@0: gBrowser.addEventListener("DOMLinkAdded", function (event) { michael@0: gBrowser.removeEventListener("DOMLinkAdded", arguments.callee, false); michael@0: executeSoon(aResultFunc); michael@0: }, false); michael@0: } michael@0: michael@0: function test() { michael@0: waitForExplicitFinish(); michael@0: michael@0: gBrowser.selectedTab = gBrowser.addTab(); michael@0: browser = gBrowser.selectedBrowser; michael@0: browser.addEventListener("load", function (event) { michael@0: event.currentTarget.removeEventListener("load", arguments.callee, true); michael@0: iconDiscovery(); michael@0: }, true); michael@0: var rootDir = getRootDirectory(gTestPath); michael@0: content.location = rootDir + "discovery.html"; michael@0: } michael@0: michael@0: var iconDiscoveryTests = [ michael@0: { text: "rel icon discovered" }, michael@0: { rel: "abcdefg icon qwerty", text: "rel may contain additional rels separated by spaces" }, michael@0: { rel: "ICON", text: "rel is case insensitive" }, michael@0: { rel: "shortcut-icon", pass: false, text: "rel shortcut-icon not discovered" }, michael@0: { href: "moz.png", text: "relative href works" }, michael@0: { href: "notthere.png", text: "404'd icon is removed properly" }, michael@0: { href: "data:image/x-icon,%00", type: "image/x-icon", text: "data: URIs work" }, michael@0: { type: "image/png; charset=utf-8", text: "type may have optional parameters (RFC2046)" } michael@0: ]; michael@0: michael@0: function runIconDiscoveryTest() { michael@0: var test = iconDiscoveryTests[0]; michael@0: var head = doc().getElementById("linkparent"); michael@0: var hasSrc = gBrowser.getIcon() != null; michael@0: if (test.pass) michael@0: ok(hasSrc, test.text); michael@0: else michael@0: ok(!hasSrc, test.text); michael@0: michael@0: head.removeChild(head.getElementsByTagName('link')[0]); michael@0: iconDiscoveryTests.shift(); michael@0: iconDiscovery(); // Run the next test. michael@0: } michael@0: michael@0: function iconDiscovery() { michael@0: if (iconDiscoveryTests.length) { michael@0: setHandlerFunc(runIconDiscoveryTest); michael@0: gBrowser.setIcon(gBrowser.selectedTab, null); michael@0: michael@0: var test = iconDiscoveryTests[0]; michael@0: var head = doc().getElementById("linkparent"); michael@0: var link = doc().createElement("link"); michael@0: michael@0: var rootDir = getRootDirectory(gTestPath); michael@0: var rel = test.rel || "icon"; michael@0: var href = test.href || rootDir + "moz.png"; michael@0: var type = test.type || "image/png"; michael@0: if (test.pass == undefined) michael@0: test.pass = true; michael@0: michael@0: link.rel = rel; michael@0: link.href = href; michael@0: link.type = type; michael@0: head.appendChild(link); michael@0: } else { michael@0: searchDiscovery(); michael@0: } michael@0: } michael@0: michael@0: var searchDiscoveryTests = [ michael@0: { text: "rel search discovered" }, michael@0: { rel: "SEARCH", text: "rel is case insensitive" }, michael@0: { rel: "-search-", pass: false, text: "rel -search- not discovered" }, michael@0: { rel: "foo bar baz search quux", text: "rel may contain additional rels separated by spaces" }, michael@0: { href: "https://not.mozilla.com", text: "HTTPS ok" }, michael@0: { href: "ftp://not.mozilla.com", text: "FTP ok" }, michael@0: { href: "data:text/foo,foo", pass: false, text: "data URI not permitted" }, michael@0: { href: "javascript:alert(0)", pass: false, text: "JS URI not permitted" }, michael@0: { type: "APPLICATION/OPENSEARCHDESCRIPTION+XML", text: "type is case insensitve" }, michael@0: { type: " application/opensearchdescription+xml ", text: "type may contain extra whitespace" }, michael@0: { type: "application/opensearchdescription+xml; charset=utf-8", text: "type may have optional parameters (RFC2046)" }, michael@0: { type: "aapplication/opensearchdescription+xml", pass: false, text: "type should not be loosely matched" }, michael@0: { rel: "search search search", count: 1, text: "only one engine should be added" } michael@0: ]; michael@0: michael@0: function runSearchDiscoveryTest() { michael@0: var test = searchDiscoveryTests[0]; michael@0: var title = test.title || searchDiscoveryTests.length; michael@0: if (browser.engines) { michael@0: var hasEngine = (test.count) ? (browser.engines[0].title == title && michael@0: browser.engines.length == test.count) : michael@0: (browser.engines[0].title == title); michael@0: ok(hasEngine, test.text); michael@0: browser.engines = null; michael@0: } michael@0: else michael@0: ok(!test.pass, test.text); michael@0: michael@0: searchDiscoveryTests.shift(); michael@0: searchDiscovery(); // Run the next test. michael@0: } michael@0: michael@0: // This handler is called twice, once for each added link element. michael@0: // Only want to check once the second link element has been added. michael@0: var ranOnce = false; michael@0: function runMultipleEnginesTestAndFinalize() { michael@0: if (!ranOnce) { michael@0: ranOnce = true; michael@0: return; michael@0: } michael@0: ok(browser.engines, "has engines"); michael@0: is(browser.engines.length, 1, "only one engine"); michael@0: is(browser.engines[0].uri, "http://first.mozilla.com/search.xml", "first engine wins"); michael@0: michael@0: gBrowser.removeCurrentTab(); michael@0: finish(); michael@0: } michael@0: michael@0: function searchDiscovery() { michael@0: var head = doc().getElementById("linkparent"); michael@0: michael@0: if (searchDiscoveryTests.length) { michael@0: setHandlerFunc(runSearchDiscoveryTest); michael@0: var test = searchDiscoveryTests[0]; michael@0: var link = doc().createElement("link"); michael@0: michael@0: var rel = test.rel || "search"; michael@0: var href = test.href || "http://so.not.here.mozilla.com/search.xml"; michael@0: var type = test.type || "application/opensearchdescription+xml"; michael@0: var title = test.title || searchDiscoveryTests.length; michael@0: if (test.pass == undefined) michael@0: test.pass = true; michael@0: michael@0: link.rel = rel; michael@0: link.href = href; michael@0: link.type = type; michael@0: link.title = title; michael@0: head.appendChild(link); michael@0: } else { michael@0: setHandlerFunc(runMultipleEnginesTestAndFinalize); michael@0: setHandlerFunc(runMultipleEnginesTestAndFinalize); michael@0: // Test multiple engines with the same title michael@0: var link = doc().createElement("link"); michael@0: link.rel = "search"; michael@0: link.href = "http://first.mozilla.com/search.xml"; michael@0: link.type = "application/opensearchdescription+xml"; michael@0: link.title = "Test Engine"; michael@0: var link2 = link.cloneNode(false); michael@0: link2.href = "http://second.mozilla.com/search.xml"; michael@0: michael@0: head.appendChild(link); michael@0: head.appendChild(link2); michael@0: } michael@0: }